Какая практическая польза от лени как встроенной языковой функции?

Совершенно очевидно, почему язык функционального программирования, который хочет быть ленивым, должен быть чистым. Я смотрю на обратный вопрос: если язык хочет быть чистым, есть ли большое преимущество в лени? Один из аргументов одного из разработчиков Haskell заключается в том, что он устраняет соблазн; возможно, но я пытаюсь взвесить более конкретные преимущества.

Учитывая, что вы хотите заниматься функциональным программированием, в каких случаях встроенная лень позволяет вам выражать вещи более ясно, просто или лаконично?

Проще говоря: Почему лень настолько важна, что вы хотите встроить ее в язык?

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


comment
Это интересная тема, но вы задаете ее в довольно неудачной манере, по сути запрашивая сбор информации о любых сценариях, в которых кто-то может представить себе ленивую оценку полезной. Если вы разрабатываете язык, вам следует сосредоточиться на конкретных решениях, которые вы пытаетесь принять, и попросить помощи во взвешивании вариантов, чтобы вы могли сделать осознанный выбор.   -  person Shog9    schedule 27.11.2011
comment
Я не знаю, получите ли вы здесь хорошие ответы, этот вопрос больше для разработчиков языков программирования, чем для программистов. Это вопрос типа того, что сайт о компьютерных науках будет работать лучше для. Я рекомендую статьи , процитированные в Википедии (а не саму статью WP), особенно «Почему FP имеет значение ».   -  person Gilles 'SO- stop being evil'    schedule 27.11.2011
comment
rwallace: Основываясь на правке @Gilles, я внес дополнительные изменения, чтобы подчеркнуть лень в вопросе как встроенную функцию (с примерами, используемыми для иллюстрации, а не с примерами в качестве конечной цели), и снова открыл, исходя из предположения, что это приемлемо. Если вы не согласны, обсудите.   -  person Shog9    schedule 27.11.2011
comment
Ничего страшного, спасибо, с правками согласен, вопрос проясняют. Что касается статей, цитируемых в Википедии, они, безусловно, содержат много полезной информации, но если они содержат много обсуждений практических вариантов использования лени как особенности языка, я пропустил это.   -  person rwallace    schedule 28.11.2011


Ответы (3)


«Ничего не оценивается, пока это не понадобится в другом месте» - это упрощенная метафора, которая не охватывает все аспекты ленивой оценки (например, не упоминает феномен строгости).

С теоретической точки зрения при разработке чистого языка (конечно, если он основан на каком-то лямбда-исчислении, а не на более экзотических моделях оценки) можно пойти тремя способами: строгий, нестрогий и тотальный.

У каждого из них есть свои достоинства и недостатки, поэтому вам необходимо ознакомиться с соответствующими исследовательскими работами.

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

Однако все языки наименее выразительны: полный язык не может быть полным по Тьюрингу. Частый подход к достижению достаточно хорошей выразительности - это иметь встроенную систему доказательств для хорошо обоснованной рекурсии, которую не намного проще построить, чем анализаторы для неполных языков.

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

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

Что касается того, «кто это пишет десять раз до обеда» - это делает любой, кто использует Haskell в своих проектах. Я думаю, что разработка не игрушечного проекта с использованием языка (нестрогого языка в вашем случае) - лучший способ понять его преимущества и недостатки.

Ниже приведены несколько общих сценариев использования лени, проиллюстрированных неигровыми примерами:

  1. Случаи, когда поток управления трудно предсказать. Подумайте о грамматиках атрибутов, когда вам без лени нужно выполнить топологическую сортировку атрибутов для разрешения зависимостей. Повторная сортировка кода каждый раз при изменении графа зависимостей нецелесообразна. В Haskell вы можете реализовать формализм грамматики атрибутов без явной сортировки, и на Hackage есть как минимум две фактические реализации. Грамматики атрибутов имеют широкое применение при построении компиляторов.

  2. Подход «генерировать и искать» для решения многих задач оптимизации. На строгом языке вы должны чередовать генерацию и поиск, в Haskell вы просто составляете отдельные функции генерации и поиска, и ваш код остается синтаксически модульным, но чередуется во время выполнения. Подумайте о проблеме коммивояжера (TSP), когда вы генерируете все возможные туры, а затем просматриваете их, используя алгоритм ветвей и границ. Обратите внимание, что алгоритм перехода по границе проверяет только определенные первые города тура, генерируются только необходимые части маршрутов. Даже в самом чистом виде TSP имеет несколько применений, таких как планирование, логистика и производство микрочипов. Слегка измененный, он появляется как подзадача во многих областях, таких как секвенирование ДНК.

  3. Ленивый код имеет немодульный поток управления, поэтому одна функция может иметь много возможных потоков управления в зависимости от среды, в которой она выполняется. Это явление можно рассматривать как своего рода «полиморфизм потока управления», поэтому абстракции ленивого потока управления являются более общими. чем их строгие аналоги, а стандартная библиотека функций высшего порядка гораздо полезнее на ленивом языке. Подумайте о генераторах, циклах и итераторах списков Python: функции списков в Haskell охватывают все три варианта использования, при этом поток управления адаптируется к различным сценариям использования из-за лени. Он не ограничивается списками - подумайте о Data.Arrow и итерациях, ленивых и строгих версиях монады состояния и т. Д. Также обратите внимание, что немодульный поток управления является одновременно преимуществом и недостатком, поскольку он усложняет рассуждения о производительности.

  4. Ленивые, возможно, бесконечные структуры данных полезны не только в игрушечных примерах. См. Работы Конала Эллиотта о запоминании функций высшего порядка с помощью попыток. Бесконечные структуры данных выглядят как бесконечные пространства поиска (см. 2), бесконечные циклы и никогда не утомляющие генераторы в смысле Python (см. 3).

person nponeccop    schedule 27.11.2011
comment
Источником упомянутой метафоры, по-видимому, является «Ленивый оценщик» Хендерсона и Морриса, POPL'76. - person nponeccop; 15.05.2012

Core Image в Mac OS X - хороший практический пример ленивой оценки.

По сути, Core Image позволяет создавать ориентированный ациклический граф генераторов изображений и фильтров. Фактически оценка не происходит до последнего шага процесса: материализации. Когда вы запрашиваете материализацию графа Core Image, окончательный кадр изображения распространяется в обратном направлении посредством преобразований графа, тем самым сводя к минимуму количество фактических значений пикселей, которые необходимо оценить.

person smokris    schedule 26.11.2011

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

person Michael J. Barber    schedule 28.11.2011