Модула-3 - Modula-3
Парадигмы | императивный , структурированный , процедурный , модульный , параллельный |
---|---|
Семья | Вирт Модула |
Разработано | Лука Карделли , Джеймс Донахью, Люсиль Глассман, Мик Джордан; Билл Калсо, Грег Нельсон |
Разработчики |
DEC Olivetti elego Software Solutions GmbH |
Впервые появился | 1988 |
Стабильный выпуск | 5.8.6 / 14 июля 2010 г .
|
Предварительный выпуск | 5.8.6 / 14 июля 2010 г .
|
Печатная дисциплина | сильный , статический , безопасный или, если небезопасный, явно безопасный изолированный |
Сфера | Лексический |
Платформа | IA-32 , x86-64 , PowerPC , SPARC |
Операционные системы | Кроссплатформенность : FreeBSD , Linux , Darwin , SunOS. |
Веб-сайт | www |
Основные реализации | |
SRC Modula-3, CM3, PM3, EZM3, M3 / PC Клагенфурт | |
Под влиянием | |
АЛГОЛ , Евклид , Меса , Модула-2 , Модула-2 + , Оберон , Паскаль | |
Под влиянием | |
C # , Java , Nim , OCaml , Python |
Modula-3 - это язык программирования, задуманный как преемник обновленной версии Modula-2, известной как Modula-2 + . Хотя он оказал влияние в исследовательских кругах (оказал влияние на дизайн таких языков, как Java , C # и Python ), он не получил широкого распространения в промышленности. Он был разработан Лукой Карделли , Джеймсом Донахью, Люсиль Глассман, Миком Джорданом (ранее в Лаборатории программных технологий Оливетти ), Биллом Калсо и Грегом Нельсоном из Центра системных исследований (SRC) Digital Equipment Corporation (DEC) и Исследовательского центра Оливетти ( ORC) в конце 1980-х гг.
Основными особенностями Modula-3 являются простота и безопасность при сохранении мощи языка системного программирования. Modula-3 нацелена на продолжение традиции Pascal в области безопасности типов, одновременно вводя новые конструкции для практического программирования в реальном мире. В частности, в Modula-3 добавлена поддержка общего программирования (аналогичного шаблонам ), многопоточности , обработки исключений , сборки мусора , объектно-ориентированного программирования , частичного выявления и явной маркировки небезопасного кода. Целью разработки Modula-3 был язык, реализующий наиболее важные функции современных императивных языков программирования в довольно простых формах. Таким образом, якобы опасные и усложняющие функции, такие как множественное наследование и перегрузка операторов, были опущены.
Историческое развитие
Проект Modula-3 стартовал в ноябре 1986 года, когда Морис Уилкс написал Никлаусу Вирту с некоторыми идеями для новой версии Modula. Незадолго до этого Уилкс работал в DEC, а затем вернулся в Англию и присоединился к Совету по стратегии исследований Оливетти. Вирт уже перешел в Оберон , но у него не было проблем с командой Уилкса, продолжающей разработку под названием Modula. Определение языка было завершено в августе 1988 года, а обновленная версия - в январе 1989 года. Вскоре последовали компиляторы от DEC и Olivetti, а после этого были реализованы сторонние реализации.
На его дизайн сильно повлияла работа над языком Modula-2 +, который использовался в SRC и в Исследовательском центре Acorn Computers (ARC, позже ORC, когда Olivetti приобрел Acorn) в то время, который был языком операционной системы для Была написана многопроцессорная рабочая станция VAX от DEC Firefly, на которой был написан компилятор Acorn для Acorn C и библиотека выполнения Modula (CAMEL) в ARC для проекта операционной системы ARX для линейки компьютеров Acorn Archimedes на базе ARM . Как говорится в пересмотренном отчете Modula-3, на этот язык повлияли другие языки, такие как Mesa , Cedar , Object Pascal , Oberon и Euclid .
В течение 1990-х годов Modula-3 приобрел значительную популярность в качестве учебного языка, но так и не получил широкого распространения в промышленности. Этому, возможно, способствовала кончина DEC, ключевого сторонника Modula-3 (особенно когда она перестала эффективно поддерживать его до того, как DEC была продана Compaq в 1998 году). В любом случае, несмотря на простоту и мощность Modula-3, похоже, что процедурный компилируемый язык с ограниченной реализацией объектно-ориентированного программирования практически не пользовался спросом . Какое-то время коммерческий компилятор под названием CM3, поддерживаемый одним из главных разработчиков DEC SRC, который был нанят до того, как DEC был продан Compaq , интегрированная среда разработки (IDE) под названием Reactor и расширяемая виртуальная машина Java (лицензированная в двоичном коде) и исходный код форматы и работоспособен с реактором) были предложены Critical Mass, Inc., но компания прекратила активную деятельность в 2000 году и дала некоторым из исходного кода своей продукции elego Software Solutions GmbH. Модула-3 сейчас преподается в университетах в основном на курсах сравнительного языка программирования, и его учебники больше не издаются. По сути, единственным корпоративным сторонником Modula-3 является компания elego, которая унаследовала исходные коды от Critical Mass и с тех пор сделала несколько выпусков системы CM3 в исходном и двоичном коде. Reactor IDE была выпущена с открытым исходным кодом после того, как несколько лет назад ее не было, под новым названием CM3-IDE. В марте 2002 года elego также взяла на себя репозиторий другого активного дистрибутива Modula-3, PM3, который до этого поддерживался в Политехнической школе Монреаля, но который позже продолжился работой над HM3, улучшился с годами до тех пор, пока он не был устаревшим.
Синтаксис
Типичный пример синтаксиса языка - «Hello, World!» программа .
MODULE Main;
IMPORT IO;
BEGIN
IO.Put("Hello World\n")
END Main.
Все программы в Modula-3 имеют как минимум файл модуля, в то время как большинство также включают файл интерфейса, который используется клиентами для доступа к данным из модуля. Как и в некоторых других языках, программа Modula-3 должна экспортировать основной модуль, который может быть либо файлом с именем Main.m3, либо файлом, который может вызывать EXPORT
экспорт основного модуля.
MODULE Foo EXPORTS Main
Рекомендуется, чтобы имена файлов модулей совпадали с именами в исходном коде. Если они различаются, компилятор выдает только предупреждение.
Другие соглашения в синтаксисе включают именование экспортируемого типа интерфейса T
, поскольку типы обычно квалифицируются своими полными именами, поэтому T
будет именоваться тип внутри модуля с именем Foo Foo.T
. Это способствует удобочитаемости. Другое аналогичное соглашение - это именование общедоступного объекта, Public
как в примерах ООП выше.
Особенности языка
Модульность
Прежде всего, все скомпилированные модули являются либо INTERFACE
реализациями MODULE
, либо разными. Скомпилированный модуль интерфейса, начинающийся с ключевого слова INTERFACE
, определяет константы, типы, переменные, исключения и процедуры. Модуль реализации, начинающийся с ключевого слова MODULE
, предоставляет код и любые другие константы, типы или переменные, необходимые для реализации интерфейса. По умолчанию модуль реализации будет реализовывать интерфейс с тем же именем, но модуль может явно связываться EXPORT
с модулем с другим именем. Например, основная программа экспортирует модуль реализации для основного интерфейса.
MODULE HelloWorld EXPORTS Main;
IMPORT IO;
BEGIN
IO.Put("Hello World\n")
END HelloWorld.
Любой скомпилированный модуль может иметь IMPORT
другие интерфейсы, хотя циклический импорт запрещен. Это можно решить, выполнив импорт из МОДУЛЯ реализации. Сущности в импортированном модуле могут быть импортированы вместо только имени модуля, используя FROM Module IMPORT Item [, Item]*
синтаксис:
MODULE HelloWorld EXPORTS Main;
FROM IO IMPORT Put;
BEGIN
Put("Hello World\n")
END HelloWorld.
Обычно импортируется только интерфейс и используется нотация «точка» для доступа к элементам в интерфейсе (аналогично доступу к полям в записи). Типичное использование - определение одной структуры данных (записи или объекта) для каждого интерфейса вместе с любыми вспомогательными процедурами. Здесь основной тип получит имя 'T', а один будет использовать как в MyModule.T
.
В случае конфликта имен между импортированным модулем и другим объектом в модуле зарезервированное слово
AS
может использоваться, как вIMPORT CollidingModule AS X;
Безопасный vs небезопасный
Некоторая способность считается небезопасной, когда компилятор больше не может гарантировать согласованность результатов; например, при взаимодействии с языком C. Ключевое слово с UNSAFE
префиксом перед INTERFACE
или MODULE
может использоваться для указания компилятору включить определенные низкоуровневые функции языка. Например, небезопасная операция - это обход системы типов, использующий LOOPHOLE
для копирования битов целого числа в число с плавающей запятой REAL
.
Интерфейс, импортирующий небезопасный модуль, также должен быть небезопасным. Безопасный интерфейс может быть экспортирован небезопасным модулем реализации. Это типичное использование при взаимодействии с внешними библиотеками , когда создаются два интерфейса: один небезопасный, другой безопасный.
Дженерики
Общий интерфейс и соответствующий ему универсальный модуль, используйте префикс ключевого слова INTERFACE
or и принимайте в качестве формальных аргументов другие интерфейсы. Таким образом (подобно шаблонам C ++ ) можно легко определять и использовать абстрактные типы данных, но, в отличие от C ++ , детализация находится на уровне модуля. Интерфейс передается универсальному интерфейсу и модулям реализации в качестве аргументов, и компилятор сгенерирует конкретные модули.
MODULE
GENERIC
Например, можно определить GenericStack, а затем создать его экземпляр с помощью таких интерфейсов, как IntegerElem
, или RealElem
, или даже интерфейсов для объектов, если каждый из этих интерфейсов определяет свойства, необходимые для универсальных модулей.
Голые типы INTEGER
или REAL
их нельзя использовать, потому что они не являются модулями, а система универсальных типов основана на использовании модулей в качестве аргументов. Для сравнения, в шаблоне C ++ будет использоваться пустой тип.
ФАЙЛ: IntegerElem.i3
INTERFACE IntegerElem;
CONST Name = "Integer";
TYPE T = INTEGER;
PROCEDURE Format(x: T): TEXT;
PROCEDURE Scan(txt: TEXT; VAR x: T): BOOLEAN;
END IntegerElem.
ФАЙЛ: GenericStack.ig
GENERIC INTERFACE GenericStack(Element);
(* Here Element.T is the type to be stored in the generic stack. *)
TYPE
T = Public OBJECT;
Public = OBJECT
METHODS
init(): TStack;
format(): TEXT;
isEmpty(): BOOLEAN;
count(): INTEGER;
push(elm: Element.T);
pop(VAR elem: Element.T): BOOLEAN;
END;
END GenericStack.
ФАЙЛ: GenericStack.mg
GENERIC MODULE GenericStack(Element);
< ... generic implementation details... >
PROCEDURE Format(self: T): TEXT =
VAR
str: TEXT;
BEGIN
str := Element.Name & "Stack{";
FOR k := 0 TO self.n -1 DO
IF k > 0 THEN str := str & ", "; END;
str := str & Element.Format(self.arr[k]);
END;
str := str & "};";
RETURN str;
END Format;
< ... more generic implementation details... >
END GenericStack.
ФАЙЛ: IntegerStack.i3
INTERFACE IntegerStack = GenericStack(IntegerElem) END IntegerStack.
ФАЙЛ: IntegerStack.m3
MODULE IntegerStack = GenericStack(IntegerElem) END IntegerStack.
Прослеживаемость
Любой идентификатор можно проследить до того места, где он возник, в отличие от функции «включить» в других языках. Скомпилированный модуль должен импортировать идентификаторы из других скомпилированных модулей с помощью IMPORT
оператора. Даже в перечислениях используется та же «точечная» нотация, которая используется при доступе к полю записи.
INTERFACE A;
TYPE Color = {Black, Brown, Red, Orange, Yellow, Green, Blue, Violet, Gray, White};
END A;
MODULE B;
IMPORT A;
FROM A IMPORT Color;
VAR
aColor: A.Color; (* Uses the module name as a prefix *)
theColor: Color; (* Does not have the module name as a prefix *)
anotherColor: A.Color;
BEGIN
aColor := A.Color.Brown;
theColor := Color.Red;
anotherColor := Color.Orange; (* Can't simply use Orange *)
END B.
Динамическое размещение
Modula-3 поддерживает размещение данных во время выполнения . Есть два типа памяти, которые можно выделить, TRACED
и UNTRACED
разница в том, видит ли ее сборщик мусора или нет. NEW()
используется для распределения данных любого из этих классов памяти. В UNSAFE
модуле DISPOSE
доступно для освобождения неотслеживаемой памяти.
Объектно-ориентированный
В Modula-3 можно использовать методы объектно-ориентированного программирования, но их использование не требуется. Многие другие функции, предоставляемые в Modula-3 (модули, обобщения), обычно могут заменять объектную ориентацию.
Поддержка объекта намеренно сведена к простейшим условиям. Тип объекта (называемый «классом» в других объектно-ориентированных языках) вводится с OBJECT
объявлением, которое имеет, по существу, тот же синтаксис, что и RECORD
объявление, хотя тип объекта является ссылочным типом, тогда как записи в Modula-3 не являются ( аналогично структурам в C). Экспортируемые типы обычно называются T по соглашению и создают отдельный «общедоступный» тип для предоставления методов и данных. Например:
INTERFACE Person;
TYPE T <: Public;
Public = OBJECT
METHODS
getAge(): INTEGER;
init(name: TEXT; age: INTEGER): T;
END;
END Person.
Это определяет интерфейс Person
с двумя типами, T
и Public
, который определяется как объект с двумя методами, getAge()
и init()
. T
определяется как подтип Public
с помощью <:
оператора.
Чтобы создать новый Person.T
объект, используйте встроенную процедуру NEW
с методом init()
как
VAR jim := NEW(Person.T).init("Jim", 25);
REVEAL
Конструкция Modula-3 обеспечивает концептуально простой и чистый, но очень мощный механизм для сокрытия деталей реализации от клиентов с произвольно большим количеством уровней удобства . Используйте, REVEAL
чтобы показать полную реализацию Person
интерфейса сверху.
MODULE Person;
REVEAL T = Public BRANDED
OBJECT
name: TEXT; (* These two variables *)
age: INTEGER; (* are private. *)
OVERRIDES
getAge := Age;
init := Init;
END;
PROCEDURE Age(self: T): INTEGER =
BEGIN
RETURN self.age;
END Age;
PROCEDURE Init(self: T; name: TEXT; age: INTEGER): T =
BEGIN
self.name := name;
self.age := age;
RETURN self;
END Init;
BEGIN
END Person.
Обратите внимание на использование BRANDED
ключевого слова, которое «маркирует» объекты, чтобы сделать их уникальными и избежать структурной эквивалентности. BRANDED
также может принимать строку в качестве аргумента, но если он опущен, для вас создается уникальная строка.
Modula-3 - один из немногих языков программирования, который требует, чтобы внешние ссылки из модуля были строго квалифицированы. То есть ссылка в модуле A
на объект, x
экспортированный из модуля, B
должна иметь форму B.x
. В Modula-3 невозможно импортировать все экспортированные имена из модуля.
Из-за требований языка к уточнению имени и переопределению метода невозможно сломать работающую программу, просто добавив новые объявления в интерфейс (любой интерфейс). Это дает возможность редактировать большие программы одновременно многими программистами, не беспокоясь о конфликтах имен; и это также позволяет редактировать библиотеки основных языков с твердым пониманием того, что ни одна существующая программа не будет повреждена в процессе.
Исключения
Обработка исключений основана на TRY
... EXCEPT
блочной системе, которая с тех пор стала обычным явлением. Одна особенность, которая не была принята в других языках, за заметными исключениями Delphi , Python [1] , Scala [2] и Visual Basic.NET , заключается в том, что EXCEPT
конструкция определяет форму оператора switch с каждым возможным исключением как случай. в собственном предложении EXCEPT. Модуле-3 также поддерживает LOOP
... EXIT
... END
конструкция, петли , пока EXIT
не происходит, структура эквивалентна простой петлей внутри TRY
... EXCEPT
п.
Многопоточный
Язык поддерживает использование многопоточности и синхронизацию между потоками. В библиотеке времени выполнения ( m3core ) есть стандартный модуль под названием Thread, который поддерживает использование многопоточных приложений. Среда выполнения Modula-3 может использовать отдельный поток для внутренних задач, таких как сборка мусора.
Встроенная структура данных MUTEX
используется для синхронизации нескольких потоков и защиты структур данных от одновременного доступа с возможным повреждением или условиями гонки. LOCK
Оператор вводит блок , в котором мьютекс заблокирован. Разблокировка a MUTEX
подразумевается выходом локуса выполнения кода из блока. Это MUTEX
объект, и поэтому другие объекты могут быть производными от него.
Например, в разделе ввода / вывода (I / O) библиотеки libm3 читатели и писатели (Rd.T и Wr.T) являются производными от MUTEX, и они блокируются перед доступом или изменением любых внутренних данных, таких как буферы.
Резюме
Таким образом, особенности языка:
- Модули и интерфейсы
- Явная маркировка небезопасного кода
- Дженерики
- Автоматический сбор мусора
- Строгая типизация , структурная эквивалентность типов
- Объекты
- Исключения
- Потоки
Modula-3 - один из редких языков, эволюция функций которого задокументирована.
В Системном программировании с помощью Modula-3 интенсивно обсуждаются четыре основных момента проектирования языка. Это следующие темы: структурная эквивалентность и эквивалентность имен, правила выделения подтипов, общие модули и режимы параметров, например READONLY
.
Стандартные функции библиотеки
Продолжая тенденцию, начатую с языка C , многие функции, необходимые для написания реальных программ, были исключены из определения языка и вместо этого предоставлялись через стандартный набор библиотек . Большинство интерфейсов ниже подробно описаны в
Стандартные библиотеки, предоставляющие следующие возможности. Они называются стандартными интерфейсами и требуются (должны быть предоставлены) на языке.
- Текст: операции с неизменяемыми строковыми ссылками, называемые
TEXT
s - Поток: операции, относящиеся к потокам, включая
MUTEX
условную переменную и приостановку потока. Библиотека потоковой передачи обеспечивает упреждающее переключение потоков. - Слово: побитовые операции с целыми числами без знака (или машинными словами). Обычно реализуется непосредственно компилятором
- Интерфейсы с плавающей запятой
Некоторые рекомендуемые интерфейсы реализованы в доступных реализациях, но не требуются
- Lex: для разбора номера и других данных
- Fmt: форматирование различных типов данных для печати
- Pkl (или Pickle): сериализация объектов любых ссылочных типов, доступных сборщику мусора.
- Таблица: Общие модули для карт
Как и в C, ввод-вывод также предоставляется через библиотеки, в Modula-3 это называется Rd
и Wr
. Объектно-ориентированный дизайн библиотек Rd (читатели) и Wr (писатели) подробно описан в книге Грега Нельсона. Интересным аспектом Modula-3 является то, что это один из немногих языков программирования, стандартные библиотеки которых официально проверены на отсутствие различных типов ошибок, включая ошибки блокировки. Это было сделано под эгидой проектов Larch / Modula-3 (см. Семейство Larch ) и расширенных статических проверок в DEC Systems Research Center .
Реализации
Доступно несколько компиляторов, большинство из них с открытым исходным кодом .
- DEC-SRC M3, оригинал.
- Исследовательский центр Оливетти (ORC) Набор инструментов Modula-3, первоначально представлявший собой компилятор, теперь доступен в виде библиотеки для синтаксического, лексического и семантического анализа программ Modula-3.
- Критическая масса CM3, другой преемник DEC-SRC M3
- Polytechnique Montreal Modula-3 PM3, преемник DEC-SRC M3, в настоящее время сливается с CM3
- EzM3, независимая легкая и легко переносимая реализация, разработанная совместно с CVSup.
- HM3, преемник PM3-1.1.15 версии PM3, с поддержкой нативной потоковой передачи с использованием NPTL
- CM3, преемник Critical Mass CM3. Это единственная актуальная, поддерживаемая и развиваемая реализация. Релизы доступны по адресу http://www.opencm3.net/releng/ .
Поскольку единственный аспект структуры данных C , который является отсутствующей от Modula-3 является типом союза, вся сохранившаяся до наших дней реализации Modula-3 способна обеспечить хорошую двоичный код совместимость с декларациями типа языка С массивами и структурами .
Книги
Ни одна из этих книг до сих пор не издается, хотя можно получить использованные копии, а некоторые оцифрованы, частично или полностью, а некоторые главы одной из них имеют предыдущие или последующие версии, доступные в виде отчетов об исследованиях в Интернете.
- Грег Нельсон, редактор « Системное программирование с помощью Modula-3» . Исчерпывающий справочник по языку Modula-3 с интересными статьями по построению программного обеспечения объектно-ориентированных систем и документацией обсуждения, ведущего к окончательным особенностям языка. Некоторые из них были ранее (см. Главу 2, главу 4, главу 5, главу 6) и некоторые позже (см. Главу 1 и более обновленные две, то есть обеих предыдущих версий определения языка, а также главу 3 и главу 6). глава седьмая) опубликованных версий большинства из восьми глав, отдельно доступных в предыдущем Центре системных исследований DEC (SRC) в качестве исследовательских отчетов для загрузки.
- Сэмюэл П. Харбисон, Modula-3 Простой в использовании учебник для занятий.
- Роберт Седжвик , Алгоритмы в Модуле-3
- Ласло Босорменьи и Карстен Вайх, Программирование на Modula-3: Введение в программирование со стилем
- Ренцо Орсини, Агостино Кортези Программа на Модуле-3: введение в императивную программу на итальянском языке, объясняющую ее основные особенности.
Проекты с использованием Модула-3
Программное обеспечение, которое программируется Модула-3, включает:
- SPIN операционная система
- Программа синхронизации репозитория программного обеспечения CVSup
- Язык Obliq , который использует возможность сетевых объектов Modula-3 прозрачно перемещать объекты по локальным сетям, обеспечивая распределенные возможности парадигмы объектно-ориентированного программирования Modula-3. Он использовался для создания распределенных приложений, компьютерной анимации и приложений веб-программирования в форме расширения сценариев для Modula-3.
Влияния на другие языки программирования
Хотя Modula-3 не получил статуса мейнстрима, некоторые части дистрибутива DEC-SRC M3 получили. Вероятно, наиболее влиятельной частью была библиотека сетевых объектов, которая легла в основу первой реализации Java Remote Method Invocation (RMI), включая сетевой протокол. Только когда Sun перешла от стандарта Common Object Request Broker Architecture (CORBA) к протоколу на основе IIOP, она отказалась. Документация Java по сборке мусора удаленных объектов все еще относится к новаторской работе, проделанной для сетевых объектов Modula-3. Реализация классов в Python также была вдохновлена механизмом классов, найденным в C ++ и Modula-3. Также в языке Nim используются некоторые аспекты Modula-3, такие как отслеживаемые и неотслеживаемые указатели.
использованная литература
внешние ссылки
- Официальный веб-сайт
- Modula3 на GitHub
- Веб-сайт внедрения CM3
- Домашняя страница Модулы-3 (давно мертвая, зеркало )
- Modula-3: определение языка
- Программные решения elego
- Группа новостей Модула-3 , в основном заброшенная
- Список рассылки разработчиков Modula-3 , активный
- Заметки из класса CS2 Калифорнийского технологического института, преподаваемого на Модуле-3 в 2002 и 2003 годах.
- CS3 класс 2009 Caltech на Wayback Machine (архивировано 23 мая 2013 г.)
- Зеркало Программирование в Модуле-3 : примеры программ
- Создание распределенных объектно-ориентированных приложений: объекты Modula-3 в действии . Мишель Р. Дагене. Черновая версия (январь 1997 г.)
- Модула-3: язык, библиотеки и инструменты . Презентация на Модуле-3 более 120 слайдов. Майкл Р. Дагенэйс , мертв
- Объектно-ориентированная абстракция данных в Modula-3 . Джозеф Бергин (1997)
- Интервью Computerworld с Лукой Карделли о Modula-3