Введение
Modula 3 — это язык программирования, задуманный как преемник усовершенствованной версии Modula 2, известной как Modula 2+. Хотя он оказал значительное влияние в научных кругах (повлияв на разработку языков, таких как Java, C#, Python и Nim), он не получил широкого распространения в промышленности. Он был разработан Лукой Карделли, Джеймсом Донахью, Люсиль Глассман, Миком Джорданом (ранее в лаборатории программных технологий Olivetti), Биллом Калсоу и Грегом Нельсоном в исследовательском центре систем Digital Equipment Corporation (DEC) (SRC) и исследовательском центре Olivetti (ORC) в конце 1980-х годов. Основными характеристиками Modula 3 являются модульность, простота и безопасность, при этом сохраняется мощность языка системного программирования. Modula 3 был призван продолжить традицию типобезопасности Pascal, одновременно вводя новые конструкции для практического программирования в реальных условиях. В частности, Modula 3 добавила поддержку обобщённого программирования (аналогичного шаблонам), многопоточности, обработки исключений, сборки мусора, объектно-ориентированного программирования, частичного сокрытия и явного обозначения небезопасного кода. Целью разработки Modula 3 был язык, реализующий наиболее важные возможности современных императивных языков программирования в достаточно простых формах. Таким образом, были исключены потенциально опасные и усложняющие функции, такие как множественное наследование и перегрузка операторов.
Историческое развитие
Проект Modula 3 начался в ноябре 1986 года, когда Морис Уилкс написал Никлаусу Вирту с некоторыми идеями для новой версии Modula. Уилкс незадолго до этого работал в DEC, затем вернулся в Англию и присоединился к совету по исследовательской стратегии Olivetti. Вирт уже перешел к разработке Oberon, но не возражал против того, чтобы команда Уилкса продолжала разработку под именем Modula. Определение языка было завершено в августе 1988 года, а обновленная версия – в январе 1989 года. Вскоре после этого появились компиляторы от DEC и Olivetti, а затем и сторонние реализации. Дизайн языка во многом был обусловлен работой над языком Modula 2+, который использовался в SRC и в исследовательском центре Acorn Computers Research Center (ARC, позднее ORC после приобретения Acorn компанией Olivetti) в то время. На этом языке была написана операционная система для многопроцессорной рабочей станции DEC Firefly VAX, а также компилятор Acorn для Acorn C и Modula Execution Library (CAMEL) в ARC для проекта операционной системы ARX, предназначенной для компьютеров Acorn Archimedes на базе ARM. Как указано в пересмотренном отчете о Modula 3, на язык также повлияли другие языки, такие как Mesa, Cedar, Object Pascal, Oberon и Euclid. В 1990-х годах Modula 3 получил известность как язык для обучения, но не получил широкого распространения в промышленности. Этому могла способствовать ликвидация DEC, ключевого сторонника Modula 3 (особенно после того, как компания прекратила эффективно поддерживать язык до продажи Compaq в 1998 году). В любом случае, несмотря на простоту и мощность Modula 3, похоже, что спрос на процедурный компилируемый язык с ограниченной поддержкой объектно-ориентированного программирования был невелик. В течение некоторого времени коммерческий компилятор CM3, поддерживаемый одним из ведущих разработчиков DEC SRC, который был принят на работу до продажи DEC компании Compaq, интегрированная среда разработки (IDE) Reactor и расширяемая виртуальная машина Java (лицензированная в форматах бинарного и исходного кода и собираемая с помощью Reactor) предлагались компанией Critical Mass, Inc., но в 2000 году эта компания прекратила свою деятельность и передала часть исходного кода своих продуктов компании Software Solutions GmbH. В настоящее время Modula 3 преподается в университетах в основном в рамках курсов сравнительного анализа языков программирования, а его учебники больше не издаются. По сути, единственным корпоративным спонсором Modula 3 является , которая унаследовала исходный код от Critical Mass и с тех пор выпустила несколько версий системы CM3 в исходном и двоичном коде. IDE Reactor была выпущена под открытой лицензией спустя несколько лет после прекращения разработки, под новым названием CM3 IDE. В марте 2002 года также взяла на себя поддержку репозитория другого активного дистрибутива Modula 3, PM3, который до этого поддерживался в École Polytechnique de Montréal, но впоследствии разработка была продолжена в рамках проекта HM3, который со временем был улучшен и устарел.
Безопасное против небезопасного
Некоторые возможности считаются небезопасными, поскольку компилятор больше не может гарантировать согласованность результатов; например, при взаимодействии с языком C. Ключевое слово UNSAFE, поставленное перед INTERFACE или MODULE, может использоваться для указания компилятору на необходимость включения определенных низкоуровневых функций языка. Например, небезопасной операцией является обход системы типов с использованием LOOPHOLE для копирования битов целого числа в число с плавающей точкой REAL. Интерфейс, импортирующий небезопасный модуль, также должен быть небезопасным. Безопасный интерфейс может быть экспортирован небезопасным модулем реализации. Это типичный случай при взаимодействии с внешними библиотеками, когда создаются два интерфейса: один небезопасный, другой безопасный.
Динамическое распределение
Модуль 3 поддерживает выделение данных во время выполнения. Существует два типа памяти, которые могут быть выделены: ТРАССИРУЕМАЯ и НЕТРАССИРУЕМАЯ, различие между ними заключается в том, доступна ли она для сборщика мусора или нет. Оператор NEW используется для выделения данных любого из этих типов памяти. В небезопасном модуле (UNSAFE), оператор DISPOSE позволяет освободить нетрассируемую память.
Исключения
Обработка исключений основана на системе блоков TRY EXCEPT, которая с тех пор получила широкое распространение. Одной из особенностей, не перенятых другими языками, за редкими исключениями, такими как Delphi, Python, Scala и Visual Basic .NET, является то, что конструкция EXCEPT определяла форму оператора switch, где каждое возможное исключение являлось отдельным случаем в своем собственном блоке EXCEPT. Modula 3 также поддерживает конструкцию LOOP EXIT END, которая выполняет цикл до тех пор, пока не произойдет EXIT, структуру, эквивалентную простому циклу внутри блока TRY EXCEPT.
Многопрофильные
Язык поддерживает использование многопоточности и синхронизацию между потоками. В библиотеке времени выполнения (m3core) имеется стандартный модуль Thread, который поддерживает разработку многопоточных приложений. Среда выполнения Modula 3 может использовать отдельный поток для внутренних задач, таких как сборка мусора. Встроенная структура данных MUTEX используется для синхронизации нескольких потоков и защиты структур данных от одновременного доступа, который может привести к повреждению данных или гонкам. Оператор LOCK определяет блок, в котором мьютекс блокируется. Разблокировка MUTEX происходит автоматически при выходе точки исполнения кода из этого блока. MUTEX является объектом, и на его основе могут быть созданы другие объекты. Например, в разделе ввода/вывода (I/O) библиотеки libm3 читатели и писатели (Rd.T и Wr.T) являются производными от MUTEX и блокируют себя перед доступом или изменением любых внутренних данных, таких как буферы.
Влияние на другие языки программирования
Хотя Modula 3 не получила широкого распространения, некоторые части дистрибутива DEC SRC M3 получили его. Вероятно, наиболее влиятельной частью была библиотека Network Objects, которая послужила основой для первой реализации Java Remote Method Invocation (RMI), включая сетевой протокол. Она была отброшена только после того, как Sun перешла от стандарта Common Object Request Broker Architecture (CORBA) к протоколу на основе IIOP. Документация Java по сборке мусора удаленных объектов до сих пор ссылается на новаторскую работу, выполненную для Network Objects Modula 3. Реализация классов в Python также была вдохновлена механизмом классов, реализованным в C++ и Modula 3. Кроме того, язык Nim использует некоторые аспекты Modula 3, такие как отслеживаемые и неотслеживаемые указатели.