Te hemos entrenado en variables y funciones, y ahora, entramos en el lúgubre pantano de las listas Scheme.
Antes hablamos más sobre las listas, es necesario que sepas la diferencia entre valores atómicos y listas..
Ya has 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ás hacer esto. Nota 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)
Intenta teclear ambas declaraciones en la Consola Script-Fu y verás como contesta. Cuando tecleas la primera declaración, responde con el resultado:
8
Cuando tecleas la otra declaración, responde con el siguiente resultado:
(1 3 5)
Cuando responde con el valor 8 está informandote que
x
contiene el valor atómico 8. Cuando
responde con (1 3 5), Entonces, está informandote que
x
no contiene un valor simple, sino una
lista de valores. Nota 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 eso 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 ser definida como:
'()
o simplemente:
()
Las listas pueden contener valores atómicos, tanto como otras listas:
(let* ( (x '("The Gimp" (1 2 3) ("is" ("great" () ) ) ) ) ) x )
Nota que después del primer apóstrofe, no necesitas usar un apóstrofe cuando definas las listas internas. Adelante, copia la declaración en la Consola Script-Fu y mira que devuelve.
Notarás 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 de las listas como compuestas de una "cabeza" y una "cola". La cabeza es el primer elemento de la lista, la cola es el resto de la lista. Verás 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ás es la función cons. Toma un valor y prepends it to el segundo argumento, una lista. En la sección previa, sugerí que pienses de una lista como que se está componiendo 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. Puedes crear una lista como sigue:
(cons 1 '(2 3 4) )
El resultado es la lista (1 2 3 4)
.
Tambien, podrías crear una lista con un elemento:
(cons 1 () )
Puedes usar, previamente, variables declaradas en lugar de literales, como espararías.
Para definir una lista compuesta de literales o previamente variables declaradas, usa la función list:
(list 5 4 3 a b c)
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, usa 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. Las a y d representan las cabezas y las colas de la lista, así
(car (cdr (car x) ) )
podría ser escrito como:
(cadar x)
Para ver una lista completa de la lista de funciones, te 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, intenta teclear lo siguiente (excepto, todo en una linea si estás usando la consola); usa 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 )
Intenta acceder al número 3 en la lista usando solo dos llamadas a función. Si puedes hacer eso, estás en el camino para llegar a ser un Maestro 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 puedes usar esto para añadir comentarios para refrescar tu memoria cuando vuelvas a mirar tu script. |