Где разумное использование строгой оценки? - PullRequest
6 голосов
/ 16 марта 2009

Кажется, что на лениво оцененном языке есть множество примеров умных вещей, которые нельзя сделать в среде со строгой оценкой. Например, бесконечные списки в Haskell или , заменяющие каждый элемент дерева минимальным значением дерева за один проход .

Есть ли какие-нибудь примеры умных действий, выполняемых на строго оцененном языке, которые нелегко сделать на лениво оцененном языке?

Ответы [ 9 ]

8 голосов
/ 20 марта 2009

Основные вещи, которые вы можете легко сделать на нетерпеливом (строгом) языке, а не на ленивом:

  • Прогнозирование из исходного кода затрат времени и места на ваши программы

  • Разрешить побочные эффекты, включая постоянное обновление изменяемых массивов, что упрощает быструю реализацию некоторых алгоритмов

По моему мнению, главное преимущество языка программирования состоит в том, что ваш код гораздо проще заставить работать так, как вы хотите, и очень мало ловушек производительности, в которых небольшое изменение в коде приводит к огромным изменениям. в исполнении.

Сказав это, в целом я предпочитаю писать сложные вещи на Хаскеле.

5 голосов
/ 17 марта 2009

Нет; есть некоторые вещи, которые вы можете сделать * с помощью отложенной оценки (сокращение нормального порядка AKA или крайнее левое уменьшение), которые вы не можете сделать с помощью строгой оценки, но не наоборот.

Причина этого заключается в том, что ленивая оценка является в некотором роде «наиболее общим» способом оценки, который известен как:

Теорема вычислительной адекватности : Если некоторый порядок оценки завершается и дает конкретный результат, то отложенная оценка также завершается и дает тот же результат.

* (обратите внимание, что мы не говорим об эквивалентности по Тьюрингу здесь)

4 голосов
/ 16 марта 2009

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

2 голосов
/ 11 мая 2009

Наиболее очевидное использование лени в повседневном языке - это оператор if, в котором выполняется только одна ветвь условного выражения.

Противоположностью чисто нестрогого (ленивого) языка был бы чисто строгий язык.

Существует, по крайней мере, один случай, когда выгоден «чисто строгий», а именно предикация ветвей .

Грубый парафраз связанной статьи:

Давным-давно в мире процессоров инструкции по выполнению были загружены при тестировании состояния ветвления. В какой-то момент были добавлены конвейеры инструкций, чтобы сократить время загрузки. Недостатком было то, что ЦП не знал, какую ветку ему нужно загрузить, поэтому он по умолчанию загружает одну. Если ветвь пошла другим путем, конвейер остановился бы, пока загружался код для другой ветки.

Решение состоит в том, чтобы загрузить обе ветви, выполнить обе ветви, тогда результат условного запроса скажет вам, какой результат ветви сохранить, а какой выбросить. Тогда вы не получите трубопровода в стойло.

Это мой любимый (только?) Пример использования чисто строгого языка.

1 голос
/ 09 июня 2010

Программы «Здравствуй, мир» приходят на ум или все, что связано с побочными эффектами.

При строгой оценке оценка выражения может легко иметь побочный эффект, поскольку у вас есть четкий обзор порядка оценки и, следовательно, порядка побочных эффектов, обычно важных для побочных эффектов. Это основное преимущество строгой оценки, а также того, почему она есть у большинства языков. И почему даже ориентированные на производительность языки, такие как C, часто используют модель передачи по значению.

Оба могут делать то же самое, только с разными уровнями сложности человека, вы можете прекрасно моделировать бесконечные списки на строгом языке, и вы можете моделировать все эффекты побочных эффектов с нестрогими языками.

0 голосов
/ 08 апреля 2009

Ответ, который был оценен как лучший, страдает, к сожалению, от логической ошибки. Из теоремы, которую цитирует Поргес, не следует, что на ленивом языке можно делать больше.

Доказательством обратного является то, что все программы на ленивых языках компилируются в эквиваленты на строгих языках (которые компилируются далее для программ на ассемблере) или выполняются интерпретатором, написанным на строгом языке (и да, интерпретатор является ассемблерная программа ультимативно).

0 голосов
/ 17 марта 2009

Я немного программирую в Эрланге и нахожу отсутствие ленивых оценок, которые я выучил в университете, довольно разочаровывающим.

Я кратко рассмотрел некоторые проблемы проекта Эйлера, особенно те, которые касаются простых чисел.

При ленивой оценке у вас может быть функция, которая возвращает список всех простых чисел, но на самом деле возвращает только те, которые вам действительно нужны. Следовательно, действительно легко сказать «дай мне первые n простых чисел».

Без ленивых вычислений вы склоняетесь к более ограничивающему «дайте мне список всех простых чисел от 1 до n ».

0 голосов
/ 16 марта 2009

Как Чарли Мартин написал , результат строгой и ленивой программы должен быть эквивалентным. Разница заключается во временных и пространственных ограничениях и / или языковой выразительности. Помимо эффекта лени на производительность для ненужных значений, в ленивом языке можно легко вводить новые языковые конструкции без дополнительной языковой концепции (например, макрос в LISP). Во всяком случае, лень может вас укусить Как работает хвостовая рекурсия на Haskell? и то же самое может быть сложнее, чем на строгом языке. (Разве компилятор haskell не должен признать, что вычисления +1 дешевле, чем make thunk ( x + 1 )?)

0 голосов
/ 16 марта 2009

На языке строгой оценки, таком как C #, можно добиться ленивой оценки, возвращая значение в значение (Func) вместо самого значения. В качестве примера при построении Y-Combinator в c # можно сделать так:

public Func<int, int> Y(Func<Func<int, int>, Func<int, int>> f)
{
    return x => f(Y(f))(x);
}

Эта декларация была бы более краткой в ​​ленивой среде:

Y f = f (Y f)
...