Gibt es etwas, ähnlich wie return-Anweisung von C in Lisp?
Möchte ich zum implementieren einer Basis-Bedingung in eine rekursive Funktion geschrieben in Lisp, aber ich bin nicht in der Lage, dies zu tun, da es keine return-Anweisung in Lisp.
Mein Lisp-code basiert auf diesem C-code
if (n==0) return;
Wie implementiere ich dies in Lisp?
Lisp wird Häufig als eine funktionale Programmiersprache. Dies bedeutet, dass-Ausgänge Begriff/stdout als "Nebenwirkungen" und etwas (ohne so schwere negative Konnotation) unrein. Natürlich, eine beliebige Funktion in Common Lisp wird die Bewertung nach unten, um den Wert seiner finalmost form.
So etwas wie abort all dies, wenn n gleich 0 in einer Funktion, wir rufen Sie #'foo würden Sie wahrscheinlich verwenden Sie ein conditional - in den meisten Fällen wäre dies wohl die #'cond - Funktion, aber hier ist eine einfache Implementierung mit #', wenn, eine oft-built-in makro.
lisp ist nicht mehr funktional als perl, mit Ausnahme einfacher zu zitieren. einige Probleme können nicht gelöst werden, in einem funktionalen Stil ohne dass in einer state-Maschine, die effektiv macht das gleiche wie unerlässlich code mit Ausnahme der Transformationen in die Umgebung erfolgen durch Kopie bei jedem Vorgang. eines dieser Probleme ist die partielle Reduzierung, wo Sie wollen, zu reduzieren, eine Liste von Schritten, die während der Transformation der Umwelt, aber halt reduzieren, wenn eine bestimmte Bedingung erfüllt ist; "zwingende" code effektiv abstrahiert die Komplexität dieser, während "rein funktionalen" macht es unpraktisch.
zum Beispiel, rein funktionalen Ansatz kämpft mit dem Ausdruck
So etwas wie abort all dies, wenn n gleich 0 in einer Funktion, wir rufen Sie #'foo würden Sie wahrscheinlich verwenden Sie ein conditional - in den meisten Fällen wäre dies wohl die #'cond - Funktion, aber hier ist eine einfache Implementierung mit #', wenn, eine oft-built-in makro.
(when (= n 0) (return-from foo nil))
Im oben genannten wenn in form des null kann ersetzt werden durch eine mehr komplizierte form, aber wenn es notwendig ist, werden Sie wahrscheinlich wollen, um den Bau einer Umsetzung von (cond)
oder (case)
etcetera.lisp ist nicht mehr funktional als perl, mit Ausnahme einfacher zu zitieren. einige Probleme können nicht gelöst werden, in einem funktionalen Stil ohne dass in einer state-Maschine, die effektiv macht das gleiche wie unerlässlich code mit Ausnahme der Transformationen in die Umgebung erfolgen durch Kopie bei jedem Vorgang. eines dieser Probleme ist die partielle Reduzierung, wo Sie wollen, zu reduzieren, eine Liste von Schritten, die während der Transformation der Umwelt, aber halt reduzieren, wenn eine bestimmte Bedingung erfüllt ist; "zwingende" code effektiv abstrahiert die Komplexität dieser, während "rein funktionalen" macht es unpraktisch.
zum Beispiel, rein funktionalen Ansatz kämpft mit dem Ausdruck
find the index of the string "hi" in my array xs
, da reduzieren müssen gehen durch das ganze array selbst, nachdem er Sie findet, und filter gehen durch das ganze array und nicht einmal wissen, was zuerst ist, weil es soll eine ungeordnete Betrieb. Es gibt also keine Möglichkeit, um dieses problem zum Ausdruck korrekt, ohne dass in einer state-Maschine/stream/"Monade", und ein solcher Ansatz ist isomorph zur imperativen Ansatz.InformationsquelleAutor Akash Babu | 2014-10-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Common Lisp hat die spezielle form RÜCKKEHR-VON (und seine relative ZURÜCK) zu tun, was Sie wollen.
Gesagt, dass ich lieber mit COND beim schreiben von rekursiven Funktionen.
cond
hat keinen Körper Formen, dann, wenn das test-Formular gibt nicht null, das Ergebnis der test-Formular zurückgegeben. Das bedeutet, dass Sie schreiben können(cond ((null list) 0) ((+ (first list) ...)))
; es gibt keine Notwendigkeit für diet
in diesem Fall.Kommentar gilt nicht für CL.) In Scheme ist es immer noch besser zu nutzen
else
statt der Verwendung des Ausdrucks, wie Sie das Formular testen, weil dieelse
Ausdruck Schwanz in position, während das test-Formular muss noch getestet werden truthiness.Danke. Ich wusste nicht, dass.
Guter Punkt, um das Modell/CL-Unterschiede, die Frage ist nur, tagged lisp, es ist also nicht klar, was das Ziel Lisp ist, aber diese Antwort verwendet
defun
, also bin ich davon ausgegangen, Common Lisp. Ich kann sehen, warum ein stand-alone-test wäre in nicht-tail-position, wenn es folgenden Paragraphen, aber wenn es die Letzte Klausel, wäre das nicht ein stand-alone-test werden in Schwanz-position. E. g., in(cond ... ((+ 2 3)))
wenn Sie den ganzen Weg zu(+ 2 3)
, dann wird der Rückgabewert. Es ist wie in der(and ... last)
und(or ... last)
Fall, ist es nicht?erkennen aber, dass System hat eine spezifische Liste der Dinge, die Schwanz-Positionen, so ist dies möglicherweise nicht abgedeckt werden.)
InformationsquelleAutor Mark Cox
Für ein Algol-Programmierer (oder einer der es viele Dialekte wie C, Java, perl, ...) jeder Ausdruck in einer LISP funktioniert wie ein "return Ausdruck". Beispiel:
In LISP kann dies geschrieben werden wie diese:
Wie Sie vielleicht bemerkt LISP
if
ist mehr wie der ternäre operator( expression ? consequent : alternative )
als ein Cif
.BEARBEITEN
Nun, dass Sie Hinzugefügt haben, ein Beispiel usng
return
in C, die Sie übersetzen möchten, sehe ich, dass Sie nicht mitreturn
um einen Wert zurückzugeben, sondern alsgoto
um die Funktion zu verlassen früh. Da springen ist immer noch schädlich nur mit CLreturn-from
ist nicht immer die richtige Antwort, selbst wenn, dass wäre sicher die beste wörtliche übersetzung.In jeder LISP-Sie müssen einen Wert zurückgeben, obwohl Sie nicht, es zu benutzen (für die Funktionen genannt, die für Ihre Nebenwirkungen). Wenn Sie nicht gehen, den Wert zu verwenden, können Sie einfach
nil
:Wenn du mehr als eine Anweisung (für die Nebenwirkungen), die Sie verwenden
let
,progn
oder switch die ganze Sache zu einemcond
:return-from
wenn es gefordert ist, algorithmisch. 🙂Ich mag die Vorstellung, es immer noch als schädlich und, dass es Ausnahmen gibt. So denkt man jedes mal, wenn Sie es schreiben. Es ist wie
call/cc
im Schema, das ich fast nie verwenden.Ich persönlich mag strukturierten lokalisierte gotos. YMMV, wie Sie sagen. 🙂 Gerade vor kurzem habe ich codiert einige-Schleife in C mit zwei Einstiegspunkte, die manchmal mussten einige interne Initialisierung (nach der
concatMap ... span ...
Paradigma, im Grunde, die Arbeit durch die Stücke, doch ist die Herstellung eines flach-Ausgabe). Messing mit Merkmale scheint so viel m, auf mich.InformationsquelleAutor Sylwester
Machst du einfach nur die
if
für den ganzen Körper, und stecktenil
eher alsreturn
wenn Sie wirklich wollen, dass die return-die Rückkehr "nichts".Damit sich alle zahlen von 0 bis n:
Also, wenn
n==0
die rekursive Funktion gibt 0 zurück. Sonst führt er den Zusatz hinzufügenn
zuf(n-1)
und gibt das Ergebnis. (Bitte beachten Sie, dass dies nicht der ideale Algorithmus, nur ein Beispiel für eine rekursive Funktion).Erinnern, Lisp gibt den Wert von was auch immer expr war letzten Ausführung in einer Funktion als Wert. Wenn
n==0
, die vor 0 zurück. Wennn > 0
es gibt das Ergebnis der+
expr.Wenn Sie ein multi-step-test (zum Beispiel, um sicherzustellen, dass Sie nicht weitergegeben werden, eine negative Zahl),
cond
ist der Weg (wie bereits erwähnt). So oder so, der Wert der letzten Sache ausgeführt, ist der Wert der Funktion.InformationsquelleAutor eric.green