Булонь — Пон-де-Сен-Клу (станция метро)
- 1 year ago
- 0
- 0
Клу ( англ. Clu , CLU ) — объектно-ориентированный язык программирования , одним из первых реализовавший концепцию абстрактных типов данных и парадигму обобщённого программирования . Создан группой учёных Массачусетского технологического института под руководством Барбары Лисков в 1974 году , широкого применения в практике не нашёл, однако многие его элементы использованы при создании таких языков, как Ада , C++ , Java , , Python , C# .
Систематические работы над созданием языка программирования, реализующего на синтаксическом уровне идеи абстракции данных , начаты весной 1973 года Барбарой Лисков и сотрудником исследовательской лаборатории IBM Стивом Зиллесом ( Steve Zilles ). В сентябре 1973 года вышла их совместная заметка , где описана предварительная версия такого паскалеподобного языка, в ней фигурирует такая отличительная особенность будущего языка как кластеры ; на основе этой заметки подготовлен доклад на конференции по сверхвысокоуровневым языкам 1974 года . К концу 1973 года Лисков и Зиллес уже определились с наименованием будущего языка: название «Clu» было выбрано от первых трёх букв английского слова cluster . В качестве оппонента привлекался Остин Хендерсон ( Austin Henderson ).
В декабре 1973 года в лаборатории информатики Массачусетского технологического института при поддержке Национального научного фонда и DARPA начаты работы по созданию языка, руководила группой Лисков, на начальных стадиях над языком активно работал Зиллес, на постоянной основе в группе трудились три аспиранта — Расс Аткисон ( Russ Atkinson ), Крейг Шафферт ( Craig Schaffert ) и Алан Снайдер ( Alan Snyder ), периодически к работе подключались также студенты и сотрудники института. Все работы велись на машинах PDP-10 .
Лисков выделила 7 ключевых принципов языка: строгий фокус на абстракцию данных (отказ от глубокой проработки возможностей, напрямую не связанных с абстракцией данных), минимализм, простота, выразительность средств, унификация (встроенные типы не должны отличаться от типов, определяемых программистом), безопасность и высокая производительность . В соответствии с этими принципами в реализации избраны такие решения, как отказ от перечисляемых типов , параллельное присваивание , статическая типизация , проверка типов на этапе компиляции, сборка мусора на этапе выполнения . В 1974 году был реализован первый компилятор языка, выпускавший код на Лиспе, позднее компилятор переписан под генерацию программ на диалекте Лиспа , имевшем более богатый набор встроенных структур данных и проверку типов на этапе компиляции. Первая реализация языка 1974 года называлась CLU .5 , в ней поддерживались основные конструкции абстракции данных, но пока ещё не были реализованы обработка исключений и итераторы , а реализация параметризованных типов требовала динамической проверки типов в среде выполнения. В 1975 году был в основном спроектирован механизм обработки исключений.
К 1976 году все ключевые элементы языка были реализованы, в 1977 году написан первый компилятор, генерировавший код на ассемблере . Компилятор создавался на самом языке Клу, чем должен был продемонстрировать выразительность средств языка. Построение компилятора, порождающего высокопроизводительные программы, потребовало создания специальной среды выполнения, реализующей сборку мусора, отладку, особые техники отработки исключений и поддержки итераторов. В 1979 году проектирование языка завершено , в 1980 году выпущен полноценный компилятор для PDP-10, несколько позднее реализованы компиляторы для MC68000 и VAX . Трудозатраты на создание языка оценены в 14 человеко-лет .
В середине 1980-х годов компилятор Клу реализован для советских суперкомпьютеров « Эльбрус », язык был отобран среди прочих кандидатов ( Ады , Модулы-2 , Симулы ) как наиболее целостно воплощающий концепцию абстрактных типов данных, при этом достаточно простой в реализации . В 1989 году выпущен компилятор для SPARC под управлением SunOS .
В начале — середине 1990-х годов был создан компилятор clu2c, генерирующий кроссплатформенный код на Си , а также несколько версий Portable Clu со сборками для Linux , NetBSD , Mac OS , Windows NT , Digital Unix (на Alpha ), но практический интерес к языку существенно снизился, и с конца 1990-х годов реализации фактически не развивались, а новое программное обеспечение на Клу не разрабатывалось.
Барбара Лисков стала лауреатом премии Тьюринга 2008 года, в номинации проектирование языка Клу и создание серии эффективных компиляторов для него отмечены как фундаментальный вклад в информатику, доказавший практическую осуществимость идей абстракции данных и превративший теоретическую концепцию в общепризнанный в индустрии программирования подход .
Абстрактный тип данных в Клу реализуется понятием кластера — конструкции, обеспечивающей инкапсуляцию в рамках типа операций над ним и обеспечивающий полиморфизм (кластер может описывать широкий класс типов данных с общей спецификацией — одинаковым набором операций, но различной реализацией).
Начальный фрагмент описания кластера полиморфного списка (с операциями в лисп-нотации):
list = cluster [t: type] is create, car, cdr, cons, elems
rep = array [t]
create = proc () return (cvt) % создание списка
return (rep$new ())
end create;
car = proc (l:cvt) return (t) signals (empty) % получение первого элемента списка
if rep$empty (l)
then signal empty
else return (rep$bottom(l))
end
end car;
% другие операции
end list
В определении кластера указывается спецификация — набор операций над типом, определяется внутреннее представление (
rep
) и описывается реализация операций. Используются такие конструкции, как преобразование типа из внутреннего представления в объектное и обратно (
cvt
),
$
-нотация для доступа к операциям типа. Создание реализации кластера и его
экземпляра
реализуется указанием конкретного типа:
lint = list [int]; % список целых чисел
l:lint := lint$create(); % создание экземпляра списка
l := lint$cons(1, lint$cons (2, lint$cons(3, l))) % конструирование списка
Встроенные типы также реализуются как кластеры
. В отличие от определяемых в программном коде кластеров, никакая операция над базовыми встроенными типами данных Клу (
int
,
real
,
bool
,
null
,
char
,
string
) не может изменить структуру и значение объекта (всякий раз создаётся новый экземпляр объекта с зафиксированным соответствующим состоянием). Но в стремлении к унификации доступ к операциям над встроенными типами доступен в кластерной нотации:
int$add(n1,n2)
складывает
n1
с
n2
,
string$fetch(s,i)
обеспечивает доступ к
i
-му символу строки
s
, а
string$concat(s1,s2)
конкатенирует
строки
s1
и
s2
, притом реализован
синтаксический сахар
, обеспечивающий сокращённую запись таких операций:
n1+n2
,
s[i]
и
s1||s2
соответственно, который распространяется на одноимённые операции (
add
,
fetch
,
concat
), вводимые в определяемых разработчиком кластерах.
Как полиморфные кластеры реализованы встроенные композитные типы, называемые в Клу «генераторами типов» — массивы , , записи , структуры (постоянные записи), объединения , .
Одной из ключевых новаций языка стало введение абстракции управления — итератора . Идея итератора в том, чтобы обеспечить обобщённую реализацию доступа к элементам абстрактного типа данных вне зависимости от его параметризации и внутренней структуры. Пример итератора полиморфного списка:
elems = iter (l:cvt) yields (t)
for elt:t in rep$elements(l) do
yield (elt)
end
end elems
Вызов такого итератора:
for i:int in lint$elems(l) do
writeint (i)
end
Применение итератора позволяет исключить использование явных счётчиков цикла в условиях, когда заранее неизвестна конкретная реализация типа данных.
Идея итератора, построенного по принципу сопрограммы , была впоследствии заимствована в таких языках, как Icon , , Python , Ruby , C# (начиная с версии 2.0 ) .
В Клу реализована
структурная обработка исключений
, исключительные ситуации в языке подразделяются на статические и динамические, первые используются для завершения исполнения блока в пределах одного программного блока (вызываются оператором
exit s(x1, …, xn)
), вторые — завершают выполнение программы (вызываются оператором
signal s(x1, …, xn)
). В обоих случаях обработка исключительной ситуации выполняется программным блоком, начинаемым ключевым словом
except
, если статическое исключение не обработано в текущем блоке, то оно передаётся в следующий; исключения, не обработанные в программе, прерывают её выполнение с выдачей соответствующих сообщений. Исключения, которые может генерировать процедура, задаются в её спецификации, исключения рассматриваются как альтернативный выход из процедуры, то есть, процедура должна передать на выход заявленное в спецификации значение при помощи оператора
return
, либо выдать одно из заявленных в спецификации исключений при помощи операторов
signal
или
resignal
(вызывается в блоке
except
для повторения вызывавшего исключения) с соответствующими параметрами. Во встроенных типах реализованы стандартные исключения.
При проектировании механизма исключений были заимствованы решения из ПЛ/1 и , но используемая в них модель возобновления исключений существенно упрощена и структурирована , и важным нововведением стала возможность передачи параметров исключений.