La tua variabile y
è un argomento formale della funzione incrementBy
restituita (in realtà una chiusura creata dinamicamente ), quindi sta ottenendo il suo valore quando quella funzione (la chiusura appena costruita) è applicata.
La tua variabile x
(all'interno di incrementBy
) è una variabile chiusa. Deve essere all'interno della chiusura realizzata all'interno di startAt
. Quella nuova chiusura viene creata dinamicamente in fase di esecuzione, quando chiami startAt
.
Quindi una chiusura sta mischiando i dati (i valori -o forse i riferimenti- delle variabili chiuse) e il codice (molto come gli oggetti, c'è una profonda somiglianza tra chiusure e oggetti) ed è generalmente costruito in fase di esecuzione.
Leggi anche le funzioni anonime dal momento che stanno creando chiusure in fase di runtime. Leggi anche il λ-calcolo & currying wikipage ... Con funzioni anonime introdotte dalla parola chiave fun
(come in Ocaml), l'esempio può essere riscritto:
let startAt x =
let incrementBy y = x + y in
incrementBy
che è uguale a
let startAt x =
fun y -> x + y
In Scheme (o Lisp) utilizzerai la parola chiave lambda
per rendere la funzione anonima:
(define (startAt x) (lambda (y) (+ x y)))
Se sei familiare o curioso di Lisp, leggi Lisp In Small Pieces di Queinnec libro, che spiega tutto ciò con grandi dettagli, con tecniche di implementazione.
BTW, leggi SICP . Sta spiegando lo scopo dei valori funzionali (quindi quali chiusure sono) piuttosto bene.
Una nozione correlata (e anche difficile) è continuazione .
Se sei principalmente un programmatore web, prova HOP o Opa (o forse ocsigen ). Usano tutte benissimo chiusure e continuazioni (attraverso CPS ), in particolare per combinare facilmente i calcoli lato server e lato server.