Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Common lisp common lisp中意外循环列表的问题_Common Lisp_Circular List - Fatal编程技术网

Common lisp common lisp中意外循环列表的问题

Common lisp common lisp中意外循环列表的问题,common-lisp,circular-list,Common Lisp,Circular List,在linux中运行sbcl 1.3.7时,我有一个对象,它有一个插槽,按照Rainer Joswig在中的建议,它是一个循环列表,还有一个全局变量,它是一个适当的列表,而不是循环列表 (setf *print-circle* t) (defun circular (items) (setf (cdr (last items)) items) items) (defclass circular () ((items :accessor items :initarg :items

在linux中运行sbcl 1.3.7时,我有一个对象,它有一个插槽,按照Rainer Joswig在中的建议,它是一个循环列表,还有一个全局变量,它是一个适当的列表,而不是循环列表

(setf *print-circle* t)

(defun circular (items)
   (setf (cdr (last items)) items)
   items)

(defclass circular ()
  ((items :accessor items :initarg :items)))

(defmethod initialize-instance :after ((c circular) &rest initargs)
   (setf (slot-value c 'items)
         (circular (slot-value c 'items))))

(defmethod next-item ((c circular))
  (prog1 (first (slot-value c 'items))
    (setf (slot-value c 'items)
          (rest (slot-value c 'items)))))

(defparameter *notes* (make-instance 'circular :items '(A A# B C C# D D# E F F# G G#)))

(defparameter *stuff1* '(A A# B C C# D D# E F F# G G#))
(defparameter *stuff2* (list 'A 'A# 'B 'C 'C# 'D 'D# 'E 'F 'F# 'G 'G#))
我的问题是参数*stuff1*,它应该是一个简单的符号列表。至少我是这么想的。在sbcl中编译上述内容,*stuff1*返回

> *stuff1*
#1=(A |A#| B C |C#| D |D#| E F |F#| G |G#| . #1#)
我绝对没有想到这个非循环列表会变成一个锐号等号项目。更重要的是,尽管我设置了*print circle*t,但sbcl没有错误地挂起以下内容:

(member '|Bb| *stuff1*)
另一方面,*stuff2*按预期工作

那么,有两个问题,1为什么*stuff1*列表会变成一个循环cons,导致一个不正确的列表,*stuff2*保持一个正确的列表,2我如何测试*stuff1*的成员身份

显然,我可以使用*stuff2*版本,但我显然误解了这里的一些关键内容。欢迎使用任何指针。

文字列表

'bc是代码中引用的文字列表。通用Lisp标准表示,更改这些内容的效果尚未定义

规则:不要更改文字列表。将它们视为常量数据。有关如何在运行时创建新列表的信息,请参见诸如list、copy list和copy tree之类的函数

在代码中共享文字对象

编译器可以检测到代码中的两个文本列表(如bc和bc)相等。由于它们是常量数据(见上文),编译器可以生成代码,这样它只分配一个列表,并且该列表在多个位置共享。SBCL文件编译器就是这样做的

规则:聪明的编译器可以共享相同的文本列表

圆形构件

Common Lisp的成员仅支持正确的列表。不是循环列表

循环列表的mapc函数是一个很好的构建块:

(defun circular-mapc (function list)
  (loop for fast = list then (cddr fast)
        for slow = list then (cdr slow)
        do
        (funcall function (car slow))
        (when (eq (cddr fast) (cdr slow))
          (return-from circular-mapc nil))))

(defun circular (items)
  (check-type items cons)
  (setf (cdr (last items)) items)
  items)

(defun circular-member-p (item list)
  (circular-mapc (lambda (e)
                   (when (eql item e)
                     (return-from circular-member-p t)))
                 list))
例如:

CL-USER 38 > (circular-member-p 'a (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 39 > (circular-member-p 'b (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 40 > (circular-member-p 'c (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 41 > (circular-member-p 'd (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 42 > (circular-member-p 'e (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 43 > (circular-member-p 'f (circular (list 'a 'b 'c 'd 'e)))
NIL
文字列表

'bc是代码中引用的文字列表。通用Lisp标准表示,更改这些内容的效果尚未定义

规则:不要更改文字列表。将它们视为常量数据。有关如何在运行时创建新列表的信息,请参见诸如list、copy list和copy tree之类的函数

在代码中共享文字对象

编译器可以检测到代码中的两个文本列表(如bc和bc)相等。由于它们是常量数据(见上文),编译器可以生成代码,这样它只分配一个列表,并且该列表在多个位置共享。SBCL文件编译器就是这样做的

规则:聪明的编译器可以共享相同的文本列表

圆形构件

Common Lisp的成员仅支持正确的列表。不是循环列表

循环列表的mapc函数是一个很好的构建块:

(defun circular-mapc (function list)
  (loop for fast = list then (cddr fast)
        for slow = list then (cdr slow)
        do
        (funcall function (car slow))
        (when (eq (cddr fast) (cdr slow))
          (return-from circular-mapc nil))))

(defun circular (items)
  (check-type items cons)
  (setf (cdr (last items)) items)
  items)

(defun circular-member-p (item list)
  (circular-mapc (lambda (e)
                   (when (eql item e)
                     (return-from circular-member-p t)))
                 list))
例如:

CL-USER 38 > (circular-member-p 'a (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 39 > (circular-member-p 'b (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 40 > (circular-member-p 'c (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 41 > (circular-member-p 'd (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 42 > (circular-member-p 'e (circular (list 'a 'b 'c 'd 'e)))
T

CL-USER 43 > (circular-member-p 'f (circular (list 'a 'b 'c 'd 'e)))
NIL

我没有意识到sbcl会重用文字列表,重新创建循环。这就解决了问题。@worly您可能会找到一本有用的读物。我没有意识到sbcl会重用文字列表,重新创建循环。这就解决了问题。@worly你可以找到一本有用的书。