【问题标题】:defining setf-expanders in Common Lisp在 Common Lisp 中定义 setf-expanders
【发布时间】:2012-07-12 12:17:50
【问题描述】:

事情是这样的:我没有“得到” setf-expanders 并且想了解它们是如何工作的。

我需要了解它们是如何工作的,因为我遇到了一个问题,这似乎是你应该学习 setf-expanders 的典型示例,问题如下:

(defparameter some-array (make-array 10))

(defun arr-index (index-string)
  (aref some-array (parse-integer index-string))

(setf (arr-index "2") 7) ;; Error: undefined function (setf arr-index)

如何为 ARR-INDEX 编写合适的 setf-expander?

【问题讨论】:

    标签: common-lisp setf


    【解决方案1】:
    (defun (setf arr-index) (new-value index-string)
      (setf (aref some-array (parse-integer index-string))
            new-value))
    

    在 Common Lisp 中,function name 不仅可以是一个符号,还可以是一个以 SETF 为第一个符号的两个符号的列表。往上看。 DEFUN 因此可以定义SETF 函数。函数名称为(setf arr-index)

    setf 函数可以在place形式中使用:CLHS: Other compound forms as places

    那么新值就是第一个参数。

    CL-USER 15 > some-array
    #(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)
    
    CL-USER 16 > (setf (arr-index "2") 7)
    7
    
    CL-USER 17 > some-array
    #(NIL NIL 7 NIL NIL NIL NIL NIL NIL NIL)
    

    【讨论】:

    • 我在 CLHS 中找不到这个,它在哪里?
    • 我在词汇表中看到过,但它在哪里解释了如何使用 (defun (setf foo)...) 定义 setf 函数?
    • @Nowhereman:没有直接的解释。但是它定义了一个 setf 函数可以在一个地方表单中使用,并且defun 可以定义一个带有 setf 名称的函数。
    • #'(setf arr-index) 现在是一个可以调用的函数。这就是 setf 宏扩展的内容,即(funcall #'(setf arr-index) new-value index-string)
    【解决方案2】:

    Rainer 的回答很到位。在 ANSI Common Lisp 之前,有必要使用 defsetf 为可以通过简单函数调用设置的简单位置定义扩展器。 setf(setf arr-index) 这样的函数通过 CLOS 进入语言并简化了很多事情。特别是,setf 函数可以是泛型的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-24
      • 2010-10-26
      • 2012-07-13
      • 2020-09-14
      • 2015-05-10
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      相关资源
      最近更新 更多