Suche…


S-Ausdruck

Ein Ausdruck in Schema ist das, was ausgeführt werden soll. Ein S-Ausdruck, wie er normalerweise heißt, beginnt mit einem ( und endet mit einem ) . Das erste Element des Ausdrucks ist das, was ausgeführt werden soll. Das folgende Element des Ausdrucks sind die Parameter, die während der Auswertung des Ausdrucks an den Ausdruck gesendet werden.

Zum Beispiel das Hinzufügen von Zahlen:

(+ 1 2 3)

In diesem Fall ist + ein Symbol für eine Add- Funktion, die mehrere Parameter akzeptiert. 1 , 2 und 3 werden an die Funktion + gesendet.

S-Ausdruck kann S-Ausdrücke als Parameter enthalten, wie im folgenden Beispiel gezeigt:

(if (< x y)
  x
  y)

Was gelesen werden kann als ob x kleiner als y , gibt x zurück und gibt y . In diesem Beispiel werten wir den Bedingungsausdruck aus. Abhängig vom aufgelösten Wert wird entweder x oder y zurückgegeben. Es könnte dies bewertet werden

(if #t x y)
x
(if #f x y)
y

Ein weniger offensichtliches Beispiel für Anfänger ist, einen S-Ausdruck als Teil des ersten Mitglieds eines S-Ausdrucks zu haben. Auf diese Weise können wir das Verhalten einer Methode ändern, indem Sie die aufgerufene Funktion ändern, ohne Zweige mit denselben Parametern erstellen zu müssen. Hier ist ein schnelles Beispiel für einen Ausdruck, der Zahlen hinzufügt oder subtrahiert, wenn x unter y liegt.

((if (< x y) + -) 
  1 2 3)

Wenn x unter y , wird der Ausdruck folgendermaßen ausgewertet:

(+ 1 2 3)
6

Andernfalls

(- 1 2 3)
-4

Wie Sie sehen, ermöglicht Scheme dem Programmierer, komplexe Codeelemente aufzubauen, während er dem Programmierer die Tools zur Verfügung stellt, die das Duplizieren von Code verhindern. In anderen Sprachen könnten wir dasselbe Beispiel als solches sehen:

(wenn (<xy) (+ 1 2 3) (- 1 2 3))

Das Problem bei dieser Methode ist, dass wir eine Menge Code duplizieren, während die einzige Änderung die Methode ist, die aufgerufen wird. Dieses Beispiel ist ziemlich einfach, aber mit mehr Bedingungen könnten viele ähnliche Zeilen dupliziert werden.

Einfaches Makro lassen

Die Let-Ausdrücke im Schema sind tatsächlich Makros. Sie können mit Lambdas ausgedrückt werden. Ein einfaches Let könnte so aussehen:

(let ((x 1) (y 2))
  (+ x y))

Es wird 3 zurückgegeben, wenn der Wert des letzten Ausdrucks des Let-Körpers zurückgegeben wird. Wie Sie sehen, führt ein let-Ausdruck tatsächlich etwas aus. Wenn wir diesen Teil des Codes mit Lambdas übersetzen, würden wir so etwas bekommen:

((lambda (x y) (+ x y)) 1 2)

Hier sehen wir, dass wir das anonyme Lambda mit 1 und 2 direkt anrufen. Das Ergebnis ist in diesem Fall also auch 3.

In diesem Sinne verstehen wir, dass ein Let-Ausdruck aus zwei Teilen besteht. Es hat Parameter und einen Körper wie ein Lambda, aber der Unterschied besteht darin, dass Ausdruck direkt nach ihrer Auswertung aufgerufen wird.

Um zu erklären, wie ein Let-Ausdruck von einer abstrakten zu einer konkreten Ansicht funktioniert, würde er so aussehen.

(let params body ...)
(let (param1 param2 ...) body ...)
(let ((p1 val1) (p2 val2) ...) body ...)

Die Parameter sind eine Liste von Paaren (name value) , die im Hauptteil des let .

Warum lassen wir Ausdruck verwenden?

Lassen Sie Ausdrücke besonders nützlich sein, um Variablen in einer Methode zu speichern, genau wie Initialisierungen von Variablen in c-ähnlichen Sprachen. Dies ist günstig für die Verwendung von define da aus dem let-Ausdruck die Variablen weg sind ... Bei Verwendung von define wird tatsächlich eine Variable zur aktuellen Ausführungsumgebung hinzugefügt. Variablen, die zur globalen Umgebung hinzugefügt werden, können nicht entfernt werden. Lassen Sie den Ausdruck überall sicher verwenden. Es kann auch zum Geisterbild von Variablen verwendet werden, ohne die übergeordneten Bereiche zu berühren.

Zum Beispiel:

(let ((x 1))
  (let ((x 2) (y x))
    (display x)
    (display y))
  (display x))

Es wird gedruckt:

2
1
1

In diesem Fall wird x mit 1 definiert und dann durch das x im zweiten let mit dem Wert 2 gespiegelt. Die Variable y wird mit dem Wert x des übergeordneten Bereichs gestartet. Nachdem der innere let Ausdruck ausgeführt wurde, wird der Anfangswert von x mit 1 angezeigt. Der innere let Ausdruck hat den Wert des übergeordneten Bereichs nicht geändert.

Wann immer Sie Variablen initialisieren müssen, sollten Sie let-Ausdrücke wie folgt verwenden:

(let (
  (user (get-current-user session))
  (db (get-current-db session))
  (ids (get-active-ids session))
  )
  (mark-task-completed db user ids)
  (change-last-logged db user)
  (db-commit db))

In diesem Beispiel werden die Variablen im Codeblock mehrmals initialisiert und verwendet. Wenn der let-Ausdruck beendet ist, werden die Variablen automatisch freigegeben, da sie nicht mehr benötigt werden.

Gepunktete Syntax für Paare

Es gibt eine bestimmte Syntax, mit der wir cons Zellen kompakter schreiben können als mit dem cons Konstruktor.

Ein Paar kann so geschrieben werden:

'(1 . 2) == (cons 1 2)

Der große Unterschied ist, dass wir pairs mit Zitat erstellen können. Andernfalls würde Scheme eine korrekte Liste erstellen (1 . (2 . '())) .

Die Punktsyntax erzwingt, dass der Ausdruck nur zwei Mitglieder hat. Jedes Mitglied kann einen beliebigen Typ haben, einschließlich Paare.

'(1 . (2 . (3 . 4)))
> (1 2 3 . 4)

Beachten Sie, dass die unzulässige Liste mit einem Punkt am Ende angezeigt werden sollte, um anzuzeigen, dass die cdr des letzten Paares der Liste nicht die leere Liste ist '() .

Diese Art, Listen anzuzeigen, ist manchmal verwirrend, da der folgende Ausdruck nicht so ausgedrückt wird, wie man es erwarten würde.

'((1 . 2) . ( 3 . 4))
> ((1 . 2) 3 . 4)

Da überspringt die Liste normalerweise das . Das erste Argument der Liste wäre (1 . 2) , das zweite Argument wäre 3 aber da die Liste nicht korrekt ist, ist das letzte Argument das letzte Argument . wird angezeigt, um anzuzeigen, dass das letzte Element der Liste nicht '() . Die Daten werden zwar anders dargestellt, die internen Daten sind jedoch so, wie sie erstellt wurden.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow