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.
closure2
is a version ofincrementBy
, and it gets its parameter explicitly passed in, just likeincrementBy
. If you pass 3, theny
will be bound to 3 during that call. Nothing unusual about that. (Or did you mean "where x is initialized"?)closure2
is a method wherex
is perpetually 5, because that's the value it had whenstartAt(5)
was called. That's whyx+y
evaluates to 8:x
is 5 andy
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.