Почему Common Lisp REPL продолжает работать бесконечно после вставки этого кругового списка?

Я использую Common Lisp, SBCL и Slime. Я новичок в Common Lisp.

Судя по всему, это круговой список в Common Lisp:

#1=('a 'b 'c . #1#)

Это обеспечило бы бесконечное число 'a'b'c'a'b'c'a...

Когда я помещаю это в REPL, оно продолжает работать вечно:

CL-USER> #1=('a 'b 'c . #1#)

Почему это происходит? Почему REPL не возвращает полученный объект?

Я могу понять бесконечное поведение, если бы я просил следующий элемент списка. Однако я спросил REPL о самом объекте.

Я ожидал такого же поведения, которое происходит с правильными списками или пунктирными списками:

CL-USER> (list 'a 'b 'c)
(A B C)

CL-USER> (cons 'a  (cons 'b 'c))
(A B . C)

person Pedro Delfino    schedule 15.05.2021    source источник
comment
Кроме того, обратите внимание, что обычно не нужно заключать символы в кавычки внутри списка в кавычках.   -  person Rainer Joswig    schedule 16.05.2021


Ответы (2)


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

Почему? Следующий элемент не является операцией с бесконечным временем вычислений. Это просто получение следующего элемента, что является простой операцией. Это просто следующий элемент в циклическом списке.

Что бесконечно, так это когда кто-то запрашивает следующий элемент в цикле, проверяя конец списка.

(cdr list)

vs.

(dolist (e list)
  ...)

Вероятно, принтер (часть цикла печати Read Eval, которая печатает результат) будет делать что-то подобное, когда ему нужно напечатать элементы бесконечного списка. TFB упомянул, что нужны специальные проверки для обнаружения цикличности, чтобы ограничить вычисления.

person Rainer Joswig    schedule 16.05.2021

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

Что ж, CL позволяет вам приручить это: есть ряд переменных управления принтером, из которых, пожалуй, наиболее полезная здесь — *print-circle*. Вы можете установить для этого параметра значение true, чтобы включить обнаружение циркулярности в принтере. Если вы сделаете это, вы также, вероятно, поймете, почему по умолчанию это nil.

person Community    schedule 15.05.2021