O ile nie używasz rozszerzeń Common Lisp zgodnie z sugestią @legoscia, musisz sprawdzić, czy podano opcjonalny argument. Pamiętaj, że tak naprawdę nie musisz let
tutaj używać . Wydaje mi się to bardziej idiomatyczne:
(defun command (a &optional b)
(or b (setq b default))
(command-body a b))
Jak sugerowano w komentarzach, użycie unless
może być lepsze niż or
:
(defun command (a &optional b)
(unless b (setq b default))
(command-body a b))
Również z komentarzy: należy zastosować bardziej czysty styl funkcjonalny let
, jak w pierwotnym pytaniu, ale nie potrzebujesz osobnych nazw zmiennych:
(defun my-command (a &optional b)
(let ((b (or b default)))
(command-body a b)))
Oczywiście, jeśli opcjonalny parametr jest potrzebny tylko raz, powinieneś po prostu to zrobić:
(defun my-command (a &optional b)
(command-body a (or b default)))
setq
„czysta” boolowska formaor
. Moim zdaniemwhen
jest to zdecydowanie bardziej odpowiednie tutaj, ale ogólnielet
jest to wyrażenie wyboru w celu ustanowienia lub zmiany lokalnych powiązań. IOW, oryginalny kod wygląda dla mnie o wiele ładniej.(unless b (setq b default)
może być lepsze. Osobiście uważam, żelet
jest tutaj zbędny, ponieważb
jest już lokalny dladefun
.let
niż efekt uboczny, taki jaksetq
. Jest to kod parametru domyślnego, ale swobodne użyciesetq
do zmiany lokalnych zmiennych powoduje, że kod jest trudny do odczytania i śledzenia. Myślę, że najlepiej rozważyć wszystkie lokalne powiązania jako niezmienne i ustanawiać tylko nowelet
. IOW, wolę styl funkcjonalny od nadrzędnego.Możesz użyć
cl-defun
, co pozwala określić wartość domyślną dla opcjonalnych argumentów:W tym przypadku wartość domyślna
default-b
będzie oceniana przy każdym wywołaniu funkcji.źródło