Dinge, die ich über Cond weiß
Eine Sache, die ich nicht unterscheiden kann, ist die, die cond von einer Funktion unterscheidet!
Ein Funktionsaufruf (e0 e1 e2)
wird wie folgt ausgewertet
Beachten Sie, dass alle Ausdrücke e0
, e1
und e2
ausgewertet werden, bevor der Rumpf der Funktion aktiviert wird.
Dies bedeutet, dass ein Funktionsaufruf wie (foo #t 2 (/ 3 0))
zu einem Fehler führt, wenn (/ 3 0)
ausgewertet wird - bevor die Kontrolle an den Körper von foo
übergeben wird.
Betrachten Sie nun die spezielle Form if
. In (if #t 2 (/ 3 0))
wird der Ausdruck #t
ausgewertet und seit dem Wert nicht-falsch wird der zweite Ausdruck 2
ausgewertet und der resultierende Wert ist 2. Hier wird (/ 3 0)
niemals ausgewertet.
Wenn if
hingegen eine Funktion wäre, dann werden die Ausdrücke #t
, 2
und (/ 3 0)
ausgewertet, bevor der Körper von aktiviert wird. Und jetzt erzeugt (/ 3 0)
einen Fehler - obwohl der Wert dieser Ausdrücke nicht benötigt wird.
Kurz gesagt: Funktionsaufrufe werten immer alle Argumente aus, bevor das Steuerelement an den Funktionskörper übergeben wird. Wenn einige Ausdrücke nicht ausgewertet werden sollen, ist ein spezielles Formular erforderlich.
Hier sind if
und cond
Beispiele für Formulare, die nicht alle Teilausdrücke auswerten - also müssen sie spezielle Formen sein.
Wenn cond
keine spezielle Form war, dann der Ausdruck:
würde entweder:
verursachen eine Endlosschleife, weil triangle-using-cond
sich immer wieder rekursiv über den Tail-Aufruf (triangle-using-cond (1- number))
aufrufen würde.
oder, der letzte Ausdruck würde versuchen, den Wert #f
oder #t
als Funktion anzuwenden (was in einem Typ-2-Lisp wie ANSI Common Lisp möglich ist, aber in einem Typ nicht möglich ist) 1 Lisp wie Racket oder Scheme) und einen Fehler erzeugen.
Was cond
zu einer speziellen Form macht, ist die Tatsache, dass seine Argumente nur langsam ausgewertet werden, während Funktionen in Scheme oder Common Lisp ihre Argumente eifrig auswerten.
Wie bereits beantwortet, werden alle Argumente für einen Aufruf einer Funktion f ausgewertet, bevor das Ergebnis der Anwendung von f berechnet wird. Bedeutet dies aber, dass cond
oder if
oder beide spezielle Formen sein sollten?
Nun, zuerst, wenn Sie if
haben, können Sie leicht eine cond
mit verschachtelten Tests simulieren. Umgekehrt ist if
nur eine entartete Form von cond
. Man kann also sagen, dass es ausreicht, eine von ihnen in einer speziellen Form zu haben. Wählen wir if
, weil es einfacher zu spezifizieren ist.
Soll if
also etwas Besonderes sein?
Wenn die zugrunde liegende Frage "ist if
ausdrückbar in Form einer kleineren Menge spezieller Formulare?" ist, dann lautet die Antwort yes : Implementiere einfach if
in Bezug auf Funktionen :
Immer wenn Sie einen booleschen Wert zurückgeben können, geben Sie stattdessen eine der obigen Funktionen zurück.
Sie könnten beispielsweise entscheiden, #t
und #f
an diese Funktionen zu binden.
Beachten Sie, wie sie einen der beiden Eingabeparameter aufrufen.
Die bedingte Bewertung von Code ist wirklich eine grundlegende Rechenoperation. Der Versuch, minimale Spezialformen zu finden, bei denen man das nicht direkt ausdrücken kann, führt aus der Perspektive des Programmierers zu einer ärmeren Programmiersprache, jedoch "sauber" ist die Kernsprache.
Von einem gewissen Standpunkt aus gesehen ist das if
form (oder cond
) notwendig , denn ohne sie wird es wirklich schwierig, eine bedingte Ausführung in a auszudrücken wie ein Compiler / Interpreter effizient umgehen kann.
Dieses Dokument wird von uselpa Erörterung der Verwendung von Schließungen zur Implementierung von if
und schließt:
Allerdings wäre die syntaktische Unannehmlichkeit so groß, dass sogar Scheme definiert, wenn als ein spezielles Formular.
Tags und Links programming-languages functional-programming scheme racket