CLISP представление списка - PullRequest
0 голосов
/ 30 июня 2018

Я экспериментирую с использованием substitute-if. Здесь я пытаюсь заменить все значения, которые есть даже в '((1) (2) (3) (4)) на '(0)

[9]> (substitute-if '(0) #'evenp '((1) (2) (3) (4)) :start 1 :key #'car)
((1) #1=(0) (3) #1#)

Я запутался в #1=(0) и #1 в списке. Я ожидал, что он вернется '((1) (0) (3) (0)).

Я неправильно понимаю, как работает substitute-if, или неправильно понимает представление списка?

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Похоже, вы установили динамическую глобальную переменную *print-circle* в нечто истинное. Если вы оцените *print-circle*, вы увидите это.

; make a list (1 1 1 1 1 ...)
(defparameter *test* (list 1))
(setf (cdr *test*) *test*)

(setf *print-circle* t)
(substitute-if '(0) #'evenp '((1) (2) (3) (4)) :start 1 :key #'car)
; ==> ((1) #1=(0) (3) #1#)
*test*
; ==> #1=(1 . #1#)

(setf *print-circle* nil)
(substitute-if '(0) #'evenp '((1) (2) (3) (4)) :start 1 :key #'car)
; ==> ((1) (0) (3) (0))
*test* ; never finishes

Последний будет зависать, пока не закончится память. спешите отменить его, иначе ваша система наверняка будет работать медленно, когда она использует всю доступную память и буферы и начнет заставлять систему заменять другие вещи.

Вот почему у нас *print-circle*. Возможность видеть списки, которые являются круглыми. Структура напечатанных данных всегда одинакова, поэтому отличается только то, как она отображается.

Когда вы используете substitute-if и заменяете на '(0), он имеет один адрес в памяти и, таким образом, когда *print-circle* верен, он напечатает его только один раз, а другие ссылки будут показаны как ссылки, так как система ищет тот же объект, а не если он действительно круговой или нет.

0 голосов
/ 01 июля 2018

Я неправильно понимаю, как работает substitute-if, или неправильно понимает представление списка?

Вероятно, последний.

#1=... отмечает место в структуре данных, а #1# ссылается на него. Идея состоит в том, чтобы показать, что оба элемента относятся к одному и тому же списку. (См. Также http://www.lispworks.com/documentation/HyperSpec/Body/02_dhp.htm.)

Это как:

(let ((x '(0)))
  (list '(1) x '(3) x))

Поскольку они ссылаются на один и тот же объект, если бы вы изменили второй список на месте, это изменение также появилось бы в четвертом списке.

...