В более ранней статье я представил краткую историю алгебраических языков программирования высокого уровня, начиная с Fortran 58 и 60, вплоть до начальной разработки языка Algol в период с 1958 по 1960 год. В этой статье я собираюсь обсудить некоторые технические особенности Algol, которые повлияли на последующие языки программирования высокого уровня, такие как BCPL и, в конечном итоге, C.

Типы данных

В языках программирования высокого уровня до Algol не было типов данных. Переменные просто стали существовать, присвоив им значение, целое или действительное. В Фортране был небольшой набор данных, в котором целые числа должны были определяться с использованием букв I, J, K, L, M и N. Любая другая существующая переменная была бы реальной переменной.

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

Однако, как я обнаружил, читая историю Algol, до Algol 68 не существовало реальной теории типов данных, встроенной в язык.

Вот пример использования типов данных в Algol 60. Этот фрагмент программы считывает некоторые значения с карты данных (!):

begin real E, R, L, C
  read(E, R, L, C)
  …
end

Объявления переменных

В самых ранних версиях Fortran и других языков высокого уровня до Algol не было объявлений переменных. Переменные просто возникли, когда им было присвоено значение. Разработчики Algol поняли, что компиляторы (и люди, читающие программы) будут более эффективными, если переменные будут объявлены до их использования.

Вот пример Fortran, демонстрирующий, как переменные использовались в тех ранних версиях языка:

  READ(5,1) X
1 FORMAT (F10.5)
  A=X/2
2 B=(X/A+A) / 2
. . .

Вот пример Algol, демонстрирующий, как переменные объявляются перед их первым использованием:

begin real a, b, x, Ans1, Ans2, Ans3
Read (a,b,x)
  begin real temp
  temp := sqrt(a + b × x)
  . . .

В Algol переменные объявлялись в начале блока, что упрощало определение объема каждой переменной.

Точка с запятой как терминатор оператора

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

Вот пример, когда два массива объявлены в одной строке:

Boolean array N[10:20]; array ABC [1:9, 0:10];

Другой пример - когда процедура объявляется вместе с переменной, которая является параметром процедуры. Вот код:

real procedure arcsin(x); real x;

Блоки

Одной из наиболее важных функций, которые Algol привнес в языки программирования, является блочная структура. Предыдущие языки программирования не могли идентифицировать блоки, кроме как косвенно по меткам и операторам goto, так что операторы внутри цикла DO в Фортране можно было рассматривать как блок, но они не были идентифицированы как таковые.

Алгол изменил это, сначала определив полную программу как блок. Чтобы пометить блок, Алгол использовал ключевые слова begin и end. В качестве примера приведем короткую программу на языке Algol 60, отображающую «Hello World!»:

begin
  file rmt (kind = remote);
  write(rmt, <"Hello World!">);
end

В этом коде есть некоторые особенности ввода-вывода Algol, которые я не обсуждал, но вы можете понять смысл кода.

Вы также можете создавать блоки внутри блоков, чтобы программа на языке Algol имела область видимости блока. Например:

begin real a;
  a := 1.11;
  begin real a;
    a := 2.22;
  end
end

Переменная a во внутреннем блоке является отдельной переменной от переменной a во внешнем блоке. Конечно, современные программисты вполне довольны областью видимости блока, но в 1960 году это была новая концепция.

Цикл for

В предыдущих языках высокого уровня единственным типом цикла был цикл DO. Вот пример типичного цикла Fortran DO:

  DO 8 I=1,500
8 READ (5,7) N(I)

Цикл DO loop Фортрана имел одно существенное ограничение: DO цикл разрешал только цикл арифметической прогрессии. В приведенном выше коде, например, циклы должны были выполняться от 1 до N. Не было возможности написать цикл DO, который работал бы до тех пор, пока не будет выполнено какое-либо условие, как это разрешено в do while или do until loop в более современных языках программирования.

Алгол решил эту проблему, разработав цикл for. Цикл Algol for очень гибкий. Вы можете записать это как цикл арифметической прогрессии, как в этом примере, который я нашел в старом учебнике по Алголу:

begin real R, S
for R := 20 step 5 until 200 do
  begin
    S :- if R<200 then 17000–0.485×R↑2
    Print(R, S)
  end
end

Здесь управляющая переменная R начинается с 20 и останавливается, когда достигает 200, перемещаясь с шагом 5 для каждой итерации цикла. Цикл for в приведенном выше примере также можно было бы записать так:

for R := 200 step -5 until 20 do
  ...

Третий способ написать цикл for в Algol - это написать его как цикл while, чтобы цикл выполнялся не арифметически, а в зависимости от условия. Вот пример начала цикла for на основе while:

for R := 15, R + 5 while R ≤ 200 do
  . . .

Рекурсия

Алгол был первым языком программирования высокого уровня, реализовавшим рекурсию. Рекурсия была предложена для Алгола в 1959 году профессором Джоном Маккарти, тогда работавшим в Массачусетском технологическом институте. Неудивительно, что Маккарти был одним из тех, кто предложил добавить рекурсию к языку, поскольку в то же время он разрабатывал язык программирования Lisp, для которого рекурсия была основным методом итераций.

Вот пример того, как факториальная процедура, по сути рекурсивный алгоритм, реализована в Algol 60:

real procedure factorial (n);
if n = 1 then factorial := 1 else
  factorial := n × factorial (n-1);

А вот современный перевод на C ++:

int factorial(int n){
  if (n == 1) {
    return 1;
  }
  else {
    return n * factorial(n-1);
  }
}

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

Структуры данных не учитывались

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

Влияние Алгола

Как я упоминал в начале этой статьи, Algol, вероятно, самый влиятельный язык, у которого не было большой пользовательской базы, особенно в Соединенных Штатах. Сразу после того, как был разработан Algol, набирали обороты несколько других языков, включая Fortran и COBOL. IBM разработала PL / I в конце 1960-х, и этот язык взял часть пользовательской базы от Algol. К тому же, как известно большинству, к началу 1970-х годов C стал популярным языком и помог ограничить использование Algol.

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

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

использованная литература

В своем исследовании я использовал две книги. Они есть:

История языков программирования, Ричард Л. Вексельблат, изд. Глава 3: Сессия Алгола. 1981

Руководство по программированию на алгоритмах, Дэниел Д. Маккракен. 1962 г.