Este es un seguimiento de los comentarios sobre esta respuesta . Los siguientes bits de código parecen ser equivalentes:
(and a b)
(when a b)
Por supuesto and
te permite poner más condiciones: (and a b c d)
significa(when (and a b c) d)
Tiendo a usar when
solo para expresar ramificaciones. ¿Hay diferencias reales? ¿Es mejor usar uno u otro?
No tengo la fuente C de Emacs a la mano; and
es una función C; when
es una macro que se expande if
, que en sí misma es una función C.
elisp
elisp-macros
conditionals
Clemente
fuente
fuente
Respuestas:
TL; DR:
when
se trata de efectos secundarios,and
es para expresiones booleanas puras.Como se ha notado,
and
ywhen
sólo se diferencian en la sintaxis, pero por lo demás está totalmente equivalentes.Sin embargo, la diferencia sintáctica es bastante importante:
when
envuelve un implícitoprogn
alrededor de todas las formas excepto el primer argumento.progn
es una característica inherentemente imperativa: evalúa todas las formas del cuerpo, excepto la última, solo por sus efectos secundarios, descartando cualquier valor que hayan devuelto.Como tal, también
when
es una forma imperativa: su propósito principal es envolver las formas de efectos secundarios, porque solo el valor de la última forma realmente importa para el cuerpo.and
Por otro lado, es una función pura, cuyo objetivo principal es mirar los valores de retorno de las formas de argumento dadas: a menos que envuelva explícitamenteprogn
alguno de sus argumentos, el valor de cada forma de argumento es importante y nunca se ignora ningún valor .Por lo tanto, la verdadera diferencia entre
and
ywhen
es estilística: se usaand
para expresiones booleanas puras ywhen
para proteger las formas de efectos secundarios.Por lo tanto, estos son mal estilo:
Y estos son buenos:
Sé que algunas personas no están de acuerdo con esto, y felizmente lo usan
and
para proteger los efectos secundarios, pero creo que este es un estilo realmente malo. Tenemos estas diferentes formas por una razón: la sintaxis importa . Si no fuera así, todos lo usaríamos alguna vezif
, que es la única forma condicional que realmente necesita semánticamente en Emacs Lisp. Todas las demás formas booleanas y condicionales se pueden escribir en términos deif
.fuente
and
se trata de preocuparse por el valor de retorno . No se trata necesariamente de usar efectos secundarios. Si mi programa se preocupa por el valor de retorno, entonces lo usoand
. Si no es así, lo usowhen
. IOW,when
solo lo uso para efectos secundarios, pero bien podría usarprogn
uno en uno de los argumentos paraand
. Se trata de si el valor de retorno importa, no de si solo importa.and
no es una función en ningún Lisp que conozco. En Emacs Lisp es una forma especial, en Common Lisp es una macro, simplemente porque se espera que tenga un comportamiento de cortocircuito (imposible de lograr con funciones, porque siempre evalúan sus argumentos).and
es una función, cuando no lo es. No importa cuán relevante sea el hecho para la pregunta, siempre debemos usar términos correctos, eso es todo.nil
de palabras para significar todo "falso", "la lista vacía", "vacío", etc. Por ejemplo, en Scheme and Racket, el resultado no verdadero dewhen
esvoid
( es decir, "sin significado") mientras que paraand
esto es#f
("falso"). Aunque esto es N / A para Elisp, es algo que un generalista de Lisp podría considerar.Permítanme comenzar diciendo eso
(and a b)
y,(when a b)
en su ejemplo, hagan lo mismo: Primeroa
se evalúa.b
se evalúa sia
es verdadero # .Pero
and
ywhen
se utilizan para diferentes cosas.Usted usaría
(and a b)
para devolver el verdadero # si AMBOSa
yb
son verdaderos # (o no-nulo); y de lonil
contrarioUsarías
(when a b)
o para ser más correcto,cuando quiere que el código "b" se ejecute si y solo si
a
es verdadero # .Aquí hay un ejemplo donde usas
when
yand
juntos:Arriba, la función
do-c
se llama SOLO si AMBOSa
yb
son verdaderos # .Referencias para estudio
when
sección aquí)and
sección aquí)# Todas las referencias a verdadero se refieren a Boolean TRUE.
fuente
and
no regresat
si todos sus argumentos son no nulos, sino el valor del último argumento.t
, me refería al booleano VERDADERO o no nulo. Gracias, aclararé eso en mi respuesta.(when (and a b) c)
). Además, la parte sobre cómoand
ywhen
sugiere que en realidad así es como se usan en general, pero la base misma de esta pregunta fue el hecho de que a menudo veo que se usan de manera diferente (ver, por ejemplo, la respuesta a la que me vinculé en mi pregunta).