2.3 Символы

Символы (не строковые символы (или буквы)) являются Lisp’овыми объектами данных, созданы для нескольких целей и имеют несколько интересных свойств. Каждый объект типа symbol имеет имя, называемое его выводимым именем (print name). Существует возможность получить имя символа в виде строки. Также возможно обратное действие, получение имени символа из строки. (Более подробно: символы могут быть организованы в пакеты, и все символы в пакете имеют уникальные имена. Смотрите главу 11.)

У символов есть компонент, называемый список свойств, или plist. Список свойств всегда является списком, у которого чётные элементы (начиная с нулевого) являются символами, они выступают в качестве имён свойств, и нечётные элементы являются связанными со свойствами значениями. Для манипуляций с этим списком свойств предоставляются функции, это позволяет символу выступать в роли расширяемой структуры.

Символы также используются для представления определённых видов переменных в Lisp программах, и для манипуляции значениями связанными с символами в такой роли также предоставляются функции.

Символ может быть обозначен просто записью его имени. Если его имя непустое, и если его имя содержит только алфавитные буквы в верхнем регистре, цифры или некоторые псевдо-алфавитные строковые символы (но не разделители, как круглые скобки и пробелы), и если имя символа не может быть интерпретировано как число, тогда имя символа задаётся последовательностью букв его имени. Во внутреннем представлении все буквы записанные в имени символа переводятся в верхний регистр. Например:

FROBBOZ ;Символ, имя которого FROBBOZ
frobboz ;Другой путь записи того же символа
fRObBoz ;Ещё один путь записи полюбившегося символа
unwind-protect ;Символ с дефисом в имени
+$ ;Символ с именем +$
1+ ;Символ с именем 1+
+1 ;Это число 1, а не символ
pascal_style ;Этот символ содержит знак подчёркивания в своём имени
b̂2-4*a*c ;Это один символ
; Этот символ содержит некоторые специальные знаки в своём имени
file.rel.43 ;Символ содержит точки в своём имени
/usr/games/zork ;Символ содержит наклонные черты в своём имени

В дополнение к буквам и числам, следующие строковые символы допускаются в использовании в написании имени символа:

+  -  *  /  @  $  %  ̂  &  _  =  <  >  ~  .

Некоторые из этих строковых символов имеют специальные общепринятые значения для имён. Например, символы, которые задают специальные переменные, обычно имеют имена начинающиеся и заканчивающиеся звёздочкой *. Одиночная точка используется для задания cons-ячеек или списков с точкой. Точка также является разделителем дробной части.

Следующие строковые символы предназначены для использования в качестве макросимволов для изменения и расширения синтаксиса языка:

?  !  [  ]  {  }

Выводимое имя символа может содержать буквы в верхнем и нижнем регистрах. Однако, при чтении Lisp reader обычно конвертирует буквы нижнего регистра в верхний. В реализации все символы, которые именуют все стандартные Common Lisp переменные и функции хранятся в верхнем регистре. Однако в книге все эти символы для удобства приводятся в нижнем регистре. Использование имён символов в нижнем регистре при написании программы возможно, потому что read конвертирует все считываемые символы в верхний регистр.

Существует функция readtable-case, которая контролирует поведение функции read касаемо преобразования регистров букв в именах символов.

Если символ не может быть задан, потому что в его имени используются недопустимые буквы и знаки, их можно «экранировать» двумя способами. Один из них заключается в использовании обратной наклонной черты перед каждым экранируемым знаком. В таком случае имя символа никогда не будет ошибочно интерпретировано, как число. Например:

\( ;Символ с именем (
\+1 ;Символ с именем +1
+\1 ;Также символ с именем +1
\frobboz ;Символ с именем fROBBOZ
3.14159265\s0 ;Символ с именем 3.14159265s0
3.14159265\S0 ;Другой символ с именем 3.14159265S0
3.14159265s0 ;short-format с плавающей точкой для аппроксимации числа π
APL\\360 ;Символ с именем APL\360
apl\\360 ;Также символ с именем APL\360
\(b̂2\)\ -\ 4*a*c ;Имя (B̂2) - 4*A*C;
; содержит скобки и два пробела
\(\b̂2\)\ -\ 4*\a*\c ;Имя (b̂2) - 4*a*c;
; буквы явно указаны в нижнем регистре

Если таких «запрещённых» букв в имени много, использование \ перед каждой буквой утомительно. Альтернативным методом экранирования знаков в имени символа является заключение всего имени или только его части в скобки из вертикальных черт. Это эквивалентно тому, что каждая буква была бы экранирована обратной косой чертой.

|"| ;То же что и \"
|(b̂2) - 4*a*c| ;Имя (b̂2) - 4*a*c
|frobboz| ;Имя frobboz, а не FROBBOZ
|APL\360| ;Имя APL360, потому что \ экранирует the 3
|APL\\360| ;Имя APL\360
|apl\\360| ;Имя apl\360
|\|\|| ;То же, что и \|\|: имя ||
|(B̂2) - 4*A*C| ;Имя (B̂2) - 4*A*C;
; содержит скобки и два пробела
|(b̂2) - 4*a*c| ;Имя (b̂2) - 4*a*c