2016-04-08 12 views
1

las ich in Let über Lambda über lexikalische clojures und dieser Code Probe wurde für Common Lisp gegeben:Racket mit lexikalische Verschlüsse

(let ((counter 0)) 
    (lambda() (incf counter))) 

Ich habe versucht, schreibe dies in Racket als:

(let ((counter 0)) 
    (lambda() (+ counter 1))) 

Als ich nennen es in der REPL als counter es mir den Fehler gibt:

counter: undefined; 
cannot reference an identifier before its definition 

Soweit ich unde Das Mischen von Let/Set mit Lambda gibt Ihnen die Möglichkeit, in einem Lambda einen Zustand zu speichern, der von anderen Funktionen auf die gleiche Weise verarbeitet werden kann, wie der menschliche Speicher durch die Eingabe von den Sinnen verarbeitet und verändert werden kann. Ich bin daran interessiert, in meinen LISP-Programmen Teile des Codes zu haben, die durch ihre Interaktion mit anderen Funktionen verändert werden. Auch wenn Lambda dies nicht tut, möchte ich es dennoch verstehen (die Lambda-Funktion), weil es ein wichtiger Teil von Racket und anderen LISP-Dialekten zu sein scheint.

Antwort

4

(incf x) in Common Lisp ist (+ x 1) in Racket nicht gleichwertig, sondern ist die Kombination von ersten x Inkrementieren: (set! x (+ x 1)), und dann den neuen Wert zurück.

Wenn Sie also eine ähnliche Funktion in Racket definieren möchten können Sie dies schreiben, zum Beispiel:

(define count 
    (let ((counter 0)) 
    (lambda() (begin (set! counter (+ counter 1)) counter)))) 

(count) ; returns 1 

(count) ; returns 2 
+0

Es funktioniert perfekt. Ich werde mit dieser Technik einige Funktionen neu schreiben, die ich in der Vergangenheit gemacht habe, um zu sehen, ob ich wirklich lambda verstehe. Vielen Dank! –

0

Mit Schema/Schläger, werden Sie set! statt incf verwenden müssen, die eine Lisp-Funktion (btw, set! nicht den neuen Wert zurückgibt, im Gegensatz zu infc).