Свойства символа

У символа могут быть свойства

  В Lisp с символом можно связать именованные свойства. Свойства символа записываются в вектор свойств. У каждого символа разные свойства.

У свойств есть имя и значение

  Вектор свойств может быть пуст или содержать произвольное количество свойств. Свойства отсортированы по имени. Его форма такова:

  #((имя1 . значение1) (имя2 . значение2) … (имяn . значениеn))

  Например, у символа ягода-рябины может быть такой вектор свойств:

  #((вкус . кислый) (цвет . красный))

  Вектор свойств символа можно обновлять или удалять с помощью дополнительных методов. Программист должен сам предусматривать и обрабатывать интересующие его свойства.

Системные и определяемые свойства

  С символом связаны лишь его имя, произвольное, назначенное функцией присваивания (setq), значение и назначенное определением класса и методов (defclass, defmethod, …). Значение и определение класса являются встроенными системными свойствами, которые управляют работой интерпретатора в различных ситуациях. Весь список свойств также является системным свойством. Работающие со свойствами символов прикладные системы могут свободно определять новые свойства.
  Далее мы рассмотрим псевдофункции для чтения, изменения и удаления свойств, определяемых пользователем.

Чтение свойства

  Выяснить значение свойства, связанного с символом, можно с помощью функции get:

  (символ get свойство)

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

>('ягода-рябины  get 'вкус)
кислый
>('ягода-рябины  get 'вес)
nil

  Так как у символа ягода-рябины нет свойства вес, то get вернёт значение nil.

Присваивание свойства

  Присваивание нового свойства или изменение значения существующего свойства осуществляется функцией put:

  (символ put свойство значение)

  Свойства символов находятся в связанных с символами ячейках памяти. Приведём пример:

>('ягода-рябины  put 'вес '(2 г))
(2  г)
>('ягода-рябины  get 'вес)
(2  г)

  Побочным эффектом вызова будет изменение вектора свойств символа ягода-рябины следующим образом:

  #((вес 2 г) (вкус . кислый) (цвет . красный))

Удаление свойства

  Удаление свойства и его значения осуществляется функцией remprop:

  (символ remprop свойство)

  Приведём пример:

>('ягода-рябины  remprop 'вкус)
true
>('ягода-рябины  get 'вкус)
nil

  Функция remprop возвращает в качестве значения true или false. Если удаляемого свойства нет, то возвращается false. Свойство можно удалить, присвоив ему значение nil.
  Читать из вектора свойств, создавать и обновлять в нём свойства можно не только по отдельности, но и целиком. Например, значением вызова

  (символ properties)

является весь вектор свойств:

>('ягода-рябины  properties)
#((вес 2 г) (цвет . красный))

Свойства хранятся в пространстве имён

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