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] 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.