TL; DR: when
riguarda gli effetti collaterali, and
è per espressioni booleane pure.
Come avete notato, and
e when
differiscono solo nella sintassi, ma sono comunque del tutto equivalente.
La differenza sintattica è piuttosto importante, però: when
avvolge un implicito progn
attorno a tutte le forme tranne il primo argomento. progn
è una caratteristica intrinsecamente imperativa: valuta tutto tranne l'ultima forma del corpo solo per i loro effetti collaterali, scartando qualsiasi valore restituito.
Come tale, when
è anche una forma imperativa: il suo scopo principale è avvolgere le forme con effetti collaterali, perché solo il valore dell'ultima forma conta davvero per il corpo.
and
d'altra parte è una funzione pura, il cui scopo principale è quello di esaminare i valori di ritorno delle forme di argomento fornite: A meno che non si avvolga esplicitamente progn
uno qualsiasi dei suoi argomenti, il valore di ogni forma di argomento è importante e nessun valore viene mai ignorato .
Quindi, la vera differenza tra and
ed when
è stilistica: usi and
per le espressioni booleane pure e when
per proteggere le forme con effetti collaterali.
Quindi, questi sono cattivi stili:
;; `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 questi sono buoni:
(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)))
So che alcune persone non sono d'accordo su questo, e felicemente usano and
per proteggere gli effetti collaterali, ma penso che questo sia davvero uno stile cattivo. Abbiamo queste diverse forme per un motivo: la sintassi conta . In caso contrario, useremmo sempre e solo if
, che è l'unica forma condizionale di cui hai davvero bisogno in Emacs Lisp semanticamente. Tutte le altre forme booleane e condizionali possono essere scritte in termini di if
.