Emacs Lispには、オプションパラメータの非nilデフォルトの構文サポートがありません。これらのパラメーターを提供するための推奨イディオムは何ですか?
私の主張を明確にするために、これを行う過度に明示的な方法を以下に示します。
(defun command (a &optional supplied-b)
(let ((b (or supplied-b default-b)))
(command-body a b)))
どちらかといえば、推奨されるスタイルは何ですか?
Emacs Lispには、オプションパラメータの非nilデフォルトの構文サポートがありません。これらのパラメーターを提供するための推奨イディオムは何ですか?
私の主張を明確にするために、これを行う過度に明示的な方法を以下に示します。
(defun command (a &optional supplied-b)
(let ((b (or supplied-b default-b)))
(command-body a b)))
どちらかといえば、推奨されるスタイルは何ですか?
回答:
@legosciaが提案するCommon Lisp拡張機能を使用しない限り、オプションの引数が指定されているかどうかを確認する必要があります。ここで実際に使用する必要はないことに注意してくださいlet。これは私にとってより慣用的なようです:
(defun command (a &optional b)
(or b (setq b default))
(command-body a b))
コメントで示唆されているように、使用unlessすることが望ましい場合がありますor:
(defun command (a &optional b)
(unless b (setq b default))
(command-body a b))
また、コメントから:より純粋な機能スタイルはlet、元の質問のようにを使用することですが、別個の変数名は必要ありません:
(defun my-command (a &optional b)
(let ((b (or b default)))
(command-body a b)))
もちろん、オプションのパラメーターが必要なのが1回だけの場合は、次のようにします。
(defun my-command (a &optional b)
(command-body a (or b default)))
(unless b (setq b default)がより良いかもしれないことに同意します。個人的には、すでにローカルにあるため、letここでは冗長だと思います。bdefun
letような副作用のあるフォームを好みますsetq。パラメータのデフォルトのコードですが、setqローカル変数を変更するために寛大に使用すると、コードの読み取りと追跡が難しくなります。すべてのローカルバインディングを不変と見なし、新しいバインディングのみを確立することが最善であると思いますlet。IOW、命令的なスタイルよりも機能的なスタイルを好む。
setq「純粋な」ブール形式のような副作用のある表現を使用するのは良いスタイルだとは思いませんor。私の意見でwhenは、ここでは間違いなくより適切ですが、一般letに、ローカルバインディングを確立または変更するための選択の表現です。IOW、元のコードは私にとってはるかに良く見えます。