• OK, I just fell in 😍 with stdlib’s Result(catching:).

    extension Request where Response: Decodable {
        func handle(response: Result<Data, Error>, 
                              completion: (Result<Response, Error>) -> Void) {
            completion(Result { 
                try JSONDecoder().decode(Response.self, from: response.get())
            })
        }
    }
    
  • Reminder: If you’re running into limitations with default parameters (for example, the value can’t be computed, they can’t specialize a generic, defaults don’t exist in literals), you can always replace a default with an explicit overload.

    func f(x: Int = 0) {}
    

    is the same as

    func f(x: Int) {}
    func f() { f(0) }
    

    stackoverflow.com/questions…

  • One of these days I’ll remember not to delete the app that Xcode is debugging. Sometimes it’s fine. Lots of times it hangs Xcode and I have to force quit. Days since I forgot: 0

  • I’m finally to that comfortable part in Horizon (~level 43, all overrides unlocked, upgraded spear, lots of Shadow armor) where I’m powerful enough to take on most anything I wander across without much trouble, so I can do what I love to do.

    Hunt for flowers. Climb to vistas. Collect little statues.

    I’ll get back to the big important saving the world part soon enough. But there’s this town being hassled by bandits, and a worried father who doesn’t know where his daughter is, and I can just fix that for them.

  • CBPeripheral is much more KVO compliant than I expected. I figured you had to implement the delegate to learn about its changes, but, not so much.

    But…it does yell at you about API misuse if you don’t implement the delegate (which is proably smart, because you need the error).

  • One reason it’s hard to teach PATs is the most famous PAT is Collection, and every common impl of Collection is also generic, which makes things confusing. Looking for a common PAT where most impls aren’t generic. One example is Equatable, but it’s more confusing to explain.

  • Periodic PSA (because I forgot again and was about to complain about it…): When you’re missing header files, remember that Xcode’s “Generated Interface” is very similar. I’m sure there’s some way it fails me, but…actually it’s kind of fine as I get used to it.

  • I love throws. I know many people don’t, and I get it. It’s immature, and I’m very impatient for coroutines. Without async/await, throws is a weird little cul-de-sac that you have to constantly lift into Result. (If you’re lifting into (Value?, Error?), just stop it. Stop it. Unless you have the unusual case where both could be non-nil, that’s just wrong.)

    I write a lot of Result-based code, and it’s cool and all, and I teach it because it’s an important part of Swift today (and deep down it’s a very beautiful idea). But all those beautiful composition features require closures and closures mean what-kind-of-self-oh-no-weak hell, and frankly I think it’s a mess in Swift and I think it will always be a mess in Swift because Swift will (I’m pretty willing to bet) never be garbage collected, and all those FP composition techniques were designed on a Lisp machine where cyclic garbage collection is like breathing. (I’m not making any argument here for GC. That’s its own can of worms.)

    But when you have a whole system that uses throws (and is synchronous, and doesn’t have to interact with anything that doesn’t use throws), I love it. All that weird ?? and guard let that you have all over the place in Optional code evaporate. Low-level things generate errors. High level things handle errors. Mid-level things get to ignore it.

    And I’m glad that throws currently is untyped. I love types. I love them so much. And I hope some day Swift has a typed throws for the cases where it’s useful (and there are important cases where it is). But for most of my systems, untyped throws is so much better. So thanks for that.

    So anyway, I don’t get to use throws as often as I’d like, because “a little” throws is obnoxious. It’s a pain to convert to-and-from other systems, and it’s annoying to have to create a special Error type for every little thing. You don’t get any of that cost back if you only have one or two methods doing it. But when you have a whole system…yeah, it’s a nice design.

    Please coroutines soon. Please.

  • I thought I could live with going back to Xcode 9 while I wait for the fix to 10b5 for Crashlytics. But…I can’t do it. Xcode 10 is too good. Rolling back to b4.

  • I’m usually very sanguine about my stock strategy of “stick to the plan, don’t try to time the market.” And it generally works out to the good as often as it fails, which is the whole point. But I’m kind of worked up over a sale I just made, according to plan, right at a local minimum. I missed out on about $600, which is much smaller than the amounts I’ve made or lost in the past following the plan, and less than the amount I’ve made on that stock anyway. But…dang it. It’s up over 3.5% the day after I sold. Privileged problems, but still. Dang it.

  • I’m tempted to say (which is to say I’m wrong, but maybe there’s something to be learned by pretending it’s true) that everyone should build their own little reactive framework from scratch.

    They’re not that hard to build (if you keep it simple to start). My latest work is in a one-file gist. But there are so many subtleties. It just became very clear to me why RxSwift’s Variable requires you to call asObserverable() on it before you can treat it as an Observable. Why not just have it be an Observable I asked? So I built a system like that. And it actually works fine…for a while. And then you hit the little tricky bits where things don’t compose the way you think they would. (See the now commented-out LatchedStream.)

    The lesson I’m learning (by doing) is that mutable state can actually be pretty simple (heresy I know, but simple mutable state maps quite naturally to common intuition and is a powerful tool that is excessively maligned, but that’s another posting). And streams of values can be pretty simple. But trying to blur them together; the desire that leads to creating Variable in the first place, is a bit a minefield. I see why RxSwift has deprecated it.

    But it’s so much easier to use for some things; it’s hard to give up.

  • The things you learn digging into compiler output

    Consider the line of code, creating a global variable:

    let keys = ["s3kretSkwarl", "Ha!U'llNevar(Find)Me", ...] // the rest doesn't matter
    

    Archive your app. Grep for “Nevar”. Shows up, just like you’d think. Sure. Grep for “s3kret”. Nothing?!?!?!! How is that possible? The program even calls print(keys) at one point, so the characters have to be in there somewhere. I hunt and hunt, and then I find them.

    movz       x8, #'wa'
    movk       x8, #'rl', lsl #16
    movk       x8, #'\x00\xec', lsl #48
    movz       x9, #'s3'
    movk       x9, #'kr', lsl #16
    movk       x9, #'et', lsl #32
    movk       x9, #'Sk', lsl #48
    stp        x8, x9, [x0, #0x20]
    adr        x8, #0x1000067d0 ; "Ha!U'llNevar(Find)Me"
    

    While longer strings are stored in the strings section, apparently shorter strings sometimes are inlined with move instructions. Did not expect that. I expected this for strings shorter than 8 characters (due to tagged pointers), but this is a 12 character string. It takes about 9 instructions to get it in place, but I’m guessing that’s better than storing it in the Strings section.

    I am such a novice at understanding ARM assembly. I always feel like I’m wandering around, knocking over shiney things, with no idea what’s the grown-ups have built.


    UPDATE: My expected turn takes an unexpected turn: It’s possible it’s an optimizer bug.

  • From a new, irregular series, “Rejected Presentation Slides.”

  • Note to self: you’re doing too much in one object again. That’s why it’s gotten so crazy complicated.

  • I’m always on the lookout for places where contributions at my level can make a big impact. The Bail Project (bailproject.org) is now top of my list. There are so many deep problems beneath the one their attacking, but when “just throw money at it” can fix a problem this big, throw money.

  • Spent so much time practicing bass guitar today that I can barely type. Seriously, my left little finger keeps missing the ‘a’ and I have to go back and type it with another finger. So I guess it’s a good day and time for bed. :D

  • Today I finally get back to studying bass guiar. I’ve really enjoyed the lessons at Talking Bass. I find having some structure to be really useful.

  • I admit, I still have some nervousness after App.net, but maybe it’s time to give another idea a try.

subscribe via RSS