2017-11-14 10 views
0

Ein Anfänger in Schema lassen .. den folgenden Code versuchen, um die Äquivalenz von Lambda zu testen undLambda-Scheme und Fehler

(lambda (x y) 
    (+ x y) 
    10 
    (* x 2)) 

(let ((k 10) 
     (y (* 2 k))) 
    (+ k y)) 

die Ausgabe

#<procedure> 
. . k: undefined; 
cannot reference undefined identifier 
> 

Jede Hilfe

würde geschätzt lassen
+1

Der erste Ausdruck sieht ziemlich gebrochen aus. Es fügt 'x' und' y' hinzu und vergisst das Ergebnis. Das einzige, was der Ausdruck tatsächlich tut, ist das Verdoppeln von "x", weil nur der Wert des letzten Ausdrucks von einer Funktion zurückgegeben wird. – ceving

+0

Eine gebundene Bindung ist nicht gleichbedeutend mit einem Lambda, sie entspricht einem Lambda, das auf ein Argument angewendet wird. '(let ((x e)) body)' <=> '((lambda (x) body) e)'. – molbdnilo

Antwort

0

Scheme's let hat zwei Einschränkungen.

  1. Die durch let definierten Variablen sind für die nachfolgenden Definitionen nicht sichtbar.
  2. Die durch let definierten Variablen sind für den eigentlichen Text der Definition nicht sichtbar.

Die erste Einschränkung gilt für Ihr Beispiel.

(let ((k 10) 
     (y (* 2 k))) 
    (+ k y)) 

In diesem Beispiel ky und sind in der gleichen let definiert. Der Körper von y kennt k. Um k für den Körper von y sichtbar zu machen, müssen Sie zwei let Ausdrücke verwenden.

(let ((k 10)) 
    (let ((y (* 2 k))) 
    (+ k y))) 

Um diese Art von Verschachtelung zu vermeiden, bietet Schema die let* Alternative.

(let* ((k 10) 
     (y (* 2 k))) 
    (+ k y)) 

Wenn Sie die Spezifikation von let* lesen, sollten Sie auch die Angabe von letrec lesen, die die zweite Einschränkung ist beseitigt.

0

FWIW, die äquivalente lambda Konstruktion

(let ((k 10)) 
    (let ((y (* 2 k))) 
    (+ k y))) 

ist

((lambda (k) 
    ((lambda (y) 
     (+ k y)) 
    (* 2 k))) 
10) 
0

Die Bindungen in let kann nicht vor dem Körper der let Form verwendet werden. So müssen Sie k definieren:

(define k 99) 

(let ((k 10) 
     (y (* 2 k))) ; the k here is not the one in the same `let` 
    (+ k y)) 
; ==> 208 

let ist nur Syntax Zucker für ein angerufenes anonymen Verfahren. Es ist gleich dieser:

((lambda (k y) 
    (+ k y)) 
10 
(* 2 k)) 

Mit dieser Syntax ist vielleicht offensichtlich, dass k nicht derjenige 10 zugeordnet sein kann?Es gibt eine andere Syntax namens let* und es können Sie die bisherigen Bindungen verwenden:

(let* ((k 10) 
     (y (* 2 k))) ; the k here is not the one in the same `let` 
    (+ k y)) 
; ==> 30 

Es ist gleich verschachtelte anonyme Prozedur aufruft:

((lambda (k) 
    ((lambda (y) 
     (+ k y)) 
    (* 2 k))) 
10) 

Hier ist es einfach, die k in (* 2 k) ist die eine Schranke sehen zu 10.