> был очень витиеватый цикл for, который мог быть даже while

Вот именно: while-ом можешь ты и быть, но for-ом все равно быть обязан.
Хочешь не хочешь, а for и «управляющая переменная» обязательны для
цикла.  Даже когда переменная никак не нужна и нигде не используется.
Поэтому написал, что оператор цикла в Алголе-60 единственный.

А в Алголе-68 не так: там никакая часть не обязательна.  Можно
счетчик использовать, можно и условие, но все на выбор.

(Еще более это развито в ПЛ/1 — в нем голова кружится от возможностей
написать цикл, как впрочем и почти все остальное.  Цикл ПЛ/1 скопирован
в REXX, который и ныне здравствует.)

> Впрочем, и польза от разумной структурности тоже вполне обоснована

Конечно, это само собой, никто не спорит.
Проблема в том, что принято только пользу подчеркивать, а о вреде
умалкивают.  Ниже приведу пример в этом духе.

> Читал как-то отечественную книжку 80-х годов про Симулу-67. Редкий метод в 
> ней обходился без goto

Если и была такая книжка, не думаю что она показательна в данном
отношении.  Книг по программированию на русском у меня много, а
покупал их как раз в это время.  (Тогда у нас их продавали в большом
количестве, очень недорого, и у меня накопилась библиотека приличного
размера.)  Но злоупотребление goto нигде не встречал.

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

> … в конце 70-х Владимир Леонидович Топунов учил что, если предполагаемый 
> эффект от оптимизации меньше 10%, то не следует даже браться...

Роджер Хюи, автор (совместно с К.Айверсоном) и главный реализатор
языка J (наследника APL) утверждает, что никакую оптимизацию не стоит
делать, если приведет к улучшению не больше чем в два раза!

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

Приведу пример: процедура проталкивания в пирамиду.  У меня она
получается так:

void sift(T a[], unsigned n, unsigned p) {
  unsigned j;
  T x = a[p];
  for (;;) {
    if (j=2*p+1, j+1<n && a[j]<a[j+1])  ++j;
    if (j>=n || a[j]<=x)  break;
    a[p] = a[j];  p = j;
  }
  a[p] = x;
}

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

А это вариант Н.Вирта из его известной книги — текст то ли на Модуле,
то ли на Обероне:

PROCEDURE sift(L, R: INTEGER);
  VAR i, j: INTEGER; x: Item;
BEGIN i := L; j := 2*i+1; x := a[i];
  IF (j < R) & (a[j] < a[j+1]) THEN j := j+1 END;
  WHILE (j <= R) & (x < a[j]) DO
    a[i] := a[j]; i := j; j := 2*j+1;
    IF (j < R) & (a[j] < a[j+1]) THEN j := j+1 END
  END;
  a[i] := x
END sift;

Есть различия несущественные, но главная в моем понимании проблема
здесь — дублирование строк 4 и 7, только из желания избежать выхода
из тела цикла, быть «структурным».  Не знаю чем это может быть
полезным, для меня оно выглядит нелепо.  Хоть и из уст великих.
В самом первом варианте книги (на Паскале) Вирт использовал goto для
выхода из цикла и дублирования действий нет.  Потом «эволюировал».

Ответить