Ich mache Lambda-Kalkül und in meinem Lehrbuch heißt es, wie würde ich schreiben? let*
mit Lambda-Kalkül.
Meine Antworten: x, y und z sind die Parameter; v1, v2 und v3 die Argumente; e ist der Körper:
((lambda (x y z) (e)) v1 v2 v3)
Antwort im Buch:
((lambda(x)
((lambda(y)
((lambda(z) e) v3))
v2))
v1)
Ich bin nicht sicher, ob meine Antwort gleichwertig ist. Wenn nein, warum ist meine Antwort falsch und wie kann die ursprüngliche Antwort abgeleitet werden?
Antworten:
10 für die Antwort № 1Update 2: Ich habe festgestellt, dass meine ursprüngliche Antwort korrekt war und auf das Original zurückgesetzt wurde. Ich werde jedoch einige Erläuterungen hinzufügen.
In Schema, let*
erlaubt spätere Werte von früheren abhängig zu machen. So können Sie zum Beispiel schreiben (in der üblichen Syntax):
(let* ((foo 3)
(bar (+ foo 1))
(baz (* bar 2)))
(* foo bar baz))
was bindet foo
bis 3 bar
bis 4 baz
bis 8 und gibt 72 zurück. Die Implementierung Ihres Lehrbuchs ermöglicht dies.
Ihre Implementierung lässt dies jedoch nicht zu. Sie erfordert, dass alle Werte unabhängig voneinander ausgewertet werden let
nur nicht von let*
.
Die Antwort Ihres Lehrbuchs funktioniert so, dass die früheren Werte vor den späteren gebunden sind. So lautet der obige Code in der Implementierung des Lehrbuchs beispielsweise wie folgt:
((lambda (foo)
((lambda (bar)
((lambda (baz) (* foo bar baz)) (* bar 2)))
(+ foo 1)))
3)
Wenn Sie jedoch versuchen, Ihre Implementierung auf dieselbe Weise zu verwenden:
((lambda (foo bar baz) (* foo bar baz)) 8 (+ foo 1) (* bar 2))
; Error - foo and bar aren"t bound
dann ist die foo
im (+ foo 1)
wird ungebunden sein, als foo
ist nicht im Geltungsbereich (gleiches gilt für die bar
im (* bar 2)
.
Als eine Randnotiz, die (e)
in deiner implementierung sollte es eigentlich nur sein e
, wie in der Implementierung des Lehrbuchs; Ersteres ist ein Anruf, während Letzteres nur ein Ausdruck ist.
0 für die Antwort № 2
Istvans Antwort ist richtig, aber der Unterschied zwischen Ihrem Code und Ihren Lehrbüchern ist der Unterschied zwischen let
und let*
. Grundsätzlich gilt, let*
ist eine verschachtelte Serie von let
s und in der Tat eine typische Definition von let*
ist wie folgt:
(define-syntax let*
(syntax-rules ()
;; if no bindings, same as let
((let* () body ...)
(let () body ...))
;; otherwise, take one binding, then nest the rest
((let* (binding next ...) body ...)
(let (binding)
(let* (next ...)
body ...)))))