### 3.3. Liste, liste e ancora liste

Abbiamo fatto pratica con le variabili e le funzioni, ora si entra nella palude fangosa delle liste di Scheme.

#### 3.3.1. Definire una lista

Prima di approfondire le liste è necessario comprendere la differenza tra valori atomici e liste.

Abbiamo già visto i valori atomici quando abbiamo inizializzato le variabili nella sessione precedente. Un valore atomico è un valore singolo. Ad esempio possiamo assegnare alla variabile «`x`» il singolo valore 8 nell'istruzione seguente:

    (let* ( (x 8) ) x)

(abbiamo aggiunto l'espressione `x` alla fine per stampare il valore assegnato a `x`; normalmente non si dovrebbe averne bisogno. Si noti come `let*` operi come una funzione: il valore dell'ultima istruzione è il valore restituito)

Una variabile può anche riferirsi ad una lista di valori piuttosto che a un singolo valore. Per assegnare alla variabile `x` la lista di valori 1, 3, 5 si digiti:

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

Si provi a digitare entrambe le istruzioni nella console Script-fu e si osservino le risposte. Quando si digita la prima istruzione si ottiene semplicemente il risultato:

    8

Mentre se si digita l'altra istruzione si ottiene il seguente risultato:

    (1 3 5)

Quando si ottiene il valore 8 l'interprete sta informando che `x` contiene il valore atomico 8 mentre quando si ottiene `(1 3 5)` sta informando che `x` contiene non un valore singolo bensì una lista di valori. Si noti che non ci sono virgole nella dichiarazione o assegnamento della lista, tantomeno nel risultato stampato.

La sintassi per definire una lista è:

    '(a b c)

dove `a`, `b`, e `c` sono letterali. Si usa l'apostrofo (') per indicare che ciò che segue nelle parentesi è una lista di valori letterali piuttosto che una funzione o un'espressione.

Una lista vuota può essere definita come segue:

    '()

o semplicemente:

    ()

Le liste possono contenere valori atomici così come altre liste:

    (let*
       (
            (x
               '("GIMP" (1 2 3) ("è" ("grande" () ) ) )
            )
        )
        x
    )

Si noti che dopo il primo apostrofo non vi è più bisogno di utilizzare un apostrofo per definire le liste interne. Si provi a copiare l'istruzione nella console Script-Fu e ad eseguirla per vedere cosa restituisce.

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. Come concepire le liste

È utile pensare alle liste come composte di una «testa» e una «coda». La testa è l'elemento iniziale della lista, la coda è la parte restante. Si capirà l'importanza di questo concetto quando si parlerà di come si compongono le liste e come accedere agli elementi di una lista.

#### 3.3.3. Creazione di liste attraverso la concatenazione (la funzione Cons)

Una delle funzioni più comuni che si incontrano è la funzione cons. Prende un valore e lo mette in testa al suo secondo argomento, una lista. Nel capitolo precedente si è suggerito di pensare una lista come composta da un elemento (la testa) è la parte restante (la coda), questo è esattamente il comportamento della funzione cons: aggiunge un elemento in testa alla lista. Si potrebbe creare una lista come segue:

    (cons 1 '(2 3 4) )

Il risultato è la lista `(1 2 3 4)`.

Si può anche creare una lista con un solo elemento:

    (cons 1 () )

Si possono utilizzare variabili dichiarate in precedenza al posto di qualunque letterale come ci si aspetta.

#### 3.3.4. Definizione di una lista usando la funzione `list`

Per definire una lista composta da letterali oppure da variabili precedentemente dichiarate si utilizza la funzione `list`:

    (list 5 4 3 a b c)

Ciò costruirà e restituirà una lista contenente i valori mantenuti dalle variabili `a`, `b` e `c`. Ad esempio:

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

                   (list 5 4 3 a b c)
            )

Questo codice crea la lista `(5 4 3 1 2 3)`.

#### 3.3.5. Accedere ai valori contenuti in una lista

Per accedere ai valori in una lista usare le funzioni `car` e `cdr`, che restituiscono rispettivamente il primo elemento della lista e la porzione restante. Queste funzioni spezzano la lista nel costrutto testa::coda precedentemente menzionato.

#### 3.3.6. La funzione `car`

`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 '("primo" 2 "terzo"))

che è:

    "primo"

#### 3.3.7. La funzione `cdr`

`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 '("primo" 2 "secondo"))

restituisce:

    (2 "terzo")

mentre l'istruzione seguente:

    (cdr '("uno e solo"))

restituisce:

    ()

#### 3.3.8. Accedere ad altri elementi di una lista

Bene, si è ora in grado di ottenere il primo elemento di una lista così come la parte restante ma come si accede agli altri elementi di una lista? Esistono parecchie funzioni di "convenienza" per accedere alla testa della testa (`caadr`) o analogamente alla coda di una lista (`cddr`), ecc.

La convenzione sui nomi di base è semplice: le a e le d rappresentano le teste e le code quindi

    (car (cdr (car x) ) )

si potrebbe scrivere come:

    (cadar x)

Per impratichirsi con le funzioni di accesso alle liste si provi a digitare quanto segue (su di un'unica riga se si utilizza la console), si utilizzino differenti varianti di `car` e `cdr` per accedere ai differenti elementi della lista:

            (let* (
                    (x '( (1 2 (3 4 5) 6) 7 8 (9 10) )
                    )
                  )
                  ;  metti il tuo codice car/cdr qui
            )

Si provi ad accedere al numero 3 nella lista utilizzando solo due chiamate a funzione. Se si è in grado di farlo si è sulla buona strada per diventare un maestro di Script-Fu!

| Nota
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. Variabili e funzioni |  | 3.4. Il primo script Script-Fu

Report a bug in GIMP Segnalate l'errore sulla piattaforma apposita