/ / Wie implementiere let * mit Lambda - Lambda, Schema, Lambda - Kalkül, let

Wie zu implementieren lasst * mit Lambda - Lambda, Schema, Lambda-Kalkül, lassen

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 № 1

Update 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 letnur 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 lets 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 ...)))))