<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://demowiki.knowlus.com/index.php?action=history&amp;feed=atom&amp;title=Scheme</id>
	<title>Scheme - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://demowiki.knowlus.com/index.php?action=history&amp;feed=atom&amp;title=Scheme"/>
	<link rel="alternate" type="text/html" href="https://demowiki.knowlus.com/index.php?title=Scheme&amp;action=history"/>
	<updated>2026-05-15T11:43:43Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Demo Wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://demowiki.knowlus.com/index.php?title=Scheme&amp;diff=13787&amp;oldid=prev</id>
		<title>imported&gt;Neubadener: Vereinheitliche Großschreibung vom Namen „Lisp“ (keine Abkürzung im üblichen Sinne)</title>
		<link rel="alternate" type="text/html" href="https://demowiki.knowlus.com/index.php?title=Scheme&amp;diff=13787&amp;oldid=prev"/>
		<updated>2025-07-13T21:12:39Z</updated>

		<summary type="html">&lt;p&gt;Vereinheitliche Großschreibung vom Namen „Lisp“ (keine Abkürzung im üblichen Sinne)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Dieser Artikel|behandelt die Programmiersprache. Für die Bedeutung des alemannischen Wortes Scheme für Maske siehe [[Larve (Maske)]].}}&lt;br /&gt;
&lt;br /&gt;
{{Infobox Programmiersprache&lt;br /&gt;
| Name                   = Scheme&lt;br /&gt;
| Logo                   = [[Datei:Lambda lc.svg|100px|Logo]]&lt;br /&gt;
| Paradigma              = [[Programmierparadigma|Multi-Paradigma]]: [[Funktionale Programmierung|funktional]], [[Prozedurale Programmierung|prozedural]], [[Metaprogrammierung|meta]]&lt;br /&gt;
| Erscheinungsjahr       = 1975&lt;br /&gt;
| Entwickler               = [[Guy L. Steele]] und [[Gerald Jay Sussman]]&lt;br /&gt;
| AktuelleVersion        = R&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;RS (ratified standard)&lt;br /&gt;
| AktuelleVersionFreigabeDatum = 2013&lt;br /&gt;
| Typisierung             = [[Starke Typisierung|stark]], [[Dynamische Typisierung|dynamisch]]&lt;br /&gt;
| Implementierung        = viele z.&amp;amp;nbsp;B. MIT/GNU Scheme&lt;br /&gt;
| Beeinflusst_von          = [[Lisp]], [[ALGOL]], [[MDL (Programmiersprache)|MDL]]&lt;br /&gt;
| Beeinflusste             = [[Common Lisp]], [[JavaScript]], [[R (Programmiersprache)|R]], [[Ruby (Programmiersprache)|Ruby]], [[Dylan (Programmiersprache)|Dylan]], [[Lua]], [[Racket (Programmiersprache)|Racket]], [[Snap! (Programmiersprache)|Snap! / BYOB]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Die [[Programmiersprache]] &amp;#039;&amp;#039;&amp;#039;Scheme&amp;#039;&amp;#039;&amp;#039; ist eine [[Lisp]]-Variante.&lt;br /&gt;
Sie ist [[Funktionale Programmierung|funktional]], unterstützt jedoch auch andere [[Programmierparadigma|Programmierparadigmen]] (z.&amp;amp;nbsp;B. [[imperative Programmierung]]).&lt;br /&gt;
&lt;br /&gt;
Scheme zeichnet sich dadurch aus, dass nur wenige Programmierkonzepte durch die [[Syntax]] vorgegeben sind.&lt;br /&gt;
In Scheme gibt es daher mehr Möglichkeiten ein Programm zu beschreiben als in vielen anderen Programmiersprachen.&lt;br /&gt;
&lt;br /&gt;
Beispielsweise gibt es im Scheme-Standard keine Hilfsmittel zur objektorientierten Programmierung; solche können aber mittels [[Makro]]s und [[Lambda-Ausdruck|λ-Ausdrücken]] in Scheme programmiert und zur objektorientierten Programmierung in Scheme verwendet werden:&lt;br /&gt;
Scheme ist eine programmierbare Programmiersprache.&lt;br /&gt;
&lt;br /&gt;
Entwickelt wurde Scheme von [[Gerald Jay Sussman]] und [[Guy Lewis Steele Jr.]] am [[Massachusetts Institute of Technology]], wo auch die formale [[Spezifikation]] zur Verfügung steht, der sogenannte [[The Revised Report on the Algorithmic Language Scheme|Revised Report]]. Die derzeit aktuelle Spezifikation ist R&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;RS.&amp;lt;ref&amp;gt;[http://www.scheme-reports.org/2015/working-group-1.html Seite des Standards R7RS]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Syntax und Semantik ==&lt;br /&gt;
Die [[Syntax]] von Scheme ist sehr regelmäßig und einfach. Grundlage ist eine vollständig geklammerte Präfix-Notation (siehe auch [[Polnische Notation]]). Ein Programm besteht aus [[Ausdruck (Programmierung)|Ausdrücken]] und Definitionen. Ausdrücke sind entweder [[Literal#Literale in Programmiersprachen|Literale]] oder &amp;#039;&amp;#039;zusammengesetzte Ausdrücke&amp;#039;&amp;#039;, die einen Funktionsaufruf darstellen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (operator operand-1 operand-2 ... operand-n)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Jedes Element eines zusammengesetzten Ausdrucks ist wieder ein Ausdruck.&lt;br /&gt;
&lt;br /&gt;
Die Bedeutung (oder Semantik) von Ausdrücken ist über ihre [[Auswertung (Informatik)|Auswertung]] definiert.&lt;br /&gt;
Die Bedeutung (Semantik) eines literalen Ausdrucks ist der konstante Wert des Ausdrucks. Zum Beispiel hat die Zeichenfolge &amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot; inline&amp;gt;2&amp;lt;/syntaxhighlight&amp;gt; den Wert der Zahl 2 und die Zeichenfolge &amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot; inline&amp;gt;#t&amp;lt;/syntaxhighlight&amp;gt; hat den booleschen [[Wahrheitswert]] für „wahr“.&lt;br /&gt;
Bei der Auswertung zusammengesetzter Ausdrücke muss der Ausdruck &amp;lt;code&amp;gt;operator&amp;lt;/code&amp;gt; (in Anlehnung an mathematische [[Operator (Mathematik)|Operatoren]]) zu einer Funktion auswerten. Rechts des Operators stehen beliebig viele [[Ausdruck (Programmierung)|Operanden]], die wiederum einfache oder zusammengesetzte Formen sind.&lt;br /&gt;
&lt;br /&gt;
Die Klammern sind damit von besonderer Bedeutung und können im Gegensatz zu den meisten anderen [[Programmiersprache]]n nicht beliebig gesetzt werden. Die zusammengesetzte Form&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
(foo 42)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
etwa ist ein Ausdruck, der auf semantischer Ebene den Aufruf der an die Variable &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; gebundenen Funktion mit dem Argument &amp;lt;code&amp;gt;42&amp;lt;/code&amp;gt; bedeutet. Die Auswertung des Ausdrucks&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
(foo (42))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
dagegen führt zu einem Fehler zur Laufzeit: Bei &amp;lt;code&amp;gt;(42)&amp;lt;/code&amp;gt; handelt es sich um eine zusammengesetzte Form und die Semantik sieht die Anwendung des Operators vor. Da &amp;lt;code&amp;gt;42&amp;lt;/code&amp;gt; allerdings eine Zahl und keine Funktion ist, kommt es zu einem Fehler.&lt;br /&gt;
&lt;br /&gt;
Ein Vorteil der vollständig geklammerten Präfix-Notation besteht darin, dass diese Notation nur mit einer einzigen [[Operatorrangfolge|Präzedenz]] für alle [[Operator (Mathematik)|Operatoren]] auskommt. Eine gängige Kritik an der [[Syntax]] von Scheme bezieht sich auf die hohe Zahl der Klammern, die die Erstellung und Bearbeitung des Quelltextes erschweren. Scheme-Programmierer begegnen dieser Schwierigkeit, indem sie [[Editor (Software)|Editoren]] verwenden, die die Bearbeitung von Scheme-Quelltexten in besonderer Weise unterstützen (zum Beispiel [[Emacs]]). Zu diesen Hilfen zählen die automatische Einrückung des Codes und die Markierung zusammengehöriger Klammerpaare während des Editierens.&lt;br /&gt;
&lt;br /&gt;
Einige Scheme-Implementierungen, wie zum Beispiel Racket, erlauben abweichend vom Sprachstandard zusätzlich die Verwendung von eckigen Klammern. Dadurch soll die Übersichtlichkeit erhöht werden. Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (let ([x 42]&lt;br /&gt;
        [y 23])&lt;br /&gt;
     (+ x y))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Spezialform Lambda ==&lt;br /&gt;
Das Schlüsselwort &amp;#039;&amp;#039;lambda&amp;#039;&amp;#039; leitet die Spezialform für sogenannte Lambda-Ausdrücke ein. Ein Lambda-Ausdruck wertet zu einer Prozedur aus, die in Scheme ein Wert erster Klasse ist. Prozeduren können damit wie Werte anderer Typen im Programm verwendet werden, also etwa an Namen gebunden werden, als Argumente bei einem Prozeduraufruf übergeben werden oder von einer Prozedur zurückgegeben werden.&lt;br /&gt;
&lt;br /&gt;
Definition der Spezialform lambda:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;(lambda (argument) expression)&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
(lambda (x) (* x x)) ; Bildet das Quadrat von x&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Aufruf der vom obigen Lambda-Ausdruck erzeugten Prozedur:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
((lambda(x) (* x x)) 5) ; Bildet das Quadrat von 5&lt;br /&gt;
; (Rückgabe = 25)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Name dieser Spezialform geht auf den [[Lambda-Kalkül]] zurück.&lt;br /&gt;
&lt;br /&gt;
== Globale Definitionen ==&lt;br /&gt;
Eine Definition mit dem Schlüsselwort &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; bindet einen Wert an einen Namen. Der Name ist global gebunden, kann also an einer beliebigen Stelle im Programm nach der Definition verwendet werden. Da Prozeduren in Scheme ebenfalls Werte sind, können mit &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; auch globale Prozeduren definiert werden. Im folgenden Code-Abschnitt wird der Name &amp;lt;code&amp;gt;a-number&amp;lt;/code&amp;gt; an die Zahl 42 gebunden und anschließend der Name &amp;lt;code&amp;gt;square&amp;lt;/code&amp;gt; an eine Funktion, die eine Zahl quadriert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (define a-number 42)&lt;br /&gt;
&lt;br /&gt;
  (define square&lt;br /&gt;
     (lambda (x)&lt;br /&gt;
        (* x x)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Definition globaler Prozeduren kann auch eine vereinfachte Notation verwendet werden, bei der der &amp;lt;code&amp;gt;lambda&amp;lt;/code&amp;gt;-Ausdruck weggelassen wird. Obige Definition von &amp;lt;code&amp;gt;square&amp;lt;/code&amp;gt; kann in abgekürzter Form wie folgt geschrieben werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (define (square x)&lt;br /&gt;
    (* x x))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel dafür, dass eine Funktion eine andere Funktion zurückgeben kann, liefert folgender Ausdruck:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
(define (sum-with x)&lt;br /&gt;
    (lambda (y) (+ y x)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Der Parameter x der Funktion sum-with bestimmt, wie sich die zurückgegebene Funktion verhält: Die zurückgegebene Funktion addiert ein Argument y genau um den in sum-with angegebenen Faktor x.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
((sum-with 5) 1)&lt;br /&gt;
; Ergebnis: 6&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Lokale Bindungen ==&lt;br /&gt;
Die [[Deklaration (Programmierung)|Variablen- und Funktionsdeklaration]] gestaltet sich in Scheme etwas anders als in konventionellen Programmiersprachen. Zum einen müssen Variablen und Funktionen (Prozeduren) &amp;#039;&amp;#039;nicht&amp;#039;&amp;#039; an [[Bezeichner]] gebunden werden, zum anderen geschieht die Deklaration über Prozeduren, es gibt keine gesonderten Schlüsselwörter.&lt;br /&gt;
&lt;br /&gt;
Zur Deklaration stehen die Formen &amp;#039;&amp;#039;&amp;#039;define&amp;#039;&amp;#039;&amp;#039; und &amp;#039;&amp;#039;&amp;#039;let&amp;#039;&amp;#039;&amp;#039; zur Verfügung, je nach Bedarf können anstelle von &amp;#039;&amp;#039;&amp;#039;let&amp;#039;&amp;#039;&amp;#039; auch die Variationen &amp;#039;&amp;#039;&amp;#039;let*&amp;#039;&amp;#039;&amp;#039; und &amp;#039;&amp;#039;&amp;#039;letrec&amp;#039;&amp;#039;&amp;#039; verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== let ===&lt;br /&gt;
&amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; bindet mehrere Werte an die angegebenen Bezeichner. Diese Bindungen sind nur innerhalb des Rumpfes von &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; sichtbar. &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; hat die folgende Syntax:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (let ((name-1 &amp;#039;&amp;#039;ausdruck-1&amp;#039;&amp;#039;)&lt;br /&gt;
       (name-2 &amp;#039;&amp;#039;ausdruck-2&amp;#039;&amp;#039;)&lt;br /&gt;
       ...&lt;br /&gt;
       (name-n &amp;#039;&amp;#039;ausdruck-n&amp;#039;&amp;#039;))&lt;br /&gt;
   ...&lt;br /&gt;
   ; Rumpf des let-Ausdrucks&lt;br /&gt;
   ; name-1, ..., name-n sind nur innerhalb des Rumpfes von &amp;#039;&amp;#039;&amp;#039;let&amp;#039;&amp;#039;&amp;#039; gebunden&lt;br /&gt;
   ...&lt;br /&gt;
 )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Ausdrücke &amp;lt;code&amp;gt;ausdruck-1&amp;lt;/code&amp;gt; bis &amp;lt;code&amp;gt;ausdruck-n&amp;lt;/code&amp;gt; werden in einer nicht spezifizierten Reihenfolge ausgewertet, bevor die resultierenden Werte an die jeweiligen Namen gebunden werden. Danach wird der Rumpf des &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;-Ausdrucks ausgewertet. Erst im Rumpf gelten die Bindungen &amp;lt;code&amp;gt;name-1&amp;lt;/code&amp;gt; bis &amp;lt;code&amp;gt;name-n&amp;lt;/code&amp;gt;. Es ist insbesondere mit &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; nicht möglich, im Ausdruck &amp;lt;code&amp;gt;ausdruck-&amp;#039;&amp;#039;i&amp;#039;&amp;#039;&amp;lt;/code&amp;gt; auf einen anderen Namen zuzugreifen, der im selben &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;-Ausdruck gebunden wird (vgl. &amp;lt;code&amp;gt;let*&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Der Wert des letzten Ausdrucks im Rumpf ergibt den Wert des gesamten &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;-Ausdrucks. Da die Auswertungsreihenfolge der Ausdrücke &amp;lt;code&amp;gt;ausdruck-&amp;#039;&amp;#039;i&amp;#039;&amp;#039;&amp;lt;/code&amp;gt; nicht festgelegt ist und theoretisch sogar alle Ausdrücke zeitgleich ausgewertet werden dürfen, spricht man auch von einem &amp;#039;&amp;#039;parallelen &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (let ((a 3)&lt;br /&gt;
       (b (+ 10 12))&lt;br /&gt;
       (c (lambda (n) (* n 2))))&lt;br /&gt;
      (c (+ a b)))&lt;br /&gt;
 =&amp;gt; 50&lt;br /&gt;
&lt;br /&gt;
 (let ((a 1))&lt;br /&gt;
      (let ((a 0)&lt;br /&gt;
            (b a))&lt;br /&gt;
           b))&lt;br /&gt;
 =&amp;gt; 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; ist eine vereinfachte Syntax, die in einen Funktionsaufruf übersetzt wird. Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (let ((a (+ 1 1)) (b (+ 2 2)))&lt;br /&gt;
    (+ a b))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
expandiert zu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  ((lambda (a b) (+ a b)) (+ 1 1) (+ 2 2))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== let* ===&lt;br /&gt;
&amp;lt;code&amp;gt;let*&amp;lt;/code&amp;gt; hat dieselbe Syntax wie &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; und eine ähnliche Semantik. Im Unterschied zu &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; ist bei &amp;lt;code&amp;gt;let*&amp;lt;/code&amp;gt; die Reihenfolge, in der die Ausdrücke in den Name-Ausdruck-Paaren ausgewertet werden, festgelegt: Die Auswertung erfolgt von links nach rechts. Man spricht daher auch von einem &amp;#039;&amp;#039;sequentiellen &amp;lt;code&amp;gt;let*&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;. Im Unterschied zu &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; kann in den Ausdrücken (rechte Seiten der Name-Ausdruck-Paare) auf die Namen der weiter links stehenden Bindungspaare zugegriffen werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (let ((a 1))&lt;br /&gt;
      (let* ((a 0)&lt;br /&gt;
             (b a))&lt;br /&gt;
            b))&lt;br /&gt;
 =&amp;gt; 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; ist auch &amp;lt;code&amp;gt;let*&amp;lt;/code&amp;gt; eine vereinfachte Syntax und wird in verschachtelte Funktionsaufrufe übersetzt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (let* ((a (+ 1 1))&lt;br /&gt;
         (b (+ a 1)))&lt;br /&gt;
    (* a b))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
expandiert zu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  ((lambda (a)&lt;br /&gt;
     ((lambda (b) (* a b)) (+ a 1)))&lt;br /&gt;
   (+ 1 1))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== letrec und named let ===&lt;br /&gt;
&amp;lt;code&amp;gt;letrec&amp;lt;/code&amp;gt;-Ausdrücke haben dieselbe Syntax wie &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;-Ausdrücke. Hinsichtlich der Sichtbarkeit der zu bindenden Namen gibt es jedoch einige Unterschiede. Die Namen (also die linken Seiten der Bindungspaare) können in jedem Ausdruck der Bindungspaare verwendet werden. Die vom &amp;lt;code&amp;gt;let*&amp;lt;/code&amp;gt; her bekannte Einschränkung, dass sich die Namen in einem Ausdruck nur auf vorhergehende (also weiter links stehende) Namen beziehen können, fällt also weg. Insbesondere kann &amp;lt;code&amp;gt;letrec&amp;lt;/code&amp;gt; zur Definition von lokalen rekursiven Funktionen verwendet werden. Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (letrec ((sum (lambda (lst s)&lt;br /&gt;
                 (if (null? lst)&lt;br /&gt;
                   s&lt;br /&gt;
                   (sum (cdr lst) (+ s (car lst)))))))&lt;br /&gt;
    (sum (list 1 2 3) 0))&lt;br /&gt;
  =&amp;gt; 6&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es können auch wechselseitig rekursive Funktionen definiert werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (letrec ((even? (lambda (n)&lt;br /&gt;
                  (if (zero? n)&lt;br /&gt;
                    #t&lt;br /&gt;
                    (odd? (- n 1)))))&lt;br /&gt;
           (odd? (lambda (n)&lt;br /&gt;
                  (if (zero? n)&lt;br /&gt;
                    #f&lt;br /&gt;
                    (even? (- n 1))))))&lt;br /&gt;
    (even? 42))&lt;br /&gt;
  =&amp;gt; #t&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Variante von &amp;lt;code&amp;gt;letrec&amp;lt;/code&amp;gt; ist das sogenannte &amp;#039;&amp;#039;named &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;, das besonders zur Programmierung von Schleifen verwendet wird. Die Syntax ist&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (let &amp;#039;&amp;#039;name&amp;#039;&amp;#039; (&amp;#039;&amp;#039;bindungen&amp;#039;&amp;#039;) &amp;#039;&amp;#039;rumpf&amp;#039;&amp;#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
, wobei &amp;lt;code&amp;gt;bindungen&amp;lt;/code&amp;gt; die vom &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt; her bekannten Paare aus Name und Ausdruck sind. Der Rumpf des &amp;#039;&amp;#039;named &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;&amp;#039;&amp;#039; wird als Rumpf einer Prozedur mit dem Namen &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; verwendet, die genau so viele Argumente hat wie Bindungspaare angegeben wurden. Das &amp;#039;&amp;#039;named &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;&amp;#039;&amp;#039; ist ein Makro, welches in den Aufruf dieser Prozedur &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; expandiert. Als Argumente werden die rechten Seiten der Bindungspaare verwendet. Das Beispiel für &amp;lt;code&amp;gt;letrec&amp;lt;/code&amp;gt; kann mit einem &amp;#039;&amp;#039;named &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;&amp;#039;&amp;#039; folgendermaßen geschrieben werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (let sum ((lst (list 1 2 3))&lt;br /&gt;
            (s 0))&lt;br /&gt;
    (if (null? lst)&lt;br /&gt;
        s&lt;br /&gt;
        (sum (cdr lst) (+ s (car lst)))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== define ===&lt;br /&gt;
&amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt; wird meist benutzt, um auf globaler Ebene Funktionen und Konstanten zu deklarieren, aber es ist auch innerhalb des Rumpfes von Prozeduren verwendbar. Die Sichtbarkeit der so gebundenen Variablen beschränkt sich auf den Rumpf, in dem die Definition steht. &amp;lt;code&amp;gt;define&amp;lt;/code&amp;gt;, die nicht auf globaler Ebene stehen, werden &amp;#039;&amp;#039;interne Definitionen&amp;#039;&amp;#039; genannt und gelegentlich der besseren Lesbarkeit wegen anstatt eines &amp;lt;code&amp;gt;letrec&amp;lt;/code&amp;gt; verwendet.&lt;br /&gt;
&lt;br /&gt;
Die Syntax ist:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (define bezeichner ausdruck)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Ausdruck darf sich auch rekursiv auf &amp;#039;&amp;#039;bezeichner&amp;#039;&amp;#039; beziehen.&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel werden &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; intern definiert. Beide Variablen sind nur innerhalb des Rumpfes des &amp;lt;code&amp;gt;let&amp;lt;/code&amp;gt;-Ausdrucks sichtbar.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (let ((x 5))&lt;br /&gt;
&lt;br /&gt;
    (define (foo y)&lt;br /&gt;
      (bar x y))&lt;br /&gt;
&lt;br /&gt;
    (define (bar a b)&lt;br /&gt;
      (+ (* a b) a))&lt;br /&gt;
&lt;br /&gt;
    (foo (+ x 3)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obiger Code entspricht dieser Version mit &amp;lt;code&amp;gt;letrec&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (let ((x 5))&lt;br /&gt;
    (letrec ((foo (lambda (y) (bar x y)))&lt;br /&gt;
             (bar (lambda (a b) (+ (* a b) a))))&lt;br /&gt;
      (foo (+ x 3))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Datentypen ==&lt;br /&gt;
=== Prozeduren ===&lt;br /&gt;
Prozeduren gehören zu den wichtigsten Sprachelementen von Scheme. Sie können mit einem [[Lambda-Ausdruck]] (&amp;#039;&amp;#039;&amp;#039;lambda&amp;#039;&amp;#039;&amp;#039;) beschrieben werden. Da sie in Scheme wie jeder andere Datentyp behandelt werden, ist es möglich, sie mit &amp;#039;&amp;#039;&amp;#039;let&amp;#039;&amp;#039;&amp;#039; oder &amp;#039;&amp;#039;&amp;#039;define&amp;#039;&amp;#039;&amp;#039; an einen [[Bezeichner]] zu binden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Eine Prozedur mit zwei Argumenten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (define test&lt;br /&gt;
   (lambda (arg1 arg2)&lt;br /&gt;
         ... ))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es gibt eine vereinfachte Notation, mit der der &amp;#039;&amp;#039;&amp;#039;define&amp;#039;&amp;#039;&amp;#039;- und der &amp;#039;&amp;#039;&amp;#039;lambda&amp;#039;&amp;#039;&amp;#039;-Ausdruck zusammengefasst werden können:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (define (test arg1 arg2)&lt;br /&gt;
  ...)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aufgerufen wird diese Prozedur wie folgt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (test wert1 wert2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Prozeduraufrufe müssen generell mit zwei Klammern eingeschlossen werden. Scheme betont die Rolle von Ausdrücken, die einen Wert haben, gegenüber Befehlen, die etwas tun. Deswegen ist es – im Gegensatz zu vielen anderen Sprachen – nicht nötig, den Ausdruck im Körper der Prozedurbeschreibung als Rückgabewert zu markieren. Im Gegenteil: Es sind besondere Konstrukte wie &amp;#039;&amp;#039;begin&amp;#039;&amp;#039; nötig, um Anweisungen ohne Rückgabe ihres Wertes auszuführen.&lt;br /&gt;
&lt;br /&gt;
Natürlich gibt es eine Reihe von vordefinierten Prozeduren wie &amp;#039;&amp;#039;cons&amp;#039;&amp;#039;, &amp;#039;&amp;#039;car&amp;#039;&amp;#039;, &amp;#039;&amp;#039;cdr&amp;#039;&amp;#039;, &amp;#039;&amp;#039;+&amp;#039;&amp;#039;, &amp;#039;&amp;#039;-&amp;#039;&amp;#039;, &amp;#039;&amp;#039;*&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;lt;&amp;#039;&amp;#039;. Diese vordefinierten Prozeduren können neu definiert werden, wie folgendes Beispiel zeigt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (define (+ x y)&lt;br /&gt;
     (- x y))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;+&amp;#039;&amp;#039; würde jetzt nicht addieren, sondern subtrahieren.&lt;br /&gt;
&lt;br /&gt;
Dadurch, dass die mathematischen Operatoren ebenfalls durch Prozeduren realisiert sind, ergibt sich für Berechnungen eine [[Präfixnotation]]. Scheme kennt keine Operatorhierarchie, alle Formeln sind eindeutig.&lt;br /&gt;
&lt;br /&gt;
=== Paare und Listen ===&lt;br /&gt;
[[Liste (Datenstruktur)|Listen]] werden in Scheme-Programmen relativ häufig gebraucht. Wichtigster Baustein für Listen in Scheme sind &amp;#039;&amp;#039;Paare&amp;#039;&amp;#039;. Ein Paar ist eine Datenstruktur, die zwei beliebige Scheme-Werte enthält. Mit &amp;lt;code&amp;gt;cons&amp;lt;/code&amp;gt; wird ein neues Paar erzeugt. Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (cons &amp;#039;sinn 42)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Aufruf von &amp;lt;code&amp;gt;cons&amp;lt;/code&amp;gt; erzeugt ein neues Paar, dessen erstes Feld das [[Symbol (Informatik)|Symbol]] &amp;lt;code&amp;gt;&amp;#039;sinn&amp;lt;/code&amp;gt; enthält und dessen zweites Feld die Zahl 42. Auf das erste Feld eines Paares kann mit der eingebauten Funktion &amp;lt;code&amp;gt;car&amp;lt;/code&amp;gt; (sprich: „carr“) zugegriffen werden, auf das zweite Feld mit &amp;lt;code&amp;gt;cdr&amp;lt;/code&amp;gt; (sprich: „kudder“). Die Namen &amp;lt;code&amp;gt;car&amp;lt;/code&amp;gt; („&amp;#039;&amp;#039;c&amp;#039;&amp;#039;ontent of &amp;#039;&amp;#039;a&amp;#039;&amp;#039;ddress &amp;#039;&amp;#039;r&amp;#039;&amp;#039;egister“) und &amp;lt;code&amp;gt;cdr&amp;lt;/code&amp;gt; („&amp;#039;&amp;#039;c&amp;#039;&amp;#039;ontent of &amp;#039;&amp;#039;d&amp;#039;&amp;#039;ecrement &amp;#039;&amp;#039;r&amp;#039;&amp;#039;egister“) sind historisch begründet, haben sich aber so erhalten. Sie beziehen sich auf Operationen, die seinerzeit bei der ersten [[Lisp]]-Implementation auf der [[IBM 704]] benutzt wurden. Die eingebauten Funktionen &amp;lt;code&amp;gt;set-car!&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;set-cdr!&amp;lt;/code&amp;gt; setzen die Werte der entsprechenden Felder eines Paares auf einen neuen Wert. Das Typ-Prädikat &amp;lt;code&amp;gt;pair?&amp;lt;/code&amp;gt; gibt genau dann &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; (für wahr) zurück, wenn es auf ein Paar, also einen mit &amp;lt;code&amp;gt;cons&amp;lt;/code&amp;gt; erzeugten Wert angewendet wurde.&lt;br /&gt;
&lt;br /&gt;
Die Definition von Listen ist [[Vollständige Induktion|induktiv]]: Die leere Liste, geschrieben &amp;lt;code&amp;gt;&amp;#039;()&amp;lt;/code&amp;gt;, ist eine Liste. Außerdem ist ein Paar, dessen &amp;lt;code&amp;gt;cdr&amp;lt;/code&amp;gt; eine Liste ist, eine Liste. Durch die Definition ergibt sich, dass eine Liste aus Paaren besteht: Im &amp;lt;code&amp;gt;car&amp;lt;/code&amp;gt;-Feld eines Paares steht ein beliebiger Wert, im &amp;lt;code&amp;gt;cdr&amp;lt;/code&amp;gt;-Feld das Paar, das das nächste Listenelement enthält. Das Ende der Liste ist erreicht, wenn im &amp;lt;code&amp;gt;cdr&amp;lt;/code&amp;gt;-Feld die leere Liste zu finden ist, was sich mit der eingebauten Funktion &amp;lt;code&amp;gt;null?&amp;lt;/code&amp;gt; überprüfen lässt. Beispiele für Listen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;#039;()&lt;br /&gt;
  (cons 1 &amp;#039;())&lt;br /&gt;
  (cons 1 (cons 2 &amp;#039;()))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die Erzeugung von Listen gibt es außerdem noch die komfortable Funktion &amp;lt;code&amp;gt;list&amp;lt;/code&amp;gt;, die eine beliebige Anzahl von Argumenten nimmt und diese als Liste zurückgibt. Die folgenden beiden Listen sind äquivalent:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
(list 1 2 3)&lt;br /&gt;
(cons 1 (cons 2 (cons 3 &amp;#039;())))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funktionen, die Listen verarbeiten, sind meist rekursive Funktionen. Mit dieser Funktion lässt sich zum Beispiel die Länge einer Liste bestimmen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (define (length lst)&lt;br /&gt;
    (if (null? lst)&lt;br /&gt;
       0&lt;br /&gt;
       (+ 1 (length (cdr lst)))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scheme-Programmierer machen von der Möglichkeit, die Felder eines Paares mit &amp;lt;code&amp;gt;set-car!&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;set-cdr!&amp;lt;/code&amp;gt; zu ändern, fast nie Gebrauch. Die Verarbeitung von Listen erfolgt fast immer rein [[Funktionale Programmiersprache|funktional]], d.&amp;amp;nbsp;h. aus Listen werden neue Listen erzeugt. Ein Beispiel ist diese Funktion &amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt;, die eine Funktion &amp;lt;code&amp;gt;f&amp;lt;/code&amp;gt; auf alle Elemente einer Liste anwendet:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (define (map f lst)&lt;br /&gt;
    (if (null? lst)&lt;br /&gt;
       &amp;#039;()&lt;br /&gt;
       (cons (f (car lst)) (map f (cdr lst)))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Weitere Datentypen ===&lt;br /&gt;
Weitere Datentypen sind unter anderem:&lt;br /&gt;
* integer (ganze Zahlen, beliebige Stellenzahl)&lt;br /&gt;
* rational (Brüche, beliebige Genauigkeit)&lt;br /&gt;
* real ([[Dezimalzahl]]en)&lt;br /&gt;
* komplexe Zahlen&lt;br /&gt;
* [[Symbol (Informatik)|Symbole]]&lt;br /&gt;
* Zeichen&lt;br /&gt;
* Strings (Zeichenkette)&lt;br /&gt;
* Paare&lt;br /&gt;
* Vektoren&lt;br /&gt;
* Port (Repräsentation für Eingabe/Ausgabe-Geräte, Dateien etc.)&lt;br /&gt;
* Boolean&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;wahr&amp;#039;&amp;#039; und &amp;#039;&amp;#039;falsch&amp;#039;&amp;#039; werden durch &amp;lt;code&amp;gt;#t&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;#f&amp;lt;/code&amp;gt; dargestellt, wobei Scheme jedoch nur &amp;lt;code&amp;gt;#f&amp;lt;/code&amp;gt; (in veralteten Implementierungen nur ein Synonym für leere Liste &amp;lt;code&amp;gt;&amp;#039;()&amp;lt;/code&amp;gt;) als logisch falsch interpretiert; alle anderen Werte gelten als wahr.&lt;br /&gt;
&lt;br /&gt;
== Fallunterscheidung ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;if&amp;lt;/code&amp;gt; wertet einen &amp;#039;&amp;#039;Test-Ausdruck&amp;#039;&amp;#039; aus und wertet je nach dessen Wahrheitswert den zweiten Operanden (&amp;#039;&amp;#039;Konsequente&amp;#039;&amp;#039;) oder den dritten Operanden (&amp;#039;&amp;#039;Alternative&amp;#039;&amp;#039;) aus. Der Wert des gesamten &amp;#039;&amp;#039;If-Ausdrucks&amp;#039;&amp;#039; ergibt sich aus der Auswertung der Konsequente bzw. Alternative. Nur wenn der Test-Ausdruck den Wert &amp;lt;code&amp;gt;#f&amp;lt;/code&amp;gt; hat, wird die Alternative ausgewertet, andernfalls die Konsequente. D.&amp;amp;nbsp;h. jeder Wert außer &amp;lt;code&amp;gt;#f&amp;lt;/code&amp;gt; gilt als logisch wahr.&lt;br /&gt;
&lt;br /&gt;
Ein entsprechender Ausdruck sieht zum Beispiel so aus:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (if (&amp;gt; x 0)&lt;br /&gt;
    &amp;#039;positive&lt;br /&gt;
    &amp;#039;not-positive)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieser Ausdruck wertet entweder zum Symbol &amp;lt;code&amp;gt;&amp;#039;positive&amp;lt;/code&amp;gt; oder zum Symbol &amp;lt;code&amp;gt;&amp;#039;not-positive&amp;lt;/code&amp;gt; aus. Da &amp;#039;&amp;#039;If&amp;#039;&amp;#039; ein Ausdruck ist, kann &amp;#039;&amp;#039;If&amp;#039;&amp;#039; innerhalb von Ausdrücken verwendet werden:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
  (* 2 (if (&amp;gt; x max) max x))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cond&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Mit &amp;lt;code&amp;gt;cond&amp;lt;/code&amp;gt; ist es möglich, mehrere Fälle zu unterscheiden. Ein &amp;#039;&amp;#039;Fall&amp;#039;&amp;#039; besteht aus einem &amp;#039;&amp;#039;Test&amp;#039;&amp;#039; und einer &amp;#039;&amp;#039;Konsequente&amp;#039;&amp;#039;. Die Fälle werden von links nach rechts überprüft. Liefert der Test eines Falles nicht &amp;lt;code&amp;gt;#f&amp;lt;/code&amp;gt; zurück, wird die entsprechende Konsequente ausgewertet: Dieser Wert ergibt dann den Wert des gesamten &amp;lt;code&amp;gt;cond&amp;lt;/code&amp;gt;-Ausdrucks. Trifft keiner der angegebenen Fälle zu, wird, falls vorhanden, der &amp;#039;&amp;#039;else-Fall&amp;#039;&amp;#039; ausgewertet. Ist kein else-Fall vorhanden, ist der Wert des &amp;lt;code&amp;gt;cond&amp;lt;/code&amp;gt;-Ausdrucks nicht definiert. Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (cond ((= wert 65) &amp;#039;a)&lt;br /&gt;
       ((= wert 66) &amp;#039;b)&lt;br /&gt;
       (else &amp;#039;unbekannt))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Schleifen ==&lt;br /&gt;
Scheme besitzt keinerlei Programmiersprachen-Konstrukte für Schleifen (allerdings wird in den automatisch inkorporierten „Scheme Standard Libraries“ beispielsweise mit dem do-Konstrukt die Möglichkeit von Schleifen angeboten). Schleifen werden in der Regel durch [[Rekursion|rekursive Funktionsaufrufe]] implementiert. Eine [[Endlosschleife (Programmierung)|Endlosschleife]] sieht im einfachsten Fall so aus:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (define (loop)&lt;br /&gt;
  (loop))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein häufig gezeigtes Beispiel, um dies zu demonstrieren, ist die Berechnung der [[Fakultät (Mathematik)|Fakultät]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (define (fak n)&lt;br /&gt;
    (if (= n 0) 1&lt;br /&gt;
        (* n (fak (- n 1)))))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um dieses theoretisch ansprechende Konzept praktikabel umzusetzen, optimiert Scheme die endstämmige Rekursion (bzw. allgemeiner: alle endstämmigen Funktionsaufrufe). Bei der nicht-endstämmigen [[Rekursion]] leistet die Funktion nach dem Selbstaufruf noch Arbeit. Im Beispiel die Multiplikation:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (fak 4)&lt;br /&gt;
 (* 4 (fak 3))&lt;br /&gt;
 (* 4 (* 3 (fak 2)))&lt;br /&gt;
 (* 4 (* 3 (* 2 (fak 1))))&lt;br /&gt;
 (* 4 (* 3 (* 2 (* 1 (fak 0)))))&lt;br /&gt;
 (* 4 (* 3 (* 2 (* 1 1))))&lt;br /&gt;
 (* 4 (* 3 (* 2 1)))&lt;br /&gt;
 (* 4 (* 3 2))&lt;br /&gt;
 (* 4 6)&lt;br /&gt;
 24&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier wird während des Ablaufs zum Speichern der Zwischenergebnisse zunehmend mehr (Speicher-)Platz benötigt. Eine endständige (tail-recursive) Variante des obigen Beispieles wäre:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (define (fak-iter n a)&lt;br /&gt;
  (if (= n 0) a&lt;br /&gt;
      (fak-iter (- n 1) (* n a))))&lt;br /&gt;
&lt;br /&gt;
 (define (fak n)&lt;br /&gt;
  (fak-iter n 1))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Ablauf würde dann wie folgt aussehen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scheme&amp;quot;&amp;gt;&lt;br /&gt;
 (fak 4)&lt;br /&gt;
 (fak-iter 4 1)&lt;br /&gt;
 (fak-iter 3 4)&lt;br /&gt;
 (fak-iter 2 12)&lt;br /&gt;
 (fak-iter 1 24)&lt;br /&gt;
 (fak-iter 0 24)&lt;br /&gt;
 24&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Scheme erkennt, dass das Ergebnis des Prozeduraufrufs nur noch zurückgegeben wird, und kann somit für alle Prozeduraufrufe denselben Speicherplatz verwenden. Die zusätzliche Variable &amp;#039;&amp;#039;a&amp;#039;&amp;#039; in der Prozedur &amp;#039;&amp;#039;fak-iter&amp;#039;&amp;#039; [[Akkumulator (Computer)|akkumuliert]] die Zwischenergebnisse.&lt;br /&gt;
&lt;br /&gt;
== Kommentare ==&lt;br /&gt;
Kommentare werden durch ein [[Semikolon]] (;) eingeleitet und reichen bis zum Zeilenende.&lt;br /&gt;
&lt;br /&gt;
== Vergleich zwischen Scheme und Lisp ==&lt;br /&gt;
Drei wesentliche Merkmale unterscheiden Scheme von [[Lisp]]:&lt;br /&gt;
* In Scheme gibt es die [[Funktion (Programmierung)|Funktion]] &amp;#039;&amp;#039;call-with-current-continuation&amp;#039;&amp;#039;. Sie erlaubt, die gegenwärtige [[Continuation]] (d.&amp;amp;nbsp;h. eine Art Ausführungszustand des laufenden [[Computerprogramm|Programms]]) als [[Variable (Programmierung)|Variable]] zu verwenden. Damit ist es möglich, später im Programmablauf zur Stelle dieser Continuation zurück zu springen.&lt;br /&gt;
* Der Scheme-Standard schreibt &amp;#039;&amp;#039;proper tail recursion&amp;#039;&amp;#039; vor: Prozeduraufrufe in einer [[endrekursiv]]en Position dürfen keinen Speicherplatz auf dem [[Aufrufstapel]] des Programms verbrauchen. Das bedeutet, dass eine unbegrenzte Anzahl an endrekursiven Aufrufen einer Prozedur möglich ist.&lt;br /&gt;
* Im Gegensatz zu Lisp sind [[Makro]]s in Scheme „hygienisch“: Innerhalb eines Makros eingeführte [[Variable (Programmierung)|Bezeichner]] [[Variable (Programmierung)#Sichtbarkeitsbereich von Variablen (Scope)|verdecken]] keine anderen Bezeichner der [[Lexikalische Umgebung|lexikalischen Umgebung]] außerhalb des Makros, also des aufrufenden Programms. Umgekehrt werden innerhalb eines Makros verwendete Bezeichner immer innerhalb der lexikalischen Umgebung des Makros aufgelöst, nicht außerhalb. Das bedeutet, dass die Bezeichner eines Makros nur für das Makro selbst [[Sichtbarkeit (Programmierung)|sichtbar]] sind und das Makro nicht auf Bezeichner des übergeordneten Programms zugreifen kann, sowie dass das Programm nicht auf die internen Bezeichner des Makros zugreifen kann.&lt;br /&gt;
&lt;br /&gt;
== Implementierungen und Entwicklungswerkzeuge ==&lt;br /&gt;
Es steht eine große Zahl von Implementierungen der Programmiersprache zur Verfügung.&amp;lt;ref&amp;gt;[http://community.schemewiki.org/?scheme-faq-standards#implementations Liste bekannter Implementierungen]&amp;lt;/ref&amp;gt; Im Folgenden werden nur einige populäre Implementierungen erwähnt:&lt;br /&gt;
* Bigloo&amp;lt;ref&amp;gt;[http://www-sop.inria.fr/mimosa/fp/Bigloo/ Bigloo-Webseite]&amp;lt;/ref&amp;gt; übersetzt Scheme-Code in verschiedene andere Sprachen: [[C (Programmiersprache)|C]], [[Java (Programmiersprache)|Java]] und [[.NET (Oberbegriff)|.NET]].&lt;br /&gt;
* [[Chicken (Scheme)|Chicken]] ist eine Implementierung, die Scheme nach C übersetzt und deswegen auf praktisch allen Plattformen läuft. Sie stellt sowohl einen Interpreter als auch einen Compiler zur Verfügung und hat wegen der Anbindung zu C eine umfangreiche Bibliothek an Erweiterungen. Die Implementierung ist weitgehend R5RS-konform.&lt;br /&gt;
* Gambit C&amp;lt;ref&amp;gt;[http://www.iro.umontreal.ca/~gambit/ Gambit C-Webseite]&amp;lt;/ref&amp;gt; verfügt neben einem Scheme-[[Interpreter]] auch über einen der effizientesten Scheme-zu-C-[[Compiler]].&lt;br /&gt;
* Gauche&amp;lt;ref&amp;gt;[http://practical-scheme.net/gauche/ Gauche-Webseite]&amp;lt;/ref&amp;gt; ist eine R7RS-konforme Implementierung. Sie ist als Skriptinterpreter für Entwickler und Administratoren konzipiert. Einige der Entwicklungsziele sind eine kurze Startzeit, eine eingebaute Systemschnittstelle, native Mehrsprachenunterstützung. Weiterhin können zahlreiche Erweiterungen eingebunden werden, z.&amp;amp;nbsp;B. für [[OpenGL]] und [[GTK+]].&lt;br /&gt;
* [[GNU Guile]] ist ein Interpreter, der als Bibliothek eingebunden werden kann. Ziel ist in erster Linie, Programme leicht um Scripting-Fähigkeiten erweitern zu können.&lt;br /&gt;
* LispMe&amp;lt;ref&amp;gt;[http://www.lispme.de/lispme/index_de.html LispMe-Webseite]&amp;lt;/ref&amp;gt; ist eine Implementierung für PalmOS-kompatible PDAs.&lt;br /&gt;
* Racket&amp;lt;ref&amp;gt;[http://www.racket-lang.org/ Racket-Webseite]&amp;lt;/ref&amp;gt; (früher PLT Scheme) ist eine verbreitete Implementierung, die neben einer großen Menge von Bibliotheken eine eigene [[Integrierte Entwicklungsumgebung|Entwicklungsumgebung]] mit dem Namen &amp;#039;&amp;#039;[[DrRacket]]&amp;#039;&amp;#039; (früher DrScheme) beinhaltet. &amp;#039;&amp;#039;DrRacket&amp;#039;&amp;#039; ist speziell auf den Einsatz in der Programmieranfängerausbildung zugeschnitten und leicht zu bedienen. Racket enthält mehrere Compiler, die Racket-/Scheme-Code zu &amp;lt;!-- nativem //Hä? Ist da Maschinencode gemeint? --&amp;gt; [[Bytecode|Byte-]]&amp;lt;!-- Bytecode für Racket? Oder wofür? JVM? --&amp;gt; oder C-Code umwandeln.&lt;br /&gt;
* Scheme 48&amp;lt;ref&amp;gt;[http://www.s48.org/ Scheme-48-Webseite]&amp;lt;/ref&amp;gt; ist eine komplett in Scheme geschriebene Scheme-Implementierung. Zum [[Bootstrapping (Programmierung)|Bootstrapping]] wird ein [[Statische Typisierung|statisch typisierter]] Scheme-Dialekt namens &amp;#039;&amp;#039;PreScheme&amp;#039;&amp;#039; verwendet. Scheme 48 übersetzt Scheme-Code in Bytecode, der in einem Speicherimage gesichert werden kann. Scheme 48 zeichnet sich besonders durch seine Möglichkeiten aus, Scheme-Code zu debuggen.&lt;br /&gt;
* SIOD.&amp;lt;ref&amp;gt;{{Webarchiv |url=http://www.cs.indiana.edu/scheme-repository/imp/siod.html |text=SIOD-Webseite |wayback=20070406212001}}&amp;lt;/ref&amp;gt; Ein kleiner, schneller Scheme-Interpreter, der unter anderem Verwendung in [[GIMP]]s &amp;#039;&amp;#039;[[ScriptFu]]&amp;#039;&amp;#039; bis Version 2.4 fand.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
* Hal Abelson, Gerald Jay Sussman: &amp;#039;&amp;#039;[[Structure and Interpretation of Computer Programs]]&amp;#039;&amp;#039;. McGraw-Hill, ISBN 0-07-000422-6&lt;br /&gt;
* Hal Abelson, Gerald Jay Sussman: &amp;#039;&amp;#039;Struktur und Interpretation von Computerprogrammen&amp;#039;&amp;#039;. Springer-Verlag, ISBN 3-540-42342-7&lt;br /&gt;
* R. Kent Dybvig: &amp;#039;&amp;#039;The Scheme Programming Language&amp;#039;&amp;#039;. The MIT Press, ISBN 0-262-54148-3 ([http://www.scheme.com/tspl4/ 4. Ausgabe online])&lt;br /&gt;
* Iain Ferguson: &amp;#039;&amp;#039;The Schemer’s Guide&amp;#039;&amp;#039;. Schemers Inc., ISBN 0-9628745-2-3&lt;br /&gt;
* Daniel P. Friedman, Matthias Felleisen: &amp;#039;&amp;#039;The Little Schemer&amp;#039;&amp;#039;. The MIT Press, ISBN 0-262-56099-2&lt;br /&gt;
* Daniel P. Friedman, Matthias Felleisen: &amp;#039;&amp;#039;The Seasoned Schemer&amp;#039;&amp;#039;. The MIT Press, ISBN 0-262-56100-X&lt;br /&gt;
* Daniel P. Friedman, Matthias Felleisen: &amp;#039;&amp;#039;The Reasoned Schemer&amp;#039;&amp;#039;. The MIT Press, ISBN 0-262-56214-6&lt;br /&gt;
* George Springer, Daniel P. Friedman: &amp;#039;&amp;#039;Scheme and the Art of Programming&amp;#039;&amp;#039;. The MIT Press, ISBN 0-262-19288-8&lt;br /&gt;
* Herbert Klaeren, Michael Sperber: &amp;#039;&amp;#039;Die Macht der Abstraktion: Einführung in die Programmierung&amp;#039;&amp;#039;. Teubner, ISBN 3-8351-0155-2&lt;br /&gt;
* Herbert Klaeren, Michael Sperber: &amp;#039;&amp;#039;Vom Problem zum Programm&amp;#039;&amp;#039;. Teubner, ISBN 3-519-22242-6&lt;br /&gt;
* Jacques Chazarain: &amp;#039;&amp;#039;Programmer avec Scheme&amp;#039;&amp;#039;. International Thomson Publishing, France, ISBN 2-84180-131-4&lt;br /&gt;
* Chris Hanson, Garald Jay Sussman: &amp;#039;&amp;#039;Software Design for Flexibility&amp;#039;&amp;#039;. The MIT Press, ISBN 978-0-262-04549-0&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
{{Wikisource|Scheme: An Interpreter for Extended Lambda Calculus|lang=en}}&lt;br /&gt;
* [http://www.schemers.org/ schemers.org] Materialsammlung zu Scheme&lt;br /&gt;
* Guy Steele, Gerald Sussman: [http://library.readscheme.org/page1.html The Original ‚Lambda Papers‘.]&lt;br /&gt;
* [http://srfi.schemers.org/ SRFI (Scheme Requests for Implementation)] stellt eine Sammlung von Funktionalitäten bereit, die sich praktisch als Standard-Bibliothek für Scheme-Implementierungen herausgebildet hat.&lt;br /&gt;
&lt;br /&gt;
=== Einführungen ===&lt;br /&gt;
* [http://www.htdp.org/ How To Design Programs] (HTDP) – Einsteiger-Scheme-Buch&lt;br /&gt;
* [http://mitpress.mit.edu/sicp/ &amp;#039;&amp;#039;Structure and Interpretation of Computer Programs&amp;#039;&amp;#039;] (SICP) – Dieses Scheme-Buch wurde jahrelang in den Einsteiger-Programmierkursen am [[Massachusetts Institute of Technology|MIT]] und anderen Universitäten verwendet.&lt;br /&gt;
* [https://ds26gte.github.io/tyscheme/index.html &amp;#039;&amp;#039;Teach Yourself Scheme in Fixnum Days&amp;#039;&amp;#039;.] – Online-Kurs für Einsteiger.&lt;br /&gt;
&lt;br /&gt;
=== Sprachstandards ===&lt;br /&gt;
* [http://www.schemers.org/Documents/Standards/R5RS/ Definition des veralteten Sprachstandards R&amp;lt;sup&amp;gt;5&amp;lt;/sup&amp;gt;RS]&lt;br /&gt;
* [http://www.r6rs.org/ Definition des vorherigen Sprachstandards R&amp;lt;sup&amp;gt;6&amp;lt;/sup&amp;gt;RS]&lt;br /&gt;
* [https://bitbucket.org/cowan/r7rs/raw/4c27517de187142ad2cf4bcd8cb9199ae1e48c09/rnrs/r7rs.pdf Definition des aktuellen Sprachstandards R&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;RS] (PDF; 679&amp;amp;nbsp;kB)&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Lisp]]&lt;br /&gt;
[[Kategorie:Funktionale Programmiersprache]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Neubadener</name></author>
	</entry>
</feed>