Mir verschließt sich weiterhin der Sinn des
[img]
http://mokrates.de/cgi-bin/texstring?%5Clambda[/img]-Abstrakors. Im Skript steht dazu:
Es ist sehr lästig, allem und jeden einen Namen geben zu müssen, auch wenn man etwas nur einmal braucht, denn Namen müssen inerhalb der Umgebung eindeutig sein
Aber wenn ich gewissem Code keinen Namen geben will und den Code auch nicht Global als Funktion nutzen kann (Was bei einer durch lambda definierten Funktion ja aufgrund des fehlenden Names nicht geht) kann ich ich den Code doch auch direkt in meinen Quellcode einfügen, ohne lambda (Zur Not eben auch mit (begin)).
Ansetlle von
( (lambda (r) (* (/ 4 3) pi r r r)) 4)
Könnte ich doch auch gleich
(* (/ 4 3) pi 4 4 4))
schreiben.
Manchmal will man aber eine Funktion haben, und die NICHT gleich auswerten.
Ansetlle von
( (lambda (r) (* (/ 4 3) pi r r r)) 4)
Könnte ich doch auch gleich
(* (/ 4 3) pi 4 4 4))
schreiben.
Ja. Nur anstelle von
(map (lambda (r) (* (/ 4 3) pi r r r))
'(1 2 3 4))
kannst du kein
(map (begin (* (/ 4 3) pi r r r))
'(1 2 3 4))
schreiben. Du willst ja eine Funktion übergeben, und keinen Wert - und LAMBDA erzeugt eine Funktion.
Apropos lambda:
Im Script 2d auf S. 168 ist folgende Funktion:
((lambda (n)
((lambda (fact-iter)
(fact-iter fact-iter 1 1))
(lambda (fact-iter product counter)
(if (> counter n)
product
(fact-iter fact-iter
(* counter product)
(+ counter 1))))))
4)
Es kommt 24 raus und dass die Fakultät berechnet wird ist mir auch klar.
Unklar ist mir folgendes:
Das innerste lambda sieht für mich so aus, als würde es keinen Aufrufswert erhalten.
Das äußere Lambda wird mit 4 aufgerufen, d.h. lambda (4), also ist das n an 4 gebunden.
Dann scheinen mir aber alle anderen Variablen nicht instantiiert zu sein?
Kann mir das jemand etwas näherbringen?
Danke!
also, das mittlere lambda gibt eine funktion zurück, diese funktion wird dann aufgerufen und zwar mit dem rückgabewert des innersten lambda als als parameter (fac-iter), und diser parameter wird dann als name für eine funktion benutzt
Automatisches Einrücken ist schon was feines :)
Also, wenn ich das richtig interpretiere:
Das dritte lambda nimmt 3 Parameter entgegen: fact-iter, pruduct, counter. Es wird nicht direkt aufgerufen, sondern als Parameter an das 2. lambda übergeben. Dort wird es aufgerufen, und zwar mit sich selbst, 1, 1 als Parametern.
Automatisches Einrücken ist schon was feines :)
Also, wenn ich das richtig interpretiere:
Das dritte lambda nimmt 3 Parameter entgegen: fact-iter, pruduct, counter. Es wird nicht direkt aufgerufen, sondern als Parameter an das 2. lambda übergeben. Dort wird es aufgerufen, und zwar mit sich selbst, 1, 1 als Parametern.
Ok, danke, das hört sich plausibel an ;)
Edit: Einrücken ist erledigt, hatte die (Code) Klammern vergessen..
Erstmal in sinnvoll indentiert:
((lambda (n)
((lambda (fact-iter)
(fact-iter fact-iter 1 1))
(lambda (fact-iter product counter)
(if (> counter n)
product
(fact-iter fact-iter
(* counter product)
(+ counter 1))))))
4)
Ok, der Zentralbaustein hier sieht folgendermaßen aus:
((lambda (f) ;; A
(f f 1 1))
(lambda (f ...) ;; B
...))
Was wird hier getan? Dem lambda A wird eine Funktion f übergeben. Diese ruft er auf, und übergibt ihr sich selbst - also die funktion wieder - als Argument.
B hat nun aber dank A eine Referenz auf sich selbst, und kann sich so rekursiv aufrufen. Normalerweise erhält ein Lambda keine Referenz auf sich selbst.
So ein "Stunt" wie da oben ist normalerweise nicht nötig, da wir ja DEFINE bzw. LETREC haben. Aber es ist ein Beispiel dafür, dass lambda recht mächtig ist - eben Turing-vollständig (Lambda-Kalkül). Der "Stunt" heißt übrigens in genereller Form "Y Combinator" oder Y-Operator. Für den interessierten:
http://www.jetcafe.org/~jim/lambda.html (und viele weitere Infoseiten im Netz)
Edit: Meine Güte schreiben hier viele Leute wenn man mal kurz beim Editieren Abendbrot isst…