3.3. Listas, listas y más listas
| 3. Un tutorial de Script-Fu |

### 3.3. Listas, listas y más listas

Le hemos entrenado en variables y funciones, y ahora, entramos en el lúgubre pantano de las listas Scheme.

#### 3.3.1. Definir una lista

Antes de hablar más sobre las listas, es necesario que sepa la diferencia entre valores atómicos y listas.

Ya ha visto los valores atómicos al inicializar variables en la lección anterior. Un valor atómico es un valor simple. Así, por ejemplo, se puede asignar a la variable “`x`” el valor simple de 8 en la siguiente declaración:

    (let* ( (x 8) ) x)

(Añadimos la expresión “`x`” al final para imprimir el valor asignado a “`x`”, normalmente no necesitará hacer esto. Tenga en cuenta cómo `let*` opera justamente como una función: el valor de la última declaración es el valor devuelto.)

Una variable también puede referirse a una lista de valores, en lugar de como un valor simple. Para asignar a la variable `x` la lista de valores 1, 3, 5, escribimos:

    (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

Sin embargo, 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. Sin embargo, cuando responde con `(1 3 5)`, está informando que `x` no contiene un valor simple, sino una lista de valores. Tenga en cuenta que no hay comillas en nuestra declaración o en la asignación de la lista, ni en el resultado mostrado.

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, casi como una función o expresión.

Una lista vacía se puede definir como:

    '()

o simplemente:

    ()

Las listas pueden contener valores atómicos, así como otras listas:

    (let*
       (
            (x
               '("GIMP" (1 2 3) ("es" ("genial" () ) ) )
            )
        )
        x
    )

Tenga en cuenta que después del primer apóstrofe, no necesitará 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; en lugar de eso, es una lista de un literal `("GIMP")`, la lista `(1 2 3)`, etc.

#### 3.3.2. ¿Como se representan las listas?

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.

#### 3.3.3. Crear listas mediante concatenación (la función «Cons»)

Una de las funciones más comunes que encontrará es la función «cons». Toma un valor y lo sitúa en el segundo argumento, una lista. En la sección previa, se sugirió que pensase que una lista está compuesta de un elemento (la cabeza) y el resto de la lista (la cola). Así es exactamente como funciona «cons», 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)`.

También podrá crear una lista con un elemento:

    (cons 1 () )

Puede usar, previamente, variables declaradas en lugar de literales, como cabría esperar.

#### 3.3.4. Definir una lista usando la función `list`

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)`.

#### 3.3.5. Acceder a los valores de una lista

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 se mencionó antes.

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

`car` devuelve el primer elemento de la lista (la cabeza de la lista). La lista necesita no ser nula. La siguiente devuelve el primer elemento de la lista:

    (car '("primero" 2 "tercero"))

que es:

    "primero"

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

`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 '("primero" 2 "tercero"))

devuelve:

    (2 "tercero")

donde la siguiente:

    (cdr '("uno y sólo"))

devuelve:

    ()

#### 3.3.8. Acceder a otros elementos de una lista

Bien, bravo, podemos obtener el primer elemento en una lista, tanto como el resto de la lista, pero ¿cómo 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) ) )

se podría escribir como:

    (cadar x)

Para tener práctica con las funciones de acceso a listas, intente escribir lo siguiente (en una sola línea 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) )
                     )
                  )
                  ; escriba su código car/cdr aquí
            )

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. El intérprete del script ignorará esto y todo lo que siga en la misma línea, así que puede usar esto para añadir comentarios para refrescar su memoria cuando vuelva a mirar su script.

3.2. Variables y funciones |  | 3.4. Su primer código de Script-Fu

Informe de un error en Bugzilla