Представление NIL в реализации PC Scheme TI - PullRequest
1 голос
/ 08 марта 2012

Я изучаю LISP с использованием реализации PC Scheme TI и из книги «Структура и интерпретация компьютерных программ». Схема ПК, похоже, не имеет переменной 'nil'

[ВМ ОШИБКА обнаружена!] Переменная не определена в текущей среде NIL

Вместо '()', кажется, работает. [55] (определить от одного до четырех (список 1 2 3 4 ())) ОДИН ЧЕРЕЗ ЧЕТЫРЕ

Оба имеют одинаковое значение? Как правильно использовать последовательность без элементов в диалекте схемы ПК?

Спасибо.

1 Ответ

4 голосов
/ 08 марта 2012

Когда вы говорите, что этот диалект "не имеет переменной NIL", вы правы в двух отношениях. Мало того, что nil не существует, он, кажется, рассматривается как обычный символ, который вы можете использовать в качестве переменной. Там написано «Переменная не определена».

В диалектах Лисп, где nil имеет особое значение, nil обычно нельзя использовать в качестве переменной.

nil эквивалентно () только в «классических» Лиспах (мой термин). Под этим я подразумеваю Лисп, который связан по происхождению или подражанию с оригинальным Джоном Маккарти Лиспом. Emacs Lisp и Common Lisp именно таковы. Классический Лисп использует nil в качестве ограничителя списка: то есть (cons 1 nil) создает список (1)

Схема не является классическим Лиспом в этом смысле. Там нет nil. Он использует () в качестве печатной нотации для пустого списка, и когда вы хотите, чтобы это значение в выражении, оно заключалось в кавычки, как непустой литерал списка: '(). На схеме (cons 1 nil) написано (cons 1 '()). Логическое значение false представлено объектом, обозначенным #f. Пустой список - это истина, а не ложь, поэтому (if '() 1 2) дает 1, а не 2, как в классическом Лиспе. Ни '(), ни #f не являются символами.

Схема также чувствительна к регистру. Даже если у вас есть переменная NIL в схеме, она не имеет ничего общего с nil. Вы можете использовать оба в качестве имен переменных.

Текст SICP вызывает путаницу в этой теме, поскольку в его первых главах делается ссылка на переменную с именем nil, которая содержит значение '(). В схеме нет такой переменной; Вы должны сделать это самостоятельно, если хотите, чтобы эти примеры работали. Это неудачный аспект учебника.

Если вы определяете переменную nil, значением которой является объект '(), так что код главы 2 из SICP работает, он все равно не эквивалентен пустому списку, как в классическом Лиспе, потому что в классический Лисп, nil и () - эквивалентные обозначения для символа. Сам символ nil является пустым списком, и наоборот. Это не имя переменной, которая просто содержит список. И поэтому выражение кавычки 'nil также приводит к пустому списку! Тогда как в схеме 'nil вычисляется обычный символ nil, даже если вы определили его как переменную, содержащую пустой список.

Относительно второго вопроса: «(), кажется, работает, имеют ли оба значения одинаковое значение?». Аспект «того же значения» описан выше: нет, это не то же самое значение в Схеме. Насколько это работает, рассмотрим следующую цитату из отчета схемы R5RS:

Примечание: во многих диалектах Лисп пустая комбинация () является допустимым выражением. В схеме комбинации должны иметь хотя бы одно подвыражение, поэтому () не является синтаксически допустимым выражением. [4.1.3 Процедурные вызовы]

Таким образом, эта неуклюжая трактовка () как допустимого выражения, создающего пустой список, представляется расширением поведения схемы ПК, а не стандартной схемой. Он принимает выражение, которое не является синтаксически допустимым выражением Scheme.

...