TL; DR: when
adalah tentang efek samping, and
adalah untuk ekspresi boolean murni.
Seperti yang telah Anda perhatikan, and
dan when
hanya berbeda dalam sintaksis, tetapi sebaliknya sepenuhnya sama.
Perbedaan sintaksis cukup penting, meskipun: when
membungkus implisit di progn
sekitar semua kecuali bentuk argumen pertama. progn
adalah fitur yang secara inheren penting: Ini mengevaluasi semua kecuali bentuk tubuh terakhir untuk efek sampingnya saja, membuang nilai apa pun yang mereka kembalikan.
Dengan demikian, when
adalah bentuk imperatif juga: Tujuan utamanya adalah untuk membungkus bentuk efek samping, karena hanya nilai bentuk terakhir yang paling penting bagi tubuh.
and
di sisi lain adalah fungsi murni, yang tujuan utamanya adalah untuk melihat nilai kembali dari bentuk argumen yang diberikan: Kecuali jika Anda secara eksplisit membungkus progn
argumennya, nilai setiap bentuk argumen adalah penting, dan tidak ada nilai yang pernah diabaikan .
Oleh karena itu, perbedaan nyata antara and
dan when
gaya: Anda gunakan and
untuk ekspresi boolean murni, dan when
untuk menjaga di sekitar bentuk efek samping.
Karenanya, ini adalah gaya yang buruk:
;; `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)))
Dan ini bagus:
(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)))
Saya tahu bahwa beberapa orang tidak setuju tentang hal ini, dan dengan senang hati menggunakannya and
untuk menjaga efek samping, tetapi saya pikir ini adalah gaya yang benar-benar buruk. Kami memiliki berbagai bentuk ini karena suatu alasan: Sintaks penting . Jika tidak, kita semua hanya akan menggunakan if
, yang merupakan satu-satunya bentuk kondisional yang Anda butuhkan di Emacs Lisp secara semantik. Semua bentuk boolean dan kondisional lainnya dapat ditulis dalam bentuk if
.