Swift TIL 12

Posted on 2020-07-18 10:16 +0100 in TIL • 3 min read

First a small aside: To be honest, the T part of TIL is getting to be less and less true with this series of posts, but the posts themselves serve a useful purpose for me. As I've been reading the book I'm working through, I've also been making notes on my iPad in the Apple Notes application. I'm not really convinced that that's the best final location for such notes, so early on I made an extra step in keeping track of what I'm doing and trying to reinforce what I'm learning: transfer the notes into Org-Mode documents in my notebook repository.

This repository contains lots of Org-Mode files, broken down into subject directories, that hang on to longer-form information I want to keep track of regarding software development and general operating system use. I'm sure you know the sort of thing, the things where you know you know them but you can't always retain all the detail -- so having the detail where you know you'll find it is useful.

So I've made that part of the process: read book, find thing worth noting, note in Apple Notes, a wee while later re-read and test out by writing sample code and transfer to the Org-Mode notebook. During that latter step I sometimes also write up something that I really liked or found interesting here to further reinforce the learning process.

The "TIL" I wanted to note quickly today is how happy I was to see that Swift has something that's a reasonably recent addition to Emacs Lisp: conditional binding. Skipping off into Emacs Lisp for a moment, it would be very common for me to find myself writing something like this (this actually happens in all languages really):

(let ((foo (get-something-from-elsewhere)))
  (when foo
    (do-something-with foo)))

Quite simply: I'd get a value from elsewhere, that value could possibly be nil to mark that there was a failure to get a value, but that failure wasn't in any way fatal or even a problem worthy of note: I just needed to skip along. But that binding followed by the test was always a little jarring. And then, back in 25.1, if-let and when-let got added (of course, this being Lisp, it would have been very simple to add them anyway), and it was easier to write the code so it looked just a little nicer:

(when-let ((foo (get-something-from-elsewhere)))
  (do-something-with foo))

It's a small difference, but I find it a pleasing one.

So of course I was pleased to find that Swift has something similar with if and Optional values, where you can write something like:

if let foo = getSomethingFromElsewhere() {
    // Do something with foo but only if it's not nil
}

Which means you can do things like this (not that I'd really do things like this, but it was a handy test on the command line):

func oddRand() -> Int? {

    let n = Int.random( in: 0...99 )

    if n % 2 == 0 {
        return nil
    }

    return n
}

for _ in 0...10 {
    if let n = oddRand() {
        print( n )
    } else {
        print( "Nope" )
    }
}

As usual... of course that's horrible code, it was just thrown together to test/experience the language feature on the command line.

I like it though. I figure all the best languages have conditional binding. ;-)