2009-06-03 2 views
6

Ich lerne Scheme. Was ist mit dem unten stehenden Code falsch? Ich möchte ein Programm schreiben, das die erste Funktion aus der Liste übernimmt und dann auf eine Nummer anwendet?Wie kann ich eine anonyme Funktion aus einer Liste in Scheme anwenden?

(define num 3) 

    ;;I want to do something like this which returns 3 
    ((λ (x) x)num) 

    ;;but my functions are in a list so this should return3 
    ((first '((λ (x) x) (λ (x) (* x x)))) num) 

Im immer diese Fehlermeldung für den obigen Code:
Verfahren Anwendung: erwartetes Verfahren gegeben: (λ (x) x); Argumente waren: 3

Was bedeutet es, wenn ich diese Art von Ausgabe bekomme?

Wenn ich nichts anwende, bekomme ich einen schönen Ausgang.

(first '((λ(x) x)(λ(x) (*x x)))) 

zurückkehrt (λ (x) x)

Antwort

11

Sie zitieren, mit 'dem Lambda, so dass es nicht ausgewertet wird.

Wenn Sie nur an der Eingabeaufforderung (λ (x) x) einspeisen, zeigt DrScheme Ihnen #<procedure>, was bedeutet, dass es das Lambda tatsächlich ausgewertet hat und Ihnen eine Schließung zurückgegeben hat. Indem du es zitierst, gibst du Schema nur eine Liste von Symbolen.

Wenn Sie Ihre Funktionen in einer Liste setzen, können Sie tun:

((first (list (lambda (x) x) (lambda (x) (* x x)))) num) 

Das Zitat Sie eine Liste zu erzeugen, ermöglicht es, ja, aber eine, deren Inhalt nicht ausgewertet. Die Listenfunktion erzeugt eine Liste aller ihrer Argumente, nachdem sie ausgewertet wurden.

Sie können auch die Liste quasiquote, wenn man so will:

((first `(,(lambda (x) x) ,(lambda (x) (* x x)))) num) 
+0

Vielen Dank. – unj2

2

Was ist der Unterschied zwischen diesen Ausdrücken?

> (procedure? (lambda (n) n)) 
#t 
> (procedure? (quote (lambda (n) n))) 
#f 
> (procedure? '(lambda (n) n)) 
#f 

Jay hat es für dich beantwortet, aber ich kann ihn noch nicht aufwerten.

2

(Lambda (x) x) ist keine Prozedur. Es ist ein Formular, wertet zu einer Prozedur aus. Die Leute sind ein wenig mit Terminologie und oft nennen die Lambda-Form eine Prozedur als eine Art Kurzschrift. "Ceci n'est pas une pipe."

+0

Richtig, aber letztlich nutzlos als Erklärung für Neulinge, die von solchen Problemen verwirrt sind. Beachten Sie übrigens, dass Racket seither die Art und Weise ändert, wie er Werte ausgibt, was zu einem klareren Fehler führt: "...' erwartete Prozedur, gegeben: '(λ (x) x) '..." - das Zitat ist neu. –

+1

Als ich ein Neuling war, war das genau der Satz, den ich brauchte, um die Verwirrung zu klären, also schrieb ich ihn nieder, um anderen zu helfen. Vielleicht ist es nur "letztlich nutzlos" für alle außer mir. – rptb1

+1

Die Sache ist, dass Scheme einige (sehr absichtliche!) Verwirrung zwischen Code und Daten hat, "x" und "x", Ihre Erklärung ist richtig (wie ich schon sagte), aber es ist eine ähnliche Art von Verwirrung auf der Meta-Ebene, wobei "x" Daten und "der an x ​​* gebundene Wert" der "Code" ist. Für viele Studenten ist diese Art von Dualität sehr verwirrend und wird meist erst dann vollständig klar, wenn sie etwas wie den meta-zirkulären Evaluator durchlaufen. –

Verwandte Themen