在Common Lisp中将变量列表评估为值列表

Mad*_*ist 2 common-lisp

我想知道如何实现以下目标。假设我有一个受let上述约束的变量列表。我想将此列表转换为这些变量绑定到的值的列表。

也就是说,假设我们有

(define make-plist-from-variables (variables)
  (let ((keys variables)
        (values (mapcar #'identity variables)))
    (if (eq (length keys) (length values))
     (make-plist keys values)
     nil))))
Run Code Online (Sandbox Code Playgroud)

我可以用什么来#'identity正确解压这些值?

目前,以下调用将产生以下输出。

CL-USER> (let ((a 2) (b 3)) (make-plist-from-variables '(a b)))
(A A B B)
Run Code Online (Sandbox Code Playgroud)

我希望成为 (A 2 B 3)

Syl*_*ter 5

它必须是一个宏,因为无法根据其符号获取变量的词法值。

(defmacro make-plist-from-variables (&rest variables)
  (loop :for binding :in variables
        :collect `',binding :into result
        :collect binding :into result
        :finally (return `(list ,@result))))

(macroexpand-1 '(make-plist-from-variables a b))
; ==> (list 'a a 'b b) 

(let ((a 2) (b 3)) 
  (make-plist-from-variables a b))
; ==> (a 2 b 3)
Run Code Online (Sandbox Code Playgroud)

编辑

loop使用的实现mapcan

(defmacro make-plist-from-variables (&rest variables)
  `(list ,@(mapcan (lambda (v) `(',v ,v)) variables))
Run Code Online (Sandbox Code Playgroud)