TL; DR: when trata de efeitos colaterais, andé para expressões booleanas puras.
Como você notou, ande whendiferem apenas na sintaxe, mas são inteiramente equivalentes.
A diferença sintática é bastante importante: whenenvolve um implícito em progntorno 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.
andpor 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 explicitamente prognqualquer um de seus argumentos, o valor de cada formulário de argumento é importante e nenhum valor é ignorado. .
Portanto, a verdadeira diferença entre ande whené estilística: você usa andpara expressões booleanas puras e whenprotege as formas de efeito colateral.
Portanto, estes são um estilo ruim:
;; `when' used for a pure boolean expression
(let ((use-buffer (when (buffer-live-p buffer)
(file-exists-p (buffer-file-name buffer)))))
...)
;; `and' used as guard around a side-effecting form
(and (buffer-file-name buffer) (write-region nil nil (buffer-file-name buffer)))
E estes são bons:
(let ((use-buffer (and (buffer-live-p buffer)
(file-exists-p (buffer-file-name buffer)))))
...)
(when (buffer-file-name buffer)
(write-region nil nil (buffer-file-name buffer)))
Eu sei que algumas pessoas discordam disso e usam alegremente andpara 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íamos if, 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 de if.