Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Хорошие идеи взгляд из Зазеркалья.doc
Скачиваний:
7
Добавлен:
04.11.2018
Размер:
151.55 Кб
Скачать
          1. Сложный оператор for в языке Algol

Разработчики языка понимали, что некоторые часто встречающиеся случаи повторения лучше было бы выражать в более точной форме, чем в комбинации в операторами goto. Они ввели оператор for, особенно удобный при работе с массивами, как в следующем примере:

for i := 1 step 1 until n do a[i] := 0

Если не обращать внимание на довольно неудачный выбор слов step и until, идея кажется замечательной. К несчастью, она была заражена плохой идеей мнимой общности. Последовательность значений, которые могла принимать управляющая переменная i, можно было задавать в виде списка:

for i := 2, 3, 5, 7, 11 do a[i] := 0

Более того, элементы списка могли быть выражениями общего вида:

for i := x, x+1, y-5, x*(y+z) do a[i] := 0

Кроме того, допускались различные формы элементов списка:

for i := x-3, x step 1 until y, y+7, z

while z < 20 do a[i] := 0

Естественно, светлые головы быстро придумали патологические случаи, демонстрирующие абсурдность конструкции:

for i := 1 step 1 until i+1 do a[i] := 0

for i := 1 step i until i do i := -i

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

          1. Передача параметров по имени в языке Algol

Процедуры и параметры в языке Algol обладали намного большей общностью, чем в более ранних языках, таких как Fortran. В частности, параметры выглядели так, как полагается в традиционной математике функций, где действительный параметр текстуально замещает формальный параметр [2]. Например, при наличии объявления

real procedure square(x); real x; square := x * x

вызов square(a) должен точно интерпретироваться как a*a, а вызов square(sin(a)*cos(b)) - как sin(a)*cos(b) * sin(a)* cos(b). Для этого требуется вычислять синус и косинус дважды, что, весьма вероятно, не соответствует желанию программиста. Для предотвращения этого часто встречающегося, вводящего в заблуждение случая разработчики языка Algol постулировали вторую разновидность параметра - параметр-значение. Это означало, что должна была выделяться локальная переменная x' и инициализироваться значением действительного параметра x. При наличии объявления

real procedure square(x); value x;

real x; square := x * x

приведенный выше вызов интерпретировался бы как

x' := sin(a) * cos(b); square := x' * x',

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

Пусть имеется объявление

real procedure sum(k, x, n);

integer k, n; real x;

begin real s; s := 0;

for k := 1 step 1 until n do s := x + s;

sum := s

end

Тогда сумма a1 + a2 + : + a100 записывается просто как sum(i, a[i], 100), внутреннее произведение векторов a и b - как sum(i, a[i]*b[i], 100), а гармоническая функция - как sum(i, 1/i, n).

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

Мы могли бы просто удалить из языка параметры, передаваемые по имени. Однако эта мера была бы слишком решительной и поэтому является неприемлемой. Например, это препятствовало бы присваиванию параметрам для возврата результатов вызвавшей процедуре. Однако это соображение привело к замене в более поздних языках Algol W, Pascal и Ada средства передачи параметров по имени на средство передачи параметров по ссылке. Сегодня идея звучит следующим образом: относитесь скептически к чрезмерно сложным средствам и возможностям. В самом крайнем случае их стоимость должна быть известна пользователям до выпуска, публикации и распространения языка. Эта стоимость должна быть соразмерна преимуществам, получаемым при включении в язык данного средства.