标签: setf

SETF既不会终止也不会报告错误

我是Common Lisp的初学者,遇到了这段代码:

(let ((foo (list 42)))
  (setf (rest foo) foo))
Run Code Online (Sandbox Code Playgroud)

在尝试执行它时,REPL似乎永远循环.

common-lisp setf

1
推荐指数
1
解决办法
65
查看次数

无损设定?

Common Lisp似乎竭尽全力提供非破坏性功能(如subst和remove)和破坏性功能以及修改宏(如delete和rotatef)以供一般使用.据推测,这是为了有效地支持功能和非功能的编程风格.但是在无处不在的设计中似乎也存在对非功能性风格的特殊偏见setf.setf包含通用引用的宏显然足够灵活,可以修改任何可指定的位置(除了可能的不可变整数和字符).尽管其无功能/破坏性行为,但这种力量可能是其广泛使用的原因.

问题是为什么没有相应的"功能样式"非破坏性操作符,后面的图案setf(称之为put,因为set已经采用),类似于其他非破坏性/破坏性的lisp操作符对.这样的运算符可能会使用相同的参数,一个位置和一个值,但会返回嵌入了该位置的对象的副本,而不是该位置的新值.它也可能涉及某种通用复印机,标准setf只是在返回之前修改副本.然后可以使用非破坏性运算符代替setf大多数分配,并setf为大型对象保留.鉴于通用复印机的(推测)要求以及从嵌入其中的任意位置恢复物体的需要,这样的操作者是否可行(甚至可能)?

functional-programming common-lisp setf

1
推荐指数
1
解决办法
185
查看次数

Setf函数名称

这个问题让我思考什么构成了一个有效的表达式汽车.显然,可以使用通常的语法"调用"符号和lambdas.按照hyperspec,

函数名 ñ.1.(在环境中)符号或列表(setf符号),它是该环境中函数的名称.2.符号或列表(setf符号).

因此,理论上讲,它(setf some-name)是一个函数名称.我决定尝试一下.

(defun (setf try-this) ()
  (format t "Don't name your functions like this, kids :)"))

((setf try-this))
(funcall '(setf try-this))
(setf (try-this))
Run Code Online (Sandbox Code Playgroud)

GNU CLISP,SBCL和ABCL都将让我定义这个功能.但是,SBCL和ABCL不允许我使用代码段中显示的任何语法来调用它.另一方面,CLISP将运行前两个但仍然在第三个错误.

我很好奇哪个编译器的行为正确.由于SBCL和ABCL同意,我猜测正确的实现应该拒绝该代码.作为第二个问题,我如何从代码片段中调用我令人难以置信的无用功能,因为我上面尝试过的东西不能轻松工作.或者,也许更有用,

lisp common-lisp setf

1
推荐指数
1
解决办法
175
查看次数

无损修改哈希表

是否可以非破坏性地将新的键值对添加到 Common Lisp (SBCL) 哈希表中?向哈希表添加新元素的标准方法是调用:

(setf (gethash key *hash-table*) value)
Run Code Online (Sandbox Code Playgroud)

但调用setf修改*hash-table*破坏了原件。我有一个应用程序,我想利用哈希表查找的效率,但我也想非破坏性地修改它们。我看到的解决方法是在对其进行操作之前复制原始哈希表,但这在我的情况下不切实际,因为我正在处理的哈希表包含数千个元素并复制大型哈希表,例如循环首先会否定使用它们的计算效率优势。

lisp hashtable sbcl common-lisp setf

1
推荐指数
1
解决办法
92
查看次数

动态定义setf扩展器

我正在尝试定义一个宏,它将获取结构的名称,键和结构中哈希表的名称,并定义函数以访问和修改哈希中键下的值.

(defmacro make-hash-accessor (struct-name key hash)
  (let ((key-accessor  (gensym))
        (hash-accessor (gensym)))
    `(let ((,key-accessor  (accessor-name ,struct-name ,key))
           (,hash-accessor (accessor-name ,struct-name ,hash)))
       (setf (fdefinition ,key-accessor) ; reads
             (lambda (instance)
               (gethash ',key
                (funcall ,hash-accessor instance))))
       (setf (fdefinition '(setf ,key-accessor)) ; modifies
             (lambda (instance to-value)
               (setf (gethash ',key
                      (funcall ,hash-accessor instance))
                 to-value))))))

;; Returns the symbol that would be the name of an accessor for a struct's slot
(defmacro accessor-name (struct-name slot)
  `(intern
    (concatenate 'string (symbol-name ',struct-name) "-" (symbol-name ',slot))))
Run Code Online (Sandbox Code Playgroud)

为了测试这个,我有:

(defstruct tester
  (hash …
Run Code Online (Sandbox Code Playgroud)

macros symbols common-lisp dynamically-generated setf

0
推荐指数
1
解决办法
69
查看次数