Swift: Configuring a Constant Using Shorthand Argument Names

There is a tweet going around on initializing constants in Swift using positional references:

The original code is here.

Since it is an ephemeral tweet, and I was confused when it didn’t work as I expected on first glance, I wanted to write a more permanent blog post on the topic here.

The Problem

It’s a common pattern in Swift (and a really nice one!) to configure constants right when they are initialized in a closure vs later on in a viewDidLoad or another such method:

I’ve always found it kind of awkward to name another UIView in the closure. Now there is a “purpleView” and a “view”. Should “view” actually be named “purpleView” also? I haven’t figured out a good solution for the naming problem here.

The Solution

So I was super excited to see the tweet that uses $0 instead of bothering to name the variable! I immediately tried it like this:

But it didn’t work… Upon closer inspection of @ericasadun’s code, I learned that I had to pass in the initialized UIView when the closure is executed:

This of course makes a lot of sense!


I do really like the idea of using $0 here instead of explicitly naming the thing, but I’m upset that it didn’t come naturally to me. However, now that I know I have to pass in an initialized UIView() in there, it does logically make sense. I think I’ll use this in the future. Getting to use $0 here is just too beautiful not to!

Join me for a Swift Community Celebration 🎉 in New York City on September 1st and 2nd. Use code NATASHATHEROBOT to get $100 off!


As @khanlou pointed out, there is a super cool library called Then to make this even more readable and better:

While I’m not a fan of adding this library as a dependency to my project, @khanlou pointed out once again that it’s only 15 lines of code. So I’ll definitely consider copying this over manually into my project!

Make sure to also check out @ericasadun’s nice solution!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • ioc

    You can also check out my solution here: https://github.com/illusionofchaos/swift-package-bullet

  • I like the approach a lot. However if I refer to self within the closure outside of viewDidLoad in the object’s declaration scope I get a weird compiler error “Cannot convert value of type ‘NSObject -> () -> MyViewController’ to expected argument type ‘AnyObject?'”

    Also see this gist: https://gist.github.com/Broich/702d3d04d30de420e7c09fef9e664975

    Looks like self is not completely initialized within the closure? I’m not sure…

    • Roman Roibu

      You are right, self is not fully initialised at the time you call the closure. You need to use lazy var instead of let for that to work.

      I use an approach similar to the one in the mentioned Then library, but with a slight modification to accommodate lazy instantiation.

      See: https://gist.github.com/romanroibu/8325edc8d3887136842aa0825b5c7ee8

      This lets you start with a let property, and then change it to a lazy var if, for example, at some point you need to set the delegate.

  • Yariv

    Uber cool!

  • elio d’antoni

    Apparently “Then” stopped working on Xcode 7.3.1 (only on projects / Playgrounds are still ok). Is anyone experiencing code completion issue when using this syntax?

  • Really nice thinking!

    Although I’m having trouble creating a CLBeaconRegion:

    private let beaconRegion: CLBeaconRegion = {
    let uuidString = “”
    let uuid = NSUUID(UUIDString: uuidString)
    return CLBeaconRegion(proximityUUID: uuid!, identifier: “Estimotes”)

    Gives the following error “argument passed to call takes no arguments” for the last line. How exactly should I configure it? Thanks.

    • Derrick Ho

      Basically you aren’t using your $0 value. And it is complaining as a result. To fix you issue just remove the first argument you have passed to your closure.

      private let beaconRegion: CLBeaconRegion = {
      let uuidString = “”
      let uuid = NSUUID(UUIDString: uuidString)
      return CLBeaconRegion(proximityUUID: uuid!, identifier: “Estimotes”)

  • I’ve been using single-letter variable names for let-initialization-closures, E.G.:

    I’m normally vehemently opposed to single-letter identifiers, but that’s because I often see them used in public APIs as shorthands for mathematical/technical terms that would make sense to someone who knows that math/tech, but aren’t so helpful for someone who just wants to use the function/method without having to know how it works.

    However, here it’s used in a short, private scope, and all usages of the single-letter identifier are within a few lines of each other, so I give this a pass. That said, the $0 trick is much cooler, so I think I’ll use that from now on!

    Still, there are situations when single-letter variable names come in handy, such as this usage of nested let-initialization-closures: