Common lisp plist的通用Lisp remf指示器不工作

Common lisp plist的通用Lisp remf指示器不工作,common-lisp,plist,keyword-argument,Common Lisp,Plist,Keyword Argument,我有一个名为use的函数,它接受任意数量的关键字参数(作为plist),定义如下: (defun use (&rest plist &key &allow-other-keys) ":href should be supplied, as it is the path/to/svg#id to be used." ;; Hole die Sachen die wichtig sind aus der PListe (let ((href (getf pli

我有一个名为
use
的函数,它接受任意数量的关键字参数(作为plist),定义如下:

(defun use (&rest plist &key &allow-other-keys)
  ":href should be supplied, as it is the path/to/svg#id to be used."
  ;; Hole die Sachen die wichtig sind aus der PListe
    (let ((href (getf plist :href "#")))
      ;; Remove :href otherwise it appears in the plist again!
      (remf-indicators-from-plist '(:href) plist)
      (list plist href)
    ))
在这里,我提取一些重要的关键字参数,这些参数应该由用户指定,然后使用plist中的
remf指示符将它们从提供的关键字参数的plist中删除,这样我就不会对它们进行两次处理remf指标定义如下:

(defun remf-indicators-from-plist (indicators plist)
  "Removes indicators from the plist, 
to prevent callers from double-using them."
  (dolist (indicator indicators plist)
    (remf plist indicator)))
现在,在我看来,如果要在
use
函数中提取并删除的关键字参数不是函数的第一个参数,那么它们确实会被删除:

(use :x 34 :href 23 :c2 32)     ;((:X 34 :C2 32) 23)
(use :x 34 :c2 32 :href 23)     ;((:X 34 :C2 32) 23)
但如果它作为第一个参数出现,则不会:

(use :href 23 :x 34 :c2 32)     ;((:HREF 23 :X 34 :C2 32) 23)

为什么会这样?我如何才能正确地实现它?

问题在于功能
使用
,而plist的
remf指示器工作正常

原因是来自plist的函数
remf indicators
返回修改的列表(在
dolist
中),但返回的值在
use
中被丢弃。一种可能的解决方案是更改
使用的定义,例如:

CL-USER> (defun use (&rest plist &key &allow-other-keys)
            ":href should be supplied, as it is the path/to/svg#id to be used."
            ;; Hole die Sachen die wichtig sind aus der PListe
          (let ((href (getf plist :href "#"))
                (new-plist (remf-indicators-from-plist '(:href) plist)))
            (list new-plist href)))
USE
CL-USER> (use :x 34 :href 23 :c2 32)  
((:X 34 :C2 32) 23)
CL-USER> (use :href 23 :x 34 :c2 32) 
((:X 34 :C2 32) 23)
:href
在plist中时,一切显然都起作用,这是由于在公共Lisp中某些操作执行副作用的特殊方式造成的。有助于管理副作用操作的规则(常量数据永远不应该被修改这一事实的一部分)如下:始终返回被修改的结构,即使修改似乎“就地”发生