What’s in a name?
If a programming language comes with a named feature, you can be pretty sure it was named that way for a reason. It’s a safe bet that the language designers were purposeful in their naming, so if you can figure out that essential “Why’d they name it that?” question, you might be that much closer to understanding the feature or concept.
Now the challenge: Actually figuring out the answer to that “Why?” question.
Swift is being developed in the open, and often times that gives curious minds insight into things like naming decisions. But closures in Swift have been around for longer than Swift has been open sourced.
That being the case, I really couldn’t find much in terms of the conversation around why closures are named “closures”.
Closures exist in other languages, so maybe Swift just borrowed the name. But that doesn’t help us answer the bottom line reason for naming closures “closures”.
Unpacking “closure” (thanks, thesaurus.com!)
So… I set out on a word adventure to help shed some light on what meaning is to be conveyed by the term “closure”.
It’s one thing to know that “closures are self-contained blocks of functionality that can be passed around and used in your code.” (Apple Developer Docs), but seriously — why not just call them “functions”??
Let’s unpack the word if we can. I put “closure” into thesaurus.com, and among the synonyms that I think best clarify the term “closure” in programming languages are these:
In this sense, “closure” seems to convey the idea of keeping something in… enclosing it.
Okay, so what is a closure enclosing? Great question!
Short answer? Variables.
Inevitably, if you peruse the Internet for what closures are, you’ll come across similar definitions to Apple’s, quoted above. Often, intermingled in the various definitions I’ve found, are phrases like “capturing variables” or “closing over variables“.
These phrases always seemed to muddy the water (for me, anyways). It wasn’t entirely clear what “capturing variables” or “closing over variables” meant. Until I saw the synonyms, “plug”, “seal”, “cork”.
Then it clicked…
An example for your imagination
I want you to take a function in Swift, and I want you to imagine the function as an empty swimming pool. Got it in your mind’s eye? Swimming pool. Empty (for now).
It’s runtime, and your Swift program is happily executing along. Then there’s a moment in your program where your function gets called. It begins executing, and suddenly, water comes rushing in filling the pool. A dozen diving coins get tossed into the water as well!
The coins represent the local variables and constants that your function creates to do its work.
Your function executes all the way to the
return keyword, and at the precise moment that your function returns, the drain kicks in. Within milliseconds and with tremendous force, all the water is sucked out of the pool.
What do you think will happen to all the coins in the pool?
For this example, let’s just say the answer is, “they’ll go down the drain”. That would correlate pretty well with what normally happens to variables and constants that had been declared within your function when it returns.
Any variables and constants that are created inside a function are purged from memory whenever the function returns… down the drain, if you will.
What if, at some point while there’s still water in the pool, you were able to dive in, grab a few of the coins, and bottle them up?
What if you could stick them in a container and plug it with a cork or some other kind of seal?
If you could do that, the coins would survive the torrential drainage of the pool when the plug is pulled (i.e. the function returns). And that’s what I want you to take away from the example.
A closure acts as a mechanism for diving into the pool, scooping up the coins (i.e. variables and constants) it needs, and sealing itself, such that whenever its parent function (the pool) drains, it and the coins inside survive.
Closures in practice
When you hear that closures are “self-contained blocks of functionality that can be passed around and used in your code.”, you may not realize that they can go grab variables from their environment, package them up, and seal themselves tight, thus safeguarding those variables.
As it turns out, every closure you create has this capability built in.
Not all closures need to go out and capture variables, but all closures in Swift can do so if it’s relevant.
And that is what makes closures “closures”.