Ada программирование. Язык программирования ада

(Ада 2005), Эйфелева (Ada 2012)

C ++ , Chapel , "Драго" . , Eiffel , "Грифон" . , Java , Nim , летать на парашюте за катером , PL / SQL , PL / PgSQL , рубин , Seed7 , "SPARforte" . , Sparkel , SQL / PSM , VHDL

Особенности Ada включают в себя: сильные печатать , модульность механизмы (пакеты), во время выполнения проверки , параллельной обработки (задачи , синхронные передачи сообщений , защищенных объектов и недетерминированных операторов выбора), обработку исключений и дженерики . Ада 95 добавлена поддержка объектно-ориентированного программирования , в том числе динамической диспетчеризации .

Синтаксис Ada минимизирует выбор способов выполнения основных операций, и предпочитает английские ключевые слова (например, «или же» и « а затем») в символы (такие как «||» и «&&»). Ада использует основные арифметические операторы «+», «-», «*» и «/», но избегает использования других символов. Блоки кода ограничивается словами, такие как «объявить», «начать» и «конец», где «конец» (в большинстве случаев) следует идентификатор блока он закрывает (например, если конец, если... , петля... конец цикла ). В случае условных блоков это позволяет избежать оборванных еще , что может спариваться с неправильным вложенным if-выражения в других языках, таких как C или Java.

Ада предназначена для разработки очень больших программных систем. пакеты Ada могут быть собраны отдельно. спецификации пакета Ada (интерфейс пакета) также могут быть скомпилированы отдельно без осуществления проверки на предмет соответствия. Это позволяет обнаруживать проблемы на ранней стадии на стадии проектирования, до начала реализации.

Большое количество проверок во время компиляции поддерживается, чтобы помочь избежать ошибок, которые не будут обнаружено до времени выполнения в некоторых других языках, или же требуют явных проверок, которые будут добавлены к исходному коду. Например, синтаксис требует явного имя закрытия блоков для предотвращения ошибок из-за Несовпадающие конечные маркер. Соблюдение строгой типизации позволяет обнаружить наличие стандартных ошибок программного обеспечения (неправильные параметры, нарушения диапазона, недействительные ссылки, несоответствующие типы и т.д.) либо во время компиляции, или в противном случае во время выполнения. Как параллелизм является частью спецификации языка, компилятор может в некоторых случаях обнаружения потенциальных тупиков. Составители также обычно проверять орфографические ошибки идентификаторов, видимость пакетов, избыточных деклараций и т.д., и может предоставить предупреждения и полезные советы о том, как исправить ошибку.

Ада также поддерживает проверки времени выполнения для защиты от доступа к нераспределенной памяти, переполнение буфера ошибок, нарушений диапазона, вне череде ошибок , ошибки доступа к массиву, и других обнаруживаемых ошибок. Эти проверки могут быть отключены в интересах эффективности выполнения, но часто могут быть собраны эффективно. Она также включает в себя средства, чтобы помочь проверки программы. По этим причинам, Ада широко используется в критических системах, где любая аномалия может привести к очень серьезным последствиям, например, смерти от несчастного случая, травмы или тяжелой финансовой потери. Примеры систем, в которых используются Ada включают авионику , УВД , железные дороги, банковское дело, военный и космическую технику.

Динамическое Ады управление памятью является высоким уровнем и типа-сейф. Ада не имеет общие или нетипизированные указатели ; и не неявно объявить любой тип указателя. Вместо этого, все динамическое распределение памяти и освобождение должно происходить через явно объявленных типов доступа . Каждый тип доступа имеет соответствующий пул устройств хранения данных , который обрабатывает низкоуровневые детали управления памятью; программист может использовать либо пул хранения по умолчанию или определить новые (это особенно актуально для Non-Uniform Memory Access). Можно даже объявить несколько различных типов доступа, которые все обозначают один и тот же тип, но используют различные пулы хранения. Кроме того, язык обеспечивает доступности проверок , как во время компиляции и во время выполнения, что гарантирует, что стоимость доступа не может изгладить тип объекта он указывает.

Хотя семантика языка позволяет автоматически сбор мусора недоступных объектов, большинство реализаций не поддерживают его по умолчанию, так как это приведет к непредсказуемому поведению в системах реального времени. Ада поддерживает ограниченную форму области на основе управления памятью ; Кроме того, творческое использование пулов хранения может обеспечить ограниченную форму автоматической сборки мусора, поскольку уничтожение пула устройств хранения данных также уничтожает все объекты в бассейне.

история

Продолжается работа по совершенствованию и обновлению технического содержания языка программирования Ada. Техническое исправление к Аду 95 было опубликовано в октябре 2001 года, а основная поправке, ISO / IEC 8652: 1995 / Amd 1: 2007 было опубликовано 9 марта 2007 года В Ada-Europe 2012 конференции в Стокгольме, Ассоциация Ada ресурсов (ARA) и Ад-Europe объявили о завершении проектирования последней версии языка программирования Ada и представления справочного руководства к Международной организации по стандартизации (ISO) для утверждения. ISO / IEC 8652: 2012 был опубликован в декабре 2012 года.

Другие соответствующие стандарты включают ISO 8651 -3: 1988 Системы обработки информации, компьютерной графики, графического ядра системы (ГКС) язык привязок-Часть 3: Ада .

Языковые конструкции

"Привет, мир!" в Ada

Типичным примером такого языка в синтаксисе является Привет мир программа : (hello.adb)

with Ada.Text_IO ; use Ada.Text_IO ; procedure Hello is begin Put_Line ("Hello, world!" ); end Hello ;

Эта программа может быть составлена с использованием свободно распространяемого с открытым исходным кодом компилятора GNAT , выполнив

gnatmake hello.adb

Типы данных

Система типа Ады не на основе набора предопределенных примитивных типов , но позволяет пользователям объявлять свои собственные типы. Это заявление, в свою очередь, не основано на внутреннем представлении типа, но на описание цели, которая должна быть достигнута. Это позволяет компилятору, чтобы определить подходящий размер памяти для данного типа, и для проверки наличия нарушения определения типа во время компиляции и времени выполнения (т.е. нарушение диапазона, переполнение буфера, типа консистенция и т.д.). Ада поддерживает числовые типы, определенные в диапазоне, по модулю типов, агрегатные тип (записи и массивы), а также тип перечисления. Типы доступа определить ссылку на экземпляр указанного типа; нетипизированных указатели не разрешены. Специальные типы, предоставляемые на языке типов задач и охраняемые виды.

Например, дата может быть представлена ​​в виде:

type Day_type is range 1 .. 31 ; type Month_type is range 1 .. 12 ; type Year_type is range 1800 .. 2100 ; type Hours is mod 24 ; type Weekday is (Monday , Tuesday , Wednesday , Thursday , Friday , Saturday , Sunday ); type Date is record Day : Day_type ; Month : Month_type ; Year : Year_type ; end record ;

Типы могут быть уточнены путем объявления подтипов:

subtype Working_Hours is Hours range 0 .. 12 ; -- at most 12 Hours to work a day subtype Working_Day is Weekday range Monday .. Friday ; -- Days to work Work_Load : constant array (Working_Day ) of Working_Hours -- implicit type declaration := (Friday => 6 , Monday => 4 , others => 10 ); -- lookup table for working hours with initialization

Типы могут иметь модификаторы, такие как ограниченные, абстрактные, частные и т.д. Частные типы могут быть доступны и ограниченные типы могут быть изменены только или скопированы в пределах пакета, который определяет их только. Ada 95 добавляет дополнительные возможности для объектно-ориентированного расширения типов.

Управляющие структуры

Ада также предлагает защищенные объекты для взаимного исключения . Защищенные объекты являются монитор, как конструкция, но и использовать защитные вместо условных переменных для сигнализации (аналогично условных критических областей). Охраняемые объекты сочетают инкапсуляцию данных и безопасное взаимное исключение из мониторов, а также въездные охранник из условных критических областей. Главное преимущество по сравнению с классическими мониторами является то, что условные переменные не требуется для передачи сигналов, избегая потенциальные тупики из - за неправильную запирающих семантику. Как и задачи, защищаемый объект является встроенным ограниченным типом, и он также имеет декларацию часть и тело.

Защищенный объект состоит из инкапсулированных личных данных (которые могут быть доступны только в пределах охраняемого объекта), а также процедуры, функции и записи, которые гарантированно являются взаимоисключающими (с единственным исключением функций, которые необходимы, чтобы быть побочным эффектом бесплатно Таким образом, и может работать одновременно с другими функциями). Задача вызова защищенного объекта блокируется, если другая задача выполняется в данный момент в том же защищаемом объекте, и освобождается, когда эта другая задача оставляет защищаемый объект. Заблокированные задачи ставятся в очередь на защищаемом объекте заказанного времени прибытия.

Защищенные данные объекта аналогичны процедурам, но дополнительно имеют охрану . Если охранник оценивается как ложное, задача вызова блокируется, и добавляется в очередь этой записи; Теперь другая задача может быть допущен к защищаемому объекту, так как ни одна из задач не выполняется в данный момент внутри защищаемого объекта. Охранники переоценены всякий раз, когда задача выходит из охраняемого объекта, так как это единственный раз, когда оценка охранников может быть изменена.

Звонки на запись могут быть requeued для других записей с той же подписью. Задача, которая requeued блокируется, и добавляются в очередь целевой записи; это означает, что защищаемый объект освобождается и позволяет прием другой задачи.

Выберите оператор в Ada может быть использован для реализации неблокируемых вызовов входа и принимает, недетерминирован выбор записей (также с охраной), время ожидания и прерывает.

Следующий пример иллюстрирует некоторые концепции параллельного программирования в Ada.

with Ada.Text_IO ; use Ada.Text_IO ; procedure Traffic is type Airplane_ID is range 1. . 10 ; -- 10 airplanes task type Airplane (ID : Airplane_ID ); -- task representing airplanes, with ID as initialisation parameter type Airplane_Access is access Airplane ; -- reference type to Airplane protected type Runway is -- the shared runway (protected to allow concurrent access) entry Assign_Aircraft (ID : Airplane_ID ); -- all entries are guaranteed mutually exclusive entry Cleared_Runway (ID : Airplane_ID ); entry Wait_For_Clear ; private Clear : Boolean := True ; -- protected private data - generally more than just a flag... end Runway ; type Runway_Access is access all Runway ; -- the air traffic controller task takes requests for takeoff and landing task type Controller (My_Runway : Runway_Access ) is -- task entries for synchronous message passing entry Request_Takeoff (ID : in Airplane_ID ; Takeoff : out Runway_Access ); entry Request_Approach (ID : in Airplane_ID ; Approach : out Runway_Access ); end Controller ; -- allocation of instances Runway1 : aliased Runway ; -- instantiate a runway Controller1 : Controller (Runway1 " Access ); -- and a controller to manage it ------ the implementations of the above types ------ protected body Runway is entry Assign_Aircraft (ID : Airplane_ID ) when Clear is -- the entry guard - calling tasks are blocked until the condition is true begin Clear := False ; Put_Line (Airplane_ID " Image (ID ) & " on runway " ); end ; entry Cleared_Runway (ID : Airplane_ID ) when not Clear is begin Clear := True ; Put_Line (Airplane_ID " Image (ID ) & " cleared runway " ); end ; entry Wait_For_Clear when Clear is begin null ; -- no need to do anything here - a task can only enter if "Clear" is true end ; end Runway ; task body Controller is begin loop My_Runway . Wait_For_Clear ; -- wait until runway is available (blocking call) select -- wait for two types of requests (whichever is runnable first) when Request_Approach " count = 0 => -- guard statement - only accept if there are no tasks queuing on Request_Approach accept Request_Takeoff (ID : in Airplane_ID ; Takeoff : out Runway_Access ) do -- start of synchronized part My_Runway . Assign_Aircraft (ID ); -- reserve runway (potentially blocking call if protected object busy or entry guard false) Takeoff := My_Runway ; -- assign "out" parameter value to tell airplane which runway end Request_Takeoff ; -- end of the synchronised part or accept Request_Approach (ID : in Airplane_ID ; Approach : out Runway_Access ) do My_Runway . Assign_Aircraft (ID ); Approach := My_Runway ; end Request_Approach ; or -- terminate if no tasks left who could call terminate ; end select ; end loop ; end ; task body Airplane is Rwy : Runway_Access ; begin Controller1 . Request_Takeoff (ID , Rwy ); -- This call blocks until Controller task accepts and completes the accept block Put_Line (Airplane_ID " Image (ID ) & " taking off..." ); delay 2.0 ; Rwy . Cleared_Runway (ID ); -- call will not block as "Clear" in Rwy is now false and no other tasks should be inside protected object delay 5.0 ; -- fly around a bit... loop select -- try to request a runway Controller1 . Request_Approach (ID , Rwy ); -- this is a blocking call - will run on controller reaching accept block and return on completion exit ; -- if call returned we"re clear for landing - leave select block and proceed... or delay 3.0 ; -- timeout - if no answer in 3 seconds, do something else (everything in following block) Put_Line (Airplane_ID " Image (ID ) & " in holding pattern" ); -- simply print a message end select ; end loop ; delay 4.0 ; -- do landing approach... Put_Line (Airplane_ID " Image (ID ) & " touched down!" ); Rwy . Cleared_Runway (ID ); -- notify runway that we"re done here. end ; New_Airplane : Airplane_Access ; begin for I in Airplane_ID " Range loop -- create a few airplane tasks New_Airplane := new Airplane (I ); -- will start running directly after creation delay 4.0 ; end loop ; end Traffic ;

Прагмы

Прагма является директивой компилятора , который передает информацию в компилятор, чтобы конкретные манипуляции скомпилированной продукции. Некоторые псевдокомментарии встроены в язык, а другие реализации.

Примеры общего использования компилятора прагм будут отключать определенные функции, такие как проверка типов времени выполнения или индекс массива проверка граничной, или поручить компилятор, чтобы вставить код объекта вместо вызова функции (в C / C ++ делает с инлайн функции).

  • APSE - спецификация для среды программирования для поддержки разработки программного обеспечения в Ada
  • Ravenscar профиль - это подмножество функций Ada многозадачных, предназначенных для обеспечения безопасности критически важных жесткого реального времени вычислений
  • СПАРК (язык программирования) - язык программирования, состоящий из весьма ограниченного подмножества Ada, аннотированные с мета - информацией, описывающей желаемое поведение компонента и индивидуальных требований во время выполнения

Сергей Бобровский

История этого языка начинается отнюдь не с 1975 года, когда Министерство Обороны (МО) США приняло решение о начале разработки единого языка программирования для американских вооруженных сил, а в дальнейшем и для всего НАТО. История его начинается с названия, ибо Ада - имя Августы Ады Лавлейс, считающейся первой программисткой, дочери английского поэта Байрона и некоей Анабеллы Милбэнк, с которой супруг расстался навсегда через месяц после рождения дочери, появившейся на свет 10 декабря 1815 года. Вообще, история кибернетики окутана мрачной тайной, и лишь по отрывочным фактам можно судить, что родоначальниками этой науки в последние двести лет являлись различные мистики и оккультисты, начиная от Августа де Моргана, одного из учителей Ады, и кончая сподвижниками Норберта Винера, изучавшими способы формирования общественного мнения и манипулирования им.

После того как Чарльз Бэббидж сконструировал свою механическую вычислительную машину, Ада написала для нее первую программу для вычисления коэффициентов Бернулли. В дальнейшем она разработала настоящую теорию программирования, ввела понятие цикла и еще нескольких ключевых терминов, которые почти дословно изучают сегодня студенты кибернетических факультетов! Сегодня Ада известна всем как первая программистка - и только, но удивляет, откуда у молодой девушки такие уникальные способности? На этот вопрос откровенно ответила она сама: "Клянусь Дьяволом, что не пройдет и 10 лет, как я высосу некоторое количество жизненной крови из загадок Вселенной, причем так, как этого не смогли бы сделать обычные смертные умы и губы. Никто не знает, какие ужасающие энергия и сила лежат еще неиспользованными в моем маленьком гибком существе...". Однако спонсоров на проект вычислительной машины не нашлось - ядерных ракет тогда еще не было, и Ада, проиграв на скачках все свое состояние и попав в грязную историю, скончалась в возрасте 37 лет, как и ее знаменитый отец.

Поэтому стоило ли американцам так превозносить Аду, используя ее имя в качестве названия для столь амбициозного проекта, вопрос весьма спорный.

Но вернемся к истории самого языка. Через пять лет после начала проекта сотни экспертов отобрали из 17 вариантов единственный, удовлетворяющий требованиям МО, язык, разработанный небольшой группой под руководством талантливого ученого Жана Ишбиа. Конечная версия международного стандарта ISO 8652:1987 была опубликована в 1987 году. По официальным сообщениям, в создании и доработке этого языка участвовали все лучшие специалисты мира в области программирования, что, однако, вызывает сомнение. Это, например, подтверждается отсутствием понятия объекта в первоначальном варианте Ады и неучастием, по очевидным причинам, в этом проекте советских программистов.

В развитие инфраструктуры Ады во всем мире были вложены десятки миллиардов долларов. Это привело к появлению амбициозных заявлений типа "20-й век пройдет под знаком Ады", однако, как обычно, жизнь все расставила по своим местам.

К сожалению для МО США (и соответственно к счастью для "потенциальных противников" Америки), выработка четкого стандарта на этот язык и создание эффективных компиляторов были завершены как раз в то время (начало 80-х), когда уже стал вырисовываться на горизонте программной индустрии новый язык Си++ с объектной идеологией. Теперь трудно сказать, что испытывал комитет разработчиков Ады, видя, как растет популярность Си++ и старой, хорошо забытой, объектной парадигмы мышления. Но выделенные средства уже были потрачены, стандарт создан, и обратной дороги не было.

Структура Ады очень похожа на Паскаль, а еще точнее, на Модулу. Синтаксис большинства операторов и описаний практически идентичен синтаксису Модулы, хотя она появилась практически в одно время с Адой, и трудно сказать, кто на кого оказал влияние и оказал ли влияние вообще. В Аду, в частности, было добавлено довольно много различных расширений, так что компактным, в сравнении с тем же Паскалем, этот язык назвать никак нельзя. По количеству возможностей он скорее напомнит PL/1. Но так как основной упор создатели Ады делали на соответствие пожеланиям американских "первых отделов", то средства закрытости (видимости) данных и возможность создания отдельных блоков с использованием только спецификаций (интерфейсных описаний модулей) других разработчиков были для своего времени самыми совершенными. Например, программист, реально писавший код для вычисления траектории полета крылатой ракеты, даже не представлял, где и для каких целей его модуль будет использоваться, хотя имел доступ к требуемым спецификациям других сотрудников и мог без проблем отлаживать свой участок кода. Из-за строгого разграничения доступа к различным уровням спецификаций подчас даже бывает невозможно определить, для чего и какими средствами будет вызываться данная процедура. Однако такое стремление к независимой разработке программ привело к весьма сложной системе взаимосвязей между спецификациями модулей и появлению некоторых "дыр", способных вызвать побочные эффекты, наличие которых, впрочем, МО США сочло даже полезным.

Значительно были усилены элементы типизации данных, а также более формализованы сами типы. Все функции, связанные с вводомвыводом, были исключены из стандартного синтаксиса, а обработка исключительных ситуаций стала неотъемлемой частью языка. Кроме того, была доведена до предела мощность управляющих конструкций, что делало Аду наиболее передовым среди других паскалеподобных языков.

Фирма Borland вскоре выпустила свой Turbo Pascal, в который было встроено понятие модуля, и приблизила по возможностям свою версию Паскаля к Аде, но в дальнейшем попыток создания необъектных языков программирования 3-го поколения, предназначенных для разработки сверхбольших проектов, к счастью, не предпринималось. Поэтому Ада поставила жирную точку в длинной веренице простых процедурных языков, начиная с Фортрана и Алгола. Фактически все, что только можно было придумать в рамках идеологии структурного программирования, было воплощено в Аде. Затем стремительно расцвело объектное программирование, и Ада отошла на второй план.

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

Тем более удивительно, что МО США по тем или иным причинам отказалось от объектной идеологии, прекрасно воплощенной еще в

60-х годах в Симуле-67, и наверняка не раз пожалело об этом. Правда, в язык Ада была введена некая жалкая замена ряда возможностей, предоставляемых объектно-ориентированным программированием - так называемые шаблоны, т. е. процедуры с параметрами неопределенных типов. Но все-таки главными преимуществами Ады, позволяющими ей и сегодня выдерживать натиск более развитых языков, явились, помимо мощного финансирования, встроенная поддержка параллельного выполнения задач и мощные средства координации их взаимодействия. Необходимо отметить, что основная ориентация Ады - это отнюдь не системы автоматизации бухгалтерии в МО США, а чисто боевые задачи такого, например, рода, как микропроцессорная навигация в реальном времени самонаводящейся ракеты, где требуется одновременно обрабатывать информацию, непрерывно поступающую от множества самых разнообразных датчиков. Ранее такие задачи писались на ассемблере, что приводило к множеству ошибок и трудностям сопровождения. Для подобных задач Ада, конечно, подходит как нельзя лучше.

Однако Ада продолжает позиционироваться и как хорошее средство для разработки больших программных комплексов. Правда, теперь голоса в поддержку этого языка звучат уже тише, примерно так: "Ада, по крайней мере, не хуже Си". МО США, учтя свой главный промах - отсутствие объектов, в соответствии с современными требованиями к технологии разработки программ выработало новый стандарт языка ISO/IEC 8652:1985(E). Он описывает версию языка Ada95 (или Ada9X). Самое интересное, что эта версия является первой в мире объектно-ориентированной системой программирования, на которую международный стандарт введен, по-видимому, в приказном порядке (с Си++ так пока не получается). Кроме того, в языке была улучшена система согласования видимости данных в спецификациях модулей и добавлены средства повышения эффективности функционирования параллельных задач.

МО США довольно ревниво относится к своему дорогому детищу и даже зарегистрировало слово "Ada" как свою торговую марку. Правда, впоследствии вместо торговой марки МО решило использовать "Ada" как свой внутренний сертифицированный знак. Без особой радости МО США относится и к появлению коммерческих версий этого языка. Конечно, никто не вправе запретить вам написать свой компилятор, но, чтобы он получил коммерческое признание, необходимо его соответствие военному стандарту, а тестирование осуществляется только комитетом AJPO при МО США, который очень строго проверяет соответствие компилятора множеству требований, в том числе, очевидно, и чисто политических.

Тем не менее различные версии Ады можно получить, как это обычно бывает с языками программирования, на халяву, то бишь даром, только не пиратским способом, а просто freeware-версии, и, конечно, за деньги.

Из свободно распространяемых версий в первую очередь необходимо выделить компилятор GNAT - GNU Ada95. В рамках проекта GNU (свободно распространяемого ПО) его можно получить в исходных текстах. Работать он может и на компьютере с одним процессором, только надо, чтобы операционная система поддерживала многозадачность. Это может быть, например, какая-нибудь версия UNIX или OS/2. Что касается MS DOS - догадайтесь сами. Однако если очень хочется запустить сотню-другую параллельных процессов на вашей персоналке под MS DOS 6.x, то вполне можно попробовать Ada/Ed - компилятор и интерпретатор версии языка 1987 года, который, впрочем, совершенно несовместим со стандартом и не имеет ряда существенных элементов.

Если есть деньги, то ситуация, конечно, облегчается. В пределах месячной зарплаты среднего российского программиста можно приобрести, например, FirstAda и написать систему управления холодильником. Более дорогие системы для Windows, OS/2 или UNIX, сертифицированные МО США, вы можете попытаться приобрести непосредственно у фирм-разработчиков, коих насчитывается около десятка.

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

Было бы весьма интересно узнать, не велись ли в СССР работы над языками, предназначенными для решения похожих военных задач. Или наши спецы писали только на Ассемблере?

Язык Ада более-менее всегда был на слуху. На школьной скамье мы посмеивались над его названием, в университетской программе он сухо упоминался в качестве языка, разработанным по требованию Министерства Обороны США, но непосредственно до изучения синтаксиса или применения дошли лишь редкие программисты. Отсюда сложилось ошибочное мнение, что язык Ада функционирует лишь на прошловековом оборудовании, и потребность в нем пропадет вместе с естественной модернизацией.

И это очень далеко от правды.

Появление

В 70-х годах 20 века, в разгар холодной войны, Министерство Обороны США устроило международный конкурс, по результатам которого необходимо было выбрать язык программирования для использования в военных целях. Однако ни один из существующих языков не устроил членов комиссии, поэтому путём долгого выбора и нескольких доработок на свет появился язык Ада, названный так в честь Ады Лавлейс . Далее началась многолетняя волокита со стандартизацией, регистрация торговой марки, запреты на кастомные трансляторы и прочие действия, отбившие желание массовой аудитории работать с Ада.

На выходе же получился достаточно нишевый язык, предназначенный для сложных вычислительных систем с повышенными требованиями по безопасности. Опять-таки из-за требований Пентагона и строгих стандартов взаимодействие с другими языками программирования крайне затруднено, поэтому до недавнего времени перейти на массовый рынок у Ада практически не было шансов. Но с удешевлением техники и усложнением используемых технологий такой шанс появляется.

Синтаксис

Изначально, Ада - модульный язык программирования со строгой типизацией, унаследовавший синтаксис от Паскаль и Алгол. Если вы учили первый в школе или институте, то глядя на «Hello, World!» должны испытать ностальгию:

with Ada.Text_IO;

Procedure Hello is
use Ada.Text_IO;
begin
Put_Line("Hello, world!");
end Hello;

Одним из главных требований к языку была надёжность его использования. Соответственно, это повлекло за собой строгие ограничения по структуре, типам, написанию и многому другому. Кроме того, почти все ошибки здесь улавливаются на этапе компиляции.

Другим требованием была максимальная читаемость кода в распечатанном виде, что повлекло за собой тяжеловесность полученного языка и невысокую гибкость.

Более поздние стандарты частично решали эти проблемы, но по понятным причинам, они не сделали из Ада второй Python.

Ада сегодня

Вопреки мнению широкой аудитории, язык Ада до сих пор активно используется, не только в США и не только в военной индустрии. Так, например, часть ПО самолёта-амфибии Бериев Бе-200 написана как раз на Ада. Поезда метрополитена без машиниста, которые курсируют во многих крупных городах (Париже, Лондоне, Нью-Йорке и др.), также используют оборудование с американским военным языком.

И да, конечно, среди «клиентов» была военная и гражданская авиация (в частности, Боинг-777), ракеты, шаттлы, спутники - в общем, практически весь перечень бесконечно дорогой американской продукции, предполагающей высшую степень безопасности.

Перспективы

Язык Ада критиковался и в момент появления, и когда стало понятно, что грандиозные планы Пентагона не вполне стыкуются с реальностью, и тем более сейчас. Причиной тому является неудобный язык, сложность стандартов, написанных в 1983 и 1995 году, а также недальновидность разработчиков, лишивших язык Ада массовой аудитории.

Впрочем, почти 40 лет активного использования подтверждают, что пожалуй со своей главной задачей язык Ада справился - с его помощью всё ещё можно создавать надёжный код для систем с повышенными требованиями к безопасности. При этом, если вы посмотрите на современные тенденции, количество таких изделий неуклонно растёт: автомобили с автопилотом и гибридными двигателями, частные космические аппараты и малые летательные средства, скоростные поезда, а также огромное количество встраиваемых систем. Всё это потенциальное поле для деятельности языка Ада. Добавьте сюда тот факт, что стандарт был серьёзно переработан и модернизирован в 2012 году, инструменты для работы тоже выходят и обновляются .

Таким образом, язык Ада - это и фрагмент из не самого приятного прошлого, и один из инструментов для строительства яркого будущего. И он точно не собирается на пенсию.

Язык программирования Ада родился в середине 1970-х, когда министерство обороны США и министерство обороны Британии решили заменить сотни специализированных языков программирования для встроенных вычислительных систем, всё чаще использовавшихся в военных проектах. Язык Ада разрабатывали так, чтобы это был единственный язык, способный работать на всех этих встроенных системах, и при этом обеспечивавший надёжность и быстродействие уровнем не хуже специализированных.

После обновления от 1995 года язык приспособили для систем общего назначения, добавив объектно-ориентированное программирование, не теряя из вида ключевые ценности – надёжность, простоту поддержки и эффективность. Сегодня написанное на Ада ПО формирует основу не только военного оборудования, но и коммерческих проектов в сфере авионики и систем управления воздушным трафиком. Код на Ада управляет такими ракетами, как Ариан-4 и 5, многими спутниками, и бесчисленным количеством других систем, в которых небольшие сбои могут иметь серьёзные последствия.

Возможно, Ада подойдёт и для использования в вашем следующем встроенном проекте.

Планирование военного качества

Чтобы выбрать новый язык программирования, минобороны собрала «рабочую группу языков высшего порядка» [High Order Language Working Group (HOLWG)], состоявшую из военных и учёных экспертов, в задачи которой входило составление списка запросов и выбор языков-кандидатов. В итоге были составлены т.н. "запросы Стилмана ":

Главными пунктами запросов были:

  • Гибкая схема работы общего назначения, адаптирующаяся к нуждам встроенных вычислительных приложений.
  • Надёжность. Язык должен способствовать проектированию и разработке надёжных программ.
  • Лёгкость поддержки. Код должен быть читаемым, а программные решения - ясными.
  • Лёгкость производства эффективного кода. Должна быть возможность легко определять неэффективные конструкции.
  • Отсутствие ненужной сложности. Семантическая структура должна быть последовательной, и минимизировать количество концепций.
  • Независимость от машины. Язык не должен быть привязан к каким-то деталям ОС или оборудования.
  • Полное определение. Все части языка должны быть полностью и недвусмысленно определены.
Завершался отчёт мнением, что первая линия обороны от проблем с ПО заключается в том, чтобы не давать программистам совершать ошибок. Устраняя возможности сделать малозаметную ошибку, к примеру, через неявные преобразования типов или другие опасные конструкции, мы автоматически делаем код безопаснее и облегчаем его поддержку.

Группа заключила, что хотя среди существовавших на тот момент языков ни один не подходил для нужд минобороны, было вполне реально создать новый язык, подходящий под все указанные вопросы. Четырём проектировщикам получили это сделать. Промежуточный процесс выбора подобрал два наиболее подходящих метода работы, и в итоге лишь один язык победил в конкурсе и получил название "Ада ".

Встроенная по умолчанию защита

Система типов в Аде не просто строгая – её иногда называют сверхстрогой, поскольку она не позволяет никакого неявного приведения типов. Возьмём, к примеру, этот отрывок кода на С:

Typedef uint32_t myInt; myInt foo = 42; uint32_t bar = foo;
Это допустимый код; он откомпилируется, запустится и выдаст очевидный результат, обозначающий ответ на главный вопрос жизни, вселенной и всего такого. В Аде так не получится:

Type MyInt is Integer; foo: MyInt; bar: Integer; foo:= 42; bar:= foo;
Компилятор выдаст ошибку, поскольку Integer и MyInt – это не одно и то же. Главное преимущество такого подхода в том, что если программист потом изменит определение типа, тысячи неявных приведений типа по всей базе кода не взорвут программу. Вместо этого нужно явно приводить типы – это пропагандирует хороший код, предотвращая смешение типов, которые «достаточно схожи».

Любой программист, вязнувший в болоте из смеси стандартных определений типов C, Linux и Win32, может оценить по достоинству отсутствие необходимости рыться в бесчисленных страницах документации и плохо отформатированного кода, чтобы понять в каком из typedef или макросе содержится реальное определение чего-то, что только что помешало компиляции или вылезло при отладке.

Ада добавляет дополнительные слои защиты в проверках на этапах компиляции и запуска. В Аде программист должен явно указывать закрывающие операторы для блоков и границы, в которые должно укладываться значение переменной. Ада не определяет стандартные типы вроде int или float, а требует, чтобы программист с самого начала создал типы с определённым диапазоном. Это верно и для строк – за исключением неограниченных строк, у всех строк длина фиксирована.

На этапе работы можно проверить ошибки типа неверного доступа к памяти, переполнения буфера, выхода за установленные пределы, ошибки ±1, доступа к массиву. Затем их можно безопасно обработать, вместо того, чтобы ронять всё приложение.

Ада реализует модель ссылочных типов вместо низкоуровневых указателей. Каждый ссылочный тип обрабатывается пулом памяти, либо заданным по умолчанию, либо определённым программистом при необходимости работы с более экзотическими реализациями памяти типа NUMA. Программисту никогда не приходится обращаться к памяти напрямую, он должен использовать обработчик пула памяти.

Наконец, компилятор или программа во время исполнения решает, как передавать данные в функцию или из неё. И хотя направление передачи каждого параметра указывать нужно (‘in‘, ‘out‘, или ‘in out‘), но итоговое решение о том, передаются ли данные через регистры, кучу или по ссылке, принимает компилятор или программа во время выполнения, но не программист. Это предотвращает проблемы с переполнением стека.

Ravenscar profile и диалект SPARK являются подмножествами Ады, причём последний концентрируется на контрактах. Со временем особенности этих подмножеств перенесли в спецификацию основного языка.

Программирование на языке Ада сегодня

ANSI установила спецификацию Ada 83 в 1983. Тогда только-только вышел Intel 80286, а процессору Motorola 68000 было всего четыре года. Это была заря домашних компьютеров, а также неуклюжий переход из 1970-х в 80-е, когда популярность микроконтроллеров начала расти. Представьте себе микроконтроллер Intel 8051 и его потрясающие 4 кБ EPROM и 128 Б оперативной памяти.

Популярные сегодня микроконтроллеры во много раз более мощные по сравнению с теми, что были в 1983. Можно взять любой ARM, AVR, RISC-V, и т.п. (или Lego Mindstorms NXT kit) и начать под него разработку при помощи одинаковых инструментальных средств на базе С. Неудивительно, что популярный компилятор GNAT Ada основан на GCC. Также в разработке в рамках проекта DragonEgg находятся инструментальные средства на базе LLVM.

Существуют две версии инструментальных средств Ады на основе GCC. Вариант AdaCore поддерживается коммерчески, однако имеет свои особенности. Вариант от Free Software Foundation, естественно, свободен, и по функциональности сравним с AdaCore.

Для лёгкого старта используйте либо GNAT Programming Studio IDE (GPS), идущее в комплекте с AdaCore (копия на Github), или пишите код в текстовом редакторе и компилируйте его вручную, или при помощи Makefiles. Инструментарий тут немного посложнее, чем у С или С++, однако разработку облегчает утилита gnatmake, включающая в себя все инструменты, и работающая примерно как GCC.

Пример небольшого , но нетривиального проекта на Аде, написанного вашей покорной слугой в виде парсера аргументов командной строки. Там вы найдёте Makefile, находящийся в папке проекта ada/, где определяются папки, в которых можно найти файлы спецификации пакетов (.ads) и сами пакеты (.adb).

Эти файлы примерно соответствуют файлам с заголовками и кодом от С и С++, однако имеют и важные отличия. В отличие от С, у Ады нет препроцессора, и она не объединяет код и заголовки для создания компилируемых файлов. Вместо этого идёт ссылка на название пакета, указанное в спецификации. Название файла.ads тоже не обязано совпадать с названием пакета. Это даёт большую гибкость и предотвращает распространённые в С проблемы с циклической зависимостью или необходимостью линковки заголовков в определённом порядке.

Куда двигаться далее

Скачав инструментарий GNAT, запустив GPS или Vim/Emacs, и некоторое время посмотрев на мигающий курсор на пустой странице, вы можете задуматься над тем, с чего начать. К счастью, мы недавно освещали проект на основе Ады с использованием ядра PicoRV32 RISC-V. Он использует распространённый ICE40LP8K CPLD, который поддерживают инструментарии FPGA с открытым кодом, например, Yosys.

В плане документации есть вводные статьи для начинающих , рассчитанные на разработчиков Java и С++, справочник по AdaCore , справочник на WikiBooks , и, конечно же, документация Programming in Ada 2012 . Это, возможно, наиболее полные справочники, за исключением документации Ada 2012 Language Reference Manual (LRM) на 945 страниц.

Язык Ада, пусть и довольно редкий для любителей программирования, является полностью открытым языком с надёжными средствами разработки с коммерческой поддержкой, и используется для создания ПО для всего, от межконтинентальных баллистических ракет и F-15 до прошивок медицинских устройств. Хотя это довольно сложный язык, если выходить за базовые пределы, он должен определённо входить в список языков, которые вы когда-либо использовали в своих проектах – пусть даже и для того, чтобы ваше резюме выглядело покруче.

Понравилась статья? Поделиться с друзьями: