有条件地删除 lisp 宏中的 let-binding
Conditionally remove let-binding in lisp macro
如何有条件地删除在 lisp 宏中创建的 defun
中的 let 绑定?在这里,我想从结果函数中删除第一个 let-bound 变量,但是 运行 遇到了一个问题,我有一个 nil
留在 let 绑定中,导致错误。
例如,生成的函数使用 let
或 let*
,并且应根据 arg
删除第一个变量赋值。但是我写问题的方式来自用 nil
替换 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)
最简单的解决方法可能是使用 ,@(when arg '((var1 1)))
。 ,@
用于将列表拼接到位置。由于 WHEN
returns NIL
如果条件失败,并且 NIL
与空列表相同,拼接会有效地忽略它。条件成功返回((var1 1))
,(var1 1)
被拼接解包
如何有条件地删除在 lisp 宏中创建的 defun
中的 let 绑定?在这里,我想从结果函数中删除第一个 let-bound 变量,但是 运行 遇到了一个问题,我有一个 nil
留在 let 绑定中,导致错误。
例如,生成的函数使用 let
或 let*
,并且应根据 arg
删除第一个变量赋值。但是我写问题的方式来自用 nil
替换 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)
最简单的解决方法可能是使用 ,@(when arg '((var1 1)))
。 ,@
用于将列表拼接到位置。由于 WHEN
returns NIL
如果条件失败,并且 NIL
与空列表相同,拼接会有效地忽略它。条件成功返回((var1 1))
,(var1 1)
被拼接解包