3.3. Llistes, llistes i més llistes
| 3. Programa d'aprenentatge de l’Script-Fu |

### 3.3. Llistes, llistes i més llistes

Després de veure les variables i funcions, ara ve la difícil qüestió de les llistes Scheme.

#### 3.3.1. Definir una llista

Abans de parlar més sobre les llistes, heu de conèixer la diferència entre els valors atòmics i les llistes.

Ja heu vist els valors atòmics en inicialitzar les variables en la lliçó anterior. Un valor atòmic és un valor simple, és a dir, una variable amb un valor únic. Així, per exemple, es pot assignar a la variable «`x`» el valor simple de 8 a la següent declaració:

    (let* ( (x 8) ) x)

(Afegim l'expressió «`x`» al final per mostrar el valor assignat a «`x`», normalment no necessitareu fer això. Recordeu com opera el `let*` justament com una funció: el valor de l'última declaració és el valor retornat.)

Una variable també pot referir-se a una llista de valors, en lloc d'un valor simple. Per assignar a la variable `x` la llista de valors 1, 3, 5, escrivim:

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

Intenteu teclejar ambdues declaracions en la consola de Script-Fu i veureu què passa. Quan teclegeu la primera declaració, respon amb el resultat:

    8

No obstant això, quan teclegeu l'altra declaració, respon amb el següent resultat:

    (1 3 5)

Quan respon amb el valor 8 vol dir que està informant que `x` conté el valor atòmic 8. Tanmateix, quan respon amb `(1 3 5)`, està informant que `x` no conté un valor simple, sinó una llista de valors. Recordeu que no hi ha cometes a la nostra declaració o en l'assignació de la llista, ni en el resultat mostrat.

La sintaxi per definir una llista de valors és:

    '(a b c)

on `a`, `b`, i `c` són literals. Utilitzem l'apòstrof (`'`) per indicar que el que segueix entre parèntesis és una llista de valors literals, en lloc d'una funció o expressió.

Una llista buida es pot definir com:

    '()

o simplement:

    ()

Les llistes poden contenir valors atòmics, així com altres llistes:

    (let*
       (
            (x
               '("GIMP" (1 2 3) ("is" ("great" () ) ) )
            )
        )
        x
    )

Recordeu que després del primer apòstrof, ja no cal utilitzar un apòstrof en la definició de les llistes internes. Proveu aquesta declaració en la consola de Script-Fu i mireu què retorna.

Notareu que el resultat retornat no és una llista de valors simples, sinó més aviat una llista d'un literal `("GIMP")`, d'una llista `(1 2 3)`, etc.

#### 3.3.2. Com es representen les llistes?

És útil pensar que les llistes estan compostes d'un «cap» i d'una «cua». El cap és el primer element de la llista i la resta és la cua. Veureu per què és important quan considerem com afegir llistes i com accedir als elements de la llista.

#### 3.3.3. Creació de llistes per concatenació (la funció Cons)

Una de les funcions que trobareu més sovint és la funció `cons`. Pren un valor i la situa al capdavant del segon element, una llista. En la secció prèvia, s'aconsella que imagineu les llistes com constituïdes d'un cap i d'una cua. Doncs bé, la funció `cons` afegeix un element al cap de la llista. Així podeu crear una llista de la següent manera:

    (cons 1 '(2 3 4) )

El resultat és la llista `(1 2 3 4)`.

També podreu crear una llista amb un element:

    (cons 1 () )

Podeu utilitzar variables prèviament declarades en lloc de literals.

#### 3.3.4. Definiu una llista amb la funció `list`

Per definir una llista composta de literals o, prèviament, variables declarades, utilitzeu la funció `list`:

    (llista 5 4 3 a b c)

Això compondrà i retornarà una llista que conté els valors de les variables `a`, `b` i `c`. Per exemple:

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

                   (list 5 4 3 a b c)
            )

Aquest codi crea la llista `(5 4 3 1 2 3)`.

#### 3.3.5. Accediu als valors d'una llista

Per accedir als valors d'una llista, utilitzeu les funcions `car` i `cdr`, que retornen respectivament el primer element de la llista i la resta de la llista. Aquestes funcions trenquen l'estructura cap::cua que s'ha esmentat abans.

#### 3.3.6. La funció `car`

`car` retorna el primer element de la llista (el cap de la llista). La llista no ha d'estar buida. La següent retorna el primer element de la llista:

    (car '("first" 2 "third"))

que és:

    "primer"

#### 3.3.7. La funció `cdr`

`cdr` retorna la resta de la llista després del primer element, és a dir, la cua de la llista. Si només hi ha un element de la llista, retorna una llista buida.

    (cdr '("first" 2 "third"))

retorna:

    (2 "third")

mentre que la següent:

    (cdr '("one and only"))

retorna:

    ()

#### 3.3.8. Accediu a altres elements d'una llista

Bé, entesos, podem accedir al primer element i a la resta de la llista, però com ho fem per accedir al segon, tercer o altres elements de la llista? Hi ha diverses maneres d’accedir-hi, per exemple, el cap del cap d'una cua d'una llista (`caadr`), la cua de la cua d'una llista (`cddr`), etc.

La convenció bàsica és fàcil: «a» i «d» representen els caps i les cues de la llista. Així

    (car (cdr (car x) ) )

es podria escriure:

    (cadar x)

Per tenir pràctica amb les funcions d'accés a llistes, intenteu escriure el següent (en una sola línia si utilitzeu la consola); utilitzeu diferents variacions de `car` i `cdr` per accedir als diferents elements de la llista:

            (let* (
                     (x  '( (1 2 (3 4 5) 6)  7  8  (9 10) )
                     )
                  )
                  ; place your car/cdr code here
            )

Intenteu accedir al número 3 de la llista utilitzant només dues crides de la funció. Si podeu fer això, esteu en el camí per esdevenir un mestre de Script-Fu.

| Nota
En l'Scheme, un punt i coma (`;`) marca un comentari. Això farà que l'intèrpret de l'script ignori tot el que segueixi en la mateixa línia, així que es pot utilitzar per afegir comentaris que facilitaran la comprensió i us refrescaran la memòria quan torneu a mirar l'script.

3.2. Variables i funcions |  | 3.4. El vostre primer codi de Script-Fu

Report an error in the bug tracker