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