Dado que el nombre del lenguaje que estamos usando, Lisp, viene de LIST Processing, se podría suponer que el lenguaje tiene herramientas para manejar listas de elementos, ¡y no te equivocarías!
Aunque Common Lisp tiene otras estructuras de datos además de las listas, las listas se siguen usando muchísimo.
Una lista en Common Lisp es una secuencia de elementos. También se la llama cons (sobre todo por motivos históricos).
Los propios elementos no tienen por qué ser del mismo tipo.
Por ejemplo, puedes tener una lista con 1, two y "III".
Puedes escribir directamente una lista citada como esta: '(1 two "III"), y eso hará que se cree y se evalúe una lista (se evalúa a (1 two "III")).
También hay dos funciones principales que se usan para crear listas: list y cons.
list recibe cero o más argumentos y se evalúa a una lista creada con esos valores:
(list 1 'two "III") ; => (1 two "III")
cons recibe dos elementos y crea una lista que tiene el primer elemento como su car (la cabeza de la lista) y el segundo como su cdr (el resto de la lista):
(cons 1 2) ; => (1 . 2) ;; (a list without `nil` as its `cdr` is printed in this way)
(cons 1 nil) ; => (1)
(cons 1 (cons 2 nil)) ; => (1 2)
Las funciones car y cdr se pueden usar para acceder al car y al cdr de una lista.
(first y rest son sinónimos de car y cdr y funcionan exactamente igual).
La longitud de una lista se puede determinar con length.
Una lista vacía tiene longitud cero.
Se puede acceder a un elemento cualquiera con nth (ten en cuenta que las listas están indexadas desde cero).
Pedir un índice mayor que la longitud de la lista no es un error.
En su lugar, se evalúa a nil:
(nth 23 '(short list)) ; => nil
También hay varios métodos auxiliares para acceder a los primeros elementos de una lista: first, second, third, hasta llegar a tenth. Genial, ¿verdad?
Se pueden combinar dos o más listas con append:
(append '(a b c) '(1 2 3)) ; => (A B C 1 2 3)
(append '(a b c) '()) ; => (A B C)
Cada argumento que se pasa a append tiene que ser una lista.
Leslie, el alienígena de Lisp, necesita ir de compras. Es muy importante tener una lista de la compra. Hay que añadirle cosas y quitarle cosas.
Claro que un simple lápiz y papel no sirven para un alienígena de Lisp. Es más, «List» es casi toda la palabra «Lisp». Tiene que haber algunas funciones escritas que ayuden a llevar el control de la compra.
¿Puedes ayudar a Leslie a llevar el control de la lista de la compra?
Lo primero es que Leslie necesita crear una lista vacía. Una función llamada new-list sería perfecta para eso.
(new-list) ; => ()
Oh, no... Leslie ya tiene algunas cosas en mente, así que necesita una función que reciba tres elementos (por suerte, Leslie solo crea listas de tres elementos. ¡Ni más ni menos!) y cree una nueva lista de la compra con esas cosas. Escribe una función, list-of-things, que reciba tres elementos y devuelva una lista con ellos.
(list-of-things 'bread 'milk 'butter) ; => '(bread milk butter)
Antes de ir a la tienda, Leslie mira en la despensa para ver qué necesita. Ayúdale escribiendo la función add-to-list, que añade un elemento al principio de una lista.
(add-to-list 'butter '(bread)) ; => '(butter bread)
Mientras compra, Leslie quiere saber qué buscar a continuación. También le gusta echar un vistazo a la lista para ver el segundo, el tercer o incluso el vigésimo tercer elemento (su número de la suerte).
first-thing da como resultado la primera cosa de la listasecond-thing da como resultado la segunda cosathird-thing da como resultado la tercera cosatwenty-third-thing da como resultado la vigésima tercera cosa(first-thing '(bread butter milk)) ; => 'bread
(second-thing '(bread butter milk)) ; => 'butter
(third-thing '(bread butter milk)) ; => 'milk
Leslie quiere encontrar el primer elemento de la lista y quitarlo de la estantería. Ayúdale escribiendo una función remove-first-item que da como resultado una lista con todo menos el primer elemento de la lista de entrada.
(remove-first-item '(bread butter milk)) ; => '(butter milk)
¡Leslie se ha dado cuenta de que ha hecho sin querer dos listas de la compra en lugar de una! Escribe una función, list-append, que devuelve una lista con los elementos de la primera lista seguidos de los de la segunda.
(list-append '(bread salt) '(butter milk)) ; => '(bread salt butter milk)
Leslie empieza a preocuparse de que esta compra le lleve un buen rato. ¿Cuántas cosas hay exactamente en esta lista? Escribe una función just-how-long que le diga cuánto mide su lista.
(just-how-long '(bread milk butter salt)) ; => 4
Regístrate en Exercism para aprender y dominar Common Lisp con 27 conceptos92 ejercicios y mentoría humana real, todo gratis.