Мальчиковый компилятор
Компилятор с языка POP-2, уже у нас тут упоминавшийся, оказывается, мальчиковый.
Демонстрируем на простом примере
Пишем (синтаксис уж какой в POP-2 нажили, извиняйте; комментарии на самом деле пишутся не так).
На выходе получаем, как иожидали надеялись, 9 8 7 6 5 4 3 2 1 0 0.
Ишь ты, замыкания работают, рекурсивно вызываются, the whole nine yards!
Теперь делаем рефакторинг: внесем функциональность C внутрь A, различая, что нужно делать, по знаку аргумента k:
Казалось бы, результат должен быть тот же самый. Но увы: 9 -2 -2 9.
Так что прав был Кнут: нельзя давать детям писать компиляторы со сложных языков. Ерунда получится.
Демонстрируем на простом примере
Пишем (синтаксис уж какой в POP-2 нажили, извиняйте; комментарии на самом деле пишутся не так).
function C x; x() end; # просто функция, которая вызывает свой аргумент
function A k; # целый аргумент
function B;
k-1 -> k; # декрементируем переменную из замыкания
k => # печатаем ее
if k > 0 then
C(B) # дадим себя вызывать рекурсивно
close
end;
B(); # стартуем
k => # печатаем, как снаружи видно
end;
A(10);
На выходе получаем, как и
Ишь ты, замыкания работают, рекурсивно вызываются, the whole nine yards!
Теперь делаем рефакторинг: внесем функциональность C внутрь A, различая, что нужно делать, по знаку аргумента k:
function A k x; # целое и функция
function B;
k-1 -> k; # декрементируем переменную из замыкания
k => # печатаем ее
if k > 0 then
A(-1, B) # дадим себя вызывать рекурсивно
close
end;
if k > 0 then
B() # стартуем
else
X() # вызываем аргумент
close;
k => # печатаем, как снаружи видно
end;
A(10, 0); # при положительном первом аргументе второй игнорируется
Казалось бы, результат должен быть тот же самый. Но увы: 9 -2 -2 9.
Так что прав был Кнут: нельзя давать детям писать компиляторы со сложных языков. Ерунда получится.