3.3. Listen, Listen und noch mehr Listen
| 3. Ein Skript-Fu-Tutorial |

### 3.3. Listen, Listen und noch mehr Listen

Wir haben Ihnen etwas über Variablen und Funktionen erklärt, und nun betreten wir die düsteren Sümpfe von Schemes Listen …

#### 3.3.1. Eine Liste definieren

Bevor wir mehr über Listen erzählen, müssen Sie den Unterschied zwischen atomaren Werten und Listen kennen.

Sie haben bereits atomare Werte gesehen, als wir im vorherigen Abschnitt Variablen initialisiert hatten. Ein atomarer Wert ist ein einzelner Wert. Zum Beispiel können wir in der folgenden Anweisung der Variablen „`x`“ den Wert 8 zuweisen:

    (let* ( (x 8) ) x)

(We added the expression `x` at the end to print out the value assigned to `x`—normally you won't need to do this. Notice how `let*` operates just like a function: The value of the last statement is the value returned.)

Eine Variable kann sich auch auf eine Liste von Werten statt auf einen einzelnen Wert beziehen. Um der Variablen `x` die Liste der Werte 1, 3, 5 zuzuweisen, schreiben wir:

    (let* ( (x '(1 3 5))) x)

Probieren Sie beide Anweisungen in der Skript-Fu-Konsole aus und achten Sie auf die Antworten. Bei der ersten Anweisung lautet sie einfach:

    8

Wenn Sie aber die andere Anweisung eingeben, ist die Antwort das folgende Ergebnis:

    (1 3 5)

Die erste Antwort sagt Ihnen, dass `x` den atomaren Wert 8 enthält. Aber wenn die Antwort `(1 3 5)` lautet, dann heißt das, dass `x` keinen atomaren Wert, sondern eine Liste von Werten enthält. Beachten Sie, dass weder in unserer Deklaration oder Zuweisung der Liste noch im ausgegebenen Resultat Kommas stehen.

Die Syntax, um eine Liste zu definieren, lautet:

    '(a b c)

wobei `a`, `b` und `c` Literale (buchstabengetreu einzugeben) sind. Wir verwenden den Apostroph (`'`) um anzuzeigen, dass der nachfolgende Klammerausdruck eine Liste literaler Werte ist und nicht eine Funktion oder ein Ausdruck.

Eine leere Liste kann wie folgt definiert werden:

    '()

oder einfach:

    ()

Listen können sowohl atomare Werte als auch andere Listen enthalten:

    (let*
       (
            (x
               '("GIMP" (1 2 3) ("ist" ("toll" () ) ) )
            )
        )
        x
    )

Beachten Sie, dass Sie nach dem ersten Apostroph keine weiteren Apostrophe mehr brauchen, wenn Sie innere Listen definieren. Probieren Sie es nun aus, kopieren Sie die Anweisung in die Skript-Fu-Konsole und schauen Sie, was sie zurück liefert.

You should notice that the result returned is not a list of single, atomic values; rather, it is a list of a literal `("GIMP")`, the list `(1 2 3)`, etc.

#### 3.3.2. Wie man sich Listen vorstellen sollte

Es ist hilfreich, sich Listen zusammengesetzt aus einem „Kopf“ (head) und einem „Rest“ (tail, wörtlich »Schwanz« oder »Ende«) vorzustellen. Der Kopf ist das erste Element der Liste, der Rest alle folgenden Elemente. Sie werden gleich sehen, warum das wichtig ist, wenn wir besprechen, wie man zu Listen etwas hinzufügt und wie man auf Elemente der Liste zugreift.

#### 3.3.3. Listen durch Konkatenation (Verkettung) erstellen (die `cons`-Funktion)

One of the more common functions you'll encounter is the cons function. It takes a value and places it to its second argument, a list. From the previous section, I suggested that you think of a list as being composed of an element (the head) and the remainder of the list (the tail). This is exactly how cons functions — it adds an element to the head of a list. Thus, you could create a list as follows:

    (cons 1 '(2 3 4) )

Das Ergebnis ist die Liste `(1 2 3 4)`.

Sie könnten auch eine Liste mit nur einem Element erstellen:

    (cons 1 () )

Sie können vorher deklarierte Variablen anstelle irgendwelcher Literale verwenden, genauso, wie man es erwarten würde.

#### 3.3.4. Eine Liste mit der `list`-Funktion definieren

Um eine Liste aus Literalen oder vorher deklarierten Variablen zu definieren, verwenden Sie die `list`-Funktion:

    (list 5 4 3 a b c)

Das wird eine Liste erstellen, die die Werte der Variablen `a`, `b` und `c` enthält, und diese zurückgeben. Beispiel:

            (let*  (
                      (a 1)
                      (b 2)
                      (c 3)
                   )

                   (list 5 4 3 a b c)
            )

Dieser Code erzeugt die Liste `(5 4 3 1 2 3)`.

#### 3.3.5. Auf Werte in einer Liste zugreifen

Um auf Werte in einer Liste zuzugreifen, verwenden Sie die Funktionen `car` und `cdr`, die das erste Element resp. den Rest einer Liste liefern. Diese Funktionen gliedern die Liste in die vorher erwähnte Struktur aus head (Kopf) und tail (Rest) auf.

#### 3.3.6. Die `car`-Funktion

`car` returns the first element of the list (the head of the list). The list needs to be non-null (not empty). Thus, the following returns the first element of the list:

    (car '("erstes" 2 "drittes"))

nämlich:

    "erstes"

#### 3.3.7. Die `cdr`-Funktion

`cdr` returns the remainder of the list after the first element (the tail of the list). If there is only one element in the list, it returns an empty list.

    (cdr '("erstes" 2 "drittes"))

liefert:

    (2 "drittes")

während folgende Anweisung:

    (cdr '("das einzig wahre"))

liefert:

    ()

#### 3.3.8. Auf andere Elemente der Liste zugreifen

Na schön, wir können sowohl auf das erste Element als auch auf den Rest der Liste zugreifen, aber wie kommen wir an das zweite, dritte oder irgendein anderes Element der Liste? Aus praktischen Gründen gibt es einige Zugriffsfunktionen, um beispielsweise auf den Kopf eines Kopfes eines Rests (`caadr`) oder den Rest eines Restes (`cddr`) einer Liste zuzugreifen.

Die zugrunde liegende Namenskonvention ist einfach: Die »a«s und »d«s repräsentieren Köpfe beziehungsweise Reste von Listen, d.h.

    (car (cdr (car x) ) )

kann geschrieben werden als:

    (cadar x)

Um mit den Listenzugriffsfunktionen etwas Übung zu bekommen, versuchen Sie mal, folgendes einzugeben (alles in einer Zeile, falls Sie die Konsole benutzen) und verschiedene Variationen von `car`s und `cdr`s auszuprobieren, um auf verschiedene Elemente der Liste zuzugreifen:

            (let* (
                     (x  '( (1 2 (3 4 5) 6)  7  8  (9 10) )
                     )
                  )
                  ; hierhin kommt Ihr car/cdr-Code
            )

Versuchen Sie, mit nur zwei Funktionsaufrufen auf die Zahl 3 zuzugreifen. Wenn Sie das schaffen, sind Sie auf dem besten Wege, ein Skript-Fu-Meister zu werden!

| Anmerkung
In Scheme, a semicolon (`;`) marks the beginning of a comment. It, and everything that follows it on the same line, are ignored by the script interpreter, so you can use this to add comments to refresh your memory when you look at the script later.

3.2. Variablen und Funktionen |  | 3.4. Ihr erstes Fu-Skript

Report a bug in GIMP Report a documentation error