Ist es nicht möglich, Funktionen in Schema wie jede andere Liste zu behandeln?
Grundsätzlich möchte ich Folgendes tun:
%Vor%Ich habe eine ähnliche Diskussion darüber gefunden, und ich fühle mich ein wenig enttäuscht, wenn dies mit Scheme nicht möglich ist. Wenn ja, warum ist das unmöglich? Ist es in anderen lisps möglich?
BEARBEITEN: Geändert (cdr 'foo) zu (cdr foo) - es war irreführend. Ich frage, warum kann ich nicht auf eine Funktion als Liste zugreifen?
Ihre define
-Form ist keine Funktion, sondern eine Funktionsdefinition. In der Tat ist es eine Abkürzung für
Lambda
kann man sich als "Compiler-Aufruf" vorstellen. In diesem Fall erzeugt es eine Funktion, die diese Zeichenfolge zurückgibt. Define
bindet dann diese Funktion an das Symbol% co_de%.
Vergleichen Sie dies mit
%Vor%, die nur die Zeichenfolge an das Symbol% co_de% bindet. Was würde 'foo
zurückgeben?
Nun ist es vorstellbar, dass eine Scheme-Implementierung tatsächlich speichert oder die Möglichkeit hat, das 'foo
-Formular zu speichern, wenn eine Funktion an ein Symbol gebunden wird. Sie müssen die Dokumentation überprüfen, aber die Art der reinen Interpretation, die dies beinhaltet, hätte sicherlich Auswirkungen auf die Leistung.
Wenn Sie jedoch erreichen, wird das (cdr foo)
-Formular zurückgegeben, nicht das lambda
-Formular.
MIT Scheme hat die Fähigkeit, dies zu tun. (Wenn Sie wirklich wollen, kommentieren Sie das und ich gebe Ihnen den Code. Ich musste einige undokumentierte Funktionen finden, um das zu ermöglichen.)
Es liegt jedoch nicht in der Definition der Scheme-Sprache, daher müssen Implementierungen dies nicht zulassen. Der Grund dafür ist, dass eine gute Scheme-Implementierung die Funktionen ändert, um Funktionen schneller zu machen. Dies bedeutet, dass Sie sie in einer anderen Sprache (entweder Maschinencode oder etwas ziemlich Low-Level) neu schreiben und alle nicht benötigten Bits herausnehmen müssen - zum Beispiel muss die +
-Funktion im Allgemeinen überprüfen, ob ihre Argumente Zahlen sind, und Wenn ja, welche Art von Zahlen, aber wenn Ihre Funktion eine Schleife ist, die +
aufruft, können Sie einfach einmal am Anfang überprüfen und die Funktion viel schneller machen.
Natürlich könntest du die Listen auch ohne all diese Probleme ohne allzu große Schwierigkeiten herumtragen. Aber wenn Sie versuchen würden, die Listen zu ändern , wie würde es funktionieren?
(Sie könnten es wieder zum Laufen bringen. Es wäre einfach mehr Arbeit für Implementierer, und da es normalerweise nicht in Programmen verwendet wird, wollen die meisten Leute es wahrscheinlich nicht tun.)
In arglistig,
Guile & gt; (define (foo bar) 'baz)
Guile & gt; (Prozedur-Quelle foo)
(Lambda (bar) (Zitat baz))
Guile & gt; (cdr (Prozedur-Quelle foo))
((bar) (Zitat baz))
Guile & gt;
'foo wertet ein Symbol aus, Sie können nicht die CDR eines Symbols nehmen.
Was Sie tun möchten, ist (cdr foo), aber das funktioniert nicht. Der Wert eines FOO ist eine Prozedur, keine Liste.
Sie können möglicherweise mithilfe von pp
oder pretty-print
auf die Funktion als Liste zugreifen. Allerdings müssen Sie Ihren Code möglicherweise auch im Debug-Modus ausführen. Dies ist jedoch sehr implementierungsabhängig. Ich weiß, dass es in Gambit-C funktionieren kann.
(define (foo) ...)
erzeugt ein kompiliertes Objekt, und es ist ein Wert - eine Prozedur .
Sie können nicht darüber iterieren, weil es kein s-Ausdruck ist.
Wie auch andere Vorschläge, sollten Sie Ihre Programmierumgebung überprüfen und auf
zugreifen
wenn es irgendwelche Möglichkeiten für solche Aufgaben hat.
Tags und Links reflection scheme lisp metaprogramming homoiconicity