Условно убрать let-привязку в макросе lisp
Как я могу условно удалить let-связывание в defun
создан в макросе LISP? Здесь я хочу удалить первую переменную let-bound из результирующей функции, но сталкиваюсь с проблемой, когда у меня есть nil
которая застревает в привязках let, вызывая ошибку.
Например, результирующая функция использует let
или же let*
и следует удалить первое назначение переменной в зависимости от arg
, Но то, как я это написал, проблема заключается в замене var1
с nil
, Я не уверен, как избавиться от нуля.
(cl-defmacro mac (cmd &optional arg)
(let ((fn (intern (concat "fn-" cmd))))
`(defun ,fn ()
(interactive)
(,(if arg 'let* 'let)
(cons
,(when arg
'(var1 1))
(var2 (if (bound-and-true-p var1) (+ var1 1) 1)))
(message "%s" var2)))))
(mac "fun") ; Attempt to set constant: nil
(mac "fun2" t) ; no problem
;; (symbol-function 'fn-fun)
;; (symbol-function 'fn-fun2)
;; (fn-fun)
;; (fn-fun2)
1 ответ
Самый простой обходной путь, вероятно, заключается в использовании ,@(when arg '((var1 1)))
, ,@
используется для склеивания списка в позицию. поскольку WHEN
возвращается NIL
если условие не выполняется, и NIL
такой же, как пустой список, соединение фактически игнорирует его. Когда условие успешно ((var1 1))
возвращается, и (var1 1)
разворачивается сращиванием.