stringtranslate.com

Функциональное программирование

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

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

Функциональное программирование иногда рассматривается как синоним чисто функционального программирования , подмножества функционального программирования, которое рассматривает все функции как детерминированные математические функции или чистые функции . Когда чистая функция вызывается с некоторыми заданными аргументами, она всегда будет возвращать один и тот же результат, и на нее не могут повлиять какие-либо изменяемые состояния или другие побочные эффекты . Это контрастирует с нечистыми процедурами , распространенными в императивном программировании , которые могут иметь побочные эффекты (например, изменение состояния программы или получение входных данных от пользователя). Сторонники чисто функционального программирования утверждают, что, ограничивая побочные эффекты, программы могут иметь меньше ошибок , их легче отлаживать и тестировать , а также они больше подходят для формальной проверки . [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 , C# , [26] Kotlin , [27] Perl , [28] PHP , [29] ] Python , [30] Go , [31] Rust , [32] Raku , [33] Scala , [34] и Java (начиная с Java 8) . [35]

История

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

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

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

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

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

В середине 1960-х годов Питер Ландин изобрел SECD-машину , [43] первую абстрактную машину для функционального языка программирования, [44] описал соответствие между АЛГОЛом 60 и лямбда-исчислением , [45] [46] и предложил программирование ISWIM . язык. [47]

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

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

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

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

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

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

Функциональное программирование продолжает использоваться в коммерческих целях. [53] [54] [55]

Концепции

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

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

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

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

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

Чистые функции

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

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

Рекурсия

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

Стандарт языка Scheme требует, чтобы реализации поддерживали правильную хвостовую рекурсию, то есть они должны допускать неограниченное количество активных хвостовых вызовов. [59] [60] Правильная хвостовая рекурсия — это не просто оптимизация; это языковая функция, которая гарантирует пользователям, что они могут использовать рекурсию для выражения цикла, и это будет безопасно для пространства. [61] Более того, вопреки названию, он учитывает все хвостовые вызовы, а не только хвостовую рекурсию. Хотя правильная хвостовая рекурсия обычно реализуется путем превращения кода в императивные циклы, реализации могут реализовывать ее другими способами. Например, Chicken намеренно поддерживает стек и позволяет ему переполниться . Однако, когда это произойдет, его сборщик мусора потребует пространство обратно, [62] позволяя неограниченное количество активных хвостовых вызовов, даже если он не превращает хвостовую рекурсию в цикл.

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

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

Строгая и нестрогая оценка

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

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

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

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

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

Типовые системы

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

Некоторые ориентированные на исследования функциональные языки, такие как Coq , Agda , Cayenne и Epigram , основаны на интуиционистской теории типов , которая позволяет типам зависеть от термов. Такие типы называются зависимыми типами . Эти системы типов не имеют разрешимого вывода типов, их трудно понять и программировать. [67] [68] [69] [70] Но зависимые типы могут выражать произвольные предложения в логике высшего порядка . Таким образом, благодаря изоморфизму Карри-Говарда хорошо типизированные программы на этих языках становятся средством написания формальных математических доказательств , на основе которых компилятор может генерировать сертифицированный код . Хотя эти языки представляют в основном интерес для академических исследований (в том числе в формализованной математике ), они начали использоваться и в технике. Compcert — это компилятор подмножества языка программирования C , написанного на Coq и формально проверенного. [71]

Ограниченная форма зависимых типов, называемая обобщенными алгебраическими типами данных (GADT), может быть реализована таким образом, чтобы обеспечить некоторые преимущества зависимо типизированного программирования, избегая при этом большинства его неудобств. [72] GADT доступны в компиляторе Glasgow Haskell , в OCaml [73] и в Scala , [74] и были предложены в качестве дополнения к другим языкам, включая Java и C#. [75]

Ссылочная прозрачность

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

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

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

Структуры данных

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

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

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

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

Императивное и функциональное программирование

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

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

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 ) { result += numList [ i ] * 10 ; } }                                     

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

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

Моделирование состояния

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

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

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

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

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

Проблемы эффективности

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

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

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

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

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

JavaScript , Lua , [89] Python и Go [90] с самого начала имели первоклассные функции . [91] Python имел поддержку « лямбда », « map », « reduce » и « filter » в 1994 году, а также замыканий в Python 2.2, [92] хотя Python 3 отнес «reduce» к functoolsстандартному библиотечному модулю. [93] Первоклассные функции были введены в другие основные языки, такие как PHP 5.3, Visual Basic 9 , C# 3.0, C++11 и Kotlin . [27] [ нужна ссылка ]

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

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

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

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

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

Сравнение с логическим программированием

Логическое программирование можно рассматривать как обобщение функционального программирования, в котором функции являются частным случаем отношений. [99] Например, функция мать(X) = Y (каждый X имеет только одну мать Y) может быть представлена ​​отношением мать(X, Y). В то время как функции имеют строгий шаблон ввода-вывода аргументов, отношения могут быть запрошены с любым шаблоном входов и выходов. Рассмотрим следующую логическую программу:

мать ( Чарльз ,  Элизабет ). мать ( Гарри ,  Диана ).

Программу можно запросить, как функциональную программу, для создания матерей из детей:

?-  мать ( Гарри ,  Икс ). Х  =  Диана . ?-  мать ( Чарльз ,  X ). Х  =  Элизабет .

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

?-  мать ( X ,  Элизабет ). Х  =  Чарльз . ?-  мать ( X ,  Диана ). Х  =  Гарри .

Его даже можно использовать для генерации всех экземпляров материнского отношения:

?-  мать ( X ,  Y ). X  =  Чарльз , Y  =  Элизабет . X  =  Гарри , Y  =  Диана .

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

maternal_grandmother ( X )  =  мать ( мать ( X )).

Это же определение в реляционной нотации нужно записать в невложенной форме:

maternal_grandmother ( X ,  Y )  :-  мать ( X ,  Z ),  мать ( Z ,  Y ).

Здесь :-означает если и , означает и .

Однако разница между этими двумя представлениями просто синтаксическая. В Ciao Prolog отношения могут быть вложенными, как функции в функциональном программировании: [100]

дедушка ( X )  :=  родитель ( родитель ( X )). родитель ( X )  :=  мать ( X ). родитель ( X )  :=  отец ( X ).мать ( Чарльз )  :=  Элизабет . отец ( Чарльз )  :=  Филипп . мать ( Гарри )  :=  Диана . отец ( Гарри )  :=  Чарльз .?-  дедушка ( X , Y ). X  =  Гарри , Y  =  Элизабет . X  =  Гарри , Y  =  Филипп .

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

Приложения

Таблицы

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

Академия

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

Промышленность

Функциональное программирование используется в широком спектре промышленных приложений. Например, Erlang , разработанный шведской компанией Ericsson в конце 1980-х годов, первоначально использовался для реализации отказоустойчивых телекоммуникационных систем [11] , но с тех пор стал популярен для создания ряда приложений в таких компаниях, как Nortel , Facebook . , Электрисите де Франс и WhatsApp . [10] [12] [103] [104] [105] Scheme , диалект Lisp , использовался в качестве основы для нескольких приложений на ранних компьютерах Apple Macintosh [3] [4] и применялся для решения таких задач, как обучение - программное обеспечение для моделирования [5] и управления телескопом . [6] OCaml , представленный в середине 1990-х годов, нашел коммерческое применение в таких областях, как финансовый анализ, [14] проверка драйверов , программирование промышленных роботов и статический анализ встроенного программного обеспечения . [15] Haskell , хотя изначально задумывался как исследовательский язык, [17] также применялся в таких областях, как аэрокосмические системы, проектирование аппаратного обеспечения и веб-программирование. [16] [17]

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

Функциональные «платформы» популярны в финансовой сфере для анализа рисков (особенно среди крупных инвестиционных банков). Факторы риска кодируются как функции, которые образуют взаимозависимые графики (категории) для измерения корреляций в рыночных сдвигах, аналогично оптимизации на основе Грёбнера , но также и для нормативных рамок, таких как комплексный анализ и обзор капитала . Учитывая использование вариаций OCaml и Caml в финансах, эти системы иногда считают связанными с категориальной абстрактной машиной . Функциональное программирование находится под сильным влиянием теории категорий . [ нужна цитата ]

Образование

Во многих университетах преподают функциональное программирование. [111] [112] [113] [114] Некоторые рассматривают это как вводную концепцию программирования [114] , в то время как другие сначала обучают методам императивного программирования. [113] [115]

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

Смотрите также

Примечания и ссылки

  1. ^ Худак, Пол (сентябрь 1989 г.). «Концепция, эволюция и применение языков функционального программирования» (PDF) . Обзоры вычислительной техники ACM . 21 (3): 359–411. дои : 10.1145/72551.72554. S2CID  207637854.
  2. ^ аб Хьюз, Джон (1984). «Почему функциональное программирование имеет значение».
  3. ^ аб Клингер, Уилл (1987). «Многозадачность и MacScheme». МакТех . 3 (12) . Проверено 28 августа 2008 г.
  4. ^ аб Хартхаймер, Энн (1987). «Программирование текстового редактора в MacScheme + Toolsmith». МакТех . 3 (1). Архивировано из оригинала 29 июня 2011 г. Проверено 28 августа 2008 г.
  5. ^ Аб Кидд, Эрик. Схема обучения реагированию на терроризм. КУФП 2007 . Проверено 26 августа 2009 г.
  6. ^ Аб Клейс, Ричард. Схема в космосе. КУФП 2006 . Проверено 26 августа 2009 г.
  7. ^ ab «Руководство по языку Wolfram: функциональное программирование». 2015 . Проверено 24 августа 2015 г.
  8. ^ «Функциональный и процедурный язык программирования». Кафедра прикладной математики . Университет Колорадо. Архивировано из оригинала 13 ноября 2007 г.
  9. ^ «Сценарии на основе состояния в Uncharted 2» (PDF) . Архивировано из оригинала (PDF) 15 декабря 2012 г. Проверено 8 августа 2011 г.
  10. ^ ab «Кто использует Erlang для разработки продуктов?». Часто задаваемые вопросы об Эрланге . Проверено 27 апреля 2018 г.
  11. ^ Аб Армстронг, Джо (июнь 2007 г.). «История Эрланга». Материалы третьей конференции ACM SIGPLAN по истории языков программирования . Третья конференция ACM SIGPLAN по истории языков программирования. Сан-Диего, Калифорния. дои : 10.1145/1238844.1238850. ISBN 9781595937667.
  12. ^ Аб Ларсон, Джим (март 2009 г.). «Эрланг для параллельного программирования». Коммуникации АКМ . 52 (3): 48. дои : 10.1145/1467247.1467263 . S2CID  524392.
  13. ^ «Язык программирования Elixir» . Проверено 14 февраля 2021 г.
  14. ^ аб Мински, Ярон; Уикс, Стивен (июль 2008 г.). «Caml Trading — опыт функционального программирования на Уолл-стрит». Журнал функционального программирования . 18 (4): 553–564. дои : 10.1017/S095679680800676X . S2CID  30955392.
  15. ^ аб Лерой, Ксавьер. Некоторые варианты использования Caml в промышленности (PDF) . КУФП 2007 . Проверено 26 августа 2009 г.
  16. ^ ab «Haskell в промышленности». Хаскелл Вики . Проверено 26 августа 2009 г. Haskell имеет широкий спектр коммерческого использования: от аэрокосмической и оборонной промышленности до финансов, веб-стартапов, фирм по разработке оборудования и производителей газонокосилок.
  17. ^ abc Худак, Пол ; Хьюз, Дж.; Джонс, СП; Уодлер, П. (июнь 2007 г.). История Haskell: лень с классами. Третья конференция ACM SIGPLAN по истории языков программирования. Сан-Диего, Калифорния. дои : 10.1145/1238844.1238856 . Проверено 26 сентября 2013 г.
  18. ^ Аб Мэнселл, Ховард (2008). Количественные финансы в F#. КУФП 2008 . Проверено 29 августа 2009 г.
  19. ^ Аб Пик, Алекс (2009). Первая существенная сфера бизнес-приложений на F#. CUFP 2009. Архивировано из оригинала 17 октября 2009 г. Проверено 29 августа 2009 г.
  20. ^ комментарии, 27 июня 2017 г. Matt Banz Feed 603up 2. «Введение в функциональное программирование на JavaScript». Opensource.com . Проверено 9 января 2021 г.{{cite web}}: CS1 maint: numeric names: authors list (link)
  21. ^ «В расписание конференции useR! 2006 включены статьи о коммерческом использовании R» . R-project.org. 8 июня 2006 г. Проверено 20 июня 2011 г.
  22. ^ Чемберс, Джон М. (1998). Программирование с данными: Руководство по языку S. Спрингер Верлаг. стр. 67–70. ISBN 978-0-387-98503-9.
  23. ^ Новатчев, Дмитрий. «Язык функционального программирования XSLT — доказательство на примерах» . Проверено 27 мая 2006 г.
  24. ^ Мерц, Дэвид. «Парадигмы программирования XML (часть четвертая): подход функционального программирования к обработке XML». IBM DeveloperWorks . Проверено 27 мая 2006 г.
  25. ^ Чемберлин, Дональд Д .; Бойс, Раймонд Ф. (1974). «ПРОДОЛЖЕНИЕ: структурированный английский язык запросов». Материалы ACM SIGFIDET 1974 г .: 249–264.
  26. ^ Функциональное программирование на C# - Simon Painter - NDC Oslo 2020, заархивировано из оригинала 30 октября 2021 г. , получено 23 октября 2021 г.
  27. ^ ab «Функциональное программирование — язык программирования Kotlin». Котлин . Проверено 1 мая 2019 г.
  28. ^ Доминус, Марк Дж. (2005). Perl высшего порядка . Морган Кауфманн . ISBN 978-1-55860-701-9.
  29. ^ Холиуэлл, Саймон (2014). Функциональное программирование на PHP . php[архитектор]. ISBN 9781940111056.
  30. ^ The Cain Gang Ltd. «Метаклассы Python: кто? Почему? Когда?» (PDF) . Архивировано из оригинала (PDF) 30 мая 2009 года . Проверено 27 июня 2009 г.
  31. ^ «GopherCon 2020: Дилан Миус - функциональное программирование с помощью Go» . YouTube .
  32. ^ «Функции функционального языка: итераторы и замыкания - язык программирования Rust» . doc.rust-lang.org . Проверено 9 января 2021 г.
  33. Вандербауведе, Вим (18 июля 2020 г.). «Чистый код с функциональным программированием». Архивировано из оригинала 28 июля 2020 года . Проверено 6 октября 2020 г.
  34. ^ «Эффективная Скала». Скала Вики . Проверено 21 февраля 2012 г. Эффективная Скала.
  35. ^ «Документация для пакета java.util.function начиная с Java 8 (также известной как Java 1.8)» . Проверено 16 июня 2021 г.
  36. ^ Тьюринг, AM (1937). «Вычислимость и λ-определимость». Журнал символической логики . Издательство Кембриджского университета. 2 (4): 153–163. дои : 10.2307/2268280. JSTOR  2268280. S2CID  2317046.
  37. ^ Хаскелл Брукс Карри; Роберт Фейс (1958). Комбинаторная логика . Издательская компания Северной Голландии . Проверено 10 февраля 2013 г.
  38. ^ Черч, А. (1940). «Формулировка простой теории типов». Журнал символической логики . 5 (2): 56–68. дои : 10.2307/2266170. JSTOR  2266170. S2CID  15889861.
  39. ^ Маккарти, Джон (июнь 1978 г.). История Лиспа (PDF) . История языков программирования . Лос Анджелес, Калифорния. стр. 173–185. дои : 10.1145/800025.808387.
  40. ^ Джон Маккарти (1960). «Рекурсивные функции символьных выражений и их машинное вычисление, Часть I». (PDF) . Коммуникации АКМ . ACM Нью-Йорк, Нью-Йорк, США. 3 (4): 184–195. дои : 10.1145/367177.367199. S2CID  1489409.
  41. ^ Гай Л. Стил; Ричард П. Габриэль (февраль 1996 г.). «Эволюция Лиспа». История языков программирования---II (PDF) . стр. 233–330. дои : 10.1145/234286.1057818. ISBN 978-0-201-89502-5. S2CID  47047140.
  42. ^ В мемуарах Герберта А. Саймона (1991), «Модели моей жизни» , стр. 189–190 ISBN 0-465-04640-1 , утверждается, что он, Эл Ньюэлл и Клифф Шоу «... обычно считаются родителями [области] искусственного интеллекта» за написание Logic Theorist , программы, которая автоматически доказывала теоремы из Principia Mathematica . Чтобы добиться этого, им пришлось изобрести язык и парадигму, которые, если смотреть ретроспективно, включают в себя функциональное программирование. 
  43. ^ Ландин, Питер Дж. (1964). «Механическая оценка выражений». Компьютерный журнал . Британское компьютерное общество . 6 (4): 308–320. дои : 10.1093/comjnl/6.4.308 .
  44. ^ Диль, Стефан; Хартель, Питер; Сестофт, Питер (2000). «Абстрактные машины для реализации языков программирования». Компьютерные системы будущего поколения . Том. 16. С. 739–751.
  45. ^ Ландин, Питер Дж. (февраль 1965a). «Соответствие между АЛГОЛом 60 и лямбда-нотацией Чёрча: часть I». Коммуникации АКМ . Ассоциация вычислительной техники . 8 (2): 89–101. дои : 10.1145/363744.363749 . S2CID  6505810.
  46. ^ Ландин, Питер Дж. (март 1965b). «Соответствие между АЛГОЛом 60 и лямбда-нотацией Чёрча: часть II». Коммуникации АКМ . Ассоциация вычислительной техники . 8 (3): 158–165. дои : 10.1145/363791.363804 . S2CID  15781851.
  47. ^ Ландин, Питер Дж. (март 1966b). «Следующие 700 языков программирования». Коммуникации АКМ . Ассоциация вычислительной техники . 9 (3): 157–166. дои : 10.1145/365230.365257 . S2CID  13409665.
  48. ^ Бэкус, Дж. (1978). «Можно ли программирование освободить от стиля фон Неймана?: Функциональный стиль и его алгебра программ». Коммуникации АКМ . 21 (8): 613–641. дои : 10.1145/359576.359579 .
  49. ^ РМ Берстолл. Соображения по проектированию функционального языка программирования. Приглашенный доклад, Учеб. Конференция по новейшим технологиям Infotech. «Революция программного обеспечения», Копенгаген, 45–57 (1977).
  50. ^ RM Берстолл и Дж. Дарлингтон. Система преобразований для разработки рекурсивных программ. Журнал Ассоциации вычислительной техники 24 (1): 44–67 (1977).
  51. ^ RM Burstall, DB MacQueen и DT Sannella. НАДЕЖДА: экспериментальный аппликативный язык. Учеб. Конференция LISP 1980 г., Стэнфорд, 136–143 (1980).
  52. ^ «Облегчите обнаружение метода Assign()!». OpenSCAD . Архивировано из оригинала 19 апреля 2023 г.
  53. Питер Брайт (13 марта 2018 г.). «Разработчики любят новые модные языки, но зарабатывают больше с помощью функционального программирования». Арс Техника .
  54. Джон Леонард (24 января 2017 г.). «Скрытый рост функционального программирования». Вычисление.
  55. Лео Чунг (9 мая 2017 г.). «Лучше ли функциональное программирование для вашего стартапа?». Инфомир .
  56. ^ Шон Талл - Моноидальные категории для анализа формальных концепций.
  57. ^ Паунтейн, Дик. «Функциональное программирование достигает зрелости». Байт (август 1994 г.) . Архивировано из оригинала 27 августа 2006 г. Проверено 31 августа 2006 г.
  58. ^ ab «ISO/IEC JTC 1/SC 22/WG5/N2137». Международная Организация Стандартизации. 6 июля 2017 г. {{cite journal}}: Требуется цитировать журнал |journal=( помощь )
  59. ^ «Пересмотренный отчет ^ 6 по схеме алгоритмического языка» . R6rs.org . Проверено 21 марта 2013 г.
  60. ^ «Пересмотренный отчет ^ 6 по схеме алгоритмического языка - Обоснование» . R6rs.org . Проверено 21 марта 2013 г.
  61. ^ Клингер, Уильям (1998). «Правильная хвостовая рекурсия и эффективность использования пространства». Материалы конференции ACM SIGPLAN 1998 года по проектированию и реализации языков программирования — PLDI '98 . стр. 174–185. дои : 10.1145/277650.277719. ISBN 0897919874. S2CID  16812984.
  62. ^ Бейкер, Генри (1994). «CONS не должен аргументировать CONS, часть II: Чейни о MTA»
  63. ^ Тернер, Д.А. (28 июля 2004 г.). «Тотальное функциональное программирование». Журнал универсальной информатики . 10 (7): 751–768. doi : 10.3217/jucs-010-07-0751.
  64. ^ Реализация языков функционального программирования. Саймон Пейтон Джонс, опубликовано Prentice Hall, 1987 г.
  65. ^ аб Джон Лаунбери (1993). «Естественная семантика для ленивой оценки»: 144–154. CiteSeerX 10.1.1.35.2016 .  {{cite journal}}: Требуется цитировать журнал |journal=( помощь )
  66. ^ Роберт В. Харпер (2009). Практические основы языков программирования (PDF) . Архивировано из оригинала (PDF) 7 апреля 2016 г.
  67. ^ Юэ, Жерар П. (1973). «Неразрешимость объединения в логике третьего порядка». Информация и контроль . 22 (3): 257–267. дои : 10.1016/s0019-9958(73)90301-x.
  68. ^ Юэ, Жерар (сентябрь 1976 г.). Резолюция d'Equations dans des Langages d'Ordre 1,2,...ω (доктор философии) (на французском языке). Парижский университет VII.
  69. ^ Юэ, Жерар (2002). «Объединение высшего порядка 30 лет спустя» (PDF) . Ин Карреньо, В.; Муньос, К.; Тахар, С. (ред.). Материалы 15-й Международной конференции ТФОЛ . ЛНКС. Том. 2410. Спрингер. стр. 3–12.
  70. ^ Уэллс, Дж. Б. (1993). «Типизация и проверка типов в лямбда-исчислении второго порядка эквивалентны и неразрешимы». Тех. Реп. 93-011 : 176–185. CiteSeerX 10.1.1.31.3590 . 
  71. Лерой, Ксавье (17 сентября 2018 г.). «Компилятор, проверенный Compcert».
  72. ^ Пейтон Джонс, Саймон; Витиниотис, Димитриос; Вейрих, Стефани ; Джеффри Уошберн (апрель 2006 г.). «Простой вывод типов на основе унификации для GADT». ICFP 2006 : 50–61.
  73. ^ «Руководство по OCaml». caml.inria.fr . Проверено 8 марта 2021 г.
  74. ^ «Алгебраические типы данных». Документация Скала . Проверено 8 марта 2021 г.
  75. ^ Кеннеди, Эндрю; Руссо, Клаудио (октябрь 2005 г.). Обобщенные алгебраические типы данных и объектно-ориентированное программирование (PDF) . Сан-Диего, Калифорния. ISBN 9781595930316. Архивировано из оригинала (PDF) 29 декабря 2006 г. {{cite book}}: |work=игнорируется ( помощь ) источник цитированияCS1 maint: location missing publisher (link)
  76. ^ Хьюз, Джон. «Почему функциональное программирование имеет значение» (PDF) . Технологический университет Чалмерса .
  77. ^ Чисто функциональные структуры данных Криса Окасаки , Cambridge University Press , 1998, ISBN 0-521-66350-4 
  78. ^ L'orange, Жан Никлас. «Полиматея - Понимание постоянного вектора Clojure, часть 1». Полиматея . Проверено 13 ноября 2018 г.
  79. ^ Майкл Барр, Чарльз Уэлл - Теория категорий в информатике.
  80. ^ Ньюберн, Дж. «Все о монадах: исчерпывающее руководство по теории и практике монадического программирования на Haskell» . Проверено 14 февраля 2008 г.
  81. ^ «Тринадцать способов взглянуть на черепаху» . fF# для развлечения и прибыли . Проверено 13 ноября 2018 г.
  82. Полсон, Ларри К. (28 июня 1996 г.). ML для работающего программиста. Издательство Кембриджского университета. ISBN 978-0-521-56543-1. Проверено 10 февраля 2013 г.
  83. Спивак, Дэниел (26 августа 2008 г.). «Реализация постоянных векторов в Scala». Фиксация кода .
  84. ^ «Какие программы самые быстрые? | Игра с тестами компьютерного языка» . тестыgame.alioth.debian.org. Архивировано из оригинала 20 мая 2013 г. Проверено 20 июня 2011 г.
  85. ^ Игорь Пещанский; Вивек Саркар (2005). «Спецификация неизменности и ее приложения». Параллелизм и вычисления: практика и опыт . 17 (5–6): 639–662. дои : 10.1002/cpe.853. S2CID  34527406.
  86. ^ «Глава 25. Профилирование и оптимизация». Book.realworldhaskell.org . Проверено 20 июня 2011 г.
  87. ^ Хартель, Питер; Хенк Мюллер; Хью Глейзер (март 2004 г.). «Опыт функционального C» (PDF) . Журнал функционального программирования . 14 (2): 129–135. дои : 10.1017/S0956796803004817. S2CID  32346900.; Дэвид Мерц. «Функциональное программирование на Python, часть 3». IBM DeveloperWorks . Архивировано из оригинала 16 октября 2007 г. Проверено 17 сентября 2006 г.(Часть 1, Часть 2)
  88. ^ «Функции — язык программирования D 2.0» . Цифровой Марс. 30 декабря 2012 г.
  89. ^ «Неофициальные часто задаваемые вопросы о Lua (uFAQ)» .
  90. ^ «Первоклассные функции в Go - язык программирования Go» . golang.org . Проверено 4 января 2021 г.
  91. Эйх, Брендан (3 апреля 2008 г.). «Популярность».
  92. ^ ван Россум, Гвидо (21 апреля 2009 г.). «Происхождение «функциональных» возможностей Python» . Проверено 27 сентября 2012 г.
  93. ^ «functools — Функции высшего порядка и операции над вызываемыми объектами». Фонд программного обеспечения Python. 31 июля 2011 г. Проверено 31 июля 2011 г.
  94. ^ Скарсауне, Мартин (2008). Проект SICS Java Port Автоматический перевод большой объектно-ориентированной системы со Smalltalk на Java .
  95. ^ Гослинг, Джеймс. «Замыкания». Джеймс Гослинг: на Яванской дороге . Оракул. Архивировано из оригинала 14 апреля 2013 г. Проверено 11 мая 2013 г.
  96. Уильямс, Майкл (8 апреля 2013 г.). «Краткий старт Java SE 8 Lambda».
  97. ^ Блох, Джошуа (2008). «Пункт 15: Минимизация изменчивости». Эффективная Java (Второе изд.). Аддисон-Уэсли. ISBN 978-0321356680.
  98. ^ «Object.freeze() — JavaScript | MDN» . http://developer.mozilla.org . Проверено 4 января 2021 г. Метод Object.freeze() замораживает объект. Замороженный объект больше нельзя изменить; Замораживание объекта предотвращает добавление к нему новых свойств, удаление существующих свойств, предотвращает изменение перечисляемости, возможности настройки или записи существующих свойств, а также предотвращает изменение значений существующих свойств. Кроме того, замораживание объекта также предотвращает изменение его прототипа. Freeze() возвращает тот же объект, который был передан.
  99. ^ Дэниел Фридман; Уильям Берд; Олег Киселев; Джейсон Хеманн (2018). Разумный интриган, второе издание . Массачусетский технологический институт Пресс.
  100. ^ А. Касас, Д. Кабеса, М. В. Эрменегильдо. Синтаксический подход к объединению функциональной записи, ленивого вычисления и высшего порядка в системах LP. 8-й Международный симпозиум по функциональному и логическому программированию (FLOPS'06), страницы 142–162, апрель 2006 г.
  101. ^ Уэйклинг, Дэвид (2007). «Функциональное программирование электронных таблиц» (PDF) . Журнал функционального программирования . 17 (1): 131–143. дои : 10.1017/S0956796806006186. ISSN  0956-7968. S2CID  29429059.
  102. ^ Пейтон Джонс, Саймон ; Бернетт, Маргарет ; Блэквелл, Алан (март 2003 г.). «Улучшение самого популярного в мире функционального языка: пользовательские функции в Excel». Архивировано из оригинала 16 октября 2005 г.
  103. ^ Пиро, Кристофер (2009). Функциональное программирование в Facebook. CUFP 2009. Архивировано из оригинала 17 октября 2009 г. Проверено 29 августа 2009 г.
  104. ^ «Sim-Diasca: крупномасштабный механизм одновременного моделирования дискретных событий в Erlang» . Ноябрь 2011 г.
  105. ^ 1 миллион - это так, 2011 г. Архивировано 19 февраля 2014 г. в Wayback Machine // Блог WhatsApp, 6 января 2012 г.: «Последняя важная часть нашей инфраструктуры - Erlang»
  106. ^ Момтахан, Ли (2009). Scala в EDF Trading: реализация предметно-ориентированного языка для ценообразования производных финансовых инструментов с помощью Scala. CUFP 2009. Архивировано из оригинала 17 октября 2009 г. Проверено 29 августа 2009 г.
  107. ^ Грэм, Пол (2003). «Победа над средними показателями» . Проверено 29 августа 2009 г.
  108. ^ Симс, Стив (2006). Создание стартапа с помощью стандартного машинного обучения (PDF) . КУФП 2006 . Проверено 29 августа 2009 г.
  109. ^ Лаурикари, Вилле (2007). Функциональное программирование в области безопасности коммуникаций. КУФП 2007 . Проверено 29 августа 2009 г.
  110. Лоример, RJ (19 января 2009 г.). «Анонсировано приложение Clojure для живого производства» . ИнфоQ .
  111. ^ «Функциональное программирование: 2019-2020». Факультет компьютерных наук Оксфордского университета . Проверено 28 апреля 2020 г.
  112. ^ «Программирование I (Haskell)» . Имперский колледж Лондона, факультет вычислительной техники . Проверено 28 апреля 2020 г.
  113. ^ ab «Бакалавр информатики — Модули» . Проверено 28 апреля 2020 г.
  114. ^ Аб Абельсон, Хэл ; Сассман, Джеральд Джей (1985). «Предисловие ко второму изданию». Структура и интерпретация компьютерных программ (2-е изд.). МТИ Пресс.
  115. ^ Джон ДеНеро (осень 2019 г.). «Информатика 61А, Беркли». Департамент электротехники и компьютерных наук, Беркли . Проверено 14 августа 2020 г.
  116. Эммануэль Шанцер из Bootstrap дал интервью телешоу «Триангуляция» в сети TWiT.tv.

дальнейшее чтение

Внешние ссылки

Послушайте эту статью ( 28 минут )
Разговорная иконка Википедии
Этот аудиофайл был создан на основе редакции этой статьи от 25 августа 2011 года и не отражает последующие изменения. (2011-08-25)
  1. ^ "Домашняя страница Грега Майклсона" . Математические и компьютерные науки . Риккартон, Эдинбург: Университет Хериот-Ватт . Проверено 6 ноября 2022 г.