Зачем понадобился ещё один язык: история и заказ DoD

Откуда взялся язык, который проектировали комитетом по заказу военных — и почему это оказалось не катастрофой, а одной из самых продуманных систем типов в истории.

Ada — это язык программирования общего назначения, разработанный в начале 1980-х по заказу Министерства обороны США для надёжных, долгоживущих и критически важных систем; назван в честь Ады Лавлейс, первой в истории программистки.

Кризис, которого почти никто не замечал

Чтобы понять Ada, нужно вернуться в середину 1970-х годов. Министерство обороны США (Department of Defense, далее DoD) обнаружило у себя проблему, которая на бумаге выглядела скучной бухгалтерией, а на деле грозила обернуться неуправляемым хаосом. Военные системы — от бортовых компьютеров ракет до радаров и систем связи — программировались на чудовищном разнообразии языков. Внутренний аудит насчитал более 450 разных языков и диалектов, используемых в проектах DoD. Каждый встроенный компьютер нередко имел свой собственный язык, заточенный под конкретное железо конкретного подрядчика.

Последствия были тяжёлыми. Код невозможно было переиспользовать между проектами. Программиста, обученного на одном проекте, нельзя было быстро перебросить на другой. Инструменты — отладчики, анализаторы, библиотеки — приходилось писать заново под каждый язык. А главное, военные системы живут десятилетиями: самолёт, спроектированный сегодня, будет летать и обслуживаться через тридцать-сорок лет, когда исходный подрядчик давно разорится, а авторы кода уйдут на пенсию. Поддерживать зоопарк из сотен языков на таком горизонте — финансовое самоубийство. Расходы на программное обеспечение росли быстрее, чем на железо, и впервые в истории софт стал главной статьёй затрат, а не приложением к технике.

Идея единого языка

В 1975 году DoD создал рабочую группу High Order Language Working Group (HOLWG) с дерзкой целью: найти или создать один язык высокого уровня, который заменит большинство из этих сотен. Это была не просто техническая задача, а попытка навести порядок в индустрии масштаба целого государства. Группа пошла методично. Сначала она не стала писать язык — она написала требования к языку. И вот здесь кроется первый урок Ada: язык начался не с синтаксиса, а с тщательного перечня того, что система обязана уметь.

Требования выпускались итеративно, и каждая редакция носила «прочнеющее» кодовое имя, отражающее степень готовности. Сначала появился документ Strawman («соломенный человек» — заведомо хрупкий черновик для критики), затем Woodenman (деревянный), Tinman (жестяной), Ironman (железный) и, наконец, окончательная редакция Steelman (стальной) в 1978 году. Сама эта прогрессия имён — от соломы к стали — точно передаёт инженерную культуру, из которой родилась Ada: ничего не принимается на веру, всё многократно проверяется и укрепляется.

Что требовал Steelman

Документ Steelman содержал около ста требований, и многие из них прямо предопределили облик будущего языка. Перечислю ключевые, потому что это, по сути, ДНК Ada:

  • Сильная типизация. Язык обязан ловить как можно больше ошибок на этапе компиляции. Смешивать величины разной природы (например, метры и секунды) без явного разрешения программиста запрещено.
  • Читаемость важнее краткости. Steelman прямо постулировал, что программу читают гораздо чаще, чем пишут, особенно в системах, живущих десятилетиями. Поэтому язык должен поощрять ясный, развёрнутый код.
  • Надёжность и безопасность. Никаких неопределённых поведений там, где их можно избежать. Выход за границу массива, переполнение, использование неинициализированных данных должны обнаруживаться, а не приводить к тихому повреждению.
  • Модульность и раздельная компиляция. Большие системы пишут командами; язык обязан поддерживать чёткие интерфейсы между частями (так появились пакеты).
  • Параллелизм в самом языке. Военные системы реального времени работают с множеством одновременных процессов; средства многозадачности должны быть встроены, а не прикручены библиотекой.
  • Обработка исключений. Сбои неизбежны, и язык должен давать структурированный способ на них реагировать.

Обратите внимание: ни одно из этих требований не про «писать быстро» или «писать коротко». Все они про надёжность на длинной дистанции. Это и есть водораздел между Ada и большинством популярных языков, которые оптимизируют скорость разработки.

Конкурс и рождение имени

Когда требования были готовы, DoD объявил международный конкурс на разработку языка. В нём участвовало несколько команд, и, чтобы исключить предвзятость, проекты обозначались цветами: Red, Green, Blue, Yellow. В 1979 году победил проект Green, разработанный командой французского инженера Жана Ишбиа (Jean Ichbiah) из компании CII Honeywell Bull. На основе Green и был создан язык, который получил имя Ada — в честь Ады Лавлейс (Augusta Ada King, графиня Лавлейс, 1815–1852), дочери поэта Байрона и соратницы Чарльза Бэббиджа. Её заметки к аналитической машине Бэббиджа содержали то, что многие считают первой в истории программой, поэтому Аду Лавлейс часто называют первым программистом. Дать военному языку женское имя первой программистки — изящный жест, подчёркивающий, что речь идёт о фундаменте, а не об очередной поделке.

Любопытная деталь: поскольку имя — это имя человека, а не аббревиатура, его пишут как обычное слово — Ada, а не ADA. Запись заглавными буквами выдаёт человека, не знакомого с языком.

Как работает под капотом эта философия

Стоит сразу прочувствовать, что значит «ловить ошибки рано», на крошечном примере. Представьте, что вы измеряете высоту полёта и хотите, чтобы она физически не могла стать отрицательной или превысить разумный потолок. В большинстве языков вы объявите целочисленную переменную и будете надеяться, что в неё не попадёт мусор. В Ada вы описываете ограничение прямо в типе:

Altitude_Meters : Integer range 0 .. 20_000;
Altitude_Meters := 11_500;   -- ОК, в диапазоне
Altitude_Meters := -50;      -- ошибка ещё на этапе компиляции либо
                             -- Constraint_Error во время выполнения

Подчёркивания в числах (20_000) — это разделители разрядов, чисто для читаемости; компилятор их игнорирует. Главное здесь — диапазон range 0 .. 20_000. Это не комментарий и не пожелание: это часть типа, которую компилятор и среда исполнения обязаны соблюдать. Попытка записать значение вне диапазона либо отвергается компилятором (если он может это доказать), либо порождает явное исключение Constraint_Error в момент нарушения. Программа не продолжит работу с заведомо невозможной высотой. Сравните с языком, где отрицательная высота тихо просочится сквозь все расчёты и проявится катастрофой где-нибудь в системе автопилота.

Именно из этого крошечного зерна вырастает вся надёжность Ada: знание о данных живёт в типах, а компилятор превращается из переводчика в строгого инженера-контролёра, который не пропускает заведомо невозможные состояния.

Steelman в деталях: как требования стали характером языка

Стоит задержаться на том, насколько прямо требования Steelman отпечатались в конкретных чертах Ada, потому что это лучший способ понять, почему язык выглядит именно так. Возьмём требование читаемости. Steelman настаивал, что синтаксис должен помогать человеку, который читает чужой код спустя годы. Отсюда — развёрнутые закрывающие конструкции: не безликая скобка, а end if;, end loop;, end Procedure_Name;. В большом файле, где вложенность глубока, такие явные «концы» мгновенно сообщают читателю, что именно закрывается. Критики называют это многословием; авторы языка называют это инвестицией в сопровождение. Для системы, которую обслуживают тридцать лет сменяющиеся команды, цена чтения многократно превышает цену набора текста, и Steelman это прямо признавал.

Другое требование — отсутствие «коварных» неоднозначностей. Steelman требовал, чтобы похожие по виду конструкции не имели тонко различающегося смысла, на котором легко обжечься. Поэтому в Ada присваивание (:=) и сравнение (=) — разные символы; поэтому регистр букв не создаёт двух разных имён; поэтому неявные преобразования типов сведены к минимуму. Каждое из этих решений закрывает конкретный класс ошибок, которые в других языках той эпохи уже стоили дорого. Требование надёжности породило сильную типизацию и проверки границ; требование модульности — пакеты с раздельной компиляцией; требование реального времени — встроенные задачи. Иными словами, Ada — это не набор красивых идей, придуманных из любви к элегантности, а прямой инженерный ответ на список конкретных болей, каждая из которых задокументирована.

Полезно увидеть и контекст эпохи. В конце 1970-х господствовали языки, где надёжность приносилась в жертву близости к железу или скорости разработки. Идея, что компилятор должен агрессивно искать ошибки за программиста, была не общепринятой, а почти радикальной. HOLWG, по сути, сделал ставку: вложить огромные усилия в язык, который дороже в освоении, но дешевле в эксплуатации на горизонте десятилетий. История подтвердила ставку — именно долгоживучесть и сертифицируемость удержали Ada в авиации и космосе спустя сорок лет, когда множество «модных» языков той поры давно забыты.

Частые ошибки и заблуждения

  • «Ada — мёртвый язык из 80-х». Стандарт активно развивается: последняя ревизия — Ada 2022, есть современный свободный компилятор и живое сообщество. Язык не доминирует в вебе, но прочно занимает нишу критичных систем, где как раз и нужен.
  • «Раз его делал комитет военных, он громоздкий». Многословность Ada — осознанный выбор в пользу читаемости, а не недосмотр. Развёрнутый end if; вместо закрывающей скобки помогает человеку, который будет читать чужой код через двадцать лет.
  • Писать имя как ADA. Это акроним-ловушка. Ada — имя, не сокращение.
  • Думать, что сильная типизация — это про неудобство. На практике она экономит огромное время на отладке: ошибка, пойманная компилятором, не доживает до тестов и тем более до эксплуатации.

Итоги

  • Ada родилась как ответ на кризис «языкового зоопарка» в Министерстве обороны США 1970-х: сотни несовместимых языков делали поддержку долгоживущих систем неподъёмной.
  • Язык начался не с синтаксиса, а с тщательного перечня требований, которые «прочнели» от Strawman к Steelman (1978).
  • Steelman заложил ДНК Ada: сильная типизация, читаемость, надёжность, модульность, встроенный параллелизм и обработка исключений.
  • Победивший проект Green Жана Ишбиа стал основой языка, названного в честь Ады Лавлейс — первого программиста в истории.
  • Главная идея, пронизывающая всё: ловить ошибки как можно раньше, кодируя ограничения данных прямо в типах.
Проверьте себя
1. Какая проблема Министерства обороны США в 1970-х привела к созданию Ada?
AНехватка программистов
BИспользование сотен несовместимых языков в проектах, что делало поддержку неподъёмной
CОтсутствие компьютеров
DСлишком высокая скорость разработки
2. Что означала последовательность кодовых имён требований Strawman → Steelman?
AИмена разработчиков
BПостепенное укрепление требований от хрупкого черновика к окончательной редакции
CВерсии компилятора
DНазвания ракет
3. В честь кого назван язык Ada?
AВ честь города
BВ честь Ады Лавлейс, которую считают первым программистом
CВ честь аббревиатуры
DВ честь Чарльза Бэббиджа