Reference 复杂setf表达式的简化

Reference 复杂setf表达式的简化,reference,macros,common-lisp,Reference,Macros,Common Lisp,对于通用lisp中的快速原型设计,可以方便地对任意数据结构中的对象进行功能修改。这似乎涉及调用数据结构中某个位置上的任意函数,用函数调用的结果替换该位置上的对象。Common lisp有许多专门的修改宏(例如,incf,push,getf,等等)用于特定类型的对象,还有setf用于广义位置修改(例如,setf second,setf aref,setf gethash,等等)。但是,不要为其他对象类型发明新的专用宏,或者必须在心理上考虑每个宏的特性(减慢开发),所以有一个通用的类似于SETF的修

对于通用lisp中的快速原型设计,可以方便地对任意数据结构中的对象进行功能修改。这似乎涉及调用数据结构中某个位置上的任意函数,用函数调用的结果替换该位置上的对象。Common lisp有许多专门的修改宏(例如,
incf
push
getf
,等等)用于特定类型的对象,还有
setf
用于广义位置修改(例如,
setf second
setf aref
setf gethash
,等等)。但是,不要为其他对象类型发明新的专用宏,或者必须在心理上考虑每个宏的特性(减慢开发),所以有一个通用的类似于SETF的修改能力比使用<代码> SETF 更简单。例如,与
(setf(second(getf plist indicator))(1+(second(getf plist indicator)))
(incf(second(getf plist indicator)))
不同,可以使用任何正常的单参数函数(或lambda表达式)编写
(callf(second(getf plist indicator))#'1+
由common lisp或用户提供。下面是对代码的尝试:

(defun call (object function) (funcall function object))
(define-modify-macro callf (&rest args) call)
像这样的东西对所有一般情况都有效吗?它实际上能简化实际的代码吗?

callf
我认为您需要的是12.4:

这使用了-这是处理的主要工具

请注意,
\u f
仅适用于位置。 因此,
(_f(值a b c)1+)
增加所有3个变量。 但解决这个问题并不难

它实际上可以简化实践中的代码吗?
这实际上取决于你的编码风格和你正在解决的具体问题。

你在寻找什么?就是它。网上讨论也很好。
(defmacro _f (op place &rest args)
  "Modify place using `op`, e.g., (incf a) == (_f a 1+)"
  (multiple-value-bind (vars forms var set access)
      (get-setf-expansion place)
    `(let* (,@(mapcar #'list vars forms)
            (,(car var) (,op ,access ,@args)))
       ,set)))