Le hemos entrenado en variables y funciones, y ahora, entramos en el lúgubre pantano de las listas Scheme.
Antes de que hablamos más sobre las listas, es necesario que sepa la diferencia entre valores atómicos y listas.
Ya ha visto los valores atómicos cuando inicializamos variables en la lección anterior. Un valor atómico es un valor simple. Así, por ejemplo, podemos asignar a la variable "x" el valor simple de 8 en la declaración siguiente:
(let* ( (x 8) ) x)
(Añadimos la expresión x al final para imprimir el valor asignado a x-- normalmente, no necesitará hacer esto. Note como let* opera justo como una función: El valor de la última declaración es el valor devuelto).
Una variable puede, tambien, referirse a una lista de valores, casi como un valor simple. Para asignar a la variable x , la lista de valores 1, 3, 5, tecleamos:
(let* ( (x '(1 3 5))) x)
Intente teclear ambas declaraciones en la consola de Script-Fu y verá como contesta. Cuando teclea la primera declaración, responde con el resultado:
8
Cuando teclea la otra declaración, responde con el siguiente resultado:
(1 3 5)
Cuando responde con el valor 8 está informando que
x
contiene el valor atómico 8. Cuando responde
con (1 3 5), entonces, está informando que x
no
contiene un valor simple, sino una lista de valores. Note que no hay
comillas en nuestra declaración o en la asignación de la lista, ni
en el resultado impreso.
La sintaxis para definir una lista es:
'(a b c)
donde a
, b
, y
c
son literales. Usamos el apóstrofe (') para
indicar que lo que sigue entre paréntesis es una lista de valores
literales, casí como una función o expresión.
Una lista vacia puede definirse como:
'()
o simplemente:
()
Las listas pueden contener valores atómicos, así como otras listas:
(let* ( (x '("The GIMP" (1 2 3) ("is" ("great" () ) ) ) ) ) x )
Note que después del primer apóstrofe, no necesita usar un apóstrofe cuando defina las listas internas. Adelante, copie la declaración en la consola de Script-Fu y mire que devuelve.
Notará que el resultado devuelto no es una lista de simples valores
atómicos; casí es una lista de un literal
("The GIMP")
, la lista (1 2 3)
, etc.
Es útil pensar que las listas están compuestas de una “cabeza” y de una “cola”. La cabeza es el primer elemento de la lista, la cola es el resto de la lista. Verá porque esto es importante cuando tratemos como añadir listas y como acceder elementos en la lista.
Una de las funciones más comunes que encontrará es la función
cons
.
Toma un valor y lo situa en el segundo argumento, una lista. En la
sección previa, sugerí que piense que una lista está compuesta de un
elemento (la cabeza) y el resto de la lista (la cola). Es,
exactamente, como cons
funciona -- añade un elemento a
la cabeza de la lista. Puede crear una lista como sigue:
(cons 1 '(2 3 4) )
El resultado es la lista (1 2 3 4)
.
(cons 1 () )
Puede usar, previamente, variables declaradas en lugar de literales, como cabría esperar.
Para definir una lista compuesta de literales o, previamente,
variables declaradas, use la función list
:
(list 5 4 3 a b c)
Esto compondrá y devolverá una lista conteniendo los valores de las
variables a
, b
y c
. Por ejemplo:
(let* ( (a 1) (b 2) (c 3) ) (list 5 4 3 a b c) )
Este código crea la lista (5 4 3 1 2 3)
.
Para acceder a los valores de una lista, use las funciones
car
y cdr
, que devuelven el primer elemento
de la lista y el resto de la lista, respectivamente. Estas funciones
rompen la lista en la construcción cabeza::cola que mencioné antes.
car
devuelve el primer elemento de la lista (la cabeza
de la lista). La lista necesita ser no -null. La siguiente devuelve
el primer elemento de la lista:
(car '("first" 2 "third"))
que es:
"first"
cdr
devuelve el resto de la lista después del primer
elemento (la cola de la lista). Si solo hay un elemento en la lista,
devuelve una lista vacia.
(cdr '("first" 2 "third"))
devuelve:
(2 "third")
donde la siguiente:
(cdr '("one and only"))
devuelve:
()
OK, bravo,podemos obtener el primer elemento en una lista, tanto
como el resto de la lista, pero ¿como hacemos para acceder al
segundo, tercero o otros elementos de la lista?. Existen varias
funciones convenientes para acceder, por ejemplo, la cabeza de la
cabeza de una cola de una lista (caadr
), la cola de la
cola de una lista (cddr
), etc.
La convención básica para nombrar es fácil: a y d representan las cabezas y las colas de la lista, así
(car (cdr (car x) ) )
(cadar x)
Para ver una lista completa de la lista de funciones, le remitimos al apéndice, que lista las funciones disponibles para la versión de Scheme usada por Script-Fu.
Para tener práctica con las funciones de acceso a listas, intente teclear lo siguiente ( en una sola linea si está usando la consola); use diferentes variaciones de car y cdr para acceder a los diferentes elementos de la lista:
(let* ( (x '( (1 2 (3 4 5) 6) 7 8 (9 10) ) ) ) ; place your car/cdr code here )
Intente acceder al número 3 en la lista usando solo dos llamadas a función. Si puede hacer eso, está en el camino para llegar a ser un Maestro de Script-Fu!.
Nota | |
---|---|
En Scheme, un punto y coma ";" marca un comentario. Esto y todo lo que siga en la misma linea, es ignorado por el interprete de script, así que puede usar esto para añadir comentarios para refrescar su memoria cuando vuelva a mirar su script. |