Статья
Версия для печати
Обсудить на форуме
История языков программирования. Часть 2.



Algol 60

Этот язык, пожалуй, самый загадочный из всех, упомянутых в данной статье. Он воплотил в себе все передовое, что было наработано теоретиками и практиками к моменту своего появления (конец 50-х годов), однако был встречен промышленностью и военными довольно прохладно и так и не получил должного признания.
Однако несмотря на это, роль Algol 60 (в дальнейшем - Algol) в истории языков программирования огромна, потому что идеи, заложенные в этом зыке, получили дальнейшее развитие и породили целую плеяду так называемых "алголоподобных языков", среди которых я бы в первую очередь выделил Algol 68 и Pascal. Эти языки получили значительное большее распространение (а уж историю Pascal иначе, как триумфом, и не назовешь). Кроме того,  эти языки в процессе своего развития в свою очередь стали основой для еще более развитых и мощных языков. Впрочем, о них поговорим в свое время, а сейчас вернемся к Algol'у.
Своеобразие роли Algol'а в информатике заключается еще и в том, что этот язык стал алгоритмическим, в отличие от подавляющего большинства других языков, являющихся языками программирования. Эти понятия зачастую путают, но на самом деле это далеко не синонимы. Алгоритм можно реализовать практически на любом языке программирования, будь то FORTRAN, FORTH или APL. Особенность Algol'а заключается в том, что этот язык обладал непревзойденными (на время своего появления, конечно) выразительными средствами для строгого и изящного представления алгоритма (свойства, которые Дейкстра ценил превыше всего). В результате, не получив признания в промышленности как язык программирования, Algol стал стандартом де-факто для публикации алгоритмов в научной среде. Так, например, на страницах Communications of the ACM долгие годы ему отдавалось предпочтение перед другими языками.
Лично мне Algol среди прочих языков программирования представлялся всегда в роли латыни среди естественных языков. Латынь ныне - мертвый язык, используется на практике в ограниченной среде лишь медиками, биологами и т.п. Однако от нее произошли многие современные языки романской группы, и классическое образование лингвиста не будет полноценным без тщательного изучения латыни. Жаль, что педагоги от информатики нынче почему-то пренебрегают им.
Algol разрабатывался комитетом, специально созданным для разработки языка высокого уровня общего назначения, пригодного для научных вычислений (хотя в промышленности в то время царила эйфория, навеянная успехом FORTRAN'а, в академической среде находились люди, способные заглянуть дальше и видящие, в какой тупик со временем неизбежно заведет FORTRAN).
Интересно, что впервые в истории язык был определен формально. По иронии судьбы Algol, которому было предназначено противопоставить четкость и элегантность конструкций хаотичности и сумбурности FORTRANа, был описан посредством модификации Нормальной Формы Бэкуса (создателя FORTRANа). Нормальная Форма Бэкуса была доработана одним из членов комитета, Питером Науром, и в дальнейшем стала известна как Расширенная Форма Бэкуса-Наура (РБНФ). РБНФ оказалась настолько удобной формой описания синтаксиса формальных языков, что в дальнейшем практически все языки программирования стали описываться в этой нотации (еще один, косвенный вклад Algolа в развитие информатики). В частности, Дейкстра писал:
"Четвертый проект, о котором следует упомянуть, - это ALGOL 60. В то время как до сих пор программисты на FORTRANe продолжают осознавать свой язык в рамках конкретной реализации, с которой они работают - отсюда и избыток восьмеричных или шестнадцатеричных дампов, -  в то время как определение языка LISP остается причудливой смесью описаний, что означает язык и как работает его механизм, знаменитый "Отчет об алгоритмическом языке ALGOL 60" - это продукт усилий по продвижению абстракции на один жизненно важный шаг дальше и по определению языка программирования способом, независимым от реализации. Кое-кто может возразить, что в этом отношении его авторы столь преуспели, что им удалось посеять серьезные сомнения, может ли он вообще быть реализован! "Отчет" великолепно демонстрирует мощь формального метода BNF, теперь справедливо известного как Backus-Naur-Form (Формализм Бэкуса-Наура, или Форма Бэкуса-Наура  прим. перев), и силу тщательно сформулированного английского языка, по крайней мере в изложении тех, кто владеет им столь же блестяще, как Питер Наур. Я думаю, справедливо будет заметить, что очень немногие документы, столь же короткие, как этот, оказали такое глубокое влияние на компьютерное сообщество. Легкость, с которой в последующие годы слова "ALGOL" и "ALGOL-подобный" использовались как незащищенные торговые марки, чтобы придать часть своей славы незрелым проектам, порой имеющим весьма слабое отношение к предмету, - это порой обескураживающий комплимент его основам. Сила BNF как определяющего механизма в ответе за то, что я расцениваю как одну из слабостей языка: переработанный и не слишком систематический синтаксис мог бы теперь быть втиснут всего в несколько страниц. Располагая столь мощным инструментом, каким является BNF, "Отчет об алгоритмическом языке ALGOL 60 должен был бы быть значительно короче". (Цитата из статьи "Смиренный программист" (EWD340)).
Как и в большинстве других языков программирования, программа на Algolе состоит из главной программы и набора подпрограмм. При их построении используются блоки - наборы описаний и последовательности операторов, ограниченные "скобками" begin и end. Структуры данных, созданные внутри блока, локальны в его пределах и при выходе из блока уничтожаются. Таким образом можно управлять временем жизни данных и областью видимости их идентификаторов.
Определение подпрограммы состоит из заголовка, в котором указываются имя подпрограммы и перечисляются имена и типы ее формальных параметров, и тела, которое представляет собой просто блок. Динамическое выделение памяти для переменных в блоке позволяет эффективно использовать рекурсию.
К особенностям языка можно отнести механизмы передачи параметров подпрограммам. Их два: хорошо известная передача по значению и довольно экзотическая передача по имени. В большинстве случаев она эквивалентна общеизвестной передаче по ссылке, однако между этими механизмами имеются довольно тонкие различия, которые в некоторых случаях могут привести к неожиданным сюрпризам (более подробное описание выходит за рамки данного обзора).
Очень важно, что блоки могут образовывать вложенные структуры, т.е. внутри блока может быть вложен блок, в него - другой блок и т.д. Важной особенностью языка является также то, что блок является разновидностью оператора - составным оператором и может быть употреблен везде, где допустим обычный оператор. В сочетании с развитым набором структурных управляющих конструкций (условный оператор, цикл со счетчиком, циклы с пред- и постусловием) это позволяет строить хорошо структурированные программы, обходясь без оператора go to, столь нелюбимого сторонниками ясности и элегантности программ.
К сожалению, типы и структуры данных в языке гораздо менее разнообразны, чем управляющие конструкции. Пожалуй, это и определило дальнейшую судьбу языка, применявшегося в первую очередь для научных вычислений. Из типов имеются логический, целочисленный и вещественный, а из структур данных - лишь однородный массив. Правда, массивы являются динамическими, что позволяло эффективно управлять распределением памяти.
Пример программы на Algolе:
Код:
begin
procedureSUM(V,N);valueN;
realarrayV;
integerN;
begin
integerI;
realTEMP;
TEMP:=0;
forI:=1step1untilNdo
TEMP:=TEMP+V[I];
SUM:=TEMP
end;

integerK;

START:
inreal(1,K);
ifK>0then
begin
realarrayA[1:K];
inarray(1,A);
outreal(2,SUM(A,K));
gotoSTART
end
end

Algol 68
В процессе использования Algol 60 выявлялись недочеты, допущенные при проектировании языка. В 1962 году под эгидой Международной федерации по обработке информации (International Federation for Information Processing, IFIP) был создан новый комитет, задачей которого являлись исправление и совершенствование Algol. В составе нового комитета оказалось немало ученых с мировым именем, в частности, Эдсгер Дейкстра, Никлаус Вирт и Тони Хоар.
Один из авторов разработки, Кеес Костер, впоследствии написал мемуары, в которых достаточно детально обрисовал как сам процесс, так и дух, царивший в то время в комитете. (Они были опубликованы среди прочих материалов 11 февраля 1993 года на конференции "25 лет Algolу 68" Леннартом Беншопом).
Одной из очевидных слабостей предшествующей версии был признан слабо развитый ввод/вывод. Пренебрежение к этому моменту объяснялось академической направленностью языка: для ученых главный интерес представляет сам алгоритм, а в каком виде будут представлены выходные данные - дело второстепенное. Для промышленных применений такой подход не годился, поэтому одной из приоритетных задач была объявлена разработка механизма ввода/вывода.
Вторым важным моментом, который нельзя было сбрасывать со счетов, была сильная позиция FORTRANа. Язык, проигрывающий FORTRANу по эффективности на этапе выполнения программы, не мог претендовать на успех.
Главенствующую роль в разработке играл А. Ван Вейнгаарден, директор Математического центра Амстердама. Будучи по образованию и роду деятельности чистым математиком, порой он, пользуясь своим авторитетом, принимал решения, с которыми не соглашались программисты-практики, что отложило свой отпечаток на получившийся в результате язык.
К сожалению, авторитарный стиль руководства ван Вейнгаардена нередко приводил к размолвкам в коллективе и даже стал причиной выхода Хоара и Вирта из команды. О том, как тяжела была эта потеря для команды, можете судить по такому факту: предложения Вирта, не принятые комитетом, легли в основу языка Algol W, который впоследствии перерос в Pascal. Время в итоге расставило все по своим местам - сравните нынешнюю популярность Pascalя и Algolа 68. Или, что еще убедительнее, спросите программиста с опытом в несколько лет, что говорят ему фамилии Вирт и ван Вейнгаарден. Результат, думаю, скажет сам за себя.
Хотя, безусловно, язык Algol 68 содержал немало рациональных зерен (например, механизмы расширения языка, а также средства для параллельных вычислений), он получил ограниченное применение. В Европе и, в частности, в России были коллективы энтузиастов языка, активно использовавших его в работе, и язык на основе Algolа 68 стал некогда базовым для программирования отечественного компьютера "Эльбрус", но мировой известности язык так никогда и не получил.

PL/1
В середине 60-х годов корпорацией IBM был организован комитет, целью которого было создание многоцелевого языка программирования.
В это время на смену уникальным компьютерам, создававшимся в единичных экземплярах в стенах университетов и исследовательских лабораторий, стали приходить промышленные компьютеры серийного изготовления. Цены на оборудование быстро падали, соответственно ширился круг задач, решаемых при помощи компьютеров. Если раньше в связи с высокой ценой машинного времени эти задачи преимущественно носили характер расчетов для научных и военных целей, то теперь можно было позволить себе автоматизировать экономические расчеты, управление производством и т.п. Тем не менее в распоряжении программистов не было достаточно мощного языка, пригодного для решения подобных задач.
Новый язык должен был стать преемником FORTRANа, Algolа и COBOLа одновременно. Фактически он унаследовал все лучшее от своих предшественников. От FORTRANа ему достались раздельная компиляция подпрограмм, форматный ввод/вывод, блоки COMMON; от Algolа  блочная структура и структурированные управляющие конструкции; от COBOLа  неоднородные массивы и ввод/вывод, ориентированный на записи. Этот язык получил название PL/1.
Программа на PL/1 состоит из набора подпрограмм, структура которых аналогична подпрограммам Algol. Подпрограммы могут компилироваться раздельно, что облегчает создание библиотек подпрограмм и повторное использование кода. Параметры передаются по ссылке. Допускается рекурсия при вызове подпрограмм. Предусмотрены также средства для параллельного выполнения подпрограмм (задач) и взаимодействия между ними.
Типы данных включают многочисленные простые типы, битовые цепочки, цепочки литер, указатели, метки. Допустимы также структуры данных, представляющие собой однородные и неоднородные массивы. При помощи таких структур программист может образовывать новые типы данных. Для преобразования типов друг в друга имеется большой набор встроенных примитивов.
Язык обладает богатым набором математических и логических операций над числовыми данными. Для обмена данными с внешними файлами также предусмотрен развитый механизм.
Получившийся в результате этого проекта язык обладал большим набором средств, позволяющих применять его практически для любых прикладных задач. Но эта всеядность имеет обратную сторону: язык получился настолько громоздок и сложен, что, во-первых, оказалось чрезвычайно трудно разработать компилятор, дающий эффективный код; во-вторых, изучить язык в полном объеме - также нелегкая задача. Разработчики пошли на компромисс: начинающий программист может оперировать неким подмножеством языка, достаточным для его задач. Хотя в языке имеется огромное количество всевозможных опций, для каждой из них имеется значение по умолчанию, которое по замыслу разработчиков должно устроить начинающего пользователя. Впрочем, подобные решения, неявно принимаемые машиной за пользователя, рано или поздно непременно становятся источником недоразумений, причину которых понять не столь просто.
Если вкратце подвести итог развития PL/1, то в нескольких словах его можно сформулировать так. Язык имел весьма скромные средства для расширения, поэтому разработчикам пришлось предусмотреть все необходимое и включить его в язык. В результате получился огромный неуклюжий монстр, не получивший распространения вне продуктов IBM (в нашей стране он довольно широко использовался, будучи унаследованным вместе с семейством IBM 360/370 в виде ЕС ЭВМ).
Разумеется, эти свойства языка обусловили его крайне прохладный прием в академической среде. Вот, в частности, что писал Дейкстра в своей статье Смиренный программист (EWD340):
"Наконец, хотя этот предмет не из приятных, я должен упомянуть PL/1, язык программирования, документация которого обладает устрашающими размерами и сложностью. Использование PL/1 больше всего напоминает полет на самолете с 7000 кнопок, переключателей и рычагов в кабине. Я совершенно не представляю себе, как мы можем удерживать растущие программы в голове, когда из-за своей полнейшей вычурности язык программирования - наш основной инструмент, не так ли! - ускользает из-под контроля нашего интеллекта. И если мне понадобится описать влияние, которое PL/1 может оказывать на своих пользователей, ближайшее сравнение, которое приходит мне в голову, - это наркотик. Я помню лекцию в защиту PL/1, прочитанную на симпозиуме по языкам программирования высокого уровня человеком, который представился одним из его преданных пользователей. Но после похвал в адрес PL/1 в течение часа он умудрился попросить добавить к нему около пятидесяти новых "возможностей", не предполагая, что главный источник его проблем кроется в том, что в нем уже и так слишком уж много "возможностей". Выступающий продемонстрировал все неутешительные признаки пагубной привычки, сводящейся к тому, что он впал в состояние умственного застоя и может теперь только просить еще, еще, еще Если FORTRAN называют детским расстройством, то PL/1, с его тенденциями роста подобно опасной опухоли, может оказаться смертельной болезнью".
Пример программы на PL/1:
Код:
TEST:PROCEDUREOPTIONS(MAIN);
START:
GETLIST(K);
IFk>0THEN
BEGIN;
DECLAREA(K)DECIMALFLOAT;
GETLIST(A);
PUTLIST(INPUTIS,A,SUMIS,SUM(A));
GOTOSTART;
END;
SUM:PROCEDURE(V);
DECLAREV(*)DECIMALFLOAT,
TEMPDECIMALFLOATINITIAL(0);
DOI=1TODIM(V,1);
TEMP=TEMP+V(I);
END;
RETURN(TEMP);
ENDSUM;
ENDTEST;

APL
История появления этого языка довольно своеобразна. Когда его автор Кеннет Айверсон опубликовал его описание в 1962 году, он создавал не язык программирования, а компактную и выразительную нотацию, пригодную для записи математических алгоритмов. Поэтому синтаксис языка непривычен и своеобразен. Во-первых, он включает в себя большое множество символов, которые затруднительно было бы вводить с клавиатуры терминала, особенно алфавитно-цифрового: всевозможные стрелки, треугольники, квадраты, а также греческие буквы, верхние и нижние символы и т.д. Во-вторых, его синтаксис двумерный: стрелки символизируют передачу управления.
По замыслу автора, APL планировалось использовать для разработки алгоритмов, которые потом вручную реализовывались бы на одном из языков программирования. Показателем выразительности APL является тот факт, что на нем было реализовано полное описание аппаратуры компьютера IBM 360 (!).
Востребованность APL побудила Айверсона впоследствии реализовать язык на IBM 360. Эта версия стала известна как APL\360.
В отличие от своих современников, APL разрабатывался как интерактивный (диалоговый) язык. В то время как традиционным для того времени считался пакетный режим работы (перфорировался исходный текст программы, затем он компилировался, в случае отсутствия синтаксических ошибок программа запускалась на выполнение и выводила на печать результаты работы), работа с APL производилась в интерактивном режиме посредством терминала (либо специального, поддерживающего весь набор символов языка, либо общего назначения, в этом случае приходилось заменять графические символы специальными ключевыми словами, что существенно ухудшало читаемость программы). Вводимые программистом выражения немедленно выполнялись. Имелись также встроенные средства для редактирования текста.
Особенностью APL является также то, что его примитивы могут работать не только со скалярными величинами, но и с массивами. Таким образом, можно выполнять операции над векторами и матрицами без использования циклов, что придает программированию на APL особый, неповторимый стиль.
APL позволяет пользователю максимально быстро получить результат в течение сеанса работы за терминалом. Поэтому он получил распространение в инженерной среде. В то же время ряд свойственных ему ограничений (о которых более подробно ниже) не позволил APL стать универсальным языком программирования, пригодным для решения широкого круга задач.
Основной структурой данных, как уже упоминалось ранее, является массив. Элементами массива могут быть числа либо литеры, хотя многие операторы допускают использование лишь числовых массивов.
Довольно неожиданной чертой языка является то, что внутри выражений отсутствует иерархия. Еще более странным представляется вычисление значения выражения справа налево. Выражения строятся из примитивов, каждый из которых представляет собой функцию, возвращающую некоторое значение.
Подпрограммы могут иметь не более двух аргументов, передаваемых по значению, и лишь один результат. Впрочем, поскольку как аргументы, так и результат могут быть массивами, это ограничение не представляется чрезмерно строгим.
Компактный и емкий синтаксис APL зачастую позволяет записывать весьма сложные алгоритмы, выполняющие объемные и продолжительные вычисления, в виде одной-единственной строки.
К сожалению, ограничения набора символов сайта не позволяют привести пример программы на APL.


Автор: Alf
Версия для печати
Обсудить на форуме