2010-12-12 8 views
2

Ich las die Quelle für ChanL neulich. Es enthält eine Beispielverwendung von Kanälen, um Futures zu implementieren. Die Defuns wurden in einem LET erklärt, like so:DEFUNs in einem LET - warum?

(let ((some-var some-value)) 
    (defun foo() ... (reference some-var) ...) 
    (defun bar() ...)) 

Welchen Zweck diese dienen? Gibt es nur einen gemeinsamen Wert, den mehrere Funktionen gemeinsam nutzen können, und halten Sie die Kapselung sauber?

Antwort

6

Sie haben Ihre Frage bereits beantwortet: Gemeinsame Bindungen für eine Gruppe von Funktionen bereitstellen und die Kapselung sauber halten.

Einfaches Beispiel aus http://letoverlambda.com/textmode.cl/guest/chap2.html:

(let ((direction 'down)) 
    (defun toggle-direction() 
    (setq direction 
      (if (eq direction 'up) 
       'down 
       'up)))) 
(toggle-direction) => UP 
(toggle-direction) => DOWN 
(toggle-direction) => UP 
(toggle-direction) => DOWN 

Sie können auch eine Funktion innerhalb dieser Schließung hinzufügen, die das Verhalten auf Richtung abhängt.

+2

Das Kapitel verwiesen macht für einige wirklich interessante Lektüre. Ich werde eine Kopie von Let over Lambda kaufen müssen! –

2

Das sind nur Verschlüsse. Nur für den historischen Kontext [1],

Closures spielt eine auffällige Rolle in einer Art der Programmierung gefördert von Abelson und Sussman klassischen Struktur und Interpretation von Computerprogrammen. Verschlüsse sind Funktionen mit lokalem Status. Die einfachste Weg, um diesen Zustand zu verwenden ist in einer Situation wie folgt aus:

(let ((counter 0)) 
    (defun new-id() (incf counter)) 
    (defun reset-id() (setq counter 0))) 

Diese beiden Funktionen teilen sich eine Variable, die als Zähler dient. Die erste gibt aufeinanderfolgende Werte des Zählers zurück, und die zweite setzt den Zähler auf 0. Das gleiche könnte getan werden, indem der Zähler eine globale Variable gemacht wird, aber auf diese Weise ist er vor unbeabsichtigten Referenzen geschützt .

Paul Graham - On lisp