Swift: The joys of cascading lets

Today, I wrote a fortune shell script to demonstrate how Swift could be used for scripting without having to build an entire application. I ended up using cascading let statements in a way I haven’t really to date. When 1.2 introduced these to “avoid the pyramid of doom”, I didn’t quite see how well they created a readable stack of steps.

What’s particularly interesting to me is how these steps short-cut the normal call/test for error/respond-to-error Cocoa-y flow of things. If any step fails, everything fails, leading to a central fail point (return nil). Explaining what went wrong isn’t easy to detail any further unless all the calls subscribe to an NSError** pattern.

The if-statement feels a little like an overstuffed turkey, which is not necessarily a good feeling when writing code.  I’m still trying to decide if I love this or not.


  • I think you’ll grow to love it. Scott Wlaschin has started describing this pattern as “railway-oriented programming” (http://fsharpforfunandprofit.com/posts/recipe-part2/) and it can be generalized to apply to many situations. For instance, I am currently using an `Either` variation that allows functions to return “either” a `Success<T>` or a `Failure<U>` so the `Failure` is parameterized so that it contains a reason (perhaps a string, perhaps an errorcode, etc.). In the same way that you do not have to check every time for nil or errorcode in your code, my code *reads* like it’s solely concerned with the `Success` track (what Eric Meijer calls “the happy path”), but in fact, at the end of the expression, if at one point something produced a `Failure`, it’s been propagated along perfectly.

  • A problem, as I see it, appears when you want to know why the failure happened.