Syntax: (let <Schleifen-Variable> <Bindungen> <Körper>)
Mit dem "named let" hat man eine einfache Möglichkeit, (auch rekursiv, prinzipiell aber eher:) endrekursiv Schleifen zu programmieren.
Eigentlich stellt das "named let" einen normalen Funktionsblock dar. Da er jedoch in der Umgebung, in die er eingebettet ist, nicht definiert wird, kann von außen auf den Namen der Schleifenvariablen nicht zugegriffen werden. Er ist also nur im Körper der Schleife gebunden und daher auch nur dort sichtbar .
Ein Beispiel aus der Scheme - Hilfe:
(let loop ((numbers '(3 -2 1 6 -5)) (nonneg '()) (neg '())) (cond ((null? numbers) (list nonneg neg)) ((>= (car numbers) 0) (loop (cdr numbers) (cons (car numbers) nonneg) neg)) ((< (car numbers) 0) (loop (cdr numbers) nonneg (cons (car numbers) neg))))) => ((6 1 3) (-5 -2))
Anmerkung:
Die beiden zunächst als leere Listen definierten lokalen Variablen nonneg und neg stellen beide Akkumulatoren dar, in die nacheinander die Zahlen nach ihrer Art einsortiert werden.
Übrigens zeigt die dargestellte let - Schleife ein Muster, wie man unter Scheme von einer Funktion mehrere Werte zurückgeben lassen kann:
Man macht aus ihnen eine Liste!
Syntax: (do ((<Variable-1> <Startwert-1> <Schritt-Funktion-1>) ...) (<Bedingung> <Ausdruck> ...) <Anweisungs-Teil> ...) ^-- Also der Körper
Do stellt das "eigentliche" dem " for von PASCAL/Delphi entsprechende Iterationskonstrukt dar.
Es bekommt keinen eigenen Namen, die definierten Variablen sind also nur Schleifenvariable. Mehr als das for von PASCAL/Delphi bietet es in so fern, als mehrere Schleifenvariable definiert werden können. Außerdem kann die Schrittfunktion beliebig sein.
In jedem Schleifenschritt wird zunächst die Bedingung getestet. Da es sich bei ihr um eine Abbruchbedingung handelt, wird bei "falsch" der Schleifenkörper ausgeführt, und anschließend werden die Schrittfunktionen ausgeführt. Anderenfalls wird der Ausdruck zurückgegeben.
Fehlt die Schrittfunktion, dann bleibt der Variablenwert in der Schleife konstant. Man spart sich mit diesem Konstrukt ein zusätzliches let.
Zwei Beispiele aus der Scheme - Hilfe:
(do ((vec (make-vector 5)) (i 0 (+ i 1))) ((= i 5) vec) (vector-set! vec i i)) => #(0 1 2 3 4) (do ((x x (cdr x)) (sum 0 (+ sum (car x)))) ((null? x) sum)) => 25