Циклические списки в guile

#scheme #lisp #circular-reference #guile

#схема #lisp #циклическая ссылка #хитрость

Вопрос:

Я тестировал этот код в guile:

 > (define xxx  (let ((x '(1 2 3))) (set-cdr! (cddr x) x) x))
> xxx
  

это отображение (1 2 3)

но это:

 (define x '(1 2 3))
(set-cdr! (cddr x) x)
x
=> (1 2 3 . #-2#)
  

создает циклический список

Почему первый код не работает в guile? Если вы не знаете о guile, я просто хочу знать, должно ли это работать в соответствии со спецификацией scheme, не знаю, где искать такие вещи.

Комментарии:

1. «это отображение (1 2 3)» — опять же, нет, это не так. Выдает ошибку: In procedure set-cdr!: Wrong type argument in position 1 (expecting mutable pair): (3) . Какую версию guile вы используете?

2. Они дают тот же самый, циклический, результат в Guile 2.0.13 здесь . Я считаю, что 2.0 был довольно далек от соответствия каким-либо стандартам Scheme.

3. Ни одна из них не является допустимой схемой, поскольку вы пытаетесь изменить литеральные данные в постоянных кавычках. Таким образом, если бы реализация была напечатана "BaNaNa" , это все равно было бы нормально.

Ответ №1:

Проблема с вашими примерами в том, что они не работают. Ни один из них. Я понятия не имею, как вернулся первый (1 2 3) . Но когда вы исправляете одну и ту же проблему в обоих примерах, они работают должным образом и создают круговой список.

Проблема?

'(1 2 3) и (quote 1 2 3) это нечто совсем другое, чем (list 1 2 3) . Они оба «выглядят» одинаково, но первый из них — статический список, и вы не можете его изменить. Вы можете изменять только список, созданный с помощью list функции (ну и cons ).

Исправить:

 (define xxx
  (let ((x (list 1 2 3)))
    (set-cdr! (cddr x) x)
    x))

xxx ;; => (1 2 3 . #-2#)
  

И то же самое касается второго примера:

 (define x (list 1 2 3))
(set-cdr! (cddr x) x)
  

Пожалуйста, протестируйте свой код перед публикацией.

Комментарии:

1. Второй код работал в guile, это был точный код, который я тестировал, возможно, (quote 1 2 3) работает по-другому при использовании с define . Тогда не знал, что это '(1 2 3) по-другому (list 1 2 3) . Но если quote работать по-другому, то list тогда почему это работает (let ((x '(1 2 3))) (append! x '(10))) ?

2. Я тестировал это также на guile (версия 2.2.4). И я получал сообщение об ошибке. Не знаю, почему ваш guile работает по-другому.

3. Позже guile получил защиту памяти и ошибки. Более старая версия не имеет такой защиты.