2015-02-27 2 views
0

В Common Lisp, специальный оператор цитата делает все, а затем, убрав оценивали, какCommon Lisp: Как процитировать Parenthèse в SBCL

(quote a) -> a 
(quote {}) -> {} 

Но почему форма (цитата()) дает мне nil? Я использую SBCL 1.2.6 и это то, что я получил в РЕПЛ:

CL-USER> (quote()) 
NIL 

Подробнее об этой проблеме: Это код из PCL Глава 24

(defun as-keyword (sym) 
    (intern (string sym) :keyword)) 

(defun slot->defclass-slot (spec) 
    (let ((name (first spec))) 
    `(,name :initarg ,(as-keyword name) :accessor ,name))) 

(defmacro define-binary-class (name slots) 
    `(defclass ,name() 
    ,(mapcar #'slot->defclass-slot slots))) 

Когда макрос развернуть для следующего кода:

(define-binary-class id3-tag 
    ((major-version))) 

является

(DEFCLASS ID3-TAG NIL 
     ((MAJOR-VERSION :INITARG :MAJOR-VERSION :ACCESSOR MAJOR-VERSION))) 

который NIL, а не () после имени класса ID3-TAG.

+0

@ FrédéricHamidi Спасибо :) Я этого раньше не заметил. – shizhz

+0

@ FrédéricHamidi Не могли бы вы добавить свой комментарий в качестве ответа, пожалуйста? Поэтому он может быть отмечен как правильный ответ. Спасибо. –

ответ

7

nil и () - два способа выразить ту же концепцию (пустой список).

Традиционно nil используется для выделения логического значения «false», а не пустого списка, а () используется наоборот.

Общий LISP HyperSpec says:

() [ 'ноль], п. альтернативное обозначение для записи символа nil, использовано , чтобы подчеркнуть использование nil как пустой список.

3

Ваше наблюдение связано с тем, что объект имеет более одного представления. В Common Lisp читатель (который читает код и считывает выражения) анализирует текст на структуру и данные. Когда это данные, писатель может распечатать его снова, но он не будет точно знать, как были представлены данные, когда он был первоначально прочитан. Писатель будет печатать один объект ровно одним способом, следуя настройкам по умолчанию и настройкам, даже если имеется несколько представлений для этого объекта.

Как вы заметили nil, NIL, nIL, NiL, ..., 'nil, 'NIL, () и '() все читаться как тот же объект. Я не уверен, что стандарт диктует, как именно это представление по умолчанию должно быть таким, я предполагаю, что некоторые реализации выбирают один из NIL, nil или, может быть, даже ().

С минусами представления является зависимым от cdr быть минусы/нолем или нет:

'(a . nil)  ; ==> (a) 
'(a . (b . c)) ; ==> (a b . c) 
'(a . (b . nil)) ; ==> (a b) 

С номерами читатель может получить подсказки о базе которых вы используете.Если никакой базы не используется в тексте он будет использовать все *read-base* является:

(let ((*read-base* 2)) ; read numbers as boolean 
    (read-from-string "(10 #x10)")) ; ==> (2 16) 

#x говорит читателю интерпретировать остальные как шестнадцатеричное значение. Теперь, если ваша печатная база была бы 4, ответ на вышеупомянутый был бы визуализирован как (2 100).

Подводя итог. Единственное значение в Common Lisp может иметь несколько хороших представлений, и все они будут давать одно и то же значение. Как печатается значение, будут выполняться как реализация, настройки, так и даже аргументы для функций, которые их производят. Ни то, что оно принимает в качестве значений, а также различные способы визуализации значения, ничего не говорит о том, как значение фактически хранится внутри.

+0

Спасибо :) BTW, для «Теперь, если ваша печатная база была бы 4, ответ на это был бы визуализирован как (2 100)». Вы имеете в виду набор * print-base * to 4? Coz Я попробовал _ (let ((* read-base * 2) (* print-base * 4)) (read-from-string "(10 # x10)")) _ но результат по-прежнему (2 16) – shizhz

+0

@ seki-shi Если вы использовали 'print' для печати результата внутри' let', вы бы напечатали '(2 100)', а затем вернули '(2 16)', так как '* print-base * 'было иначе. Чтобы получить REPL для печати в базе 4, вам нужно использовать 'setf/setq', так как REPL отображает результат, который является результатом' let' после исчезновения локальных привязок. например '(setf * print-base * 4)' – Sylwester

+0

Спасибо, _print_ works :-) – shizhz

Смежные вопросы