【问题标题】:How to write a multf function in common lisp如何在 common lisp 中编写 multf 函数
【发布时间】:2019-11-16 15:23:16
【问题描述】:

我正在寻找一种方法来修改属性列表中的属性值,方法是将其与给定因子相乘,类似于使用 incf 添加到值。

使用 incf 我可以说:

(let ((seq '(:x 10 :y 3)))
 (incf (getf seq :y) 3)
 seq)

-> (:x 10 :y 5)

使用宏我可以通过以下方式获得结果,但这使用了两次 getf:

(defmacro multf (place val)
  `(setf ,place (* ,place ,val)))

(let ((seq '(:x 10 :y 3)))
  (multf (getf seq :y) 2)
  seq)

-> (:x 10 :y 6)

我将如何做到这一点,以便我可以只使用一次 getf 获得相同的结果?

也许有这个功能的包,但我在网上找不到。任何帮助表示赞赏!这不是功课,我只是想优化我的代码,我很想更好地理解语言。我读到了 setf-expanders 和 compiler-macros,但我不知道它们是否适用于这里以及如何使用它们。

【问题讨论】:

    标签: common-lisp setf


    【解决方案1】:

    但这使用了两次 getf

    第一个是 SETF 形式,第二个是 getter。第一个将由 SETF 扩展。

    使用define-modify-macromultf 的简短定义可能是:

    CL-USER 28 > (define-modify-macro multf (&optional (number 1)) *)
    MULTF
    
    CL-USER 29 > (let ((seq '(:x 10 :y 3)))
                   (multf (getf seq :y) 2)
                   seq)
    (:X 10 :Y 6)
    

    LispWorks 中的完整扩展如下所示:

    (LET ((SEQ '(:X 10 :Y 3)))
      (LET* ((#:G1158 :Y))
        (LET* ()
          (LET ((#:G1157 (* (GETF SEQ #:G1158) 2)))
            (LET ((#:|Store-Var-1156| (SYSTEM::PRIMITIVE-PUTF SEQ #:G1158 #:G1157)))
              (SETQ SEQ #:|Store-Var-1156|)
              #:G1157))))
      SEQ)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2014-04-26
      • 2020-08-16
      相关资源
      最近更新 更多