TL; DR: when
副作用に関するもので、and
純粋なブール式用です。
あなたは気づいた、としてand
およびwhen
構文が異なるだけで、それ以外は全く同じです。
ただし、構文の違いは非常に重要です。最初の引数形式以外のすべてをwhen
暗黙的にラップしprogn
ます。 progn
は本質的に必須の機能です。返される値はすべて破棄し、副作用についてのみ最後のボディフォームを除くすべてを評価します。
このようにwhen
、命令型も同様です。主な目的は、副作用のあるフォームをラップすることです。なぜなら、最後のフォームの値だけが実際に身体にとって重要だからです。
and
一方、純粋な関数であり、その主な目的は、指定された引数形式の戻り値を調べることです。progn
引数のいずれかを明示的にラップしない限り、すべての引数形式の値は重要であり、値は無視されません。
したがって、間の本当の違いand
とはwhen
文体です:あなたが使用してand
、純粋なブール式のために、そしてwhen
副作用フォームの周りにガードを配置します。
したがって、これらは悪いスタイルです:
;; `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)))
そして、これらは良いです:
(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)))
一部の人々はこれに同意せず、喜んでand
副作用を防ぐために使用していることを知っていますが、これは本当に悪いスタイルだと思います。理由は次のとおりです。構文が重要です。そうでなければif
、Emacs Lispで意味的に本当に必要な唯一の条件付きフォームであるを使用するだけです。他のすべてのブール形式および条件付き形式は、に関して記述できますif
。