Вычисление списка в LISP (странное поведение минусов)

В настоящее время я играю с LISP. Все хорошо, но я не могу понять следующий вопрос.

У меня есть эта операция добавления:

(define (append l1 l2)
   (if (eq? l1 null)
      l2
      (cons (first l1)
            (myappend (rest l1) l2))))

Я использую это так:

(myappend (cons (cons 1 2) null) '(4 5))

И результат в Racket:

 '((1 . 2) 4 5)

Но почему? По моему мнению, это должно быть '(1 2 4 5), потому что cons возвращает список, а myappends добавляет два списка. Кто-нибудь может мне помочь? Что делает ЛИСП?


person Thomas Uhrig    schedule 07.04.2012    source источник
comment
Похоже, вы используете какие-то нестандартные функции, свойственные Racket. В Лиспе (ANSI Common Lisp) списки заканчиваются символом nil. В стандартной схеме (которой Racket, очевидно, является диалектом) списки не заканчиваются символом. Они заканчиваются пустым объектом списка, который записывается как () (и который должен быть заключен в кавычки при использовании в качестве выражения: '()). В Scheme вы используете (null? x), чтобы проверить, является ли x пустым списком, а не (eq x null); нет предопределенного null. В Common Lisp это (null x) или (not x) или (eq x nil).   -  person Kaz    schedule 09.04.2012


Ответы (4)


cons возвращает точечную пару, не обязательно список.

(cons 1 2) возвращает (1 . 2)

(cons 1 null) возвращает (1)

(cons 1 (cons 2 null)) возвращает (1 2)

person Jim Lewis    schedule 07.04.2012
comment
Спасибо. Но путь (cons 1 (cons 2 null)) не возвращает (1 .(2))? - person Thomas Uhrig; 07.04.2012
comment
@Thomas: оба выражения представляют одну и ту же структуру; соглашение состоит в том, чтобы по возможности предпочесть запись списка вместо записи пар с точками. Если в какой-либо ячейке cons в структуре есть cdr, который является ненулевым атомом (как в вашем вопросе), потребуется обозначение пар с точками, поскольку структура не является списком. - person Jim Lewis; 07.04.2012
comment
@ThomasUhrig Этот ответ (отказ от ответственности: он мой) содержит больше информации о печатном представлении cons-ячеек. - person Joshua Taylor; 14.10.2013

(cons 1 2) вернет объект, первый указатель которого (car) указывает на 1, а другой (cdr) указывает на 2, поэтому он печатается в виде пары точек.

Также вы можете захотеть понять глубже, я рекомендую вам прочитать CL: мягкое введение в символьные вычисления, "6.4. Сравнение CONS, LIST и APPEND", которые очень хорошо объясняют эти темы.

person Juanito Fatas    schedule 08.04.2012

Попробуйте, что (против 1 2) возвращает. Это список?

person Rainer Joswig    schedule 07.04.2012
comment
Очевидно нет. Я думаю, что я что-то пропустил. Спасибо. - person Thomas Uhrig; 07.04.2012

@ThomasUhrig: следующая информация может вам помочь.

Хотя мы говорим здесь о языке Лисп, я заметил, что это строка на страницах 8 и 9 известной книги под названием "The Маленький Интриган (4-е издание)" помогите мне понять два загадочных факта:

    Why (cons 1    2) does not look like '(1 2)?
    Why (cons 1 '(2)) does     look like '(1 2)?
    ----
    > (cons 1 2)
    (1 . 2)
    > (cons 1 '(2))
    (1 2)
    > '(1 2)
    (1 2)

Просто прочитайте "Законы минусов":

Примитив cons принимает 2 аргумента.

Второй аргумент cons должен быть списком.

Результатом является список.

На практике: (против A B) работает для всех значений A и B, И

(машина (минусы A B)) = A

(cdr (cons A B)) = B

person pimgeek    schedule 25.05.2013
comment
Ссылка на PDF больше не работает. Я все еще могу легко найти копии с помощью Google, но, похоже, они все еще продаются в некоторых местах; Я не уверен, предполагается ли его свободное распространение. При этом соответствующий Закон минусов доступен в Google Книгах предварительный просмотр. - person Joshua Taylor; 15.12.2013