Общая объектная система Lisp - Common Lisp Object System

Стандартная комбинация методов в ANSI common lisp

В Общая объектная система Lisp (CLOS) это средство для объектно-ориентированного программирования который является частью ANSI Common Lisp. CLOS - мощный динамичный объектная система, которая радикально отличается от объектов ООП, имеющихся в других статические языки такие как C ++ или Ява. CLOS был вдохновлен более ранними объектными системами Lisp, такими как MIT Flavors и CommonLoops, хотя это и более общий характер. Первоначально предложенная как надстройка, CLOS была принята как часть стандарта ANSI для Common Lisp и была адаптирована для других диалектов Lisp, таких как EuLisp или Emacs Lisp.[1]

Функции

Основные строительные блоки CLOS: классы и их методы, экземпляры этих классов и общие функции.CLOS предоставляет макросы для их определения: defclass, defmethod, и defgeneric. Экземпляры создаются методом make-instance.

У классов может быть несколько суперклассы, список слотов (переменные-члены на языке C ++ / Java) и специальный метакласс. Слоты могут быть распределены по классам (все экземпляры класса разделяют слот) или по экземплярам. У каждого слота есть имя, и к значению слота можно получить доступ по этому имени с помощью функции значение слота. Дополнительно могут быть определены специальные общие функции для записи или чтения значений слотов. Каждый слот в классе CLOS должен иметь уникальное имя.

CLOS - это множественная отправка система. Это значит, что методы могут быть специализированы на любом или на всех их требуемых аргументах. Большинство объектно-ориентированных языков являются одноконтактными, что означает, что методы специализируются только на первом аргументе. Еще одна необычная особенность состоит в том, что методы не «принадлежат» классам; классы не предоставляют пространство имен для универсальных функций или методов. Методы определяются отдельно от классов, и у них нет специального доступа (например, «this», «self» или «protected») к слотам классов.

Методы в CLOS сгруппированы в общие функции. Универсальная функция - это объект, который вызывается как функция и который связывает набор методов с общим именем и структурой аргументов, каждый из которых специализируется на разных аргументах. Поскольку Common Lisp предоставляет классы, отличные от CLOS, для структур и встроенных типов данных (числа, строки, символы, символы, ...), диспетчеризация CLOS работает также с этими классами, отличными от CLOS. CLOS также поддерживает отправку по отдельным объектам (специалистам eql). CLOS по умолчанию не поддерживает отправку по всем типам данных Common Lisp (например, диспетчеризация не работает для полностью специализированных типов массивов или для типов, представленных deftype). Однако большинство реализаций Common Lisp предоставляют протокол метаобъектов что позволяет универсальным функциям предоставлять специфические для приложения правила специализации и диспетчеризации.

Отправка в CLOS также отличается от большинства языков OO:

  1. Учитывая список аргументов, определяется список применимых методов.
  2. Этот список отсортирован в соответствии со спецификой их специализаций параметров.
  3. Выбранные методы из этого списка затем объединяются в эффективный метод с использованием комбинации методов, используемой универсальной функцией.
  4. Затем вызывается эффективный метод с исходными аргументами.

Этот механизм отправки работает во время выполнения. Таким образом, добавление или удаление методов может привести к изменению эффективных методов (даже если универсальная функция вызывается с теми же аргументами) во время выполнения. Изменение комбинации методов также может привести к другим эффективным методам.

Например,

; объявить прототип структуры общего аргумента(defgeneric ж (Икс у)); определить реализацию для (f integer t), где t соответствует всем типам(defmethod ж ((Икс целое число) у) 1)(ж 1 2.0) => 1; определить реализацию для (f целое вещественное число)(defmethod ж ((Икс целое число) (у настоящий)) 2)(ж 1 2.0) => 2 ; отправка изменена во время выполнения

Как и системы OO в большинстве динамические языки, CLOS не применяет инкапсуляция. Доступ к любому слоту можно получить с помощью значение слота функция или через (опционально автоматически) методы доступа. Чтобы получить к нему доступ через значение слота вы должны знать название слота. Программисты CL используют пакет возможность объявить, какие функции или структуры данных предназначены для экспорта.

Помимо обычных («первичных») методов, существуют также :перед, :после, и :вокруг «вспомогательные» методы. Первые два вызываются до или после основного метода в определенном порядке, основанном на иерархии классов. An :вокруг Метод может контролировать, выполняется ли основной метод вообще. Кроме того, программист может указать, все ли возможные первичные методы в иерархия классов должен быть вызван или только тот, который обеспечивает наиболее близкое соответствие.

В Стандартный метод-комбинация предоставляет основные методы, методы до, после и вокруг, описанные выше. Существуют и другие комбинации методов с другими типами методов. Могут быть определены новые (как простые, так и сложные) комбинации методов и типы методов.

CLOS позволяет множественное наследование. Если порядок по умолчанию, в котором методы выполняются при множественном наследовании, неверен, программист может разрешить проблемы наследования алмазов указав порядок комбинаций методов.

CLOS является динамическим, что означает, что не только содержимое, но и структура его объекты могут быть изменены во время выполнения. CLOS поддерживает изменение определений классов на лету (даже если экземпляры рассматриваемого класса уже существуют), а также изменение членства в классе данного экземпляра через класс изменения оператор. CLOS также позволяет добавлять, переопределять и удалять методы во время выполнения. В Задача круг-эллипс легко решается в CLOS, и большинство ООП шаблоны проектирования либо исчезают, либо становятся качественно проще.[2]

CLOS - это не язык прототипа: Классы должны быть определены до того, как объекты могут быть созданы как члены этого класса.

Протокол метаобъектов

Помимо стандарта ANSI Common Lisp, существует широко реализованное расширение CLOS, называемое Метаобъект Протокол (СС). MOP определяет стандартный интерфейс к основам реализации CLOS, рассматривая классы, описания слотов, общие функции и сами методы как экземпляры метаклассы, и позволяет определять новые метаклассы и изменять все поведение CLOS. Гибкость предварительных настроек CLOS MOP аспектно-ориентированное программирование, который позже был разработан некоторыми из тех же инженеров, например Грегор Кичалес. MOP определяет поведение всей объектной системы с помощью набора протоколов. Они определены в терминах CLOS. Таким образом, можно создавать новые объектные системы, расширяя или изменяя предоставленную функциональность CLOS. Книга Искусство протокола метаобъектов описывает использование и реализацию CLOS MOP.

Различные реализации Common Lisp немного по-разному поддерживают протокол метаобъектов. В Ближе[3] Проект направлен на предоставление недостающих функций.

Влияния старых объектных систем на основе Lisp

Ароматизаторы (и его преемник New Flavors) была объектной системой Массачусетского технологического института. Лисп-машина. Большая часть операционных систем Lisp Machine и многие приложения для нее используют разновидности или новые разновидности. Представлены вкусы множественное наследование и миксины, среди других функций. Flavors в основном устарели, хотя реализации Common Lisp существуют. Flavors использовали парадигму передачи сообщений. В New Flavors представлены общие функции.

CommonLoops был преемником LOOPS (от Xerox Интерлисп -D). CommonLoops был реализован для Common Lisp. Переносимая реализация под названием Portable CommonLoops (PCL) была первой реализацией CLOS. PCL широко переносится и до сих пор служит основой для реализации нескольких приложений CLOS. Common Lisp реализации. PCL реализован в основном на переносимом Common Lisp с несколькими зависимыми от системы частями.

CLOS на других языках программирования

Из-за мощи и выразительности CLOS, а также исторической доступности TinyCLOS (упрощенная переносимая реализация CLOS, написанная Грегор Кичалес для использования с Scheme), CLOS-подобные объектные системы на основе MOP стали де-факто норма в большинстве реализаций диалекта Лиспа, а также нашла свое отражение в некоторых других языках ' ООП удобства:

[6]

Рекомендации

  1. ^ «CLOS - это стандарт. Многие поставщики предоставляют CLOS. CLOS (или его части) используется для добавления объектной ориентации в другие диалекты Lisp, такие как EuLisp или Emacs Lisp». п. 110 от Veitch 1998
  2. ^ в Шаблоны проектирования на динамических языках слайды Питер Норвиг представляет свои выводы о том, что 16 из 23 шаблонов проектирования, взятых из различных учебников, либо «невидимы, либо проще» в Dylan или Common Lisp, чем в C ++.
  3. ^ Closer Project: ближе к СС
  4. ^ COS, объектная система C
  5. ^ VCLOS, CLOS для навыков
  6. ^ Tiny CLOS, разработанный Грегором Кичалесом
  • "CommonLoops: объединение Lisp и объектно-ориентированного программирования ", Даниэль Г. Боброу, Кеннет Кан, Грегор Кичалес, Ларри Масинтер, Марк Стефик, Фрэнк Здибел. 1986, Портленд, Орегон, США. Страницы 17–29 Конференция по системам объектно-ориентированного программирования: языки и приложения, ISSN 0362-1340.
  • «История и описание CLOS» Джима Вейтча. Страницы 107–158 из Справочник по языкам программирования, Том IV: Функциональные и логические языки программирования, изд. Питер Х. Салус. 1998 (1-е издание), Macmillan Technical Publishing; ISBN  1-57870-011-6

Литература