63

After reading many posts explaining closures here I'm still missing a key concept: Why write a closure? What specific task would a programmer be performing that might be best served by a closure?

Examples of closures in Swift are accesses of an NSUrl and using the reverse geocoder. Here is one such example. Unfortunately, those courses just present the closure; they do not explain why the code solution is written as a closure.

An example of a real world programming problem that might trigger my brain to say, "aha, I should write a closure for this", would be more informative than a theoretical discussion. There is no shortage of theoretical discussions available on this site.

Bendrix
  • 759
  • 1
  • 6
  • 8
  • 7
    "Recently reviewed exlanation of Closures here" - are you missing a link? – Dan Pichelman Jun 05 '15 at 13:38
  • 2
    You should put that clarification about the asynchronous task *in a comment,* below the relevant answer. It's not part of your original question, and the answerer will never get notified of your edit. – Robert Harvey Jun 05 '15 at 17:15
  • to sum my post up: to preserve state of variables, which would otherwise go out of scope after execution of functions. – Thomas Junk Jun 05 '15 at 17:29
  • I do not know about Swift specifically, but closures in most languages are syntactic sugar for [function objects](http://en.wikipedia.org/wiki/Function_object). They make the syntax more concise by reducing overhead, and may have other benefits. –  Jun 05 '15 at 18:00
  • 5
    Just a tidbit: The crucial point of Closures is the lexical scoping (as opposed to dynamic scoping), closures without lexical scoping are kinda useless. Closures are sometimes called Lexical Closures. – Hoffmann Jun 05 '15 at 20:01
  • Could you solve the problem "better" by not using a closure? – MrWhite Jun 05 '15 at 22:55
  • When creating a class, object, or whatever in whatever language, which only has a single method and is only called from one place, I consider whether a closure makes sense. – Brandon Jun 06 '15 at 02:32
  • 1
    Closures allow you to *instantiate functions*. – user253751 Jun 06 '15 at 05:59
  • Take a look at this [Swift Blog Post](https://developer.apple.com/swift/blog/?id=4). – Alexander Jun 10 '15 at 15:36
  • I find it odd that nobody has talked about continuation passing style yet. – Christophe De Troyer Jun 11 '15 at 21:27
  • Karl, I am asking substantially the same question on this post, which has been put on hold as too broad. Would you look at that question? The hold appears arbitrary given the scope of your bounty... http://programmers.stackexchange.com/questions/286960/closures-and-their-alternatives-in-swift-real-world-examples-only?noredirect=1#comment592349_286960 – Bendrix Jun 17 '15 at 17:02
  • @Bendrix: Your question seems to be focused specifically on soliciting examples (i.e. it's a list building exercise), whereas in this one the samples are secondary to the actual question. – Robert Harvey Jun 17 '15 at 20:27
  • Robert Harvey. A long review of the help center advice and examination of other questions has resulted in a final edit of the question on hold. It looks like a question that begs for an answer, but, if it fails then I'm totally confused about the criteria for asking an acceptable question on this site. The advice you provided is appreciated. – Bendrix Jun 18 '15 at 02:09
  • 1
    Read any good book on functional programming. Perhaps start with [SICP](http://mitpress.mit.edu/sicp/) – Basile Starynkevitch Jun 18 '15 at 14:03
  • The author of the post you linked to appears to believe that a lambda function is called a "closure" in Swift. Unless Apple decided to do some really strange stuff, that is just not the case. There are no particularly characteristic closures in the post; there are several classic lambdas, though, which are consistently misnamed. This is likely the source of a lot of your confusion. – Nathan Tuggy Jun 18 '15 at 19:43

10 Answers10

52

By way of explanation, I'm going to borrow some code from this excellent blog post about closures. It's JavaScript, but that's the language most blog posts that talk about closures use, because closures are so important in JavaScript.

Let's say you wanted to render an array as an HTML table. You could do it like this:

function renderArrayAsHtmlTable (array) {
  var table = "<table>";
  for (var idx in array) {
    var object = array[idx];
    table += "<tr><td>" + object + "</td></tr>";
  }
  table += "</table>";
  return table;
}

But you're at the mercy of JavaScript as to how each element in the array will be rendered. If you wanted to control the rendering, you could do this:

function renderArrayAsHtmlTable (array, renderer) {
  var table = "<table>";
  for (var idx in array) {
    var object = array[idx];
    table += "<tr><td>" + renderer(object) + "</td></tr>";
  }
  table += "</table>";
  return table;
}

And now you can just pass a function that returns the rendering you want.

What if you wanted to display a running total in each Table Row? You would need a variable to track that total, wouldn't you? A closure allows you to write a renderer function that closes over the running total variable, and allows you to write a renderer that can keep track of the running total:

function intTableWithTotals (intArray) {
  var total = 0;
  var renderInt = function (i) {
    total += i;
    return "Int: " + i + ", running total: " + total;
  };
  return renderObjectsInTable(intArray, renderInt);
}

The magic that is happening here is that renderInt retains access to the total variable, even though renderInt is repeatedly called and exits.

In a more traditionally object-oriented language than JavaScript, you could write a class that contains this total variable, and pass that around instead of creating a closure. But a closure is a much more powerful, clean and elegant way of doing it.

Further Reading

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • 10
    In general, you can say that "first-class function == object with only one method", "Closure == object with only one method and state", "object == bundle of closures". – Jörg W Mittag Jun 05 '15 at 17:37
  • Looks good. Another thing, and this might be pedantry, is that Javascript *is* object-oriented, and you *could* create an object that contains the total variable and pass that around. Closures remain much more powerful, clean, and elegant, and also make for far more idiomatic Javascript, but the way it's written might imply that Javascript can't do this in an object-oriented way. – KRyan Jun 05 '15 at 20:41
  • 2
    Actually, to be *really* pedantic: closures are what makes JavaScript object-oriented in the first place! OO is about data abstraction, and closures are the way to perform data abstraction in JavaScript. – Jörg W Mittag Jun 06 '15 at 13:23
  • @JörgWMittag: Like you can see cloures as objects with only one method, you can see objects as collection of closures that close over the same variables: the member variables of an object are just the local variables of the object's constructor, and the object's methods are closures defined inside the scope of the constructor and made available to be called later. The constructor function returns a higher-order function (the object) that can dispatch on each closure according to the method name that is used for invocation. – Giorgio Jun 17 '15 at 17:48
  • @Giorgio: Indeed, that's how objects are typically implemented in Scheme, for example, and it is in fact also how objects are implemented in JavaScript (not surprising considering its close relationship to Scheme, after all, Brendan Eich was originally hired to design a Scheme dialect and implement an embedded Scheme interpreter inside Netscape Navigator, and only later on was ordered to make a language "with objects that looks like C++" after which he made the absolute minimal amount of changes to comply with those marketing requirements). – Jörg W Mittag Jun 17 '15 at 18:09
  • @JörgWMittag: So, if I am not mistaken, objects can be seen as an idiom built on top of the simpler / more primitive concept of a closure. – Giorgio Jun 17 '15 at 18:54
  • @Giorgio: In JavaScript, yes. In Java, closures are an idiom built on top of the simpler / more primitive concept of an object ;-) You might be interested in Ian Piumarta's COLA (Combined Object / Lambda Abstraction), which tries to mutually explain data and behavior through objects and closures. – Jörg W Mittag Jun 17 '15 at 19:00
  • @JörgWMittag Yet, to build an object you have to combine multiple closures, whereas to build a closure you take a special, simple object (with one method only). Intuitively it seems to me that closures carry less information than objects. – Giorgio Jun 17 '15 at 19:09
  • Should your `function intTableWithTotals(...)` end with a call to `renderArrayAsHtmlTable(...)` instead of `renderObjectsInTable(...)`? Perhaps a remnant of the example in the aforementioned blog? – F Rowe Apr 15 '18 at 14:52
33

First of all, there is nothing that is impossible without using closures. You can always replace a closure by an object implementing a specific interface. It's only a matter of brevity and reduced coupling.

Second, keep in mind that closures are often used inappropriately, where a simple function reference or other construct would be more clear. You shouldn't take every example you see as a best practice.

Where closures really shine over other constructs is when using higher-order functions, when you actually need to communicate state, and you can make it a one-liner, as in this JavaScript example from the wikipedia page on closures:

// Return a list of all books with at least 'threshold' copies sold.
function bestSellingBooks(threshold) {
  return bookList.filter(
      function (book) { return book.sales >= threshold; }
    );
}

Here, threshold is very succinctly and naturally communicated from where it is defined to where it is used. Its scope is precisely limited as small as possible. filter doesn't have to be written to allow for the possibility of passing client-defined data like a threshold. We don't have to define any intermediate structures for the sole purpose of communicating the threshold in this one small function. It's entirely self-contained.

You can write this without a closure, but it will require a lot more code, and be harder to follow. Also, JavaScript has a fairly verbose lambda syntax. In Scala, for example, the entire function body would be:

bookList filter (_.sales >= threshold)

If you can however use ECMAScript 6, thanks to the fat arrow functions even the JavaScript code becomes much simpler and can be actually put on a single line.

const bestSellingBooks = (threshold) => bookList.filter(book => book.sales >= threshold);

In your own code, look for places where you generate a lot of boilerplate just to communicate temporary values from one place to another. These are excellent opportunities to consider replacing with a closure.

Andy
  • 10,238
  • 4
  • 25
  • 50
Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
  • 2
    How exactly do closures reduce coupling? – Stas Bichenko Jun 21 '15 at 10:52
  • 1
    Without closures, you have to impose restrictions on both the `bestSellingBooks` code and the `filter` code, such as a specific interface or user data argument, in order to be able to communicate the `threshold` data. That ties the two functions together in much less reusable ways. – Karl Bielefeldt Jun 21 '15 at 15:00
23

The purpose of closures is simply to preserve state; hence the name closure - it closes over state. For the ease of further explanation, I'll use Javascript.

Typically you have a function

function sayHello(){
    var txt="Hello";
    return txt;
}

where the scope of the variable(s) is bound to this function. So after execution the variable txt goes out of scope. There is no way of accessing or using it after the function has finished execution.

Closures are language construct, which allow - as said earlier - to preserve the state of the variables and so prolong the scope.

This could be useful in different cases. One use case is the construction of higher order functions.

In mathematics and computer science, a higher-order function (also functional form, functional or functor) is a function that does at least one of the following:1

  • takes one or more functions as an input
  • outputs a function

A simple, but admittely not all too useful example is:

 makeadder=function(a){
     return function(b){
         return a+b;
     }
 }

 add5=makeadder(5);
 console.log(add5(10)); 

You define a function makedadder, which takes one parameter as input and returns a function. There is an outer function function(a){} and an inner function(b){}{}.Further you define (implicitely) another function add5 as the result of calling the higher order funtion makeadder. makeadder(5) returns an anonymous (inner) function, which in turn takes 1 parameter and returns the sum of the parameter of the outer function and the parameter of the inner function.

The trick is, that while returning the inner function, which does the actual adding, the scope of the parameter of the outer function (a) is preserved. add5 remembers, that the parameter a was 5.

Or to show one at least somehow usefull example:

  makeTag=function(openTag, closeTag){
     return function(content){
         return openTag +content +closeTag;
     }
 }

 table=makeTag("<table>","</table>")
 tr=makeTag("<tr>", "</tr>");
 td=makeTag("<td>","</td>");
 console.log(table(tr(td("I am a Row"))));

Another common usecase is the so called IIFE = immediately invoked function expression. It is very common in javascript to fake private member variables. This is done via a function, which creates a private scope = closure, because it is immediatly after definition invoked. The structure is function(){}(). Notice the brackets () after the definition. This makes it possible to use it for object-creation with revealing module pattern. The trick is creating a scope and returning an object, which has access to this scope after execution of the IIFE.

Addi's example looks like this:

 var myRevealingModule = (function () {

         var privateVar = "Ben Cherry",
             publicVar = "Hey there!";

         function privateFunction() {
             console.log( "Name:" + privateVar );
         }

         function publicSetName( strName ) {
             privateVar = strName;
         }

         function publicGetName() {
             privateFunction();
         }


         // Reveal public pointers to
         // private functions and properties

         return {
             setName: publicSetName,
             greeting: publicVar,
             getName: publicGetName
         };

     })();

 myRevealingModule.setName( "Paul Kinlan" );

The returned object has references to functions (e.g. publicSetName), which in turn have access to "private" variables privateVar.

But these are more special use cases for Javascript.

What specific task would a programmer be performing that might be best served by a closure?

There are several reasons for that. One might be, that it is natural for him, since he follows a functional paradigm. Or in Javascript: it is mere necessity to rely on closures to circumvent some quirks of the language.

Thomas Junk
  • 9,405
  • 2
  • 22
  • 45
  • "The purpose of closures is simply to preserve state; hence the name closure - it closes over state.": It depends on the language, really. Closures close over external names / variables. These may denote state (memory locations that can be changed) but the may also denote values (immutable). Closures in Haskell do not preserve state: they preserve information that was known at the moment and in the context in which the closure was created. – Giorgio Jun 17 '15 at 17:51
  • 1
    » they preserve information that was known at the moment and in the context in which the closure was created« independently whether it could be changed or not, it is _state_ - perhaps _immutable state_. – Thomas Junk Jun 18 '15 at 06:52
16

There are two main use cases for closures:

  1. Asynchrony. Let's say you want to perform a task that will take a while, and then do something when it's done. You can either make your code wait for it to be done, which blocks further execution and can make your program unresponsive, or call your task asynchronously and say "begin this long task in the background, and when it completes, execute this closure", where the closure contains the code to execute when it's done.

  2. Callbacks. These are also known as "delegates" or "event handlers" depending on the language and platform. The idea is that you have a customizable object that, at certain well-defined points, will execute an event, which runs a closure passed in by the code that sets it up. For example, in your program's UI you might have a button, and you give it a closure that holds the code to be executed when the user clicks on the button.

There are several other uses for closures, but those are the two main ones.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
Mason Wheeler
  • 82,151
  • 24
  • 234
  • 309
  • 23
    So, basically callbacks then, since the first example is also a callback. – Robert Harvey Jun 05 '15 at 14:10
  • 2
    @RobertHarvey: Technically true, but they're different mental models. For example, (generally speaking,) you expect the event handler to be called multiple times, but your async continuation to only be called once. But yes, technically anything you'd do with a closure is a callback. (Unless you're converting it to an expression tree, but that's a completely different matter.) ;) – Mason Wheeler Jun 05 '15 at 14:18
  • 4
    @RobertHarvey: Viewing closures as callbacks puts you into a frame of mind that will really stop you from using them effectively. Closures are callbacks on steroids. – gnasher729 Jun 05 '15 at 22:03
  • 13
    @MasonWheeler Put it this way, it sounds wrong. Callbacks have nothing to do with closures; of course you could call back a function within a closure or call a closure as a callback; but a callback is not necessary a closure. A callback is just a simple function call. An eventhandler is not per se a closure. A delegate is not necessary a closure: it is primarily C# way of function pointers. Of course you could use it to construct a closure. Your explanation is imprecise. The point is _closing over state_ and making use of it. – Thomas Junk Jun 05 '15 at 22:20
  • If you pass in a function into another function as a callback and call it with some variable in scope of the function, that is not a closure since after returning from the outer function, the scope of both functions ceases to exist. – Thomas Junk Jun 05 '15 at 22:25
  • Also, functions that create functions, which I guess are kind of like callbacks. In JS, for example: `function makeIncrementer() { var n = 0; return function() { return ++n; } }`. Then, with `var x = makeIncrementer(); var y = makeIncrementer()`, we have `[x(), x(), y(), x()] = [1, 2, 1, 3]`. – wchargin Jun 05 '15 at 23:31
  • 5
    Maybe there are JS-specific connotations going on here that are making me misunderstand, but this answer sounds absolutely wrong to me. Asynchrony or callbacks can use anything that's 'callable'. A closure isn't required for either of them - a regular function will do fine. Meanwhile, a closure, as defined in functional programming, or as used in Python, is useful, as Thomas says, because it 'closes over' some state, i.e. a variable, and gives a function in an inner scope consistent access to that variable's value even if the function is called and exits many times. – Jonathan Hartley Jun 06 '15 at 21:02
  • `s/closure/callback/g`, and your answer would be the same. What a useless answer. – Thomas Eding Jun 14 '15 at 16:05
  • The answer by Robert Harvey seems much more conventional to me (as a die-hard non-user of JavaScript, heh) – Darren Ringer Jun 14 '15 at 19:11
  • If I understand that, would it be correct to say; "A button code that uses a function that accesses a URL that may take a long tine to respond would stop execution of the whole program until the URL responds, but if the button code used a closure then the rest of the program would continue to respond, and the closure would post the result (variable, whatever) as soon as it became available. Is that it the mental model? – Bendrix Jun 15 '15 at 21:14
13

A couple of other examples:

Sorting
Most sort functions operate by comparing pairs of objects. Some comparison technique is needed. Restricting the comparison to a specific operator means a rather inflexible sort. A much better approach is to receive a comparison function as an argument to the sort function. Sometimes a stateless comparison function works fine (e.g., sorting a list of numbers or names), but what if the comparison needs state?

For example, consider sorting a list of cities by distance to some specific location. An ugly solution is to store the coordinates of that location in a global variable. This makes the comparison function itself stateless, but at the cost of a global variable.

This approach precludes having multiple threads simultaneously sorting the same list of cities by their distance to two different locations. A closure that encloses the location solves this problem, and it gets rid of the need for a global variable.


Random numbers
The original rand() took no arguments. Pseudorandom number generators need state. Some (e.g., Mersenne Twister) need lots of state. Even the simple but terrible rand() needed state. Read a math journal paper on a new random number generator and you'll inevitably see global variables. That's nice for the developers of the technique, not so nice for the callers. Encapsulating that state in a structure and passing the structure to the random number generator is one way around the global data problem. This is the approach used in many non-OO languages to making a random number generator reentrant. A closure hides that state from the caller. A closure offers the simple calling sequence of rand() and the reentrancy of encapsulated state.

There's more to random numbers than just a PRNG. Most people who want randomness want it distributed a certain way. I'll start with numbers randomly drawn from between 0 and 1, or U(0,1) for short. Any PRNG that generates integers between 0 and some maximum will do; simply divide (as a floating point) the random integer by the maximum. A convenient and generic way to implement this is to create a closure that takes a closure (the PRNG) and the maximum as inputs. Now we have a generic and easy to use random generator for U(0,1).

There are a number of other distributions besides U(0,1). For example, a normal distribution with a certain mean and standard deviation. Every normal distribution generator algorithm I've run across uses a U(0,1) generator. A convenient and generic way to create a normal generator is to create a closure that encapsulates the U(0,1) generator, the mean, and the standard deviation as state. This is, at least conceptually, a closure that takes a closure that takes a closure as an argument.

David Hammen
  • 8,194
  • 28
  • 37
7

Closures are equivalent to objects implementing a run() method, and inversely, objects can be emulated with closures.

  • The advantage of closures is that they can be used easily anywhere you expect a function: a.k.a. higher-order functions, simple callbacks (or Strategy Pattern). You don't need to define an interface/class to build ad-hoc closures.

  • The advantage of objects is the possibility to have more complex interactions: multiple methods and/or different interfaces.

So, using closure or objects is mostly a matter of style. Here is an example of things that closures make easy but is inconvenient to implement with objects:

 (let ((seen))
    (defun register-name (name)
       (pushnew name seen :test #'string=))

    (defun all-names ()
       (copy-seq seen))

    (defun reset-name-registry ()
       (setf seen nil)))

Basically, you encapsulate a hidden state that is accessed only through global closures: you don't need to refer to any object, only use the protocol defined by the three functions.


  • I am extending the answer to address this comment from supercat*.

I trust supercat's first comment on the fact that in some languages, it is possible to control precisely the lifetime of objects, whereas the same thing is not true for closures. In the case of garbage-collected languages, however, the lifetime of objects are generally unbounded, and it is thus possible to build a closure that could be called in a dynamic context where it should not be called (reading from a closure after a stream is closed, for example).

However, it is quite simple to prevent such misuse by capturing a control variable that will guard the execution of a closure. More precisely, here is what I have in mind (in Common Lisp):

(defun guarded (function)
  (let ((active t))
    (values (lambda (&rest args)
              (when active
                (apply function args)))
            (lambda ()
              (setf active nil)))))

Here, we take a function designator function and return two closures, both of them capturing a local variable named active:

  • the first one delegates to function, only when active is true
  • the second one sets action to nil, a.k.a. false.

Instead of (when active ...), it is of course possible to have an (assert active) expression, which could throw an exception in case the closure is called when it should not be. Also, keep in mind that the unsafe code might already throw an exception by itself when used badly, so you rarely need such a wrapper.

Here is how you would use it:

(use-package :metabang-bind) ;; for bind

(defun example (obj1 obj2)
  (bind (((:values f f-deactivator)(guarded (lambda () (do-stuff obj1))))
         ((:values g g-deactivator)(guarded (lambda () (do-thing obj2)))))

    ;; ensure the closure are inactive when we exit
    (unwind-protect
         ;; pass closures to other functions
         (progn
           (do-work f)
           (do-work g))

      ;; cleanup code: deactivate closures
      (funcall f-deactivator)
      (funcall g-deactivator))))

Note that the desactivating closures could also be given to other functions as well; here, the local active variables are not shared between f and g; also, in addition to active, f only refers to obj1 and g only refers to obj2.

The other point mentioned by supercat is that closures can lead to memory leaks, but unfortunately, it is the case for almost everything in garbage-collected environments. If they are available, this can be solved by weak pointers (the closure itself might be kept in memory, but does not prevent garbage-collection of other resources).

coredump
  • 5,895
  • 1
  • 21
  • 28
  • 1
    A disadvantage of closures *as commonly implemented* is that once a closure that uses one of a method's local variable is exposed to the outside world, the method defining the closure may lose control over when that variable is read and written. There is no convenient way, in most languages, to define an ephemeral closure, pass it to a method, and guarantee that it will cease to exist once the method receiving the it has returned, nor is there any way in multi-threaded languages to guarantee that a closure won't be run in an unexpected threading context. – supercat Jun 05 '15 at 21:29
  • @supercat: Have a look at Objective-C and Swift. – gnasher729 Jun 05 '15 at 21:58
  • 1
    @supercat Wouldn't the same disadvantage exist with stateful objects? – Andres F. Jun 16 '15 at 18:02
  • @AndresF.: It is possible to encapsulate a stateful object in a wrapper that supports invalidation; if code encapsulates a privately-held `List` in a (hypothetical class) `TemporaryMutableListWrapper` and exposes that to outside code, it could be ensured that if it invalidates the wrapper, outside code will no longer have any way of manipulating the `List`. One can design closures to allow invalidation once they've served their expected purpose, but it's hardly convenient. Closures exist to make certain patterns convenient, and the effort required to guard them would negate that. – supercat Jun 16 '15 at 18:13
  • @supercat I'm probably missing something, but it seems pretty inconvenient and fragile to design shareable objects that way. I'd say it's about as inconvenient as designing shareable closures. – Andres F. Jun 17 '15 at 18:28
  • @supercat Even in garbage-collected languages, where lifetime of objects are unbounded, you can ensure a safe behaviour quite easily. Capture a control variable, say `active`, and write the closure so that it safely works only when `active` is true (for a sensible definition of what safe work is): the code that creates the closure can modify `active` as needed. Granted, there is no static check, but it works. – coredump Jun 17 '15 at 18:56
  • @coredump: If one has a language with good variable scoping, that can work and isn't too bad. Unless I'm missing something, though, that doens't work so well in something like JavaScript where all closures created within a function will import the same variables. If their lifetimes don't overlap, that's a good thing, but it makes it rather hard to have `active` be false for one closure but `true` in another. Further, " "deactivating" a closure by setting a flag won't invalidate references stored therein. Since any reference to a closure is a reference to *all* variables therein... – supercat Jun 17 '15 at 19:13
  • ...having a closure keep references to things that it is never again going to use can lead to memory leaks; that can be an especially severe problems in cases where a function generates a closure which is only used briefly but closes over something big and expensive as well as something cheap, and a closure which will be kept for a long time but only closes over the cheap thing. On some language implementations with closures, the latter closure will hold a reference to the big expensive thing even though it doesn't actually use it. – supercat Jun 17 '15 at 19:16
  • @supercat Please see edit – coredump Jun 17 '15 at 21:27
  • @supercat Hmmm, so `C1` and `C2` are two closures built in a lexical context where `expensive` and `cheap` are visible; also, `C1` refers to `{expensive, cheap}` and `C2` refers to `{cheap}`; are there really implementations where `C2` keeps a reference to `expensive`? scary. – coredump Jun 17 '15 at 21:50
  • 1
    @coredump: In C#, if two closures have any variables in common, the same compiler-generated object will serve both, since changes made to a shared variable by one closure must be seen by the other. Avoiding that sharing would have required that each closure be its own object which holds its own unshared variables as well as a reference to a shared object which holds the shared variables. Not impossible, but it would have added an extra level of dereferencing to most variable accesses, slowing everything down. – supercat Jun 17 '15 at 22:05
6

Nothing that hasn't been said already, but maybe a simpler example.

Here's a JavaScript example using timeouts:

// Example function that logs something to the browser's console after a given delay
function delayedLog(message, delay) {
  // this function will be called when the timer runs out
  var fire = function () {
    console.log(message); // closure magic!
  };

  // set a timeout that'll call fire() after a delay
  setTimeout(fire, delay);
}

What happens here, is that when delayedLog() is called, it returns immediately after setting the timeout, and the timeout keeps ticking down in the background.

But when the timeout runs out and calls the fire() function, the console will display the message that was originally passed to delayedLog(), because it is still available to fire() via closure. You can call delayedLog() as much as you want, with a different message and delay each time, and it'll do the right thing.

But let's imagine JavaScript doesn't have closures.

One way would be to make setTimeout() blocking - more like a "sleep" function - so delayedLog()'s scope does not go away until the timeout has run out. But blocking everything isn't very nice.

Another way would be to put the message variable in some other scope that'll be accessible after delayedLog()'s scope is gone.

You could use global - or at least "broader scoped" - variables, but you'd have to figure out how to keep track of what message goes with what timeout. But it can't just be a sequential, FIFO queue, because you can set any delay you want. So it might be "first in, third out" or something. So you'd need some other means to tying a timed function to variables it needs.

You could instantiate a timeout object that "groups" the timer with the message. An object's context is more or less a scope that sticks around. Then you'd have the timer execute in the object's context, so it'd have access to the right message. But you'd have to store that object because without any references it'd get garbage collected (without closures, there'd be no implicit references to it either). And you'd have to remove the object once it's fired its timeout, otherwise it'll just stick around. So you'd need some sort of list of timeout objects, and periodically check it for "spent" objects to remove - or the objects would add and remove themselves from the list, and...

So... yeah, this is getting dull.

Thankfully, you don't have to use a broader scope, or wrangle objects just to keep certain variables around. Because JavaScript has closures, you already have exactly the scope your need. A scope that gives you access to the message variable when you need it. And because of that, you can get away with writing delayedLog() like above.

Flambino
  • 181
  • 2
  • I have a problem calling that a _closure_. Perhaps I would coin it _accidental closure_. `message` is enclosed in the function scope of `fire` and therefore referred to in further calls; but it does that _accidentally_ so to say. Technically it is a closure. +1 anyways ;) – Thomas Junk Jun 06 '15 at 14:40
  • @ThomasJunk I'm not sure I quite follow. How would a "_non_-accidental closure" look? I saw your `makeadder` example above, which, to my eyes, appears much the same. You return a "curried" function that takes a single arg instead of two; using the same means, I create a function that takes zero arguments. I just don't return it but pass it to `setTimeout` instead. – Flambino Jun 06 '15 at 14:51
  • »I just don't return it« perhaps, that is the point, which makes the difference for me. I can not quite articulate my "concern" ;) In technical terms you are 100% right. Referencing `message` in `fire` generates the closure. And when it is called in `setTimeout` it makes use of the preserved state. – Thomas Junk Jun 06 '15 at 15:04
  • 1
    @ThomasJunk I see how it might smell a little different. I may not share your concern, though :) Or, at any rate, I wouldn't call it "accidental" - pretty sure I coded it that way on purpose ;) – Flambino Jun 06 '15 at 15:08
3

PHP can be used to help to show a real example in a different language.

protected function registerRoutes($dic)
{
  $router = $dic['router'];

  $router->map(['GET','OPTIONS'],'/api/users',function($request,$response) use ($dic)
  {
    $controller = $dic['user_api_controller'];
    return $controller->findAllAction($request,$response);
  })->setName('api_users');
}

So basically I am registering a function which will be executed for the /api/users URI. This is actually a middleware function which ends up being stored on a stack. Other functions will be wrapped around it. Pretty much like Node.js/Express.js does.

The dependency injection container is available (via the use clause) inside the function when it gets called. It's possible to make some sort of route action class, but this code turns out to be simpler, faster and easier to maintain.

Cerad
  • 598
  • 4
  • 9
-1

A closure is a piece of arbitrary code, including variables, that can be handled as first class data.

A trivial example is good old qsort: It's a function to sort data. You have to give it a pointer to a function that compares two objects. So you have to write a function. That function might need to be parameterized, which means you give it static variables. Which means it isn't thread safe. You are in DS. So you write an alternative that takes a closure instead of a function pointer. You instantly solve the problem of parameterization because the parameters become part of the closure. You make your code more readable because you write how objects are compared directly with the code that calls the sorting function.

There are tons of situations where you want to perform some action that requires a good deal of boiler plate code, plus one tiny but essential piece of code that needs to be adapted. You avoid the boilerplate code by writing a function once that takes a closure parameter and does all the boilerplate code around it, and then you can call this function and pass the code to be adapted as a closure. A very compact and readable way to write code.

You have a function where some non-trivial code needs to be performed in many different situation. This used to produce either code duplication or contorted code so that the non-trivial code would be present only once. Trivial: You assign a closure to a variable and call it in the most obvious way wherever it is needed.

Multithreading: iOS / MacOS X has functions to do things like "perform this closure on a background thread", "... on the main thread", "... on the main thread, 10 seconds from now". It makes multithreading trivial.

Asynchronous calls: That's what the OP saw. Any call that accesses the internet, or anything else that could take time (like reading GPS coordinates) is something where you can't wait for the result. So you have functions that do things in the background, and then you pass a closure to tell them what to do when they are finished.

That's a small start. Five situations where closures are revolutionary in terms of producing compact, readable, reliant, and efficient code.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
-4

A closure is a shorthand way of writing a method where it is to be used. It saves you the effort of declaring and writing a separate method. It is useful when the method will be used only once and the method definition is short. The benefits are reduced typing as there is no need to specify the name of the function, its return type or its access modifier. Also, when reading the code you don't have to look elsewhere for the method's definition.

The above is a summary of Understand Lambda Expressions by Dan Avidar.

This clarified the use of closures for me because it clarifies the alternatives (closure vs. method) and the benefits of each.

The following code is used once, and once only during setup. Writing it in place under viewDidLoad saves the trouble of searching for it elsewhere, and shortens the size of the code.

myPhoton!.getVariable("Temp", completion: { (result:AnyObject!, error:NSError!) -> Void in
  if let e = error {
    self.getTempLabel.text = "Failed reading temp"
  } else {
    if let res = result as? Float {
    self.getTempLabel.text = "Temperature is \(res) degrees"
    }
  }
})

In addition, it provides for an asynchronous process to complete without blocking other parts of the program, and, a closure will retain a value for reuse in subsequent function calls.

Another closure; this one captures a value...

let animals = ["fish", "cat", "chicken", "dog"]
let sortedStrings = animals.sorted({ (one: String, two: String) -> Bool in return one > two
}) println(sortedStrings)
Bendrix
  • 759
  • 1
  • 6
  • 8
  • 4
    Unfortunately, this confuses closures and lambdas. Lambdas often use closures, because they are usually far more useful if defined a) very tersely and b) within and depending on a given method context, including variables. However, the actual closure has nothing to do with the idea of a lambda, which is basically the ability to define a first-class function in place and pass that around for later use. – Nathan Tuggy Jun 17 '15 at 17:29
  • While you are voting this answer down, read this... When should I vote down? Use your downvotes whenever you encounter an egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect. My answer may lack some of the reasons for using a closure, but it is neither egregiously sloppy nor dangerously incorrect. There are many papers and discussions of closures that center on functional programming and lambda notation. All my answer says is that this explanation of functional programming helped me understand closures. That and the persistent value. – Bendrix Jun 18 '15 at 18:43
  • 1
    The answer is not *dangerous* perhaps, but it is certainly "clearly […] incorrect". It uses the wrong terms for concepts that are highly complementary and thus often used together — exactly where clarity of distinction is essential. This is likely to cause design problems for programmers reading this if left unaddressed. (And since, as far as I can tell, the code example simply does not contain any closures, only a lambda function, it does not help to explain why closures would be helpful.) – Nathan Tuggy Jun 18 '15 at 19:03
  • Nathan, that code example is a closure in Swift. You can ask someone else if you doubt me. So, if it is a closure, would you vote it up? – Bendrix Jun 18 '15 at 19:19
  • What variables or values does it enclose? Sure, the syntax is a little funny to my eye, but I'm pretty sure I can piece it out: it calls an API with a callback parameter in the form of a lambda function with a couple parameters that are then filled in by that API. The lambda uses those parameters to set values on the implicit this/self pointer common to most OOP languages. Now, sure, you can argue that self is enclosed, but implicit use of self is ubiquitous in OOP, and most of its uses aren't particularly interesting, closure-wise, so while true, that's a poor introduction to the concept. – Nathan Tuggy Jun 18 '15 at 19:26
  • Saying "OOP and closures are formally inter-expressible" is a powerful insight for certain things, but for practical purposes, most programmers (\*cough\* except JS programmers) won't make much use of that, because most languages aren't well-suited syntactically to that sort of shenaniganry. – Nathan Tuggy Jun 18 '15 at 19:28
  • So, is it a closure? The syntax and the usage indicate it is. I think your definition of a closure is too narrow. This quote from Swift by Tutorials suggests that the ability to capture values is just one feature of closures... One of the most powerful features of closures is their ability to “capture” constants and variables from their surrounding context. A closure can use these values even after the original context has been destroyed!........ But hey, its not worth debating. More experience people than me offered that code as an example of a closure. – Bendrix Jun 18 '15 at 23:10
  • https://en.wikipedia.org/wiki/Anonymous_function and https://en.wikipedia.org/wiki/Closure_%28computer_programming%29 give the generally-applicable definitions. What you're referring to is a lambda (anonymous function, function literal, etc) in general computer science. It looks like Apple *did* choose to use misleading terminology for Swift; shame on them. For clarity: I care less about "more experienced people" and more about "having a sound reason based on their expertise for their naming choices"; even experts can be ignorant of certain things. – Nathan Tuggy Jun 18 '15 at 23:27
  • As a side note, all [but one](http://programmers.stackexchange.com/a/285944/158187) of the other answers carefully explain the merits of *closures* in the strict sense, not merely lambdas. Hopefully that serves as a better indicator of the general level of understanding of them. – Nathan Tuggy Jun 18 '15 at 23:39
  • Nathan, OK, point made and taken. It is interesting that Apple (and others) are referring to closures in a way that does not meet the wikipedia definition. This debate has gone way past my pay grade so I'll quit trying to contribute. Now you've got to find Apple's post and downgrade them a bit, eh? :) – Bendrix Jun 18 '15 at 23:44
  • 1
    Apple fairly clearly describes exactly what they mean by closure in [their documentation](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html). "Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages." When you get to implementation and terminology it [can be confusing](http://www.sitepoint.com/closures-ruby/). –  Jun 19 '15 at 01:56
  • Illuminating article in that link you posted. According to that, some of what I've been taught are closures don't satisfy his definition. Thanks for the education. – Bendrix Jun 19 '15 at 03:50