Кложуребесие-1
Раз уж меня потянуло на лытдыбр про языки программирования и их реализацию.
Лет 10 назад в массы наконец пошла идея замыканий и лямбд (которая надо сказать придумана и реализована в районе 1960 года - в лиспе). После чего замыкания начали тащить туда куда надо и туда куда не надо. Вообще идей в этой области которые не были бы придуманы до 1970 года мало, а до 1985 (когда вчерне сформировалась современная наука про типы данных) - исчезающе мало.
Насчет "замыканий где не надо" - типовой пример - callback'и для итераторов.
NB: Замыкание конструкция не слишком хорошая уже потому, что требует динамической аллокации памяти, причем в варианте с сборкой мусора. В "общего назначения" языках это в общем щас просто оверхед, но в real time, и всякой ембежке с ограниченными ресурсами это источник крайнего геморроя, а в mission critical задачах как правило просто не приемлемо, потому что никаких способов обеспечить гарантированно надежную работу такого рода динамической памяти не существует.
Собственно одной из милых особенностей А-60 и была возможность писать функции типа (пример надуманный, для простоты)
И потом вызывать ее
Никаких замыканий и динамических аллокаций это не требовало. Все на стеке.
Серьезным недостатком такой конструкции являлась возможность написать функцию высшего порядка: например суперпозицию:
Недостаток это потому что написать что-то вроде:
Можно - но скорее всего получится seg fault. Потому что структура представляющая композицию останется на освобожденном стеке и как только она затрется - ...
Статическим анализом отделить все корректные ситуации от некорректных тоже невозможно, а хороших способов динамического контроля тоже вроде нет.
Это на сам деле было серьезным недстатокм А-68, равно как и легкость с которой в нем можно получить висячую ссылку на переменную в стеке.
[продолжение следует]
Лет 10 назад в массы наконец пошла идея замыканий и лямбд (которая надо сказать придумана и реализована в районе 1960 года - в лиспе). После чего замыкания начали тащить туда куда надо и туда куда не надо. Вообще идей в этой области которые не были бы придуманы до 1970 года мало, а до 1985 (когда вчерне сформировалась современная наука про типы данных) - исчезающе мало.
Насчет "замыканий где не надо" - типовой пример - callback'и для итераторов.
NB: Замыкание конструкция не слишком хорошая уже потому, что требует динамической аллокации памяти, причем в варианте с сборкой мусора. В "общего назначения" языках это в общем щас просто оверхед, но в real time, и всякой ембежке с ограниченными ресурсами это источник крайнего геморроя, а в mission critical задачах как правило просто не приемлемо, потому что никаких способов обеспечить гарантированно надежную работу такого рода динамической памяти не существует.
Собственно одной из милых особенностей А-60 и была возможность писать функции типа (пример надуманный, для простоты)
proc loop = (int l, int u, proc (int) void body) void:
begin
for i from l to u do body (i) od
end
И потом вызывать ее
int sum := 0; loop (1, 10, (int i) void: sum +:= i*i)
Никаких замыканий и динамических аллокаций это не требовало. Все на стеке.
Серьезным недостатком такой конструкции являлась возможность написать функцию высшего порядка: например суперпозицию:
proc compose = (proc (real) real f, proc (real) real g) proc (real) real:
(real i) real: f (g (x))
Недостаток это потому что написать что-то вроде:
proc (int) int sin cos = compose (sin, cos);
...
real x = sin cos (10.0);
Можно - но скорее всего получится seg fault. Потому что структура представляющая композицию останется на освобожденном стеке и как только она затрется - ...
Статическим анализом отделить все корректные ситуации от некорректных тоже невозможно, а хороших способов динамического контроля тоже вроде нет.
Это на сам деле было серьезным недстатокм А-68, равно как и легкость с которой в нем можно получить висячую ссылку на переменную в стеке.
[продолжение следует]