Ленивая оценка - это общее свойство чисто функциональных языков программирования, чтобы «вернуть назад производительность», она работает довольно просто, вы только оцениваете выражение, когда оно вам нужно. Например, рассмотрим в Haskell
if x == 1 then x + 3 else x + 2
В строгом (жадным) оценки, если х действительно равно двум, то х + 3 вычисляется и возвращается, иначе х + 2, в Haskell, ничего подобного не происходит, х + 3 только состоит к выражению, к примеру, у меня есть:
let x = if x == 1 then x + 3 else x + 2
Ну, тогда я храню, что в переменной, но что, если я никогда никогда никогда никогда не использовать эту переменную из-за некоторых других условными хмм? Я потратил очень дорогое целое дополнение на мой процессор. (хорошо, на практике вы не выигрываете на этом, но вы получаете идею с большими выражениями)
Тогда возникает вопрос, почему нет все 10 все языки ленивый? функциональные языки, выражения гарантированно не имеют побочных эффектов вообще. Если бы они были, мы должны были бы оценить их в правильном порядке. Вот почему на большинстве языков они с нетерпением оцениваются. В языках, где выражения не имеют побочного эффекта, нет риска в ленивой оценке, поэтому логичным выбором является отмена производительности, которую они, как правило, теряют на других территориях.
Другим интересным побочным эффектом является то, что if-then-else в Haskell действительно является функцией типа Bool -> a -> a -> a
. В Haskell это означает, что он принимает один аргумент типа Boolean, другого из любого типа, другого типа того же типа, что и первый, и снова возвращает этот тип. Вы не сталкиваетесь с бесконечной оценкой различных ветвей управления, потому что значения оцениваются только тогда, когда они необходимы, что обычно находится в самом конце программы, когда огромное выражение составлено и затем оценивается для окончательного результата, отбрасывая все, что, по мнению компилятора, не требуется для конечного результата. Например, если я делю исключительно сложное выражение, его можно просто заменить на «1» без оценки обеих частей.
Разница видна на схеме, которая традиционно строго оценивается, но ленивый вариант называется Ленивый схема, на схеме (display (apply if (> x y) "x is larger than y" "x is not larger than y"))
является ошибкой, поскольку if
не является функцией, это специализированный синтаксис (хотя некоторые говорят, что синтаксис не является особенным в Scheme вообще), поскольку он не обязательно оценивает все его аргументы, иначе у нас не хватит памяти, если мы попытались вычислить факториал, например. В Lazy Scheme это работает отлично, потому что ни один из этих аргументов не оценивается вообще, пока функция действительно не нуждается в результатах для продолжения оценки, например дисплее.
Комментарий к дате голосования – Earlz
Здесь вы задаете много разных вопросов: 1) преимущества ленивой оценки, 2) производительность, 3) как она реализована. Я бы рекомендовал разделить их на 3 отдельных вопроса. – Juliet