Ryan Booker
About Archive Replies Photos Search Stats Also on Micro.blog
  • → 7:24 AM, Jun 24
  • → 7:24 AM, Jun 24
  • → 12:02 PM, Jun 23
  • → 12:01 PM, Jun 23
  • → 12:01 PM, Jun 23
  • → 12:01 PM, Jun 23
  • → 12:04 PM, Jun 22
  • Anyone know what day it is?

    → 4:02 AM, Jun 21
  • Half way.

    → 7:26 PM, Jun 20
  • Here we go.

    → 2:15 AM, Jun 20
  • In 2016, I joined the Lipari Acheo Project for Global Underwater Explorers and the Soprintendenza del Mare of Sicily, cataloguing and mapping the “Capistello Bay” wreck, a greek cargo ship from around 300 BC.

    An amazing experience. I’m excited to rejoin the project this week.

    → 2:04 PM, Jun 19
  • → 1:44 AM, Jun 17
  • → 1:44 AM, Jun 17
  • → 1:10 AM, Jun 17
  • I like your style, Aldi.

    → 3:18 AM, Jun 12
  • Devices backed up. Betas installed. WWDC is always fun. Sometimes terrifying. But always fun.

    → 3:51 PM, Jun 5
  • I tried writing something profound. I couldn’t.

    If you have the means, please consider helping my friend Cassie in her fight against brain cancer.

    → 11:11 AM, May 29
  • Solo was fucking great.

    → 2:44 AM, May 24
  • I recently rediscovered Lego, thanks to my nephews. Hands down the greatest of all “toys”. I wonder if my parents still have the bin full I had as kid? I’ve started a new collection in any event…

    → 9:06 AM, May 18
  • C. S. Lewis, foreshadowing:

    Of all tyrannies, a tyranny sincerely exercised for the good of its victims may be the most oppressive. It would be better to live under robber barons than under omnipotent moral busybodies. The robber baron's cruelty may sometimes sleep, his cupidity may at some point be satiated; but those who torment us for our own good will torment us without end for they do so with the approval of their own conscience. They may be more likely to go to Heaven yet at the same time likelier to make a Hell of earth. This very kindness stings with intolerable insult. To be "cured" against one's will and cured of states which we may not regard as disease is to be put on a level of those who have not yet reached the age of reason or those who never will; to be classed with infants, imbeciles, and domestic animals.
    → 8:32 PM, May 13
  • A difference in perspective

    Recently, Erica Sadun wrote about inconsistencies in Swift’s function-like constructs, such as KeyPath and method references—a post that appears lost in the apocalypse befalling her site.

    Erica pointed out that method references return (A) -> () -> B functions that aren’t directly useable by higher order functions like map, which takes an (A) -> B function.

    // Basic example
    ["a", "b"].map { "a".uppercased() } // ["A", "B"]
    
    // Using a method reference. Hmm. Not quite what we wanted
    ["a", "b"].map(String.uppercased) // [() -> String, () -> String]
    
    // Junky alternatives
    ["a", "b"].map(String.uppercased).map { $0() }
    ["a", "b"].map { String.uppercased($0)() }
    

    She then works through a couple of solutions. A custom map style function on Sequence taking such a function and hiding the extra function application, and eventually an apply function that converts (A) -> () -> B to (A) -> B (and an accompanying operator).

    One thing that struct me was how Erica derived all this from first principles, essentially reimplementing a function called flip, a common function in functional programming circles. From my perspective I immediately saw the problem as:

    Oh, I need to flip this function and partially apply it to ()

    Unfortunately, because we’re using Swift, it’s not quite that easy.

    func flip<A, B, C>(f: (A) -> (B) -> C) -> (B) -> (A) -> C {
        return { b in { a in f(a)(b) } }
    }
    
    // Doesn't compile! For a couple of Swiftastic reasons.
    ["a", "b"].map(flip(String.uppercased)())
    

    Swift treats () parameters as a special case, not just another type, so () can not be used as a B. Let’s write a special case version:

    func flip<A, B>(_ f: @escaping (A) -> () -> B) -> () -> (A) -> B {
        return { { a in f(a)() } }
    }
    
    // This one does compile! Though you may notice it looks to have some redundancy.
    ["a", "b"].map(flip(String.uppercased)())
    

    And we can now reimplement Erica’s apply in terms of our special case of flip:

    func flap<A, B>(_ f: @escaping (A) -> () -> B) -> (A) -> B {
        return flip(f)()
    }
    
    ["a", "b"].map(flap(String.uppercased))
    

    Or just remove the intermediary special case of flip altogether, arriving at exactly Erica’s solution (operator not withstanding):

    func flap<A, B>(_ f: @escaping (A) -> () -> B) -> (A) -> B {
        return { a in f(a)() }
    }
    
    ["a", "b"].map(flap(String.uppercased))
    

    In the end, we’ve arrived at the same solution to this specific problem. However, I hope I’ve illustrated how viewing programming from a slightly different perspective let us identify the issue quickly, and build a solution out of existing smaller, composeable pieces.

    → 3:31 PM, May 4
  • Michael Shermer on how Classical Liberalism might heal the bonds of our affection.

    → 4:00 PM, May 1
  • Boo! Ze Frank narrates a True Facts nature documentary on Frog Fish.

    → 7:36 AM, Apr 26
  • How should I frame this? Selecting better video frames for photogrammetry

    Sometimes my spheres of interest overlap.

    Meeting Matt Carter at OzTek a couple of years ago, and working with Pim Bongaerts on mesophotic.org introduced me to photogrammetry, and over the past few weeks I’ve been processing some models using 4K video.

    Selecting useable still frames is tedious at best: manual selection is a non starter, and basic selection with ffmpeg often produces blurred frames.

    I solved this with framer.sh, a script for selecting better frames.

    Feel free to use and improve it. Pull requests accepted.

    → 3:48 PM, Apr 20
  • Today I discovered GNU Parallel, and I don’t know what to do with all this spare time.

    → 9:07 PM, Apr 19
← Newer Posts Page 8 of 10 Older Posts →
  • RSS
  • JSON Feed