首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简化复setf表达式

简化复setf表达式
EN

Stack Overflow用户
提问于 2017-02-07 21:30:28
回答 1查看 88关注 0票数 1

对于普通lisp中的快速原型,可以方便地在任意数据结构中对对象进行功能修改。这似乎涉及在数据结构中的某个位置上调用任意函数,用函数调用的结果替换该位置上的对象。Common对特定类型的对象有许多专门的修改宏(例如,incfpushgetf等),而用于广义位置修改的setf (例如,setf-secondsetf-arefsetf-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+)。下面是对代码的尝试:

代码语言:javascript
复制
(defun call (object function) (funcall function object))
(define-modify-macro callf (&rest args) call)

这样的东西在所有一般情况下都能工作吗?实际上它能简化代码吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-07 23:16:59

callf

我认为您要寻找的是来自OnLisp 12.4的OnLisp

代码语言:javascript
复制
(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+)而不是增加所有三个变量。但要解决这个问题并不难.

实际上,它能简化代码吗?

这个真正的取决于您的编码风格和您正在解决的具体问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42100353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档