Hipster Swift: Demystifying the Mysterious


I know I'm not the only one that looks at Swift sometimes and thinks to myself, "WTF does that mean?!". There are a lot of features in Swift that not many people use, but I know that one day I'm going to come across something weird and end up Googling what something is. You may not find this article particularly helpful for your day to day needs, but who cares? I'm sure someone might like it. Personally, I'll be using this post as a quick reference to the hipster stuff you see in Swift sometimes.

Now this post is a bit lengthy, but what's awesome about it is that you don't need to read everything one after another to get some use out of it. Each section is it's own thing so feel free to skip from one section to another. For your convenience, here is a link to each part of this post in case you're a know-it-all and already know most of what I already wrote about:

@noescape

This little ditty seems to be gaining steam in Swift. Before I knew what it was, every time I saw it my eyes immediately glazed over. I tell myself it's the tool of the Rob Gods, @rob_rix and @cocoaphony. But what does it actually mean though?

Turns out, it's pretty damn useful. It's a Swift attribute that's applied to the parameter of a function like so:

func prepareTheKrakenArmyForBattle(@noescape preparations: () -> Void) {
    //Make the preparations to consume the human race.
}

What it basically does is tell the compiler that the passed-in closure can NOT be used outside the body of the function it's passed into. Because closures are first-class citizens in Swift, you have the capability to store closures inside of variables to be used anywhere/anytime that you want. By marking a closure within a function as @noescape, you are telling the compiler that the closure you pass in will be executed or torn down within the body of that function and nowhere else.

An easy way of thinking about it is that the body of that function serves as a jail, and that closure is trapped inside the body of the function with no means of escape.

Here's a great image of a closure trying to escape (as you can see, the Swift compiler is having none of it.):

One awesome plus is that it by using the @noescape attribute, the compiler will further optimize your non-escaping code actually give you compiler optimizations for your code as well.

Another awesome plus is that within the body of a non escaping closure, you don't need to explicitly capture self, weakly or otherwise. Since the non-escaping closure will be executed or torn down by the end of the function that it's a parameter of, there is no need to mess with capture semantics for that closure. This allows for awesome code that looks like this:

class Kraken {}
class KrakenGeneral {
    var soldiers = [Kraken]()

    func startTheWar() {
        prepareTheKrakenArmyForBattle(punishments: {
            soldiers.removeFirst() //notice that we don't need self here.
        })
    }

    func prepareTheKrakenArmyForBattle(@noescape punishments punishments: () -> Void) {
        if someoneReportedMisbehavior {
            //Someone was misbehaving. Helping out the humans. We can't have that now.
            punishments()
        }
    }
}

Back to Top

@autoclosure

@autoclosure is another Swift attribute that you may have seen but can't figure out what it does. It's pretty similar to the @noescape attribute. First, it can only be applied to closure parameters, and the use of @autoclosure automatically applies @noescape for that closure parameter.

The @autoclosure attribute delays the execution of a function that's activated in a function parameter. Essentially, calling a function inside of a parameter will wrap the function call in a closure for later use in the function body. For example, you may see a lot of code that does this:

krakenGeneral.punishSoldier(soldiers.removeFirst())

func punishSoldier(soldier: Kraken) {
    throwSoldierInTheBrig(soldier)
    sendSoldierHomeToMommy(soldier)
}

Here, as soon as the krakenGeneral calls the punishSoldier() function, the removeFirst() function gets called. This immediately removes the first object in the soldiers array and returns that object to be passed in to the soldier parameter. Then, you do what you will with the offending kraken soldier. But what if you don't want the first soldier to be removed until later? What if you're a compassionate Kraken Officer? What if you want to give the poor guy a chance before sending him home to his mommy?

Enter @autoclosure.

Because @autoclosure wraps the passed in parameter in a closure, we can put off the removal of the soldier until we deem best in the body of the punishSoldier() function like so:

//The removeFirst() function won't get called here.
punishSoldier(soldiers.removeFirst())

//@autoclosure can only be used on closure types. Let's match our parameter to the removeFirst() function type.
func punishSoldier(@autoclosure soldierPunishment: () -> Kraken) {
    //Now we can decide when to remove our soldier.
    if someoneReportedMisbehavior {
        //This will remove the soldier and send that soldier home.
        sendSoldierHomeToMommy(soldierPunishment())
    } else {
        apologizeToSoldierAndFeedHimAHuman()
    }
}

At a high level, the above code is equivalent to this:

punishSoldier {
    soldiers.removeFirst()
}

func punishSoldier(@noescape soldierPunishment: () -> Kraken) {
    if someoneReportedMisbehavior {
        //This will remove the soldier and send that soldier home.
        sendSoldierHomeToMommy(soldierPunishment())
    } else {
        apologizeToSoldierAndFeedHimAHuman()
    }
}

The main difference in syntax is at the call site. The @autoclosure attribute isn't used often because the use of it can make your code a bit unreadable. In our first example, if we didn't know the contents of our punishSoldier() function, we still assume that the first object of our soldiers array has been removed. Because of @autoclosure, it hides the implementation of our closure parameter. Hiding implementations are almost never a good thing. Personally, I would suggest against using it unless it makes sense what is happening.

Previously, I mentioned that using @autoclosure automatically turns the closure parameter into a non-escaping closure. If you really want the closure to escape for whatever reason, you can apply an additional attribute to @autoclosure like so:

var storageForAClosure: (() -> Bool)?

func executeFunctionWithEscapableClosure(@autoclosure(escaping) houdiniClosure: () -> Bool) {
    storageForAClosure = houdiniClosure
}

executeFunctionWithEscapableClosure("kraken".hasPrefix("k"))
storageForAClosure?() //hasPrefix doesn't execute until this line of code

By putting the keyword escaping inside of parentheses to the right of the @autoclosure attribute, you are telling the compiler that the closure parameter is an escaping closure.

Back to Top

Inline Lazy Vars

This may not be new to you guys but either way, I feel this deserves a spot on the Hipster Swift board. I'm sure we all know what a lazy variable is. In case you don't, it's essentially an instance variable that is initialized only once throughout the lifetime of an object, and returns it's one-time-initialization value everytime you access it. This is useful for computationally-intensive values or when a property's value isn't known until after the the object it belongs to is created. For the most part, we create lazy variables like this:

class KrakenFoodGenerator {
    lazy var lazyHuman: Human = {
        //We want a lazy human. Kraken's get annoyed 
        //when they have to chase their food.
        return self.generateWithOptions(.Lazy)
    }()
}

Swift makes lazy initialization very easy but I get kind of annoyed when I have to put a lazy variable in my variable list and it takes up so much space. Awesomely enough, the good Humans over on the Swift team thought of this for us. We can inline our lazy vars and reduce the above code to one line:

class KrakenFoodGenerator {
    lazy var lazyHuman: Human = self.generateWithOptions(.Lazy)
}

But wait, that's weird...we're using self in the variable declaration! What kind of self is it? Will it give us a retain cycle? Lazy vars are just closures after all. How come I can use self here but not when the lazy keyword is applied?!

Well, I can't really tell you how that's possible. However, after writing the autoclosure section above, I can make a very good guess. It seems as though anything after the equals sign of a lazy variable is automatically wrapped in a closure for us. As for the use of self, it does capture it strongly. However, as long as you use it like the picture below, you shouldn't run into a retain cycle and here's the proof:

Cool, huh? Now you can go and shorten some code. Lord knows that's exactly what I'm about to do.

Back to Top

()() - AKA Currying

Yet another weird one. First time I saw this, it threw me for a loop. Coming from Objective-C, it was a little difficult to wrap my head around multiple parentheses. For the most part, Currying deserves it's own blog post. I personally don't use it but objc.io wrote a great section on it and this guy wrote a great post on it too.

At a high level, it's very much a great way of representing chained functions that curry/apply a parameter from one function to the next. If you never saw double parentheses before, you would most likely write chained functions like this:

func fourChainedFunctions(a: Int) -> (Int -> (Int -> (Int -> Int))) {
    return { b in
        return { c in
            return { d in
                return a + b + c + d
            }
        }
    }
}

fourChainedFunctions(1)(2)(3)(4)

See, now that's a pretty terrible way to live. It's nice if you wanted to have mix and match functions and such, but for the most part, there are no named parameters in the nested return functions and that return pyramid of doom makes me want to run for the hills. Currying your functions at the function declaration makes this a lot more readable. The above code, using currying, is equivalent to this:

func fourChainedFunctions(a: Int)(b: Int)(c: Int)(d: Int) -> Int {
    return a + b + c + d
}

In my opinion, that's a LOT more easily digested. Pretty code is healthy code, folks.

NOTE TO ALL THE HIPSTAS OUT THERE: Currying syntax will be removed. Personally, this isn't too big of a problem for me since I never had the need to use currying, but for all of you functional programmers out there who liked it: I'll pour a little beer out for you. I must say, I am gonna miss the ability to make code a little prettier if I needed it. For now, I will have to welcome our nested-closure-pyramid-of-death overlords.

Back to Top

That Weird Ellipse Thing (Variadic Parameters)

I tell you what, Swift is chockfull of weird function things. Variadic parameters are yet another example of this. You may have seen this floating around in your code somewhere:

func printEverythingWithAnEmojiInBetween(objectsToPrint: Any...)

Those three dots there (the ellipses) are what make the parameter variadic. Simply put, the parameter is a sequence and can be enumerated like one. To fill out our function (and to show you how to actually use a variadic parameter), check this code out:

func printEverythingWithAKrakenEmojiInBetween(objectsToPrint: Any...) {
    for object in objectsToPrint {
        print("\(object)🐙")
    }
}

//This will print "Hey🐙Look🐙At🐙Me🐙!🐙"
printEverythingWithAKrakenEmojiInBetween("Hey", "Look", "At", "Me", "!")

Yep. That's right. A for-in loop. And a comma-separated list. That's how you use it. As a matter of fact, variadic parameters are how Swift's print function works.

Back to Top

dynamic

The dynamic keyword is a declaration modifier that you can apply to either function or variable declarations. You may see this when using libraries like NewRelic or something similar for app analytics. What dynamic does is tells the runtime to use dynamic dispatch over static dispatch for the function or variables modified. It also implicitly adds the @objc attribute to the variable or function declaration.

As an important note, anything using the dynamic keyword uses the Objective-C runtime instead of the Swift runtime to dispatch messages to it.

Now we love static dispatch. However, app analytics doesn't like it so much. It's hard to generate and insert analytics code dynamically when functions are mostly static by default. Dynamic is useful for these situations but sacrifices optimizations we get from static dispatch. The use of dynamic looks like this:

class Kraken {
    dynamic var imADynamicallyDispatchedString: String

    dynamic func imADynamicallyDispatchedFunction() {
        //Hooray for dynamic dispatch!
    }
}

The other thing you get by using dynamic dispatch is better interoperability with things that use magic in the Objective-C runtime like Core Data that rely on KVC/KVO (think data bindings) at runtime. By using dynamic, you can take advantage of things we have long taken for granted in the Objective-C runtime. You know, just in case Swift wasn't cool enough for your needs. 😎

Basically, if you know that a certain function or property will be interfered/replaced/swizzled by someone at runtime, then it's a good idea to mark it dynamic. If you don't, you could get a crash from the compiler devirtualizing access/inlining implementations (this is an optimization you get for free) to your functions even though other code is trying to use runtime magic that doesn't play well with those optimizations.

Back to Top

Special Literals: FILE, LINE, COLUMN, & FUNCTION

AKA Messrs __FILE__, __LINE__, __COLUMN__, & __FUNCTION__. I think I may be blinded by the underscores.

Joking aside, these are actually pretty cool and when memorized, can save you a lot of time. They are called special literal expressions. Fairly self-explanatory if you ask me; however, I will try to shed some light on it anyways.

Much like numbers (and anything contained in quotes) are number and string literals, respectively, __FILE__, __LINE__, __COLUMN__, & __FUNCTION__ are also literals; as a result, they can be used like any normal literal. As for their return values, here's a nifty table:

Personally, my favorite one to use is the __FUNCTION__ literal. It's pretty useful for debugging purposes. For example, how many times have you asked yourself, "Self? Can you tell me where the hell this function is getting called from? It's not supposed to, you know. That's gotta be the bug I'm seeing".

Well, worry no more! When placed as the default value of a parameter, the __FUNCTION__ literal will print the name of the function that called through to the function it's a part of like so:

func wreakHavocOnHumanity(krakenArmy: [Kraken], callingFunction: String = __FUNCTION__) {
    //There's a bug! There's too much havoc being wreaked!
    //Let's figure out who all is calling this function so we can
    //fix the bug! We absolutely need to make sure that the 
    //appropriate amount of havoc be wreaked.
    print(callingFunction, "called \(__FUNCTION__)")
}

func startTheWar() {
    wreakHavocOnHumanity(krakenArmy)
}

func startEatingDinner(platter: Human) {
    wreakHavocOnHumanity(krakenArmy)
}

startTheWar() //prints "startTheWar called wreakHavocOnHumanity"
startEatingDinner(human) //prints "startEatingDinner called wreakHavocOnHumanity"

Back to Top

Loop Labels (extending break and continue)

Don't knock this one quite yet. At first look, you may be like, "Dammit Hector. I know what breaks and continues are. Stop wasting my time."

Rudeness aside, Swift takes the break and continue keywords a step further and gives you the ability to label them. Sometimes, you may find that you have nested loop logic that kind of looks like this:

for section in sections {
    var foundTheMagicalRow = false
    for row in rows {
        if row.isMagical {
            foundTheMagicalRow = true
            break
        }
    }
    if foundTheMagicalRow {
        //We found the magical row! 
        //No need to continue looping through our sections now.
        break
    }
}

Using labels for your loops, you can shorten this code quite a bit. By using a label, you can indicate a specific loop to break or continue. Now here is some pretty code for you which is the exact same as the code above:

sectionLoop: for section in sections {
    rowLoop: for row in rows {
        if row.isMagical {
            break sectionLoop
        }
    }
}

Back to Top

Conclusion

For the most part, these things are just good to know but I know that for some of you out there, you can appreciate a little bit of optimization code now and then. Plus, you can always say you knew about such and such before it was cool in Swift. You may not use these in your day-to-day code but it's always nice to see something you probably didn't know. I definitely enjoyed writing this post because, on my search for obscure things in Swift, even I learned a thing or two. And hey, you might even have a Hipster moment one day and tell someone that you knew that thing in Swift before it was cool one day like a true hipster. And with that, I'll leave you guys alone. As always, happing coding fellow nerds!