Я заинтересован в лучшем изучении функционального программирования. Для этого кажется очевидным, что я должен заставить себя использовать максимально чистый функциональный язык программирования. Следовательно, я здесь более или менее прошу упорядочить функциональные языки программирования в соответствии с их чистотой.
Мне кажется, что было бы более практично изучать Lisp или Clojure (или Scheme, или Scala и т. Д.), Но, как я недавно слышал, Haskell будет очень трудно победить в обучении принципам функционального программирования кому-то. Я еще не уверен в этом, поэтому я спрашиваю вас: какой самый чистый функциональный язык программирования? Заказ был бы великолепен, если бы несколько человек боролись за великолепное название самого функционального языка программирования.
Ответы:
Там нет шкалы для оценки степени чистоты функциональных языков. Если язык допускает побочные эффекты, он нечистый, иначе он чистый. По этому определению Haskell, Mercury, Clean и т. Д. Являются чисто функциональными языками; тогда как Scala, Clojure, F #, OCaml и т. д. являются нечистыми.
РЕДАКТИРОВАТЬ: Может быть, я должен был сформулировать это как «если язык не позволяет побочные эффекты, не сообщая системе типов , это чисто. В противном случае это нечисто».
источник
IO
монада). Просто код, вызывающий побочные эффекты, четко помечен как таковой. Я не думаю, что вообще полезно говорить о чистых / нечистых языках (Haskell позволяет вам обязательно программировать! Ага!), Но все же может быть полезно говорить о кусках кода (функции, модуля, программы и т. Д.) Как о чистых / нечистым.IO
монада является чистой. Это библиотека времени выполнения, которая не является вашим кодом, так как вашаmain
функция в основном является преобразователем состояния. (Что-то вродеmain :: World -> World
за кадром)program = "some C code"
, а затем среда выполнения имеет дело с кодом Си. :-)Поскольку обучение - ваша цель, а не написание программ как таковых, вы не можете получить ничего более чистого, чем Lambda Calculus .
Лямбда-исчисление было еще до изобретения компьютеров. Над этим работали несколько опытных логиков, чтобы понять, как вычитать (какое-то время теоретизировалось, что возможно только сложение и умножение).
Изучение того, как булевы и числа и как
if
их можно изобрести, казалось бы, ничего не добавит больше бензина в ваш бак, но это сделает ваш бак намного больше.источник
-1
.Нечистые языки в принципе не отличаются от более привычных императивных языков, особенно сейчас, когда скопировано много функциональных уловок. Отличается стиль - как вы решаете проблемы.
Считаете ли вы Haskell чистым или считаете монаду IO нечистым, стиль Haskell - это крайняя форма этого стиля, которую стоит изучить.
Монада Haskell IO получена из математической теории (конечно) монад. Тем не менее, для императивных программистов, я думаю, обратный способ достижения монад имеет больше смысла.
Первый этап - чистый функциональный язык может легко вернуть большое строковое значение в качестве результата. Эта большая строка может быть исходным кодом императивной программы, полученной чисто функциональным способом из некоторых параметров, определяющих требования. Затем вы можете создать компилятор «более высокого уровня», который запускает ваш генератор кода, а затем автоматически передает этот сгенерированный код в обязательный языковой компилятор.
Фаза вторая - вместо генерации текстового исходного кода вы генерируете строго типизированное абстрактное синтаксическое дерево. Ваш компилятор императивного языка включается в ваш компилятор "более высокого уровня" и принимает AST непосредственно в качестве исходного кода. Это намного ближе к тому, что делает Haskell.
Это все еще неловко, хотя. Например, у вас есть два разных вида функций - те, которые оцениваются на этапе генерации кода, и те, которые выполняются при запуске сгенерированной программы. Это немного похоже на различие между функциями и шаблонами в C ++.
Таким образом, для фазы 3, сделайте два одинаковых - одна и та же функция с одинаковым синтаксисом может быть частично оценена во время «генерации кода», или полностью оценена, или вообще не оценена. Далее, отбросьте все циклические узлы конструкции AST в пользу рекурсии. Фактически, полностью отбросьте идею об узлах AST как об особом виде данных - не имейте узлов AST с «буквальным значением», просто имейте значения и т. Д.
Это в значительной степени то, что делает монада IO - оператор связывания - это способ составления «действий» для формирования программ. Ничего особенного - просто функция. Многие выражения и функции могут быть оценены во время «генерации кода», но те, которые зависят от побочных эффектов ввода-вывода, должны иметь задержку оценки до времени выполнения - не по какому-либо специальному правилу, а как естественное следствие зависимостей данных в выражения.
Монады в целом являются просто обобщением - они имеют один и тот же интерфейс, но реализуют абстрактные операции по-разному, поэтому вместо оценки в виде императивного кода они вместо этого оценивают что-то другое. Наличие одного и того же интерфейса означает, что есть несколько вещей, которые вы можете делать с монадами, не заботясь о том, какая из них является полезной.
Это описание, несомненно, заставит взорваться головы пуристов, но для меня оно объясняет некоторые из реальных причин, почему Хаскель интересен. Он стирает границу между программированием и метапрограммированием и использует инструменты функционального программирования, чтобы заново изобретать императивное программирование без необходимости специального синтаксиса.
У меня есть критика шаблонов C ++ в том, что они являются своего рода сломанным чистым функциональным подъязыком в императивном языке - чтобы оценить ту же базовую функцию во время компиляции, а не во время выполнения, вам нужно заново реализовать ее, используя совершенно другой стиль кодирования. В Haskell, хотя примеси должны быть помечены как таковые в своем типе, одна и та же функция может быть оценена как в смысле метапрограммирования, так и в смысле неметапрограммирования во время выполнения в одной и той же программе - жесткой линии не существует между программированием и метапрограммированием.
Тем не менее, есть некоторые вещи метапрограммирования, которые не может сделать стандартный Haskell, в основном потому, что типы (и, возможно, некоторые другие вещи) не являются первоклассными значениями. Однако существуют языковые варианты, которые пытаются решить эту проблему.
Многое из того, что я сказал о Haskell, может быть применено на нечистых функциональных языках, а иногда даже на императивных языках. Haskell отличается тем, что у вас нет выбора, кроме как использовать этот подход - он в основном заставляет вас учиться этому стилю работы. Вы можете «написать C на ML», но вы не можете «написать C на Haskell» - по крайней мере, без изучения того, что происходит под капотом.
источник
Я лично делю языки на три уровня функциональной чистоты:
Чисто функциональные языки - то есть те, которые рассматривают всю вашу программу как чистую функцию и обрабатывают изменчивость исключительно посредством взаимодействия со средой выполнения - вероятно, канонический пример - Haskell
Нечистые функциональные языки - то есть те, которые подчеркивают функциональный стиль, но допускают побочные эффекты. Clojure явно относится к этой категории (он допускает контролируемые мутации как часть своей структуры STM), также OCaml или F #
Мультипарадигмальные языки - это в первую очередь не функциональные языки, но они могут поддерживать функциональный стиль с помощью функций первого класса и т. Д. Scala - хороший пример, я бы также включил Common Lisp в эту категорию, и вы могли бы даже включить языки, такие как JavaScript .
В вашей ситуации я бы предложил сначала изучить Haskell, а затем Clojure. Это было то, что я сделал, и это сработало очень хорошо для меня! Haskell красив и учит вас самым чистым функциональным принципам, Clojure гораздо более прагматичен и помогает вам многое сделать, оставаясь при этом очень функциональным в душе.
Я не считаю третью категорию функциональными языками (хотя после изучения Haskell и Clojure я часто использую функциональные приемы при их использовании!)
источник
Если чисто функциональный язык таков, что имеет только чистые функции (подпрограммы, не имеющие побочных эффектов), то это немного бессмысленно, потому что он не может читать ввод или запись вывода;)
Потому что это действительно для обучения, я думаю , что изоляция не обязательно путь. Функциональное программирование - это парадигма. Важно понимать, какие парадигмы подходят для каких проблем и, что более важно, как их лучше всего сочетать.
Кроме этого, если вы ищете «чистоту», вы можете взглянуть на Pure . Однако обратите внимание, что предельная простота вызова подпрограмм на Си делает его функционально неочищенным (но также очень мощным).
источник
Не совсем серьезный ответ, но Unlambda должен быть соперником. Вы не можете получить более «чистый функционал», чем комбинаторы SKI.
источник
Erlang, Haskell, Scheme, Scala, Clojure и F #
Этот вопрос, вероятно , лучше вы помочь вам в вашем поиске , как хорошо .
источник
set!
(помимо прочего) ...