对于普通lisp中的快速原型,可以方便地在任意数据结构中对对象进行功能修改。这似乎涉及在数据结构中的某个位置上调用任意函数,用函数调用的结果替换该位置上的对象。Common对特定类型的对象有许多专门的修改宏(例如,incf、push、getf等),而用于广义位置修改的setf (例如,setf-second、setf-aref、setf-gethash等)。但是,与其为其他对象类型发明新的专门宏,或者在思想上考虑每个宏的特性(减缓开发速度),不如拥有一种比setf更易于使用的通用的类似setf的修改功能。例如,可以使用公共lisp或用户提供的任何普通的一个参数函数(或lambda-表达式)来编写(setf (second (getf plist indicator)) (1+ (second (getf plist indicator))))或(incf (second (getf plist indicator))),而不是编写(callf (second (getf plist indicator)) #'1+)。下面是对代码的尝试:
(defun call (object function) (funcall function object))
(define-modify-macro callf (&rest args) call)这样的东西在所有一般情况下都能工作吗?实际上它能简化代码吗?
发布于 2017-02-07 23:16:59
callf
我认为您要寻找的是来自OnLisp 12.4的OnLisp:
(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)))这使用了get-setf-expansion -- 广义参考处理的工作马。
请注意,_f只适用于单值 places。IOW,(_f (values a b c) 1+)将而不是增加所有三个变量。但要解决这个问题并不难.
实际上,它能简化代码吗?
这个真正的取决于您的编码风格和您正在解决的具体问题。
https://stackoverflow.com/questions/42100353
复制相似问题