common-lisp
Estructuras de Control
Buscar..
Construcciones condicionales
En Common Lisp, if
es la construcción condicional más simple. Tiene la forma (if test then [else])
y se evalúa a then
si la test
es verdadera y de else
contrario. La otra parte puede ser omitida.
(if (> 3 2)
"Three is bigger!"
"Two is bigger!")
;;=> "Three is bigger!"
Una diferencia muy importante entre if
en Common Lisp y if
en muchos otros lenguajes de programación es que CL de if
es una expresión, no una afirmación. Como tal, if
formularios devuelven valores, que pueden asignarse a variables, usarse en listas de argumentos, etc.
;; Use a different format string depending on the type of x
(format t (if (numberp x)
"~x~%"
"~a~%")
x)
Common Lisp 's if
se puede considerar equivalente al operador ternario?: En C # y otros lenguajes de "corsé".
Por ejemplo, la siguiente expresión de C #:
year == 1990 ? "Hammertime" : "Not Hammertime"
Es equivalente al siguiente código Common Lisp, asumiendo que ese year
contiene un número entero:
(if (eql year 1990) "Hammertime" "Not Hammertime")
cond
es otro constructo condicional. Es algo similar a una cadena de sentencias if
, y tiene la forma:
(cond (test-1 consequent-1-1 consequent-2-1 ...)
(test-2)
(test-3 consequent-3-1 ...)
... )
Más precisamente, cond
tiene cero o más cláusulas , y cada cláusula tiene una prueba seguida de cero o más consecuentes. La construcción completa de cond
selecciona la primera cláusula cuya prueba no evalúa a nil
y evalúa sus consecuentes en orden. Devuelve el valor del último formulario en los consecuentes.
(cond ((> 3 4) "Three is bigger than four!")
((> 3 3) "Three is bigger than three!")
((> 3 2) "Three is bigger than two!")
((> 3 1) "Three is bigger than one!"))
;;=> "Three is bigger than two!"
Para proporcionar una cláusula predeterminada para evaluar si ninguna otra cláusula se evalúa como t
, puede agregar una cláusula que sea verdadera de manera predeterminada utilizando t
. Este concepto es muy similar al de CASE...ELSE
de SQL CASE...ELSE
, pero utiliza un verdadero booleano literal en lugar de una palabra clave para realizar la tarea.
(cond
((= n 1) "N equals 1")
(t "N doesn't equal 1")
)
Una construcción if
puede escribirse como una construcción cond
. (if test then else)
y (cond (test then) (t else))
son equivalentes.
Si solo necesita una cláusula, use when
o a unless
:
(when (> 3 4)
"Three is bigger than four.")
;;=> NIL
(when (< 2 5)
"Two is smaller than five.")
;;=> "Two is smaller than five."
(unless (> 3 4)
"Three is bigger than four.")
;;=> "Three is bigger than four."
(unless (< 2 5)
"Two is smaller than five.")
;;=> NIL
El bucle do
La mayoría de las construcciones condicionales y de bucle en Common Lisp son en realidad macros que ocultan construcciones más básicas. Por ejemplo, dotimes
y dolist
se basan en la macro do
. La forma para do
ve así:
(do (varlist)
(endlist)
&body)
-
varlist
se compone de las variables definidas en el bucle, sus valores iniciales y cómo cambian después de cada iteración. La parte de 'cambio' se evalúa al final del bucle. -
endlist
contiene las condiciones finales y los valores devueltos al final del bucle. La condición final se evalúa al comienzo del bucle.
Aquí hay uno que comienza en 0 y sube hasta (no incluye) 10.
;;same as (dotimes (i 10))
(do (( i (+ 1 i))
((< i 10) i)
(print i))
Y aquí hay uno que se mueve a través de una lista:
;;same as (dolist (item given-list)
(do ((item (car given-list))
(temp list (cdr temp))
(print item))
La parte varlist
es similar a la de una sentencia let
. Puede enlazar más de una variable, y solo existen dentro del bucle. Cada variable declarada está en su propio conjunto de paréntesis. Aquí hay uno que cuenta cuántos 1 y 2 están en una lista.
(let ((vars (list 1 2 3 2 2 1)))
(do ((ones 0)
(twos 0)
(temp vars (cdr temp)))
((not temp) (list ones twos))
(when (= (car temp) 1)
(setf ones (+ 1 ones)))
(when (= (car temp) 2)
(setf twos (+ 1 twos)))))
-> (2 3)
Y si una macro loop de while no ha sido implementada:
(do ()
(t)
(when task-done
(break)))
Para las aplicaciones más comunes, las macros dotimes
y doloop
más específicas son mucho más sucintas.