TL; DR: when
yan etkilerle ilgilidir, and
saf boole ifadeleri içindir.
Fark ettiğiniz gibi and
ve when
sadece sözdiziminde farklılık gösterir, ancak aksi takdirde tamamen eşdeğerdir.
Sözdizimsel fark oldukça önemlidir, ancak: ilk argüman formları when
dışındaki progn
herkese örtülü olarak sarılır . progn
doğası gereği zorunlu bir özelliktir: En son vücut formu dışındaki her şeyi sadece yan etkileri açısından değerlendirir ve geri döndürdükleri değeri atar.
Bu nedenle, when
zorunlu bir formdur: Ana amacı, yan etkili formları sarmaktır, çünkü sadece son formun değeri vücut için gerçekten önemlidir.
and
Öte yandan, asıl amacı verilen argüman formlarının dönüş değerlerine bakmak olan saf bir işlevdir: Bağımsız değişkenlerinden progn
herhangi birini açıkça sarmadıkça , her argüman formunun değeri önemlidir ve hiçbir değer göz ardı edilmez. .
Bu nedenle and
ve when
stilistik arasındaki gerçek fark : and
Saf boole ifadeleri için ve when
yan etkili formların etrafına bir koruma koymak için kullanılır.
Bu nedenle, bunlar kötü stil:
;; `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)))
Ve bunlar iyi:
(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)))
Bazı insanların buna katılmadıklarını ve and
yan etkileri korumak için mutlu bir şekilde kullandıklarını biliyorum , ancak bunun gerçekten kötü bir stil olduğunu düşünüyorum. Bir nedenden ötürü şu farklı formlara sahibiz: Sözdizimi önemlidir . Olmasaydı, hepimiz kullanacağız if
, ki bu Emacs Lisp'de semantik olarak gerçekten ihtiyacınız olan tek koşullu form. Diğer tüm boolean ve koşullu formlar açısından yazılabilir if
.