Buscar..


Observaciones

Esta es una función simple de hello world en Common Lisp. Ejemplos imprimirán el texto Hello, World! (sin comillas, seguido de una nueva línea) a la salida estándar.

Common Lisp es un lenguaje de programación que se usa en gran medida de forma interactiva mediante una interfaz conocida como REPL. El REPL (Leer Eval Print Loop) le permite a uno escribir código, hacer que se evalúe (ejecutar) y ver los resultados inmediatamente. CL-USER> indica el aviso para el REPL (en cuyo punto se escribe el código a ejecutar). A veces, algo distinto de CL-USER aparecerá antes del > pero esto sigue siendo un REPL.

Después de la solicitud, aparece algún código, generalmente una sola palabra (es decir, un nombre de variable) o un formulario (una lista de palabras / formas entre ( y ) ) (es decir, una llamada de función o declaración, etc.). En la siguiente línea habrá cualquier salida que el programa imprima (o nada si el programa no imprime nada) y luego los valores devueltos al evaluar la expresión. Normalmente, una expresión devuelve un valor, pero si devuelve varios valores, aparecen una vez por línea.

Versiones

Versión Fecha de lanzamiento
Lisp común 1984-01-01
ANSI Common Lisp 1994-01-01

Hola Mundo

Lo que sigue es un extracto de una sesión REPL con Common Lisp en la que aparece un "¡Hola mundo!" La función está definida y ejecutada. Vea las observaciones al final de esta página para obtener una descripción más detallada de un REPL.

CL-USER> (defun hello ()
           (format t "Hello, World!~%"))
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> 

Esto define la "función" de cero argumentos llamados hello , que escribirán la cadena "Hello, World!" seguido de una nueva línea a la salida estándar, y devuelve NIL .

Para definir una función escribimos

(defun name (parameters...)
  code...)

En este caso, la función se llama hello , no toma parámetros y el código que ejecuta es para hacer una llamada a la función. El valor devuelto de una función lisp es el último bit de código en la función que se ejecutará, por lo que hello devuelve lo que sea (format t "Hello, World!~%") Devuelve.

En lisp para llamar a una función se escribe (function-name arguments...) donde function-name es el nombre de la función y arguments... es la lista de argumentos (separados por espacios) de la llamada. Hay algunos casos especiales que parecen llamadas a funciones pero no están, por ejemplo, en el código anterior no hay una función defun que se llama, se trata especialmente y define una función en su lugar.

En el segundo aviso del REPL, después de que hayamos definido la función hello , la llamamos sin parámetros escribiendo (hello) . Esto, a su vez, llamará a la función de format con los parámetros t y "Hello, World!~%" . La función de format produce una salida con formato basada en los argumentos que se le dan (un poco como una versión avanzada de printf en C). El primer argumento le dice a dónde enviar, con t significa salida estándar. El segundo argumento le dice qué imprimir (y cómo interpretar los parámetros adicionales). La directiva (código especial en el segundo argumento) ~% le dice al formato que imprima una nueva línea (es decir, en UNIX puede escribir \n y en windows \r\n ). El formato generalmente devuelve NIL (un poco como NULL en otros idiomas).

Después del segundo aviso, vemos que Hello, World se imprimió y en la siguiente línea que el valor devuelto era NIL .

Hola nombre

Este es un ejemplo un poco más avanzado que muestra algunas características más de la luz común. Empezamos con un simple Hello, World! Funcionar y demostrar algún desarrollo interactivo en el REPL. Tenga en cuenta que cualquier texto de un punto y coma ; , al resto de la línea hay un comentario.

CL-USER> (defun hello ()
       (format t "Hello, World!~%")) ;We start as before
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (defun hello-name (name) ;A function to say hello to anyone
       (format t "Hello, ~a~%" name)) ;~a prints the next argument to format
HELLO-NAME
CL-USER> (hello-name "Jack")
Hello, Jack
NIL
CL-USER> (hello-name "jack") ;doesn't capitalise names
Hello, jack
NIL
CL-USER> (defun hello-name (name) ;format has a feature to convert to title case
       (format t "Hello, ~:(~a~)~%" name)) ;anything between ~:( and ~) gets it
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack")
Hello, Jack
NIL
CL-USER> (defun hello-name (name)
       (format t "Hello, ~:(~a~)!~%" name))
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello-name "jack") ;now this works
Hello, Jack!
NIL
CL-USER> (defun hello (&optional (name "world")) ;we can take an optional argument
       (hello-name name)) ;name defaults to "world"
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (hello)
Hello, World!
NIL
CL-USER> (hello "jack")
Hello, Jack!
NIL
CL-USER> (hello "john doe") ;note that this capitalises both names
Hello, John Doe!
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~a ~r" name number)) ;~r prints a number in English
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;this doesn't quite work
Hello, Louis sixteen
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~:(~a ~:r~)!" name number)) ;~:r prints an ordinal
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Sixteenth!
NIL
CL-USER> (defun hello-person (name &key (number))
       (format t "Hello, ~:(~a ~@r~)!" name number)) ;~@r prints Roman numerals
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16)
Hello, Louis Xvi!
NIL
CL-USER> (defun hello-person (name &key (number)) ;capitalisation was wrong
       (format t "Hello, ~:(~a~) ~:@r!" name number))
WARNING: redefining COMMON-LISP-USER::HELLO-PERSON in DEFUN
HELLO-PERSON
CL-USER> (hello-person "Louis" :number 16) ;thats better
Hello, Louis XVI!
NIL
CL-USER> (hello-person "Louis") ;we get an error because NIL is not a number
Hello, Louis ; Evaluation aborted on #<SB-FORMAT:FORMAT-ERROR {1006641AB3}>.
CL-USER> (defun say-person (name &key (number 1 number-p)
                                      (title nil) (roman-number t))
       (let ((number (if number-p
                 (typecase number
                   (integer
                (format nil (if roman-number " ~:@r" " ~:(~:r~)") number))
                   (otherwise
                (format nil " ~:(~a~)" number)))
                 "")) ; here we define a variable called number
         (title (if title 
                (format nil "~:(~a~) " title)
                ""))) ; and here one called title
         (format nil "~a~:(~a~)~a" title name number))) ;we use them here

SAY-PERSON
CL-USER> (say-person "John") ;some examples
"John"
CL-USER> (say-person "john doe")
"John Doe"
CL-USER> (say-person "john doe" :number "JR")
"John Doe Jr"
CL-USER> (say-person "john doe" :number "Junior")
"John Doe Junior"
CL-USER> (say-person "john doe" :number 1)
"John Doe I"
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;this is wrong
"John Doe First"
CL-USER> (defun say-person (name &key (number 1 number-p)
                                      (title nil) (roman-number t))
       (let ((number (if number-p
                 (typecase number
                   (integer
                (format nil (if roman-number " ~:@r" " the ~:(~:r~)") number))
                   (otherwise
                (format nil " ~:(~a~)" number)))
                 ""))
         (title (if title 
                (format nil "~:(~a~) " title)
                "")))
         (format nil "~a~:(~a~)~a" title name number)))
WARNING: redefining COMMON-LISP-USER::SAY-PERSON in DEFUN
SAY-PERSON
CL-USER> (say-person "john doe" :number 1 :roman-number nil) ;thats better
"John Doe the First"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number nil)
"King Louis the Sixteenth"
CL-USER> (say-person "louis" :title "king" :number 16 :roman-number t)
"King Louis XVI"
CL-USER> (defun hello (&optional (name "World") &rest arguments) ;now we will just
       (apply #'hello-name name arguments)) ;pass all arguments to hello-name
WARNING: redefining COMMON-LISP-USER::HELLO in DEFUN
HELLO
CL-USER> (defun hello-name (name &rest arguments) ;which will now just use
       (format t "Hello, ~a!" (apply #'say-person name arguments))) ;say-person
WARNING: redefining COMMON-LISP-USER::HELLO-NAME in DEFUN
HELLO-NAME
CL-USER> (hello "louis" :title "king" :number 16) ;this works now
Hello, King Louis XVI!
NIL
CL-USER>

Esto resalta algunas de las características avanzadas de la función de format de Common Lisp, así como algunas características como parámetros opcionales y argumentos de palabras clave (por ejemplo, :number ). Esto también da un ejemplo de desarrollo interactivo en un REPL en lisp común.

El sencillo programa Hello World en REPL.

Common Lisp REPL es un entorno interactivo. Cada formulario escrito después de la solicitud se evalúa, y su valor se imprime después como resultado de la evaluación. Así que el programa más simple posible de "Hello, World!" En Common Lisp es:

CL-USER> "Hello, World!"
"Hello, World!"
CL-USER>

Lo que sucede aquí es que se da un costo de cadena en la entrada al REPL, se evalúa y se imprime el resultado. Lo que se puede ver en este ejemplo es que las cadenas, como los números, los símbolos especiales como NIL y T y algunos otros literales, son formas de autoevaluación : es decir, se evalúan a sí mismas.

Expresiones basicas

Probemos alguna expresión básica en el REPL:

CL-USER> (+ 1 2 3)
6
CL-USER> (- 3 1 1)
1
CL-USER> (- 3)
-3
CL-USER> (+ 5.3 (- 3 2) (* 2 2))
10.3
CL-USER> (concatenate 'string "Hello, " "World!")
"Hello, World!"
CL-USER> 

El bloque de construcción básico de un programa Common Lisp es la forma . En estos ejemplos tenemos funciones de formas , es decir, expresiones, escritas como una lista, en las que el primer elemento es un operador (o función) y el resto de los elementos son los operandos (esto se llama "Notación de prefijo" o "Notación polaca" ”). Escribir formularios en el REPL provoca su evaluación. En los ejemplos puede ver expresiones simples cuyos argumentos son números constantes, cadenas y símbolos (en el caso de 'string , que es el nombre de un tipo). También puede ver que los operadores aritméticos pueden tomar cualquier número de argumentos.

Es importante tener en cuenta que los paréntesis son una parte integral de la sintaxis y no se pueden utilizar libremente como en otros lenguajes de programación. Por ejemplo, el siguiente es un error:

(+ 5 ((+ 2 4)))
> Error: Car of ((+ 2 4)) is not a function name or lambda-expression. ...

En Common Lisp, los formularios también pueden ser datos, símbolos, formularios macro, formularios especiales y formularios lambda. Se pueden escribir para ser evaluados, devolviendo cero, uno o más valores, o se pueden dar en entrada a una macro, que los transforma en otras formas.

Suma de lista de enteros

(defun sum-list-integers (list)
    (reduce '+ list))

; 10
(sum-list-integers '(1 2 3 4))

; 55
(sum-list-integers '(1 2 3 4 5 6 7 8 9 10))

Expresiones Lambda y Funciones Anónimas

Una función anónima se puede definir sin un nombre a través de una Expresión Lambda . Para definir este tipo de funciones, se utiliza la palabra clave lambda lugar de la palabra clave defun . Las siguientes líneas son todas equivalentes y definen funciones anónimas que dan como resultado la suma de dos números:

(lambda (x y) (+ x y))
(function (lambda (x y) (+ x y)))
#'(lambda (x y) (+ x y))

Su utilidad es notable al crear formularios Lambda , es decir, un formulario que es una lista donde el primer elemento es la expresión lambda y los elementos restantes son los argumentos de la función anónima. Ejemplos ( ejecución en línea ):

(print ((lambda (x y) (+ x y)) 1 2)) ; >> 3

(print (mapcar (lambda (x y) (+ x y)) '(1 2 3) '(2 -5 0))) ; >> (3 -3 3)

Recursos de aprendizaje comunes de Lisp

Libros en linea

Estos son libros que son de libre acceso en línea.

Referencias en linea

  • Common Lisp Hyperspec es el documento de referencia de idioma para Common Lisp.
  • El Common Lisp Cookbook es una lista de recetas útiles de Lisp. También contiene una lista de otras fuentes en línea de información de CL.
  • Referencia rápida de Common Lisp tiene hojas de referencia de Lisp imprimibles.
  • Lispdoc.com busca varias fuentes de información de Lisp (Common Lisp, Lisp exitoso, Lisp, HyperSpec) para obtener documentación.
  • L1sp.org es un servicio de redireccionamiento para documentación.

Libros fuera de linea

Estos son libros que probablemente tendrá que comprar o prestar en una biblioteca.

Comunidades Online

Bibliotecas

  • Quicklisp es el administrador de bibliotecas para Common Lisp y tiene una larga lista de bibliotecas compatibles .
  • Quickdocs alberga la documentación de la biblioteca para muchas bibliotecas CL.
  • Awesome CL es una lista curada dirigida por la comunidad de bibliotecas, marcos y otros elementos brillantes ordenados por categoría.

Entornos Lisp pre-envasados

Estos son entornos de edición de Lisp que son fáciles de instalar y comenzar porque todo lo que necesita está preempaquetado y preconfigurado.

  • Portacle es un entorno Common Lisp portátil y multiplataforma. Incluye un Emacs ligeramente personalizado con Slime, SBCL (una popular implementación de Common Lisp), Quicklisp y Git. No necesita instalación, por lo que es una forma muy rápida y fácil de ponerse en marcha.
  • Lispbox es un IDE (Emacs + SLIME), un entorno Common Lisp (Clozure Common Lisp) y un administrador de bibliotecas (Quicklisp), preempaquetado como archivos para Windows, Mac OSX y Linux. Descendiente de "Lisp in a Box" recomendado en el libro Practical Common Lisp.
  • No está pre-empacado, pero SLIME convierte a Emacs en un IDE de Common Lisp y tiene un manual de usuario para ayudarlo a comenzar. Requiere una implementación separada de Common Lisp.

Implementaciones comunes de Lisp

Esta sección enumera algunas implementaciones de CL comunes y sus manuales. A menos que se indique lo contrario, estas son implementaciones de software libre. Consulte también la lista de aplicaciones gratuitas de Common Lisp de Cliki y la lista de implementaciones comerciales de Common Lisp de Wikipedia .



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow