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 andte permite poner más condiciones: (and a b c d)significa(when (and a b c) d)
Tiendo a usar whensolo para expresar ramificaciones. ¿Hay diferencias reales? ¿Es mejor usar uno u otro?
No tengo la fuente C de Emacs a la mano; andes una función C; whenes 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:
whense trata de efectos secundarios,andes para expresiones booleanas puras.Como se ha notado,
andywhensólo se diferencian en la sintaxis, pero por lo demás está totalmente equivalentes.Sin embargo, la diferencia sintáctica es bastante importante:
whenenvuelve un implícitoprognalrededor de todas las formas excepto el primer argumento.prognes 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
whenes 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.andPor 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ícitamenteprognalguno 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
andywhenes estilística: se usaandpara expresiones booleanas puras ywhenpara 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
andpara 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
andse 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,whensolo lo uso para efectos secundarios, pero bien podría usarprognuno en uno de los argumentos paraand. Se trata de si el valor de retorno importa, no de si solo importa.andno 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).andes 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.nilde palabras para significar todo "falso", "la lista vacía", "vacío", etc. Por ejemplo, en Scheme and Racket, el resultado no verdadero dewhenesvoid( es decir, "sin significado") mientras que paraandesto 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: Primeroase evalúa.bse evalúa siaes verdadero # .Pero
andywhense utilizan para diferentes cosas.Usted usaría
(and a b)para devolver el verdadero # si AMBOSaybson verdaderos # (o no-nulo); y de lonilcontrarioUsarías
(when a b)o para ser más correcto,cuando quiere que el código "b" se ejecute si y solo si
aes verdadero # .Aquí hay un ejemplo donde usas
whenyandjuntos:Arriba, la función
do-cse llama SOLO si AMBOSaybson verdaderos # .Referencias para estudio
whensección aquí)andsección aquí)# Todas las referencias a verdadero se refieren a Boolean TRUE.
fuente
andno regresatsi 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ómoandywhensugiere 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).