2017-03-03 3 views
0

Also versuche ich einen Interpreter zu konstruieren, der benutzerdefinierte Lambda-Funktionen handhaben kann, die eine variable Anzahl von Argumenten haben können. Code sieht ein wenig wie folgt aus:Warum werden die Funktionswerte nicht an die Lambda-Funktion übergeben und ausgewertet?

((lambda (x &optional y z) (func_body)) args)) 

Gerade jetzt, das Ergebnis, das ich die richtige Funktion bekommen, ohne sie ausgewertet wird; Was ich suche ist die obige Funktion

(* X X) 

nach ausgewertet werden: zum Beispiel, erhalte ich, wenn ich square X = (* X X) und betreibe meine Dolmetscher definieren. Ich habe versucht Dinge wie:

(let ((func (lambda (x &optional y z) (func_body)))) 
    (apply/funcall func args)) 

((lambda (x &optional y z) (func_body)) args) 

Allerdings ergeben sie immer noch ein Ergebnis, das ich nicht nachher bin. Ich versuche, es so zu haben, wenn ich square X = (* X X) definieren, und setzte in (square 4) ich:

16 

Jede Anleitung, was ich fehle?

edit: Die args-Klausel wird von (cdr/car Y) oder einer anderen Funktion generiert. Wenn ich versuche, eine Lambda-Liste mit einer Funktion zu erstellen, beklagt sich Lisp, dass es kein Symbol ist, irgendeine Idee, warum das sein könnte?

Antwort

0

Der einzige Fehler, den ich sehe, ist die Syntax von let: es

sein sollte
(let ((func (lambda (x) (* x x)))) 
    (funcall func 4)) 
==> 16 

Lambda auch funktioniert:

((lambda (x) (* x x)) 5) 
==> 25 

Nun, wenn Sie Ihren Körper in einer variable gespeichert ist, wird es leicht mehr erfunden:

(defparameter *square* '(* x x)) 
(funcall (coerce `(lambda (x) ,*square*) 'function) 3) 
==> 9 

Allerdings ist es wäre aus eine viel bessere Idee, um Ihren Code als lambda zu halten bekommen gehen:

(defparameter *square* (lambda (x) (* x x))) 
(funcall *square* 4) 
==> 16 
+0

Ich sollte erwähnen, dass die args-Klausel durch (cdr/car Y) oder eine andere Funktion generiert wird. Ein Großteil der Lambda-Funktion ist jetzt, dass ich darüber nachdenke.Im Grunde liest die Befehlszeile so etwas wie '> 'Quadrat X = (* X X)' Quadrat 4' Ergebnis:'> 16' – KMK

+0

verwenden 'coerce', siehe bearbeiten. – sds

+0

Vielen Dank! – KMK

0

((lambda (x & optional yz) (func_body)) args)

Beispiele:

CL-USER 111 > ((lambda (x &optional (y 0) (z 0)) 
       (+ x y z)) 
       1 
       2 
       3) 
6 

CL-USER 112 > (apply (lambda (x &optional (y 0) (z 0)) 
         (+ x y z)) 
        '(1 2 3)) 
6 
0

Wenn ein Dolmetscher schaffen, in dem Sie auf dem Host verlassen sich nicht eval (coerce) speichern Sie die Lambda mit dem Curran t Umwelt als Daten. Ihr apply müsste unterstützen, um einen neuen Rahmen mit den an ihren Namen gebundenen Argumenten basierend auf der gespeicherten Umgebung zu erstellen. Dann muss der Körper in dieser Umgebung bewertet werden. Daher verwenden Sie nie Common Lisp lambda Makro nicht apply für Compound-Anwendung.

Die anderen Antworten, die die Verwendung von coerce vorschlagen, funktionieren nicht mit lexikalischen Variablen in Ihrem Interpreter.

Verwandte Themen