Este é um acompanhamento dos comentários sobre esta resposta . Os seguintes bits de código parecem ser equivalentes:
(and a b)
(when a b)
É claro que and
permite colocar mais condições: (and a b c d)
significa(when (and a b c) d)
Eu costumo usar when
apenas para expressar ramificação. Existem diferenças reais? É melhor usar um ou outro?
Eu não tenho a fonte C do Emacs em mãos; and
é uma função C; when
é uma macro que se expande para if
, que por si só é uma função C.
elisp
elisp-macros
conditionals
Clemente
fonte
fonte
Respostas:
TL; DR:
when
trata de efeitos colaterais,and
é para expressões booleanas puras.Como você notou,
and
ewhen
diferem apenas na sintaxe, mas são inteiramente equivalentes.A diferença sintática é bastante importante:
when
envolve um implícito emprogn
torno de todas as formas, exceto o primeiro argumento.progn
é uma característica inerentemente imperativa: avalia apenas a última forma do corpo apenas para seus efeitos colaterais, descartando qualquer valor que eles retornassem.Como tal, também
when
é uma forma imperativa: seu principal objetivo é envolver as formas de efeito colateral, porque apenas o valor da última forma realmente importa para o corpo.and
por outro lado, é uma função pura, cujo objetivo principal é examinar os valores de retorno dos formulários de argumento fornecidos: a menos que você explique explicitamenteprogn
qualquer um de seus argumentos, o valor de cada formulário de argumento é importante e nenhum valor é ignorado. .Portanto, a verdadeira diferença entre
and
ewhen
é estilística: você usaand
para expressões booleanas puras ewhen
protege as formas de efeito colateral.Portanto, estes são um estilo ruim:
E estes são bons:
Eu sei que algumas pessoas discordam disso e usam alegremente
and
para proteger os efeitos colaterais, mas acho que esse é um estilo muito ruim. Temos essas formas diferentes por um motivo: a sintaxe é importante . Caso contrário, todos nós apenas usaríamosif
, que é a única forma condicional que você realmente precisa no Emacs Lisp semântica. Todas as outras formas booleanas e condicionais podem ser escritas em termos deif
.fonte
and
trata-se de se preocupar com o valor de retorno . Não se trata necessariamente de usar efeitos colaterais. Se meu programa se importa com o valor de retorno, então eu usoand
. Se não, então eu usowhen
. IOW, eu usowhen
apenas para efeitos colaterais, mas posso usar aprogn
em um dos argumentos paraand
. É sobre se o valor de retorno é importante, não se é o único que importa.and
não é uma função em nenhum Lisp que eu conheça. No Emacs Lisp, é uma forma especial; no Common Lisp, é uma macro, simplesmente porque é esperado que ele tenha um comportamento de curto-circuito (impossível de obter com funções, porque eles sempre avaliam seus argumentos).and
é uma função, quando não é. Não importa o quão relevante seja o fato para a pergunta, devemos sempre usar termos corretos, só isso.nil
de significado como "falso", "a lista vazia", "nula" etc. etc. Por exemplo, em Esquema e raquete, o resultado não-verdadeiro dewhen
isvoid
(ie "sem sentido") enquanto que para (and
is#f
"falso"). Embora seja N / A para Elisp, é algo que um generalista do Lisp pode considerar.Deixe-me começar dizendo isso
(and a b)
e,(when a b)
no seu exemplo, faça o mesmo: Primeiroa
é avaliado.b
é avaliado sea
for verdadeiro # .Mas
and
ewhen
são usados para coisas diferentes.Você usaria
(and a b)
para retornar # verdadeiro se AMBOS e forem # verdadeiros (ou não nulos); e caso contrário.a
b
nil
Você usaria
(when a b)
ou, para ser mais correto,quando você deseja que o código "b" seja executado se e somente se
a
for verdadeiro # .Aqui está um exemplo em que você usa
when
eand
juntos:Acima, a função
do-c
é chamada SOMENTE se AMBOSa
eb
for verdadeira # .Referências para estudo
when
seção aqui)and
seção aqui)# Todas as referências a true referem-se ao Boolean TRUE.
fonte
and
não retornarát
se todos os seus argumentos forem nulos, mas o valor do último argumento.t
, eu quis dizer o booleano VERDADEIRO ou não nulo. Obrigado, vou esclarecer isso na minha resposta.(when (and a b) c)
). Além disso, a parte sobre comoand
ewhen
sugere que é realmente assim que eles são usados em geral, mas a própria base para essa pergunta foi o fato de eu frequentemente os ver usados de maneira diferente (veja, por exemplo, a resposta à qual vinculei na minha pergunta).