gpt4 book ai didi

common-lisp - Lisp : psetf not fully understood

转载 作者:行者123 更新时间:2023-12-01 07:34:01 26 4
gpt4 key购买 nike

我正在 SBCL 中尝试这个来翻转列表中的点对:

(mapcar (lambda (x) (let ((num (random 2)))
(if (= num 0)
(psetf (cdr x) (car x) (car x) (cdr x))
x)))
'((B . 21) (O . 24) (P . 15) (R . 47) (K . 49)))

但是我得到了这个(ymmv):
(NIL (O . 24) NIL (R . 47) (K . 49))

这告诉我 psetf不喜欢我在做什么。据我了解, psetf具有破坏性并返回 NIL .我在这里不明白什么?

最佳答案

您观察到的行为是正确且符合预期的:
psetf 返回 nil mapcar 放置返回值
进入返回列表,所以当 num是 0,你到达那里 nil ,
当它为 1 时,您将获得原始单元格。

轻松修复:

(mapcar (lambda (x)
(when (zerop (random 2))
(psetf (cdr x) (car x) (car x) (cdr x)))
x)
'((B . 21) (O . 24) (P . 15) (R . 47) (K . 49)))
==> ((B . 21) (24 . O) (P . 15) (47 . R) (K . 49))

实际上,CL 有一个宏 rotatef
仅针对您的情况:
(mapcar (lambda (x)
(when (zerop (random 2))
(rotatef (cdr x) (car x)))
x)
'((B . 21) (O . 24) (P . 15) (R . 47) (K . 49)))
==> ((21 . B) (O . 24) (15 . P) (R . 47) (K . 49))

最后,请注意 modifying quoted data is a very bad idea :
(defparameter *alist-0* '((B . 21) (O . 24) (P . 15) (R . 47) (K . 49)))
(defparameter *alist-1*
(mapcar (lambda (x)
(when (zerop (random 2))
(rotatef (cdr x) (car x)))
x)
*alist-0*))
(eq *alist-0* *alist-1*)
==> nil
(equal *alist-0* *alist-1*)
==> t ; !!!
(every #'eq *alist-0* *alist-1*)
==> t

即,单元格相同,但列表不同。

一致地复制所有单元格可能会更好:
(defparameter *alist-2*
(mapcar (lambda (x)
(if (zerop (random 2))
(cons (cdr x) (car x))
(cons (car x) (cdr x))))
*alist-0*))
*alist-0*
==> ((B . 21) (O . 24) (P . 15) (R . 47) (K . 49))
*alist-2*
==> ((21 . B) (O . 24) (15 . P) (R . 47) (K . 49))

关于common-lisp - Lisp : psetf not fully understood,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47565103/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com