История изменений
Исправление monk, (текущая версия) :
За это и любим.
Вот именно. А если взять функциональные языки, то в Racket хвостовая оптимизация затирает стек. В результате пишешь
(define (f x) (+ (g x) (h x) (k x) 1))
(f 'bad)
получаешь ошибку car: contract violation. На стеке только f, + и car. Потому что в одной из g, h, k хвостовой операцией оказалась операция, у которой хвостовой операцией была car.
В Haskell ещё жёстче. Чистая ленивая функция просто хранит вычисления в данных.
y = f x
z = g y
print $ head z
Получаешь ошибку *** Exception: bad data со стеком print, head. Хотя сама ошибка bad data возвращена из f или g.
Поэтому в функциональных языках отладчик считается почти бесполезным, а вместо него контракты и модульные проверки (unit tests). В Haskell и Typed Racket ещё и типизация.
Исходная версия monk, :
За это и любим.
Вот именно. А если взять функциональные языки, то в Racket хвостовая оптимизация затирает стек. В результате пишешь
(define (f x) (+ (g x) (h x) (k x) 1))
(f 'bad)
получаешь ошибку car: contract violation. На стеке только f, + и car. Потому что в одной из g, h, x хвостовой операцией оказалась операция, у которой хвостовой операцией была car.
В Haskell ещё жёстче. Чистая ленивая функция просто хранит вычисления в данных.
y = f x
z = g y
print $ head z
Получаешь ошибку *** Exception: bad data со стеком print, head. Хотя сама ошибка bad data возвращена из f или g.
Поэтому в функциональных языках отладчик считается почти бесполезным, а вместо него контракты и модульные проверки (unit tests). В Haskell и Typed Racket ещё и типизация.