Если вы не используете расширения Common Lisp, как предложено @legoscia, вам нужно проверить, был ли указан необязательный аргумент. Обратите внимание, что вам не нужно использовать 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)))
Конечно, если необязательный параметр нужен только один раз, вы должны просто сделать это:
(defun my-command (a &optional b)
(command-body a (or b default)))
setq
в «чистой» булевой форме, напримерor
. На мой взгляд,when
здесь определенно более уместно, но обычноlet
это выражение выбора для установления или изменения локальных привязок. IOW, оригинальный код выглядит намного лучше для меня.(unless b (setq b default)
может быть лучше. Лично я думаю, чтоlet
здесь избыточно, потому чтоb
это уже локально дляdefun
.let
Е. Как побочную формуsetq
. Это код для параметра по умолчанию, но либеральное использованиеsetq
для изменения локальных переменных затрудняет чтение и следование коду. Я думаю, что лучше всего считать все локальные привязки неизменными и устанавливать только новыеlet
. Я хочу отдать предпочтение функциональному стилю, а не императивному.Вы можете использовать
cl-defun
, что позволяет указать значение по умолчанию для необязательных аргументов:В этом случае значение по умолчанию
default-b
будет оцениваться при каждом вызове функции.источник