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 '("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 <code>("GIMP")</code>, la lista <code>(1 2 3)</code>, 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 <code>cons</code>. 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 <code>cons</code> 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 <code>(1 2 3 4)</code>.
También, podrías crear una lista con un elemento:
(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 <code>list</code>:
(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 <code>(5 4 3 1 2 3)</code>.
Para acceder a los valores de una lista, use las funciones <code>car</code> y <code>cdr</code>, 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.
<code>car</code> 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"
<code>cdr</code> 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 (<code>caadr</code>), la cola de la cola de una lista (<code>cddr</code>), 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) ) )
se podría escribir como:
(cadar x)
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. |