3.2. Variablen und Funktionen

Jetzt, wo wir wissen, dass jede Scheme-Anweisung von Klammern umgeben ist und dass der Funktionsname/-operator als erstes aufgeführt wird, müssen wir sehen, wie man Variablen oder Funktionen erzeugt und benutzt. Wir fangen mit den Variablen an.

3.2.1. Variablen deklarieren

Es gibt mehrere verschiedene Methoden, um Variablen zu deklarieren, aber die bevorzugte Methode ist das let*-Konstrukt. Wenn Sie mit anderen Programmiersprachen vertraut sind: Dieses Konstrukt ist äquivalent dazu, eine Liste lokaler Variablen mit zugehörigem Gültigkeitsbereich zu definieren. Um beispielsweise zwei Variablen a und b zu deklarieren und mit den Werten 1 beziehungsweise 2 zu initialisieren, würden Sie folgendes schreiben:

        (let*
           (
              (a 1)
              (b 2)
           )
           (+ a b)
        )
      

oder, als Einzeiler:

(let* ( (a 1) (b 2) ) (+ a b) )
[Anmerkung] Anmerkung

Sie müssen dies alles in eine Zeile schreiben, wenn Sie das Konsolenfenster benutzen. Im allgemeinen sollten Sie allerdings einen ähnlichen Einrückungsstil wie oben übernehmen, um Ihre Skripte lesbarer zu gestalten. Wir werden im Abschnitt über Leerzeichen noch ein wenig mehr dazu sagen.

Das deklariert zwei lokale Variablen a und b, initialisiert sie, und gibt dann die Summe der beiden Variablen aus.

3.2.2. Was ist eine lokale Variable?

Sie werden bemerkt haben, dass wir die Summe (+ a b) innerhalb der Klammern des let*-Ausdrucks und nicht außerhalb geschrieben haben.

Das kommt daher, weil die let*-Anweisung einen Bereich in Ihrem Skript definiert, in dem die deklarierten Variablen verwendet werden können. Wenn Sie die Anweisung (+ a b) nach dem Ausdruck (let* …) schreiben, erhalten Sie eine Fehlermeldung, da die deklarierten Variablen nur innerhalb des Kontexts der let*-Anweisung gültig sind. Sie sind das, was Programmierer »lokale Variablen« nennen.

3.2.3. Die allgemeine Syntax von let*

Die allgemeine Form der let*-Anweisung ist:

        (let* ( variablen )
          ausdrücke )
      

wobei Variablen innerhalb von Klammern deklariert werden, z.B. (a 2), und Ausdrücke beliebige gültige Scheme-Ausdrücke sind. Denken Sie daran, dass die hier deklarierten Variablen nur innerhalb der let*-Anweisung gültig sind – sie sind lokale Variablen.

3.2.4. Leerzeichen

Wir haben bereits vorher erwähnt, dass Sie Ihre Skripte mit Einrückungen lesbarer gestalten sollten. Das ist eine gute Vorgehensweise und überhaupt kein Problem in Scheme – Leerzeichen (A.d.Ü.: Gemeint sind Leerzeichen im erweiterten Sinne (»Freizeichen«), also auch Zeilenvorschub und -umbruch, Seitenvorschub, horizontaler und vertikaler Tabulator) werden vom Scheme-Interpreter ignoriert und können daher großzügig eingesetzt werden, um den Code in Ihrem Skript zu organisieren und zu verdeutlichen. Wenn Sie allerdings im Skript-Fu-Konsolenfenster arbeiten, müssen Sie jeden Ausdruck in eine Zeile schreiben, d.h. alles zwischen der öffnenden und der korrespondierenden schließenden Klammer eines Ausdrucks.

3.2.5. Einer Variablen einen neuen Wert zuweisen

Wenn Sie eine Variable initialisiert haben, müssen Sie ihren Wert vielleicht später im Skript verändern. Verwenden Sie dafür die set!-Anweisung:

        (let* ( (theNum 10) ) (set! theNum (+ theNum theNum)) )
      

Überlegen Sie sich, was die obige Anweisung tun wird, und dann probieren Sie es aus und geben Sie sie in der Skript-Fu-Konsole ein.

[Anmerkung] Anmerkung

Das »\« zeigt an, dass dort kein Zeilenumbruch ist. Ignorieren Sie es (tippen Sie es nicht in Ihrer Skript-Fu-Konsole ein und drücken Sie nicht auf »Eingabe«), machen Sie einfach mit der nächsten Zeile weiter.

3.2.6. Funktionen

Nachdem Sie nun den Dreh mit den Variablen raushaben, lassen Sie uns ein wenig mit Funktionen arbeiten. Sie deklarieren eine Funktion gemäß der folgenden Syntax:

        (define
           (
              name
              param-list
           )
           ausdrücke
        )
      

wobei name der der Funktion zugewiesene Name ist, param-list eine durch Leerzeichen getrennte Liste von Parameternamen und ausdrücke eine Folge von Ausdrücken, die die Funktion bei ihrem Aufruf ausführt. Zum Beispiel:

(define (AddXY inX inY) (+ inX inY) )

AddXY ist der Funktionsname, und inX und inY sind die Variablen. Die Funktion erwartet zwei Parameter und addiert sie.

Wenn Sie bereits in anderen imperativen Sprachen programmiert haben (z.B. in C/C++, Java, Pascal, etc.), dann werden Sie vielleicht bemerkt haben, dass im Vergleich zu anderen Programmiersprachen einige Dinge in dieser Funktionsdefinition fehlen.

  • Als erstes beachten Sie, dass die Parameter keinen »Typ« haben (d.h. wir haben sie nicht als Zeichenketten, Ganzzahlen etc. deklariert). Scheme ist eine typfreie Sprache. Das ist ganz praktisch und erlaubt es uns, Skripte sehr viel schneller zu schreiben.

  • Als zweites achten Sie darauf, dass wir uns keine Gedanken darüber machen müssen, wie wir das Ergebnis unserer Funktion zurückgeben – die letzte Anweisung ist der Wert, der beim Aufruf der Funktion zurückgegeben wird. Tippen Sie die Funktion in der Konsole ein, und dann versuchen Sie so etwas wie:

    (AddXY (AddXY 5 6) 4)