Модула-2

Мо́дула-2 (Modula-2) — язык программирования общего назначения, являющийся развитием Паскаля, разработанный Никлаусом Виртом в 1978 году.

Цели и принципы разработки языка 
Язык Модула-2 был разработан Никлаусом Виртом для создания системного программного обеспечения , разработка которой началась в 1977 году в Институте информатики Цюриха. Этим определяются многие его особенности. Язык изначально проектировался как средство промышленного системного программирования, позволяющее писать надёжные, понятные, удобные в сопровождении программы. При этом язык должен был, оставаясь языком высокого уровня со строгой типизацией и поддержкой всех средств надёжного программирования, давать возможность обращаться непосредственно к аппаратуре, создавать специфические системные программы, такие как обработчики прерываний и драйверы устройств, поддерживать программирование параллельно исполняющихся взаимодействующих процессов.

Непосредственным предком Модулы-2 был язык Модула, созданный Виртом в первой половине 1970-х на основе Паскаля. Основным дополнением, отразившимся и в названии языка, была возможность разбиения программы на модули — отдельные фрагменты кода, взаимодействующие через явно описанные интерфейсы. Также был переработан синтаксис и добавлены средства параллельного программирования. Единственная экспериментальная реализация Модулы появилась в 1975 году. Модулу можно рассматривать как первоначальный вариант, своего рода «альфа-версию» Модулы-2, синтаксически эти два языка очень близки. Кроме того, по словам Вирта, на Модулу-2 оказал влияние язык , разработанный в Xerox PARC.

Общая характеристика 
Язык Модула-2 — структурный, модульный язык программирования, с синтаксисом, основанным на языке Паскаль, но заметно переработанным и улучшенным. Его основные характерные особенности приведены ниже.
 Программа представляет собой набор модулей — самостоятельных единиц компиляции, которые могут компилироваться раздельно. При этом программный модуль может (но не обязан) быть разделён на две части: модуль определений и модуль реализации. Модуль определений — это внешний интерфейс модуля, то есть набор экспортируемых им имён констант, переменных, типов, заголовков процедур и функций, которые доступны внешним модулям. Модуль реализации содержит программный код, в частности, конкретизацию описаний всего, что перечислено в модуле определений. Например, некоторый тип «запись» может быть объявлен в модуле определений с указанием лишь его имени, а в модуле реализации — с полной структурой. В этом случае внешние модули могут создавать значения данного типа, вызывать процедуры и функции, работающие с ним, выполнять присваивание переменных, но не имеют прямого доступа к структуре значений, поскольку эта структура не описана в модуле определений. Если для этого же типа описать в модуле определений структуру, то она станет доступна. Помимо модулей глобального уровня в Модуле-2 допускается создавать локальные модули.
 Импорт определений, описанных в прочих модулях, полностью контролируется. Можно импортировать модули определений целиком, но синтаксис позволяет существенно уточнять списки импорта, например, импортировать из модуля конкретные константы, переменные, процедуры и функции, только те, которые необходимы.
 Все средства ввода-вывода исключены из языка. Вместо них используются библиотечные модули, на которые возложена задача реализации ввода-вывода на конкретных системах. Однако имеется набор стандартизованных библиотек ввода-вывода, предоставляющих необходимые функции для типичных случаев (ввод-вывод основных типов данных с использованием текстового терминала, файловый ввод-вывод).
 В язык введён минимум понятий и примитивов для многопоточного программирования, добавлена также стандартная библиотека, поддерживающая параллельные программы.
 Включены средства прямого доступа к аппаратуре компьютера, в частности, реализовано прямое отображение структур данных на память, в том числе с прямым заданием адреса.

Язык прост по структуре — в нём имеется только 40 зарезервированных слов (для сравнения, в Аде их 63); официальное «Сообщение о языке», содержащее исчерпывающее описание Модулы-2, занимает 40 страниц (полное описание сокращённого варианта ПЛ/1 занимает около 200 страниц).

Особенности синтаксиса 
Описать особенности Модулы-2 проще всего путём сравнения с языком Паскаль. Наиболее важные отличия, помимо введения модулей и механизмов управляемого экспорта описаний, состоят в нижеследующем.
 Язык регистро-зависимый — прописные и строчные буквы в идентификаторах различаются. Все ключевые слова пишутся в верхнем регистре.
 Синтаксис сделан более регулярным и упрощён. Все синтаксические конструкции, кроме цикла REPEAT-UNTIL, следуют принципу: конструкция, начинающаяся с ключевого слова, заканчивается ключевым словом. В частности, условный оператор имеет общий вид

IF Условие THEN
  Операторы
ELSIF Условие THEN
  Операторы
ELSIF Условие THEN
  Операторы
...
ELSE
  Операторы
END

Благодаря этому исчезла необходимость постоянного использования составных операторов BEGIN-END и «лестниц» операторов IF при многоступенчатой проверке условий.
 Циклы WHILE и FOR также предусматривают тело из набора операторов и заканчиваются зарезервированным словом END.
 Добавлен безусловный цикл LOOP-END.
 И процедуры, и функции объявляются с ключевым словом PROCEDURE.
 Добавлен предопределённый тип BITSET — битовое поле.
 Из языка исключён оператор безусловного перехода GOTO.
 Добавлен процедурный тип, дающий возможность присваивать процедуры и функции переменным. Позже эта возможность была включена и в Паскаль, где она изначально отсутствовала.

Диалекты 
Существует два основных диалекта Модулы-2. Первый — PIM (по названию книги Никлауса Вирта «Programming in Modula-2», где было дано развёрнутое описание языка и основных системных библиотек), существует в трёх основных вариантах, появлявшихся последовательно и минимально отличающихся друг от друга. Второй основной диалект — ISO, стандартизованный Международной организацией по стандартизации. Основные отличия диалектов от первоначального описания языка перечислены далее.

 PIM2 (1983)
 Требует обязательного использования директивы EXPORT в модуле определений.
 Функция SIZE является библиотечной и должна импортироваться из модуля SYSTEM.
 PIM3 (1985)
 Удалена директива EXPORT из модулей определений. Изменение мотивировалось тем, что всё содержимое модуля определений экспортируется, так что использование EXPORT является избыточным.
 Функция SIZE является предопределённой (доступна в любом месте программы без импорта).
 PIM4 (1988)
 Уточнено поведение операции MOD для отрицательных операндов.
 Добавлено требование, согласно которому все строки, описанные как ARRAY OF CHAR, должны завершаться нулевым символом (ASCII NUL), даже если строка занимает весь массив целиком.
 ISO (1996 и 1998)
 Добавлены типы данных COMPLEX and LONGCOMPLEX.
 Добавлены исключения.
 Добавлена конструкция для кода завершения модуля FINALLY.
 Полностью стандартизована библиотека ввода-вывода.
 Внесены уточнения, снявшие большинство неоднозначностей оригинального описания, сделано много мелких исправлений и разъяснений.

Достоинства и недостатки 
Можно определённо сказать, что язык Модула-2, сохранив положительные черты Паскаля, имеет ряд особенностей, делающих её языком, гораздо более мощным и лучше приспособленным как для системного, так и для прикладного программирования. Основные преимущества Модулы-2 перед современными ему языками структурного программирования следующие:

 Простота и лаконичность определения языка. Полное определение синтаксиса в нотации РБНФ занимает менее 3 страниц, полные синтаксические диаграммы — 12 страниц, официальное «сообщение о языке» имеет объём 40 страниц, что для универсального языка с такими возможностями — едва ли не абсолютный минимум. Для сравнения: официальное полное определение языка Ада занимает 400 машинописных страниц.
 Простой, логичный и однородный синтаксис, очищенный от избыточных конструкций и элементов, провоцирующих ошибки написания. Модула-2 — первый из директивных языков программирования, в котором удалось отказаться от оператора GOTO.
 Хорошо продуманный механизм разделения программы на единицы компиляции (модули) с явно описываемыми интерфейсами и полностью контролируемым импортом, позволяющим импортировать как целые модули, так и отдельные элементы с возможностью как квалифицированного (с указанием имени модуля) так и неквалифицированного использования имён импортированных объектов.
 Исключение из языка средств ввода-вывода и большинства стандартных процедур и функций и перенос их в библиотеки, оформленные в виде стандартных модулей, что упрощает язык и компилятор и предоставляет реализатору полную свободу в способах реализации стандартных процедур и функций.
 Включение в язык механизмов низкоуровневого программирования, в том числе непосредственной работы с памятью и нетипизированными данными и указателями, что позволяет писать на языке высокого уровня большинство низкоуровневых программ, которые традиционно писались на ассемблере, таких как драйверы и обработчики прерываний.
 Наличие элементарных средств параллельного программирования, выбранных таким образом, чтобы гарантировать их адекватную реализацию как на физически многопроцессорных платформах, так и на платформах с разделением времени.
 Существенным для времени создания языка было появление процедурного типа и, соответственно, переменных, которым можно динамически присваивать процедуры.

К недостаткам языка можно отнести:
 Слабость механизмов параллельного программирования, в частности — организации взаимодействия параллельных процессов. Реализация этих средств переложена на системные библиотеки, причём в стандартной библиотеке имеются лишь простейшие средства управления распараллеливанием. Параллельная программа на Модуле-2, использующая средства управления параллелизмом, выходящие за эти рамки, автоматически теряет переносимость.
 Отсутствие механизмов управления отображением абстрактных типов на память.
 Поддержка локальных модулей неоправданно усложняет компилятор. Поводами для использования вложенных модулей являются ограничение области видимости и выделение высокоприоритетных частей программы для обеспечения синхронизации при параллельной обработке, но их можно реализовать и другими, более простыми и очевидными, средствами.
 Явное разделение на модуль реализации и модуль определения — спорное решение. Оно усложняет работу компилятора и вынуждает программиста синхронизировать изменения в разных файлах. Можно отметить, что в потомке Модулы-2 — Обероне, — от такого разделения отказались, вместо этого в едином программном модуле экспортируемые элементы (составляющие интерфейс модуля) просто помечаются специальным образом.

Можно также отметить отсутствие в Модуле-2 ряда возможностей, известных и популярных на момент её создания, что может быть отнесено как к достоинствам, так и к недостаткам языка, в зависимости от точки зрения конкретного критика:
 Отсутствуют динамические массивы и строки переменного размера.
 Отсутствуют любые встроенные средства обработки исключительных ситуаций.
 Отсутствуют средства обобщённого программирования.

Использование 
В СССР первые компиляторы для Модула-2 появились в 1982-83 годах для ЭВМ СМ-4 и Электроника-60. Транслятор для БЭСМ-6 был разработан в ВЦ АН СССР (В.А. Серебряков, В.Г. Лютый, А.Н. Бездушный). Тогда же были выработаны технологии программирования и созданы первые пакеты прикладных программ на Модуле-2. Такие работы велись, в частности, на факультете Кибернетики МИФИ. ВНТК «СТАРТ» Вычислительного Центра Сибирского отделения Академии наук СССР разработал серию процессоров Кронос с аппаратной поддержкой языка программирования Модула-2.

В целом можно сказать, что Модула-2 не получила того распространения и признания, которого заслуживала по своим качествам. Язык завоевал определённую популярность в академической среде Европы, был довольно популярен среди программистов СССР, но не смог потеснить своего предшественника: новые реализации языка Паскаль, включившие в себя средства организации модулей, а позже — средства объектного программирования, всегда обходили Модулу-2 по популярности. Система Lilith, для которой создавалась Модула-2, не получила широкой известности и не смогла помочь Модуле-2 в продвижении.

Свою роль сыграло чрезвычайно широкое распространение дешёвых и быстрых Паскаль-компиляторов фирмы Borland International. Интересно, что компилятор Turbo Modula-2 для ОС CP/M был не только создан Borland, но даже поступил в продажу в Северной Америке и Западной Европе. Однако руководство компании, прежде всего Филипп Кан, приняло решение отказаться от развития этой системы, чтобы не создавать конкурента крайне успешному Turbo Pascal. Результатом этого решения стало то, что вице-президент Borland Нильс Йенсен, один из основателей компании, вместе со своей командой разработчиков в 1987 году покинул Borland, выкупив права на Turbo Modula-2. Созданная им компания JPI (Jensen & Partners International) выпустила под маркой TopSpeed линейку компиляторов для процессоров семейства x86: Assembler, Modula-2, Pascal, C/C++, Ada.

В настоящее время язык Модула-2 используется для программирования бортового программного обеспечения спутников, запускаемых в рамках проекта ГЛОНАСС. В конце 2010 г. компилятор GNU Modula-2 официально включён в коллекцию GCC.

Языки-потомки 
 Модула-3 — дальнейшее развитие Модулы-2, разработанное совместно Фирмами DEC и Olivetti при консультационной поддержке Вирта.
 Оберон — дальнейшее развитие Модулы-2, созданное Виртом в 1988 году. Оберон использует автоматическое управление памятью со сборкой мусора, также в нём изменён ряд черт, которые по опыту эксплуатации Модулы-2 автор счёл неудачными. Добавлена экономно реализованная объектная подсистема. Оберон, в свою очередь, стал родоначальником целой ветви языков: Оберон-07, Оберон-2, Component Pascal (Компонентный Паскаль), Активный Оберон, OberonScript.
 Zonnon — язык, созданный Юргом Гуткнехтом на основе Модулы-2 и Активного Оберона, с добавлением ряда новых элементов, как оригинальных, так и заимствованных из других языков.
 Алма-0 — Алма-0 является дополненной (мультипарадигмальной) версией императивного языка Modula-2.
 Parallaxis — это структурированный язык программирования для параллельного программирования данных (SIMD-системы), разработанный Томасом Браунлом в 1989 году. Язык основан на последовательной Modula-2, но расширен неавтономными параллельными конструкциями.

Помимо прямых потомков, множество других языков в той или иной мере унаследовало у Модулы-2 элементы синтаксиса и общей архитектуры. О влиянии Модулы-2 говорили создатели таких мало похожих языков, как, например, Lua и Go. Влияние Модулы-2 (и в большей степени её потомка, языка Оберон) прослеживается в Java, C#, поздних диалектах Паскаля, таких как Object Pascal и Delphi.

Примечания

Литература 
 Вирт Н. Программирование на языке Модула-2. Перевод с англ. В. А. Серебрякова, В. М. Ходукина; Под ред. В. М. Курочкина. — М. : Мир, 1987. — 222 с.
 Вирт Н. Алгоритмы и структуры данных (версия книги на языке Модула-2), Москва, Мир, 1989, ISBN 5-03-001045-9 (русск.), 0-13-022005-1 (англ)
 
 Кристиан К. Руководство по программированию на языке Модула-2. — М., Мир, 1989. — ISBN 5-03-001117-X — 463 с.

Ссылки 
 
 
 
 GNU Modula-2
 Free Modula-2 Pages: freepages.modula2.org — ресурс пользователей языка.
 примеры кода.

Языки программирования семейства Модулы
M