Перейти к содержимому

Где он использовался язык ада

  • автор:

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

Язык программирования Ada принадлежит к числу модульных. Для него характерны строгая типизация, синтаксис, ведущий происхождение от языков Паскаль и Алгол. Назван в честь Ады Лавлейс, математика первой половины XIX в., которую часто называют первым в мире программистом в связи с ее работами по созданию алгоритмов для вычислительной машины Чарльза Бэббиджа.

Рисунок 1. Логотип языка Ada. Автор24 — интернет-биржа студенческих работ

Статья: Язык программирования Ada

Поможем написать реферат за 48 часов

История развития языка Ada

Ada появился в США на рубеже 1970-1980-х гг. как язык программирования для бортовых систем управления военными объектами. Он не принадлежит к числу самых популярных языков программирования, поскольку не рассчитана на создание эффектных пользовательских приложений. В этом языке слабо развиты такие стороны, как функционал, связанный с пользовательским интерфейсом, взаимодействие с базами данных. Тем не менее, язык Ada нельзя назвать устаревшим. На нем в США разрабатывается программное обеспечение для военной промышленности, авиации, энергетики и других инфраструктурных систем. Это нишевый, но, тем не менее, активно используемый продукт.

Язык Ada был создан для решения конкретных задач, причем предметная область его применения была заранее хорошо исследована и описана. Группа его разработчиков сформировалась на основе тщательно организованного международного конкурса.

Стабильный релиз Ada был принят в качестве национального стандарта, а затем был принят и соответствующий стандарт ISO. Высокая степень стандартизации, в частности, предопределила повсеместное единообразие языка, отсутствие диалектов, а также 100%-ю обратную совместимость кода при появлении новых версий.

«Язык программирования Ada» ��
Помощь эксперта по теме работы
Решение задач по учебе за 24 часа
Реферат по этой теме за 48 часов
Замечание 1

Попытки включить Ada в систему ГОСТ предпринимались в конце 1980-х гг. и в СССР. На этом языке велась разработка ПО для лайнера Ил-96-300, амфибии Бе-200, космической станции Альфа. Он использовался и в некоторых других проектах государственного уровня. Ada довольно активно применяется для создания промышленных и транспортных систем во Франции (беспилотные поезда метро), Японии, Китае.

На сегодняшний день актуальной является версия Ada-2012.

Специфика Ada

Можно назвать следующие особенности Ada, многие из которых являются уникальными:

  • асинхронность реализована на уровне синтаксиса;
  • любые компиляторы Ada порождают идентичный бинарный код (стандарт языка предполагает, что каждый компилятор должен выдержать ряд тестов);
  • полная совместимость версий поддерживается на протяжении всего времени существования языка.

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

Ada соответствует парадигме объектно-ориентированного программирования. Есть даже мнение, что идеи классов в C++ позаимствованы из реализации Ada-83. При этом спецификация языка Ada существенно компактнее, чем у конкурирующих продуктов.

Несмотря на то, что Ada появился как язык для корпоративных целей, существует его некоммерческая версия, распространяемая под свободной лицензией — полнофункциональная платформа GNAT.

Практика программирования на Ada

Рисунок 2. Разработка на зыке Ada в IDE Wind River. Автор24 — интернет-биржа студенческих работ

Программа «Hello, World!» выглядит на Ada следующим образом:

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

Рассмотрим более сложную программу — функцию, сравнивающую две строки без учета регистра, т.е. строки «Привет!» и «ПрИвЕт!» считаются одинаковыми, а строка «Превед!!» — отличающейся от них.

 -- Объявляем функцию, получающую в качестве аргументов сравниваемые строки -- и возвращающую истинное или ложное значение, в зависимости от того, -- одинаковы ли их буквы в соответствующих позициях. -- Прописные буквы считаются равными строчным. function Equal_Ignore_Case (S : String; -- Сравниваемая строка 1 T : String) -- Сравниваемая строка 2 return Boolean is -- Находим разность между адресами начальных знаков сравниваемых строк. O : constant Integer := S'First - T'First; begin if T'Length /= S'Length then return False; -- Если длины строк не совпадают - дальнейшая проверка не имеет смысла. else for I in S'Range loop -- Сравниваем буквы в соответствующих позициях в цикле. if To_Lower (S (I)) /= -- Стандартная функция To_Lower превращает любые буквы в строчные, чтобы можно было сравнивать. To_Lower (T (I + O)) then -- Если буквы в одной и той же позиции не равны даже после приведения к одинаковому регистру, -- значит строки не равны. return False; end if; end loop; end if; return True; -- Различающихся букв не найдено, возвращаем истинное значение. end Equal_Ignore_Case; 

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

Язык программирования Ада родился в середине 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 до прошивок медицинских устройств. Хотя это довольно сложный язык, если выходить за базовые пределы, он должен определённо входить в список языков, которые вы когда-либо использовали в своих проектах – пусть даже и для того, чтобы ваше резюме выглядело покруче.

Ада (язык)

АДА (англ. Ada) — универсальный язык программирования высокого уровня, ориентированный на применение в системах реального времени и предназначенный для автоматизации задач управления процессами и/или устройствами, например, в бортовых (корабельных, авиационных) компьютерах.

Язык Ada разработан по инициативе Министерства обороны США в 1980-х годах, назван в честь математика Ады Августы Лавлейс (1815-1851). При проектировании языка в первую очередь внимание акцентировалось на надежности и эффективности — язык создавался специально для разработки больших программных комплексов реального времени для встроенных систем, к которым предъявляются высокие требования надежности; в первую очередь, это системы военного предназначения.
Язык Ада основан на идеях структурного программирования и обеспечивает разработку сложных многомодульных программ, высокую степень машиннонезависимости и переносимости. Ада содержит такие возможности паскалеподобных языков, как определение типов, общие управляющие структуры и подпрограммы, а также достижения теории языков программирования, полученные после 1970 года. Язык поддерживает логическую модульность, для которой данные, типы и подпрограммы — все могут быть пакетами. Физическая модульность достигается раздельной компиляцией. Язык Ада поддерживает программирование в реальном масштабе времени за счет механизмов распараллеливания и обработки исключений. Системное программирование поддерживается за счет доступа к системно-зависимым параметрам и управлением точностью при представлении данных.

К 1974 году в структурах Министерства обороны США использовалось множество различных языков программирования. Это увеличивало затраты времени и средств на разработку новых систем, на техническую переподготовку персонала. Руководители министерства пришли к выводу о необходимости использования единого языка программирования. В 1975 году был согласован список требований к такому языку. Ни один из существовавших на тот момент языков программирования (таких, как Паскаль, ALGOL-68 или PL/1) не соответствовал выдвинутым требованиям. Поэтому в 1977 году было принято решение создать новый язык, и был объявлен конкурс на его разработку. Из всех предложений было отобрано четыре (каждое из которых являлось расширением Паскаля), для последующего пересмотра и доработки. Позже, для дальнейшего уточнения, из них отобрали два, и в финале выбрали проект, представленный компанией Cii-Honeywell Bull. Этому языку было дано название Ada (изначально язык назывался DOD-1).

В 1983 году был принят стандарт языка ANSI/MIL-STD-1815A, а в 1987 — международный стандарт ISO 8652. В 1987 году появились и первые эффективные трансляторы Ады. Стандарт ISO был пересмотрен в начале 1995 года (ANSI/ISO/IEC 8652). Новый стандарт исправлял многие упущения и недостатки оригинального языка, и дополнял его многими новыми полезными свойствами, такими, как процедурные типы, базированные указательные типы (то есть указатели на нединамические объекты), иерархические библиотеки, дополнительные средства управления параллелизмом, множество стандартных библиотек. Кроме того, в Аде-95 появилась поддержка объектно-ориентированного программирования.
Следующий стандарт получил неформальное название Ada-2005, несмотря на то, что в 2005 году он еще не был принят. Ада-сообщество приняло решение отойти от традиции в неофициальном назывании стандарта по году опубликования, поскольку в 2005 году были согласованы все его основные параметры. В язык добавились множественное наследование, префиксная форма доступа к методам объектов, более гибкие ссылочные типы, улучшенное управление задачами и большое количество новых стандартных библиотек. Кроме того, Ада-2005 удовлетворяет стандарту ISO/IEC 10646 (2003), что позволяет использовать в названиях идентификаторов (имена переменных, функций) буквы русского и греческого алфавитов.
Ада считается единым языком программирования как для вооруженных сил США, так и для НАТО.

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

Ада используется в высших учебных заведениях США и Западной Европы, как основа для изучения программирования, часто применяется в научно-исследовательских разработках. Ада-программа управляет движением поездов без машинистов в парижском метрополитене. Ряд фирм специализируются на разработке компиляторов, различных библиотек и инструментальных средств, охватывая широкий спектр аппаратных платформ и операционных систем. Кроме коммерческих средств разработки, существуют свободно доступные версии компиляторов, такие как ObjectAda от Aonix или GNAT от Ada Core Technologies.

Ада — самый стандартизованный язык программирования. Международный стандарт был принят до того, как появились первые работающие версии трансляторов, что позволило избежать несовместимости различных диалектов Ады. Ада превосходит СИ и C++ по строгости типизации данных, гибкости раздельной компиляции, возможности создания высоконадежных систем реального времени, наличием средств строгого контроля за параметрами функций и выходом индексов за границы массивов (80% ошибок, возникающих при создании программ на C/C++, связано именно с этим) и машинно-независимого представления двоичных значений (вместо битовых операций выполняется выборка полей записи). При этом Ада прозрачна семантически и синтаксически, поэтому изучать ее проще, чем Java.

Ада уступает C/C++ в поддержке новых операционных систем, а также в наличии средств сопровождения, отладки и формирования графических интерфейсов. Но в стандарт языка входят автоматически формируемые спецификации для стыковки с другими языками программирования, и на практике вместе с Адой применяются математические библиотеки Фортрана, системные функции, написанные на Си, классы Java для работы с Интернет. Поэтому встречаются многоязыковые интегрированные среды разработки, поддерживающие другие зыки, кроме Ады, например, IBM Rational Ada Developer (C/C++/Ada).

В Аде реализована как автоматическая сборка мусора (как в Java или C#), так и возможность непосредственного высвобождения памяти (как в C, C++, Pascal). Как и в C/C++, в Аде доступны богатые низкоуровневые средства. Встроенная поддержка многозадачности является уникальной особенностью языка программирования Ада, которая выгодно отличает его от большинства языков программирования. Эта поддержка обеспечивается не расширениями или внешними библиотеками, а с помощью стандартизированных средств, которые встроены непосредственно в язык программирования.

  • ТЕХНИКА » Компьютеры и интернет » Программное обеспечение » Программирование » Языки программирования
  • НАУКА » Математика, кибернетика » Вычислительная математика. Программирование
  • ТЕХНИКА » Основные отрасли техники » Электроника и вычислительная техника. Информатика
  • ТЕХНИКА » Компьютеры и интернет » Программное обеспечение

Язык программирования Ада

Язык программирования Ада

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

Несмотря на свое американское происхождение, в разгар холодной войны ада использовалась и в СССР. На нее даже существует ГОСТ, который стоит почитать ради одной только терминологии: например, исключения там «возбуждаются».

Мифы о языке программирования Ада

Миф об устаревшем языке опровергается одним запросом к поисковику: последняя редакция вышла в 2012 году. Если судить о сложности языка по внешним признакам, то все тоже не так страшно: спецификация ады содержит чуть менее тысячи страниц, тогда как спецификация C++ — около 1400 страниц.

Миф о низкой производительности пошел со времен первой редакции 1983 года, когда массовому пользователю были доступны разве что ZX Spectrum и IBM PC с i8086, на которых любой современный язык был бы медленным. Ада компилируется в машинный код, и любители успешно пишут на ней для Arduino с ATmega328 и прочих микроконтроллеров.

Распространенный миф о том, что по вине ады упала ракета Ariane 5 в 1996 году, нужно рассмотреть отдельно. Ракета действительно упала из-за ошибки, но проблема была в другом: компьютер, который управлял траекторией полета, был взят из Ariane 4 без изменений, несмотря на то что Ariane 5 поддерживала более широкий диапазон траекторий. Хуже того, проверка на выход значений за возможный диапазон была намеренно отключена, поэтому, когда навигационный компьютер выдал недопустимую с точки зрения Ariane 4 команду, закончилось все предсказуемо. От этой проблемы, увы, не смог бы защитить ни один язык или какое-либо программное решение вообще. Сама Ariane 4 совершила 113 успешных полетов из 116 за свою историю, а Ariane 5 уже 96 успешных из 101.

Языки и надежность программ

Ракеты — это предельный случай требований к надежности программ, но и в куда более приземленном коде ошибки могут обойтись пользователям очень дорого. В уязвимостях вроде Heartbleed можно винить разработчиков, но разве смысл компьютеров не в том, чтобы автоматизировать нудную работу и позволить людям сосредоточиться на творческих задачах?

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

В первую очередь, конечно, инструмент не должен делать работу человека сложнее, чем она и так есть. Когда Министерство обороны США разрабатывало требования к новому языку для конкурса, в котором победила ада, они в первую очередь упомянули об этом. Документ с требованиями известен как Steelman и содержит, например, такую фразу: «Одни и те же символы и ключевые слова не должны иметь разные значения в разном контексте». Почти вся первая часть рассказывает о необходимости однозначности синтаксиса, удобочитаемости кода, определенности семантики и поведения (вспомним i ++ + ++ i ).

Но и требования к выразительным средствам для своего времени там передовые. Любопытно, что обработка исключений и средства обобщенного программирования были еще в первой редакции, задолго до С++.

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

Реализации Ады

Далеко идти за реализацией не придется: компилятор ады включен в GCC под названием GNAT (GNU New [York University] Ada Translator) и доступен на всех системах, где есть GCC.

Если у тебя Linux или FreeBSD, можешь ставить из стандартных репозиториев. В Debian/Ubuntu пиши apt — get install gnat , в Fedora — dnf install gnat .

Компания AdaCore предоставляет коммерческую поддержку для GNAT и занимается другими связанными проектами. Например, там работают над графической средой разработки GNAT Programming Studio (GPS). AdaCore является, по сути, основным разработчиком GNAT и распространяет две версии компилятора: сертифицированный GNAT Pro за деньги и GNAT Libre бесплатно, но с рантайм-библиотекой под лицензией GPLv3.

Использование GPLv3 не позволяет разрабатывать программы с любыми лицензиями, кроме GPL. Однако в дистрибутивы свободных ОС включена версия FSF GNAT, лицензия которой делает исключение для библиотек. Так что ее можно использовать для разработки программ с любой лицензией.

Есть еще проприетарные реализации ады вроде Irvine и Green Hills, но для пользователей вне аэрокосмической отрасли и ВПК они малодоступны и особого интереса не представляют.

Первая программа

Традиционный Hello world дает очень мало представлений о языке, поэтому для первой программы мы возьмем что-нибудь более реалистичное, например алгоритм Пардо — Кнута. Дональд Кнут и Луис Трабб Пардо предложили его как раз для этой цели.

  1. Прочитать одиннадцать чисел со стандартного ввода.
  2. Применить к ним всем некоторую функцию и вывести результаты в обратном порядке.
  3. Если применение функции вызвало переполнение, вывести сообщение об ошибке.

С помощью такой программы уже можно показать, как определить и заполнить массив, как написать и вызвать функцию, как использовать циклы и условия и как использовать ввод-вывод. Опять же, если Hello world у любого программиста выглядит почти одинаково, то тут уже есть возможность применить разные способы и показать разные возможности языка.

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

Вот наша программа. Ее нужно будет сохранить в файл с названием pardo_knuth . adb . Несовпадение имени файла с именем основной процедуры, которая служит точкой входа, вызовет предупреждение компилятора.

— Trabb Pardo — Knuth program
with Ada . Text_IO ; use Ada . Text_IO ;
with Ada . Strings . Unbounded ;
with Ada . Text_IO . Unbounded_IO ;
procedure Pardo_Knuth is
package UIO renames Ada . Text_IO . Unbounded_IO ;
package US renames Ada . Strings . Unbounded ;
type Small_Float is new Float range — 100.0 . . 100.0 ;
package Float_IO is new Ada . Text_IO . Float_IO ( Small_Float ) ;
function Square ( X : Small_Float ) return Small_Float is
return X * X ;
end Square ;
Input : Array ( 0 . . 10 ) of Small_Float ;
Index : Integer : = 0 ;
Debug : Boolean : = False ;
if Debug then
Put_Line ( «Pardo-Knuth program is started» ) ;
Put_Line ( «Welcome to Pardo-Knuth program written in Ada!» ) ;
Input_Loop : while Index < = Input 'Last loop Raw_Value : US.Unbounded_String; Put ("Enter a value: "); UIO.Get_Line (Raw_Value); Input(Index) := Small_Float' Value ( US . To_String ( Raw_Value ) ) ; Index : = Index + 1 ; when Constraint_Error = >
Put_Line ( «Incorrect value! Enter a number from -100 to 100» ) ;
end loop Input_Loop ;
Put_Line ( «Results:» ) ;
for I in reverse Input ‘ Range loop
— No declarations
Float_IO . Put ( Square ( Input ( I ) ) , Exp = > 0 , Fore = > 4 , Aft = > 2 ) ;
when Constraint_Error = > Put_Line ( «Overflow occured!» ) ;
end Pardo_Knuth ;

Скомпилировать программу можно командой gnatmake pardo_knuth . adb . Созданный исполняемый файл будет называться pardo_knuth .

Замечу, что синтаксис ады нечувствителен к регистру символов. В стандартной библиотеке GNAT по каким-то причинам укоренился непривычный Смешанный _ Регистр , и я следую стилю стандартной библиотеки. Но если кому-то он кажется неэстетичным, можно использовать любой другой по вкусу — на работу программ это не повлияет.

Заголовок программы

Перед началом программы находится комментарий. Все комментарии в аде однострочные и начинаются с символов — .

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

Ключевое слово use делает модули видимыми в пространстве имен программы. Например, после with Ada . Text_IO мы могли бы вызывать процедуру Ada . Text_IO . Put_Line по ее полному имени. Но мы использовали конструкцию use Ada . Text_IO , которая импортирует все публичные символы этого модуля в наше пространство имен, поэтому мы можем вызвать Put_Line , Put и New_Line без имени модуля.

Распространенные функции из Ada.Text_IO

  • Put_Line — выводит данные с символом новой строки на конце.
  • Put — выводит данные без переноса строки.
  • New_Line — выводит символ переноса строки.

Модули Ada . Strings . Unbounded и Ada . Text_IO . Unbounded_IO предназначены для работы со строками произвольной длины. По умолчанию строки в аде фиксированной длины, что не всегда удобно для обработки пользовательского ввода. Строки произвольной длины легко преобразовать в фиксированные, что нередко приходится делать, потому что многие функции стандартной библиотеки ожидают именно фиксированные.

Дальше мы определяем основную процедуру, которая служит точкой входа в нашу программу. Желательно, чтобы ее имя совпадало с именем файла, хотя и не обязательно. В аде есть различие между функциями и процедурами: функции могут возвращать значения, а процедуры — только изменять переменные, которые им передают в аргументах.

Внутри нашей процедуры мы переименовали модули с длинными именами для удобства, аналогично import foo as bar в Python. Теперь мы сможем вызывать, к примеру, Ada . Strings . Unbounded . To_String как US . To_String .

Алгоритм Пардо — Кнута требует сообщать пользователю о переполнении. Чтобы упростить появление переполнений, мы создали намеренно ограниченный тип-диапазон Small_Float , с возможными значениями от -100.0 до +100.0. Для таких типов у ады есть встроенные проверки: присвоение недопустимой константы в коде приведет к ошибке компиляции, а появление недопустимых значений в ходе работы программы вызовет исключение.

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

Строка package Float_IO is new Ada . Text_IO . Float_IO ( Small_Float ) заслуживает отдельного внимания. Это уже не простое переименование, а специализация обобщенного (generic) модуля для нашего типа Small_Float .

В аде нет аналога printf , что бывает очень неудобным, но для ее целей выглядит оправданным — типобезопасный форматированный вывод возможен только в языках с совершенно другой системой типов. В С printf ( «%d» , «foo» ) вызовет segmentation fault, в Go аналогичная конструкция приведет к ошибке времени выполнения — ни то ни другое в критичной по надежности программе не принесет пользователю особой радости. Поэтому хотя бы для относительного удобства авторы стандартной библиотеки ады написали несколько модулей для ввода и вывода значений распространенных типов.

Для алгоритма Пардо — Кнута нам требуется определенная пользователем функция. Функции и процедуры в аде могут быть вложенными, чем мы и воспользуемся и определим простейшую функцию Square в заголовке основной процедуры нашей программы. Тип возвращаемых значений указан с помощью return Small_Float . Это обязательная часть синтаксиса — еще раз отметим, что создать функцию, которая не возвращает значений, невозможно, для этой цели нужно использовать процедуры.

Далее идут объявления переменных. В аде все переменные должны быть объявлены перед использованием. Глобальных переменных в смысле C в ней нет, их область видимости всегда чем-то ограничена: пакетом (то есть модулем), процедурой, функцией или блоком declare , который мы рассмотрим позже. Видимые внутри всей процедуры переменные должны быть объявлены в ее заголовке, что мы и сделаем.

С помощью Input : Array ( 0 . . 10 ) of Small_Float мы объявляем массив Input , где будут храниться введенные пользователем значения. Мы используем диапазон индексов от 0 до 10, но вообще индексы могут быть любыми, в том числе отрицательными, например от -5 до 5. Еще вместо явных индексов можно было бы создать целочисленный тип-диапазон и сослаться на него.

Переменная Index , очевидно, будет использоваться как индекс элемента массива в цикле — мы могли бы объявить ее позже, но для демонстрации оставим ее здесь. Ее начальное значение — ноль, присваивается одновременно с объявлением переменной. Все присваивания в языке производятся с помощью оператора : = , оператор = используется только для проверки равенства.

Для оператора «не равно» используется символ /= . Вполне вероятно, что Haskell заимствовал его из ады.

Переменная Debug будет служить только для демонстрации условного оператора. Она имеет тип Boolean с возможными значениями True и False . Условный оператор в аде требует выражения логического типа и никакого другого, привычное в C-подобных языках if ( 0 ) вызовет ошибку — никакие неоднозначности, связанные с интерпретацией произвольных значений в логическом контексте, в этом языке возникнуть не могут.

Заголовок основной процедуры нашей программы наконец закончился — переходим к ее телу.

Тело программы

Мы начинаем программу с довольно глупой демонстрации условного оператора — выводим другое приветствие, если переменная Debug выставлена в True . Этого не произойдет, если не поменять ее начальное значение руками, но суть не в этом, а в синтаксисе. Условный оператор имеет вид if < условие >then < высказывание >else < высказывание >end if . Часть про end if обязательна. Вообще, в аде почти нигде нельзя написать просто end , не указав, что именно здесь закончилось. Читать такой исходный код куда проще, хоть писать и дольше, но правильная настройка редактора решает эту проблему. В объявлении функции Square мы уже видели, что она кончается словами end Square , хоть и не заостряли на этом внимание.

Компилятор удаляет заведомо недостижимый код, как внутри if Debug , из исполняемых файлов, но только после проверки всех типов и всего прочего, что можно проверить на этапе компиляции. Такие константы — стандартный способ реализации feature toggles и отладочного кода, куда более безопасная альтернатива условной компиляции с помощью препроцессора. Конечно, такой подход не работает для машинно зависимого кода, который просто не скомпилируется вне его целевой платформы. В этом случае можно использовать внешний препроцессор — gnatprep.

Для циклов можно даже указать имена: цикл ввода переменных объявлен с помощью Input_Loop : while . . . loop и закончен end loop Input_Loop . Перепутать границы вложенных циклов при таком подходе очень сложно. Синтаксис циклов радует своим единообразием — циклы с предусловием и циклы с параметром отличаются только словами перед ключевым словом loop .

Бесконечный цикл

Бесконечный цикл создать очень просто: не указывать ни тип, ни условия.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *