Показать сообщение отдельно
Старый 10.02.2017, 22:24   #44  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Цитата:
А в функциональном языке ленивое выражение (+ a b) будет в стеке n раз ))))
и вот я совсем не уверен, что оптимизация сработает с таким выражением.

И именно эта ленивость и позволяет избавиться от повторных вычислений, не так ли? ленивость и отсутствие побочных эффектов.
Нет! При чем тут ленивость и при чем тут побочные эффекты.

Половина функциональных языков программирования принципиально не поддерживают ленивость. Вот от слова "вообще". Нет ее там. А в тех языках где есть - я 10 раз подумаю, прежде чем ее использовать. Потому что в языках с поддержкой ленивых вычислений надо четко представлять, где и в какой момент это вычисление произойдет. А иначе оно произойдет в самый непоходящий для пользователя момент (в виде проблем с производительностью). Нет в моем примере никакой ленивости.

Теперь побочные эффекты. Их здесь нет, но если этот код переписать на C# или Java - их тоже не появится. Им просто не откуда здесь взяться. Ну и вообще, если говорить про функциональные языки программирования - то из тех, что используются в production я знаю только 1 - haskell. Все остальные функциональные языки программирования допускают побочные эффекты.

Цитата:
А в функциональном языке ленивое выражение (+ a b) будет в стеке n раз ))))
В языке с поддержкой хвостовой ресурсии - не будет.

Я же описал выше, что произойдет
При очередном рекурсивном вызове три параметра со стека будет сниматься и три добавляться. По сути - будет просто происходить их замена.

Цитата:
можешь рассказать подробнее как "это" работает?
Да вроде уже максимально подробно. Смотри - при вызове функции ты на стек помещаешь 4 вещи: адрес возрата и три параметра. Теперь происходит очередной рекурсивный вызов. По идее компилятор должен положить еще 4 параматера. Но он умный и видит, что после того, как ты вернешься из этого рекурсивного вызова то, что до этого лежало на стеке тебе просто уже не понадобится. Ну просто потому что после рекурсивного вызова уже нет никаких вычисленией. А значит текущие значения a, b и count можно смело снять со стека, заменив на новые.

Все равно не понятно ?