2

In this Wikipedia article about Closures

   function startAt(x)
       function incrementBy(y)
           return x + y
       return incrementBy

    variable closure1 = startAt(1)
    variable closure2 = startAt(5)

It says that "Note that, as startAt returns a function, the variables closure1 and closure2 are of function type. Invoking closure1(3) will return 4, while invoking closure2(3) will return 8."

Why invoking closure1(3) will return 4, and invoking closure2(3) will return 8? I cannot see where is y initialized.

  • closure2 is a version of incrementBy, and it gets its parameter explicitly passed in, just like incrementBy. If you pass 3, then y will be bound to 3 during that call. Nothing unusual about that. (Or did you mean "where x is initialized"?) – Kilian Foth Jul 7 '15 at 8:21
  • But if x = 3, why 3 + y = 4? I don't get how y is initialized. – zuzuleinen Jul 7 '15 at 8:29
  • 2
    closure2 is a method where x is perpetually 5, because that's the value it had when startAt(5) was called. That's why x+y evaluates to 8: x is 5 and y is 3. Thes 'freezing' of values is what closures are all about. It's weird, but you must wrap your head around it to grok closures. – Kilian Foth Jul 7 '15 at 8:35
1

Your y variable is a formal argument of the returned incrementBy function (actually a dynamically created closure), so it is getting its value when that function (the just built closure) is applied.

Your x variable (inside incrementBy) is a closed variable. It has to be inside the closure made inside startAt. That fresh closure is dynamically created at runtime, when you are calling startAt.

So a closure is mixing data (the values -or perhaps the references- of the closed variables) and code (much like objects do, there is a deep similarity between closures and objects) and it is generally built at runtime.

Read also about anonymous functions since they are building closures at runtime. Read also the λ-calculus & currying wikipage... With anonymous functions introduced by the fun keyword (like in Ocaml) the example can be rewritten:

let startAt x =
   let incrementBy y = x + y in
   incrementBy

which is the same as

let startAt x = 
   fun y -> x + y

In Scheme (or Lisp) you'll use the lambda keyword to make anonymous function:

(define (startAt x) (lambda (y) (+ x y)))

If you are familiar or curious about Lisp, read Queinnec's Lisp In Small Pieces book, which explains all that in great details, with implementation technicalities.

BTW, read SICP. It is explaining the purpose of functional values (hence what closures are) quite well.

A related (and also difficult) notion is continuation.

If you are mostly a web programmer, try HOP or Opa (or perhaps ocsigen). They all use nicely closures and continuations (thru CPS), notably to easily mix browser side and server side computations.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.