Послушайте эту статью
Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

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

Функциональное программирование иногда рассматривается как синоним чисто функционального программирования , подмножества функционального программирования, которое рассматривает все функции как детерминированные математические функции или чистые функции . Когда чистая функция вызывается с некоторыми заданными аргументами, она всегда будет возвращать один и тот же результат, и на нее не могут повлиять никакие изменяемые состояния или другие побочные эффекты . Это контрастирует с нечистыми процедурами , распространенными в императивном программировании., который может иметь побочные эффекты (например, изменение состояния программы или получение данных от пользователя). Сторонники чисто функционального программирования утверждают, что за счет ограничения побочных эффектов программы могут иметь меньше ошибок , их легче отлаживать и тестировать , и они больше подходят для формальной проверки . [1] [2]

Функциональное программирование уходит корнями в академические круги , развиваясь из лямбда-исчисления , формальной системы вычислений, основанной только на функциях. Функциональное программирование исторически было менее популярным, чем императивное программирование, но многие функциональные языки сегодня находят применение в промышленности и образовании, включая Common Lisp , Scheme , [3] [4] [5] [6] Clojure , Wolfram Language , [7] [8] Racket , [9] Erlang , [10] [11] [12] Elixir , [13] OCaml , [14][15] Haskell , [16] [17] и F # . [18] [19] Функциональное программирование также является ключом к некоторым языкам, которые добились успеха в определенных областях, например, JavaScript в Интернете, [20] R в статистике, [21] [22] J , K и Q в финансовом анализе, и XQuery / XSLT для XML . [23] [24] Декларативные языки, зависящие от предметной области, такие как SQL и Lex / Yaccиспользовать некоторые элементы функционального программирования, например запретить изменяемые значения . [25] Кроме того, многие другие языки программирования поддерживают программирование в функциональном стиле или имеют реализованные функции функционального программирования, такие как C ++ 11 , Kotlin , [26] Perl , [27] PHP , [28] Python , [29] ] Go , [30] Rust , [31] Raku , [32] и Scala . [33]

История [ править ]

Лямбда - исчисление , разработанное в 1930 годе Алонза Церковью , является формальной системой из расчета , построенный из приложения функции . В 1937 году Алан Тьюринг доказал, что лямбда-исчисление и машины Тьюринга являются эквивалентными моделями вычислений, [34] показывая, что лямбда-исчисление является полным по Тьюрингу . Лямбда-исчисление составляет основу всех языков функционального программирования. Эквивалентная теоретическая формулировка, комбинаторная логика , была разработана Мозесом Шёнфинкелем и Хаскеллом Карри в 1920-х и 1930-х годах. [35]

Позднее Черч разработал более слабую систему - лямбда-исчисление с простой типизацией , которое расширило лямбда-исчисление, присвоив тип всем термам. [36] Это формирует основу для функционального программирования со статической типизацией.

Первый функциональный язык программирования, LISP , был разработан в конце 1950-х годов для серии научных компьютеров IBM 700/7000 Джоном Маккарти в Массачусетском технологическом институте (MIT). [37] Функции LISP были определены с использованием лямбда-нотации Черча, расширенной конструкцией метки, позволяющей использовать рекурсивные функции. [38] Lisp впервые представил многие парадигматические особенности функционального программирования, хотя ранние Lisp были языками с несколькими парадигмами и включали поддержку множества стилей программирования по мере развития новых парадигм. Более поздние диалекты, такие как Scheme и Clojure, и ответвления, такие как Дилан и Джулия , стремились упростить и рационализировать Лисп на основе чисто функционального ядра, в то время как Common Lisp был разработан для сохранения и обновления парадигматических особенностей многочисленных старых диалектов, которые он заменил. [39]

Язык обработки информации (IPL), 1956, иногда упоминается как первый компьютерный язык функционального программирования. [40] Это язык ассемблера для управления списками символов. У него есть понятие генератора , который представляет собой функцию, которая принимает функцию в качестве аргумента, и, поскольку это язык уровня сборки, код может быть данными, поэтому IPL можно рассматривать как имеющую функции более высокого порядка. Однако он в значительной степени полагается на структуру изменяющегося списка и аналогичные императивные функции.

Кеннет Э. Айверсон разработал APL в начале 1960-х годов, описанный в его книге 1962 года «Язык программирования» ( ISBN  9780471430148 ). APL был основное влияние на Джона Бэкуса «s FP . В начале 1990 - х годов, Айверсон и Роджер Hui создал J . В середине 1990-х годов, Артур Уитни , который ранее работал с Айверсон, созданный K , который используется в коммерческих целях в финансовой отрасли наряду с его потомка Q .

Джон Бэкус представил ФП в своей лекции 1977 года на Премии Тьюринга «Можно ли освободить программирование от стиля фон Неймана ? Функциональный стиль и его алгебра программ». [41] Он определяет функциональные программы как построенные иерархическим образом посредством «комбинирования форм», которые позволяют создать «алгебру программ»; на современном языке это означает, что функциональные программы следуют принципу композиционности . [ необходима цитата ] Статья Бэкуса популяризировала исследования функционального программирования, хотя в ней упор делался на программирование на уровне функций, а не на стиль лямбда-исчисления, который теперь ассоциируется с функциональным программированием.

В 1973 году язык ML был создан Робином Милнером в Эдинбургском университете , а Дэвид Тернер разработал язык SASL в Университете Сент-Эндрюс . Также в Эдинбурге в 1970-х годах Берстолл и Дарлингтон разработали функциональный язык NPL . [42] NPL была основана на уравнениях рекурсии Клини и впервые была представлена ​​в их работе по преобразованию программ. [43] Берстолл, Маккуин и Саннелла затем включили полиморфную проверку типов из ML для создания языка Hope . [44]Со временем ML превратился в несколько диалектов, наиболее распространенными из которых сейчас являются OCaml и Standard ML .

В 1970-х годах Гай Л. Стил и Джеральд Джей Сассман разработали схему , как описано в « Лямбда-документах» и в учебнике 1985 года « Структура и интерпретация компьютерных программ» . Схема была первым диалектом лиспа, в котором использовалась лексическая область видимости и требовалась оптимизация хвостового вызова , функции, которые поощряют функциональное программирование.

В 1980-х годах Пер Мартин-Лёф разработал интуиционистскую теорию типов (также называемую конструктивной теорией типов), которая связала функциональные программы с конструктивными доказательствами, выраженными как зависимые типы . Это привело к новым подходам к интерактивному доказательству теорем и повлияло на развитие последующих языков функционального программирования. [ необходима цитата ]

Ленивый функциональный язык Miranda , разработанный Дэвидом Тернером, впервые появился в 1985 году и оказал сильное влияние на Haskell . Поскольку Миранда была частной собственностью, Haskell начал с консенсуса в 1987 году, чтобы сформировать открытый стандарт для исследований функционального программирования; релизы реализации продолжаются с 1990 года.

В последнее время он нашел применение в таких нишах, как параметрический САПР, благодаря языку OpenSCAD, построенному на основе геометрии CSG, хотя его ограничение на переназначение значений (все значения рассматриваются как константы) привело к путанице среди пользователей, незнакомых с функциональным программированием. как концепция. [45]

Функциональное программирование по-прежнему используется в коммерческих целях. [46] [47] [48]

Концепции [ править ]

Ряд концепций и парадигм специфичны для функционального программирования и обычно чужды императивному программированию (включая объектно-ориентированное программирование ). Однако языки программирования часто обслуживают несколько парадигм программирования, поэтому программисты, использующие «в основном императивные» языки, могли использовать некоторые из этих концепций. [49]

Функции первого и высшего порядка [ править ]

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

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

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

Чистые функции [ править ]

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

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

Хотя большинство компиляторов для императивных языков программирования обнаруживают чистые функции и выполняют исключение общих подвыражений для чистых вызовов функций, они не всегда могут делать это для предварительно скомпилированных библиотек, которые обычно не раскрывают эту информацию, тем самым предотвращая оптимизацию, включающую эти внешние функции. Некоторые компиляторы, такие как gcc , добавляют дополнительные ключевые слова для программиста, чтобы явно пометить внешние функции как чистые, чтобы включить такую ​​оптимизацию. Fortran 95 также позволяет обозначать функции как чистые . [50] В C ++ 11 добавлено constexprключевое слово с аналогичной семантикой.

Рекурсия [ править ]

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

Стандарт языка Scheme требует, чтобы реализации поддерживали правильную хвостовую рекурсию, то есть они должны допускать неограниченное количество активных хвостовых вызовов. [51] [52] Правильная хвостовая рекурсия - это не просто оптимизация; это языковая функция, которая гарантирует пользователям, что они могут использовать рекурсию для выражения цикла, и это будет безопасно для места. [53] Более того, вопреки своему названию, он учитывает все хвостовые вызовы, а не только хвостовую рекурсию. Хотя правильная хвостовая рекурсия обычно реализуется путем превращения кода в императивные циклы, реализации могут реализовывать это другими способами. Например, CHICKEN намеренно поддерживает стек и позволяет стеку переполняться . Однако, когда это происходит, егоСборщик мусора потребует обратно пространство [54], допуская неограниченное количество активных хвостовых вызовов, даже если он не превращает хвостовую рекурсию в цикл.

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

Большинство языков функционального программирования общего назначения допускают неограниченную рекурсию и являются полными по Тьюрингу , что делает проблему остановки неразрешимой , может вызвать несостоятельность эквациональных рассуждений и, как правило, требует внесения несогласованности в логику, выраженную системой типов языка . Некоторые языки специального назначения, такие как Coq, допускают только хорошо обоснованную рекурсию и строго нормализуют (неокончательные вычисления могут быть выражены только с помощью бесконечных потоков значений, называемых codata). Как следствие, эти языки не могут быть полными по Тьюрингу, и выражение в них определенных функций невозможно, но они по-прежнему могут выражать широкий класс интересных вычислений, избегая проблем, связанных с неограниченной рекурсией. Функциональное программирование, ограниченное хорошо обоснованной рекурсией с некоторыми другими ограничениями, называется полным функциональным программированием . [55]

Строгая и нестрогая оценка [ править ]

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

длина печати ([2 + 1, 3 * 2, 1/0, 5-4])

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

Обычной стратегией реализации ленивых вычислений на функциональных языках является сокращение графов . [56] Ленивое вычисление используется по умолчанию в нескольких чисто функциональных языках, включая Miranda , Clean и Haskell .

Хьюз 1984 выступает за ленивую оценку как механизм улучшения модульности программы за счет разделения задач и облегчения независимой реализации производителей и потребителей потоков данных. [2] Launchbury 1993 описывает некоторые трудности, которые создает ленивая оценка, особенно при анализе требований к памяти программы, и предлагает операционную семантику для помощи в таком анализе. [57] Harper 2009 предлагает включать как строгую, так и ленивую оценку в один и тот же язык, используя систему типов языка для их различения. [58]

Системы типов [ править ]

Особенно после разработки вывода типа Хиндли-Милнера в 1970-х годах функциональные языки программирования имели тенденцию использовать типизированное лямбда-исчисление , отклоняя все недопустимые программы во время компиляции и рискуя ложноположительными ошибками , в отличие от нетипизированного лямбда-исчисления , которое принимает все допустимые программы во время компиляции и рискуют ложноотрицательными ошибками , используемыми в Lisp и его вариантах (таких как Scheme ), хотя они отклоняют все недопустимые программы во время выполнения, когда информации достаточно, чтобы не отклонять действительные программы. Использование алгебраических типов данныхделает удобными манипуляции со сложными структурами данных; наличие строгой проверки типов во время компиляции делает программы более надежными в отсутствие других методов обеспечения надежности, таких как разработка через тестирование , а вывод типов освобождает программиста от необходимости вручную объявлять типы компилятору в большинстве случаев.

Некоторые функциональные языки, ориентированные на исследования, такие как Coq , Agda , Cayenne и Epigram , основаны на интуиционистской теории типов , которая позволяет типам зависеть от терминов. Такие типы называются зависимыми . Эти системы типов не имеют разрешимого вывода типов, их трудно понять и использовать для программирования. [59] [60] [61] [62] Но зависимые типы могут выражать произвольные предложения в логике более высокого порядка . Благодаря изоморфизму Карри – Ховарда хорошо типизированные программы на этих языках становятся средством написания формальных математических доказательств.из которого компилятор может генерировать сертифицированный код . Хотя эти языки в основном представляют интерес в академических исследованиях (в том числе в формализованной математике ), они начали использоваться и в инженерии. Compcert - это компилятор для подмножества языка программирования C, который написан на Coq и официально проверен. [63]

Ограниченная форма зависимых типов, называемая обобщенными алгебраическими типами данных (GADT), может быть реализована таким образом, чтобы обеспечить некоторые преимущества программирования с зависимой типизацией, избегая при этом большей части его неудобств. [64] GADT доступны в компиляторе Glasgow Haskell , в OCaml (начиная с версии 4.00) и в Scala (как «классы case») и были предложены в качестве дополнений к другим языкам, включая Java и C #. [65]

Ссылочная прозрачность [ править ]

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

Рассмотрим оператор присваивания Cx = x * 10 , он изменяет значение, присвоенное переменной x. Допустим, что начальное значение xбыло 1, затем две последовательные оценки переменной xдоходности 10и 100соответственно. Ясно, что замена x = x * 10на любой из 10или 100дает программе другое значение, и поэтому выражение не является ссылочно прозрачным. Фактически, операторы присваивания никогда не бывают прозрачными по ссылкам.

Теперь рассмотрим другую функцию , например, является прозрачным, поскольку он не неявно изменить входной х и , следовательно , не имеет таких побочных эффектов . Функциональные программы используют исключительно этот тип функций и поэтому являются ссылочно прозрачными.int plusone(int x) {return x+1;}

Структуры данных [ править ]

Чисто функциональные структуры данных часто представляются иначе, чем их императивные аналоги. [67] Например, массив с постоянным временем доступа и обновления является базовым компонентом большинства императивных языков, а многие императивные структуры данных, такие как хэш-таблица и двоичная куча , основаны на массивах. Массивы могут быть заменены картами или списками произвольного доступа, которые допускают чисто функциональную реализацию, но имеют логарифмическое время доступа и обновления. Чисто функциональные структуры данных обладают постоянством, свойство сохранять предыдущие версии структуры данных неизменными. В Clojure постоянные структуры данных используются как функциональная альтернатива своим императивным аналогам. Например, постоянные векторы используют деревья для частичного обновления. Вызов метода вставки приведет к созданию некоторых, но не всех узлов. [68]

Сравнение с императивным программированием [ править ]

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

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

Параллельное сравнение императивного и функционального программирования [ править ]

В следующих двух примерах (написанных на JavaScript ) достигается тот же эффект: они умножают все четные числа в массиве на 10 и складывают их все, сохраняя окончательную сумму в переменной «результат».

Традиционный императивный цикл:

const  numList  =  [ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,  10 ]; пусть  результат  =  0 ; for  ( let  i  =  0 ;  i  <  numList . length ;  i ++ )  {  if  ( numList [ i ]  %  2  ===  0 )  { результат  + =  numList [ i ]  *  10 ;  } }

Функциональное программирование с функциями высшего порядка:

const  result  =  [ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,  10 ]  . фильтр ( n  =>  n  %  2  ===  0 )  . карта ( а  =>  а  *  10 )  . уменьшить (( a ,  b )  =>  a  +  b );

Моделирование состояния [ править ]

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

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

Функциональные языки также моделируют состояния, передавая неизменяемые состояния. Это можно сделать, заставив функцию принять состояние как один из своих параметров и вернуть новое состояние вместе с результатом, оставив старое состояние неизменным. [70]

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

Для отслеживания побочных эффектов в программах были разработаны альтернативные методы, такие как логика Хоара и уникальность . Некоторые современные исследовательские языки используют системы эффектов, чтобы сделать наличие побочных эффектов явным. [ необходима цитата ]

Проблемы с эффективностью [ править ]

Функциональные языки программирования обычно менее эффективно используют процессор и память, чем императивные языки, такие как C и Pascal . [71] Это связано с тем фактом, что некоторые изменяемые структуры данных, такие как массивы, имеют очень простую реализацию с использованием существующего оборудования. Доступ к плоским массивам может быть очень эффективным с помощью ЦП с глубоким конвейером, эффективно предварительно загруженных через кеши (без сложного поиска указателей).) или обрабатывается с помощью инструкций SIMD. Также непросто создать их не менее эффективные неизменяемые аналоги общего назначения. Для чисто функциональных языков в худшем случае замедление является логарифмическим по количеству используемых ячеек памяти, поскольку изменяемая память может быть представлена ​​чисто функциональной структурой данных с логарифмическим временем доступа (например, сбалансированным деревом). [72] Однако такое замедление не является универсальным. Для программ, которые выполняют интенсивные численные вычисления, функциональные языки, такие как OCaml и Clean , лишь немного медленнее, чем C, согласно The Computer Language Benchmarks Game . [73] Для программ, которые работают с большими матрицами и многомернымибазы данных , функциональные языки массивов (такие как J и K ) были разработаны с оптимизацией скорости.

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

Ленивая оценка также может ускорить программу, даже асимптотически, тогда как она может замедлить ее максимум на постоянный коэффициент (однако при неправильном использовании может возникнуть утечка памяти ). Launchbury 1993 [57] обсуждает теоретические вопросы, связанные с утечкой памяти из-за ленивых вычислений, а O'Sullivan et al. 2008 [75] дают несколько практических советов по их анализу и исправлению. Однако наиболее общие реализации ленивых вычислений, широко использующие разыменованный код и данные, плохо работают на современных процессорах с глубокими конвейерами и многоуровневыми кэшами (где промах в кэше может стоить сотни циклов) [ необходима цитата ] .

Функциональное программирование на нефункциональных языках [ править ]

Можно использовать функциональный стиль программирования на языках, которые традиционно не считаются функциональными языками. [76] Например, и D [77], и Fortran 95 [50] явно поддерживают чистые функции.

JavaScript , Lua , [78] Python и Go [79] с самого начала имели функции первого класса . [80] Python имел поддержку « лямбда », « карта », « сокращение » и « фильтр » в 1994 году, а также закрытие в Python 2.2, [81] хотя в Python 3 «сокращение» было отнесено к functoolsстандартному библиотечному модулю. [82] Первоклассные функции были введены в другие основные языки, такие как PHP 5.3, Visual Basic 9, C # 3.0, C ++ 11 ,иКотлин . [26] [ необходима цитата ]

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

В Java , анонимные классы иногда могут быть использованы для имитации замыканий ; [83] однако анонимные классы не всегда являются подходящей заменой замыканий, потому что они имеют более ограниченные возможности. [84] Java 8 поддерживает лямбда-выражения в качестве замены некоторых анонимных классов. [85]

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

Многие шаблоны объектно-ориентированного проектирования можно выразить в терминах функционального программирования: например, шаблон стратегии просто диктует использование функции высшего порядка, а шаблон посетителя примерно соответствует катаморфизму или сворачиванию .

Точно так же идея неизменяемых данных из функционального программирования часто включается в императивные языки программирования [86], например, кортеж в Python, который является неизменяемым массивом, и Object.freeze () в JavaScript. [87]

Приложения [ править ]

Академия [ править ]

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

Промышленность [ править ]

Функциональное программирование нашло применение в самых разных промышленных приложениях. Например, Erlang , разработанный шведской компанией Ericsson в конце 1980-х годов, первоначально использовался для реализации отказоустойчивых телекоммуникационных систем [11], но с тех пор стал популярным для создания ряда приложений в таких компаниях, как Nortel , Facebook. , Électricité de France и WhatsApp . [10] [12] [88] [89] [90] Схема , диалект Лиспа, был использован в качестве основы для нескольких приложений на ранних компьютерах Apple Macintosh [3] [4] и применялся для решения таких задач, как программное обеспечение для моделирования обучения [5] и управление телескопом . [6] OCaml , представленный в середине 1990-х годов, получил коммерческое использование в таких областях, как финансовый анализ, [14] проверка драйверов , программирование промышленных роботов и статический анализ встроенного программного обеспечения . [15] Haskell , хотя изначально задумывался как язык исследований, [17]также применяется рядом компаний в таких областях, как аэрокосмические системы, проектирование оборудования и веб-программирование. [16] [17]

Другие языки функционального программирования, которые используются в промышленности, включают Scala , [91] F # , [18] [19] Wolfram Language , [7] Lisp , [92] Standard ML , [93] [94] и Clojure . [95]

Функциональные «платформы» были популярны в финансах для анализа рисков (особенно в крупных инвестиционных банках). Факторы риска кодируются как функции, которые формируют взаимозависимые графики (категории) для измерения корреляций в рыночных сдвигах, не в отличие от оптимизации на основе Гребнера, но также для соответствия нормативным требованиям, например, Комплексного анализа и проверки капитала . Учитывая использование вариантов OCAML или CAML в финансах, эти системы иногда считают относящимися к категориальной абстрактной машине или CAM. Действительно, на функциональное программирование сильно влияет теория категорий .

Образование [ править ]

Многие университеты преподают или преподают функциональное программирование в рамках своих программ бакалавриата в области компьютерных наук. [96] [97] [98] [99] Некоторые используют его как введение в программирование, [99] в то время как другие преподают его после обучения императивному программированию. [98] [100]

Помимо информатики, функциональное программирование используется как метод обучения решению задач, алгебре и геометрическим понятиям. [101] Он также использовался в качестве инструмента для обучения классической механике в Структуре и интерпретации классической механики .

См. Также [ править ]

  • Чисто функциональное программирование
  • Сравнение парадигм программирования
  • Нетерпеливые оценки
  • Список тем функционального программирования
  • Вложенная функция
  • Индуктивное функциональное программирование
  • Функциональное реактивное программирование

Ссылки [ править ]

  1. ^ Hudak, Пол (сентябрь 1989). «Концепция, эволюция и применение языков функционального программирования» (PDF) . ACM Computing Surveys . 21 (3): 359–411. DOI : 10.1145 / 72551.72554 . S2CID 207637854 .  
  2. ^ a b Хьюз, Джон (1984). «Почему так важно функциональное программирование» .
  3. ^ a b Клинджер, Уилл (1987). «Многозадачность и MacScheme» . MacTech . 3 (12) . Проверено 28 августа 2008 .
  4. ^ a b Хартхаймер, Энн (1987). «Программирование текстового редактора в MacScheme + Toolsmith» . MacTech . 3 (1). Архивировано из оригинала на 2011-06-29 . Проверено 28 августа 2008 .
  5. ^ а б Кидд, Эрик. Тренинг по борьбе с терроризмом в схеме . CUFP 2007 . Проверено 26 августа 2009 .
  6. ^ а б Клеис, Ричард. Схема в космосе . CUFP 2006 . Проверено 26 августа 2009 .
  7. ^ a b «Руководство по языку Wolfram Language: функциональное программирование» . 2015 . Проверено 24 августа 2015 .
  8. ^ "Функциональный язык против процедурного программирования" . Кафедра прикладной математики . Колорадский университет. Архивировано из оригинала на 2007-11-13.
  9. ^ «Сценарии на основе состояний в Uncharted 2» (PDF) . Архивировано 15 декабря 2012 года из оригинального (PDF) . Проверено 8 августа 2011 .
  10. ^ a b «Кто использует Erlang для разработки продуктов?» . Часто задаваемые вопросы об Erlang . Проверено 27 апреля 2018 .
  11. ^ a b Армстронг, Джо (июнь 2007 г.). История Erlang . Третья конференция ACM SIGPLAN по истории языков программирования. Сан-Диего, Калифорния. DOI : 10.1145 / 1238844.1238850 .
  12. ^ a b Ларсон, Джим (март 2009 г.). «Эрланг для параллельного программирования» . Коммуникации ACM . 52 (3): 48. DOI : 10,1145 / 1467247,1467263 . S2CID 524392 . 
  13. ^ "Язык программирования Эликсир" . Источник 2021-02-14 .
  14. ^ a b Минский, Ярон; Недели, Стивен (июль 2008 г.). «Caml Trading - опыт функционального программирования на Уолл-стрит» . Журнал функционального программирования . 18 (4): 553–564. DOI : 10.1017 / S095679680800676X . Проверено 27 августа 2008 .
  15. ^ а б Лерой, Ксавье. Некоторые виды использования Caml в промышленности (PDF) . CUFP 2007 . Проверено 26 августа 2009 .
  16. ^ a b «Haskell в индустрии» . Haskell Wiki . Проверено 26 августа 2009 . Haskell имеет широкий спектр коммерческого применения: от аэрокосмической и оборонной до финансовых, веб-стартапов, фирм по разработке оборудования и производителей газонокосилок.
  17. ^ a b c Худак, Павел ; Hughes, J .; Джонс, ИП; Уодлер, П. (июнь 2007 г.). История Haskell: лень с классом . Третья конференция ACM SIGPLAN по истории языков программирования. Сан-Диего, Калифорния. DOI : 10.1145 / 1238844.1238856 . Проверено 26 сентября 2013 .
  18. ^ a b Мэнселл, Ховард (2008). Количественные финансы на F # . CUFP 2008 . Проверено 29 августа 2009 .
  19. ^ a b Пик, Алекс (2009). Первое существенное бизнес-приложение на F # . CUFP 2009. Архивировано из оригинала на 2009-10-17 . Проверено 29 августа 2009 .
  20. ^ комментарии, 27 июня 2017 г. Мэтт Банз Feed 603up 2. «Введение в функциональное программирование на JavaScript» . Opensource.com . Проверено 9 января 2021 .
  21. ^ «Расписание конференции useR! 2006 включает доклады о коммерческом использовании R» . R-project.org. 2006-06-08 . Проверено 20 июня 2011 .
  22. ^ Чемберс, Джон М. (1998). Программирование с данными: Руководство для S языка . Springer Verlag. С. 67–70. ISBN 978-0-387-98503-9.
  23. ^ Novatchev, Dimitre. «Функциональный язык программирования XSLT - Доказательство на примерах» . Проверено 27 мая 2006 года .
  24. ^ Мертц, Дэвид. «Парадигмы программирования XML (часть четвертая): подход функционального программирования к обработке XML» . IBM developerWorks . Проверено 27 мая 2006 года .
  25. ^ Чемберлин, Дональд Д .; Бойс, Раймонд Ф. (1974). «SEQUEL: структурированный английский язык запросов». Труды 1974 ACM SIGFIDET : 249–264.
  26. ^ a b «Функциональное программирование - язык программирования Kotlin» . Котлин . Проверено 1 мая 2019 .
  27. ^ Dominus, Марк Дж. (2005). Perl высшего порядка . Морган Кауфманн . ISBN 978-1-55860-701-9.
  28. ^ Холивелл, Саймон (2014). Функциональное программирование на PHP . php [архитектор]. ISBN 9781940111056.
  29. ^ The Cain Gang Ltd. "Метаклассы Python: Кто? Почему? Когда?" (PDF) . Архивировано из оригинального (PDF) 30 мая 2009 года . Проверено 27 июня 2009 года .
  30. ^ «GopherCon 2020: Дилан Миус - Функциональное программирование с помощью Go» . YouTube.com .
  31. ^ «Функциональные возможности языка: итераторы и замыкания - язык программирования Rust» . doc.rust-lang.org . Проверено 9 января 2021 .
  32. ^ Vanderbauwhede, Вим. «Более чистый код с функциональным программированием» . Архивировано из оригинального 11 сентября 2020 . Дата обращения 6 октября 2020 .
  33. ^ «Эффективная Scala» . Scala Wiki . Проверено 21 февраля 2012 . Эффективная Scala.
  34. ^ Тьюринг, AM (1937). «Вычислимость и λ-определимость». Журнал символической логики . Издательство Кембриджского университета. 2 (4): 153–163. DOI : 10.2307 / 2268280 . JSTOR 2268280 . 
  35. ^ Хаскелл Брукс Карри; Роберт Фейс (1958). Комбинаторная логика . Издательская компания Северной Голландии . Проверено 10 февраля 2013 года .
  36. ^ Церковь, A. (1940). «Формулировка простой теории типов». Журнал символической логики . 5 (2): 56–68. DOI : 10.2307 / 2266170 . JSTOR 2266170 . 
  37. ^ Маккарти, Джон (июнь 1978 г.). История Лиспа (PDF) . История языков программирования . Лос Анджелес, Калифорния. С. 173–185. DOI : 10.1145 / 800025.808387 .
  38. ^ Джон Маккарти (1960). «Рекурсивные функции символьных выражений и их машинное вычисление, Часть I.» (PDF) . Коммуникации ACM . ACM Нью-Йорк, штат Нью-Йорк, США. 3 (4): 184–195. DOI : 10.1145 / 367177.367199 . S2CID 1489409 .  
  39. ^ Гай Л. Стил; Ричард П. Габриэль (февраль 1996 г.). Эволюция Лиспа (PDF) . В ACM / SIGPLAN Вторая история языков программирования . С. 233–330. DOI : 10.1145 / 234286.1057818 . ISBN  978-0-201-89502-5. S2CID  47047140 .
  40. В мемуарах Герберта А. Саймона (1991), Models of My Life pp.189-190 ISBN 0-465-04640-1 утверждается, что он, Эл Ньюэлл и Клифф Шоу «... обычно считаются родителями. [области] искусственного интеллекта »за написание Logic Theorist , программы, котораяавтоматическидоказывала теоремы из Principia Mathematica . Для этого им пришлось изобрести язык и парадигму, которые, если смотреть ретроспективно, включают функциональное программирование. 
  41. Перейти ↑ Backus, J. (1978). «Можно ли освободить программирование от стиля фон Неймана ?: Функциональный стиль и его алгебра программ» . Коммуникации ACM . 21 (8): 613–641. DOI : 10.1145 / 359576.359579 .
  42. ^ Р. М. Берстолл. Соображения по дизайну функционального языка программирования. Приглашенный доклад, Тр. Infotech State of the Art Conf. «Программная революция», Копенгаген, 45–57 (1977).
  43. ^ Р. М. Берстолл и Дж. Дарлингтон. Система трансформации для разработки рекурсивных программ. Журнал Ассоциации вычислительной техники 24 (1): 44–67 (1977).
  44. ^ RM Burstall, DB MacQueen и DT Sannella. НАДЕЖДА: экспериментальный прикладной язык. Proc. Конференция LISP 1980 г., Стэнфорд, 136–143 (1980).
  45. ^ "Сделайте обнаружение assign () проще!" . OpenSCAD .
  46. Питер Брайт (13 марта 2018 г.). «Разработчики любят модные новые языки, но зарабатывают больше на функциональном программировании» . Ars Technica .
  47. Джон Леонард (24 января 2017 г.). «Скрытый рост функционального программирования» . Вычислительная техника.
  48. Лео Чунг (9 мая 2017 г.). "Функциональное программирование лучше для вашего стартапа?" . InfoWorld .
  49. ^ Понтан, Дик. «Функциональное программирование достигает зрелости» . BYTE.com (август 1994 г.) . Архивировано из оригинала на 2006-08-27 . Проверено 31 августа 2006 года .
  50. ^ a b «ISO / IEC JTC 1 / SC 22 / WG5 / N2137» . Международная организация по стандартизации. 6 июля 2017 г. Цитировать журнал требует |journal=( помощь )
  51. ^ "Пересмотренный отчет ^ 6 по алгоритмической языковой схеме" . R6rs.org . Проверено 21 марта 2013 .
  52. ^ «Пересмотренный отчет ^ 6 по алгоритмической языковой схеме - обоснование» . R6rs.org . Проверено 21 марта 2013 .
  53. ^ Клинджер, Уильям (1998). «Правильная хвостовая рекурсия и эффективность использования пространства». Материалы конференции ACM SIGPLAN 1998 по проектированию и реализации языков программирования - PLDI '98 . С. 174–185. DOI : 10.1145 / 277650.277719 . ISBN 0897919874. S2CID  16812984 .
  54. ^ Бейкер, Генри (1994). "Минусы не должны ПРОТИВ его аргументов, Часть II: Чейни о MTA"
  55. ^ Тернер, DA (2004-07-28). «Полное функциональное программирование» . Журнал универсальных компьютерных наук . 10 (7): 751–768. DOI : 10.3217 / jucs-010-07-0751 .
  56. ^ Реализация языков функционального программирования . Саймон Пейтон Джонс, опубликованный Prentice Hall, 1987
  57. ^ a b Джон Лаанчбери (1993). «Естественная семантика ленивых оценок». CiteSeerX 10.1.1.35.2016 .  Цитировать журнал требует |journal=( помощь )
  58. ^ Роберт В. Харпер (2009). Практические основы языков программирования (PDF) . Архивировано из оригинального (PDF) 07.04.2016.
  59. ^ Хуэ, Жерар П. (1973). «Неразрешимость объединения в логике третьего порядка». Информация и контроль . 22 (3): 257–267. DOI : 10.1016 / s0019-9958 (73) 90301-х .
  60. ^ Huet, Gérard (сентябрь 1976). Resolution d'Equations dans des Langages d'Ordre 1,2, ... ω (доктор философии) (на французском языке). Парижский университет VII.
  61. ^ Huet, Gérard (2002). «Объединение высшего порядка 30 лет спустя» (PDF) . In Carreño, V .; Muñoz, C .; Тахар, С. (ред.). Материалы 15-й Международной конференции TPHOL . LNCS. 2410 . Springer. С. 3–12.
  62. Перейти ↑ Wells, JB (1993). «Типизация и проверка типов в лямбда-исчислении второго порядка эквивалентны и неразрешимы». Tech. Реп. 93-011 . CiteSeerX 10.1.1.31.3590 . 
  63. Лерой, Ксавье (17 сентября 2018 г.). «Компилятор, проверенный Compcert» .
  64. ^ Пейтон Джонс, Саймон; Витиниотис, Димитриос; Вейрих, Стефани ; Джеффри Вашберн (апрель 2006 г.). «Простой вывод типа на основе унификации для GADT» . Icfp 2006 : 50–61.
  65. ^ Кеннеди, Эндрю; Руссо, Клаудио (октябрь 2005 г.). Обобщенные алгебраические типы данных и объектно-ориентированное программирование (PDF) . УПСЛА . Сан-Диего, Калифорния. ISBN  9781595930316. Архивировано из оригинального (PDF) 29 декабря 2006 года. источник цитирования
  66. ^ Хьюз, Джон. «Почему так важно функциональное программирование» (PDF) . Технологический университет Чалмерса .
  67. ^ Чисто функциональные структуры данных по Крис Окасаки , Cambridge University Press , 1998, ISBN 0-521-66350-4 
  68. ^ L'orange, Жан Никлас. «polymatheia - понимание постоянного вектора Clojure, часть 1» . Полиматея . Проверено 13 ноября 2018 .
  69. ^ Ньюберн, Дж. «Все о монадах: исчерпывающее руководство по теории и практике монадического программирования в Haskell» . Проверено 14 февраля 2008 .
  70. ^ «Тринадцать способов взглянуть на черепаху» . fF # для развлечения и наживы . Проверено 13 ноября 2018 .
  71. Полсон, Ларри С. (28 июня 1996 г.). ML для работающего программиста . Издательство Кембриджского университета. ISBN 978-0-521-56543-1. Проверено 10 февраля 2013 года .
  72. ^ Spiewak, Daniel (26 августа 2008). «Реализация постоянных векторов в Scala» . Фиксация кода .
  73. ^ «Какие программы самые быстрые? | Компьютерная языковая тестовая игра» . benchmarksgame.alioth.debian.org. Архивировано из оригинала на 2013-05-20 . Проверено 20 июня 2011 .
  74. ^ Игорь Печанский; Вивек Саркар (2005). «Спецификация неизменяемости и ее приложения». Параллелизм и вычисления: практика и опыт . 17 (5–6): 639–662. DOI : 10.1002 / cpe.853 . S2CID 34527406 . 
  75. ^ «Глава 25. Профилирование и оптимизация» . Book.realworldhaskell.org . Проверено 20 июня 2011 .
  76. ^ Хартель, Питер; Хенк Мюллер; Хью Глейзер (март 2004 г.). "Функциональный опыт C" (PDF) . Журнал функционального программирования . 14 (2): 129–135. DOI : 10.1017 / S0956796803004817 . ; Дэвид Мертц. «Функциональное программирование на Python, часть 3» . IBM developerWorks . Архивировано из оригинала на 2007-10-16 . Проверено 17 сентября 2006 .( Часть 1 , Часть 2 )
  77. ^ "Функции - язык программирования D 2.0" . Цифровой Марс. 30 декабря 2012 г.
  78. ^ "Неофициальный FAQ по Lua (uFAQ)" .
  79. ^ «Первоклассные функции в Go - язык программирования Go» . golang.org . Проверено 2021 января .
  80. Перейти ↑ Eich, Brendan (3 апреля 2008 г.). «Популярность» .
  81. ^ ван Россум, Гвидо (2009-04-21). "Истоки" функциональных "возможностей Python" . Проверено 27 сентября 2012 .
  82. ^ "functools - Функции высшего порядка и операции с вызываемыми объектами" . Фонд программного обеспечения Python. 2011-07-31 . Проверено 31 июля 2011 .
  83. ^ Skarsaune, Martin (2008). Проект порта Java SICS Автоматический перевод большой объектно-ориентированной системы с Smalltalk на Java .
  84. ^ Гослинг, Джеймс. «Замыкания» . Джеймс Гослинг: на Явской дороге . Oracle. Архивировано из оригинала на 2013-04-14 . Проверено 11 мая 2013 года .
  85. ^ Уильямс, Майкл (8 апреля 2013 г.). «Быстрый запуск Java SE 8 Lambda» .
  86. ^ Блох, Джошуа (2008). «Пункт 15: Минимизируйте изменчивость». Эффективная Java (Второе изд.). Эддисон-Уэсли. ISBN 978-0321356680.
  87. ^ "Object.freeze () - JavaScript | MDN" . developer.mozilla.org . Проверено 2021 января . Метод Object.freeze () замораживает объект. Замороженный объект больше нельзя изменить; замораживание объекта предотвращает добавление к нему новых свойств, удаление существующих свойств, предотвращает изменение перечисляемости, настраиваемости или возможности записи существующих свойств и предотвращает изменение значений существующих свойств. Кроме того, замораживание объекта также предотвращает изменение его прототипа. freeze () возвращает тот же объект, который был передан.
  88. ^ Пиро, Кристофер (2009). Функциональное программирование в Facebook . CUFP 2009. Архивировано из оригинала на 2009-10-17 . Проверено 29 августа 2009 .
  89. ^ "Sim-Diasca: крупномасштабный механизм одновременного моделирования дискретных событий в Erlang" . Ноябрь 2011 г.
  90. ^ 1 миллион - итак 2011 // Блог WhatsApp, 2012-01-06: «последней важной частью нашей инфраструктуры является Erlang»
  91. ^ Момтахан, Ли (2009). Scala в EDF Trading: реализация предметно-ориентированного языка для определения производных цен с помощью Scala . CUFP 2009. Архивировано из оригинала на 2009-10-17 . Проверено 29 августа 2009 .
  92. ^ Грэм, Пол (2003). «Превосходя средние показатели» . Проверено 29 августа 2009 .
  93. Перейти ↑ Sims, Steve (2006). Создание стартапа с использованием стандартного машинного обучения (PDF) . CUFP 2006 . Проверено 29 августа 2009 .
  94. ^ Laurikari, Ville (2007). Функциональное программирование в безопасности связи . CUFP 2007 . Проверено 29 августа 2009 .
  95. Lorimer, RJ (19 января 2009 г.). "Анонсировано приложение Clojure Live Production" . InfoQ .
  96. ^ «Функциональное программирование: 2019-2020» . Факультет компьютерных наук Оксфордского университета . Проверено 28 апреля 2020 .
  97. ^ «Программирование I (Haskell)» . Имперский колледж Лондона, факультет вычислительной техники . Проверено 28 апреля 2020 .
  98. ^ a b "Бакалавриат по информатике - Модули" . Проверено 28 апреля 2020 .
  99. ^ a b Абельсон, Хэл ; Сассман, Джеральд Джей (1985). «Предисловие ко второму изданию» . Структура и интерпретация компьютерных программ (2-е изд.). MIT Press.
  100. ^ Джон ДеНеро (осень 2019). «Компьютерные науки 61A, Беркли» . Департамент электротехники и компьютерных наук, Беркли . Проверено 14 августа 2020 .
  101. ^ Эммануэль Schanzer из Bootstrap интервью на телешоу триангуляции на TWiT.tv сети

Дальнейшее чтение [ править ]

  • Абельсон, Хэл ; Сассман, Джеральд Джей (1985). Структура и интерпретация компьютерных программ . MIT Press.
  • Кузино, Гай и Мишель Мони. Функциональный подход к программированию . Кембридж, Великобритания: Издательство Кембриджского университета , 1998.
  • Карри, Хаскелл Брукс и Фейс, Роберт и Крейг, Уильям. Комбинаторная логика . Том I. Издательство Северной Голландии, Амстердам, 1958.
  • Карри, Хаскелл Б .; Хиндли, Дж. Роджер ; Селдин, Джонатан П. (1972). Комбинаторная логика . Vol. II. Амстердам: Северная Голландия. ISBN 978-0-7204-2208-5.
  • Доминус, Марк Джейсон. Perl высшего порядка . Морган Кауфманн . 2005 г.
  • Фелляйзен, Матиас; Финдлер, Роберт; Флатт, Мэтью; Кришнамурти, Шрирам (2001). Как разрабатывать программы . MIT Press.
  • Грэм, Пол. ANSI Common LISP . Энглвуд Клиффс, Нью-Джерси: Prentice Hall , 1996.
  • Макленнан, Брюс Дж. Функциональное программирование: практика и теория . Аддисон-Уэсли, 1990.
  • О'Салливан, Брайан; Стюарт, Дон; Герцен, Джон (2008). Реальный мир Haskell . О'Рейли.
  • Пратт, Терренс, В. и Марвин В. Зельковиц. Языки программирования: проектирование и реализация . 3-е изд. Энглвуд Клиффс, Нью-Джерси: Prentice Hall , 1996.
  • Салус, Питер Х. Функциональные и логические языки программирования . Vol. 4 Справочника по языкам программирования. Индианаполис, Индиана: Macmillan Technical Publishing , 1998.
  • Томпсон, Саймон. Haskell: Искусство функционального программирования . Харлоу, Англия: Addison-Wesley Longman Limited , 1996.

Внешние ссылки [ править ]

Послушайте эту статью ( 28 минут )
Разговорный значок Википедии
Этот аудиофайл был создан на основе редакции этой статьи от 25 августа 2011 года и не отражает последующих правок. ( 2011-08-25 )
  • Форд, Нил (29 января 2012 г.). «Функциональное мышление: почему растет популярность функционального программирования» . Проверено 24 февраля 2013 .
  • Ахмечет, Слава (19.06.2006). "defmacro - функциональное программирование для всех нас" . Проверено 24 февраля 2013 . Введение
  • Функциональное программирование на Python (Дэвид Мертц): часть 1 , часть 2 , часть 3