Используя генераторы и лямбду, мы можем выполнять функциональное программирование на Python. Вы также можете достичь того же с Ruby.
Поэтому возникает вопрос: зачем нам нужны специальные функциональные языки программирования, такие как Erlang, Haskell и Scheme? Есть ли что-то другое, что обеспечивают эти специфические функциональные языки программирования? Почему мы не можем просто использовать Python для функционального программирования?
programming-languages
python
functional-programming
Джошуа Партоги
источник
источник
Ответы:
Я ценю этот вопрос, потому что лично я большой поклонник как Python, так и функционального стиля программирования. У меня большой опыт работы с Python, и я недавно начал изучать Haskell, поэтому вот некоторые моменты, основанные на моем личном опыте, касающемся различий между этими языками, с функциональной точки зрения.
чистота
Даже если вы не заботитесь о чистоте функций (т. Е. Об отсутствии побочных эффектов), как о принципах, это оказывает практическое влияние на то, насколько легко читать код и рассуждать об этом. Даже если вы поддерживаете чистоту в своих собственных функциях Python, существует большая разница в том, что компилятор обеспечивает чистоту и, что самое главное, в стандартной библиотеке, основанной на принципах чистоты и неизменных структурах данных.
Спектакль
Вы можете или не можете заботиться о производительности, в зависимости от того, что является областью вашего приложения, но статическая типизация и гарантированная чистота дают компилятору гораздо больше возможностей для работы, по сравнению с Python и другими динамическими языками (хотя я должен признать, что PyPy делает великолепно и, например, LuaJIT граничит с чудесным).
Оптимизация Tail-Call
Относится к производительности, но немного отличается. Даже если вы не слишком заботитесь о производительности во время выполнения, отсутствие оптимизации хвостового вызова (особенно для хвостовой рекурсии) ограничивает способы реализации алгоритмов в Python без ограничения пределов стека.
Синтаксис
Это главная причина, почему я начал смотреть на «настоящие» функциональные языки, а не просто использовать Python с функциональным стилем. Хотя я думаю, что Python имеет очень выразительный синтаксис в целом, у него есть некоторые слабые места, характерные для функционального кодирования. Например:
f = g . h
противf = lambda *arg: g(h(*arg))
f = map g
противf = functools.partial(map, g)
sum = reduce (+) lst
противsum = reduce(operator.add, lst)
y = func1 $ func2 $ func3 x
легче читать, чемy = func1(func2(func3(x)))
когда вы знакомы с этой нотацией.источник
Это самые важные различия:
Haskell
Хаскелл и Эрланг
Erlang
Схема
Все языки
Кроме того, вам следует взглянуть на языки из семейства ML, такие как SML, Ocaml и F # и Scala, которые по-новому объединяют ОО и функциональное программирование. Все эти языки имеют уникальные интересные особенности.
источник
Трудно точно определить, что такое «функциональный язык» - из перечисленных вами языков только Haskell является чисто функциональным (все остальные используют какой-то гибридный подход). Тем не менее, существуют определенные языковые функции, которые очень полезны для функционального программирования, и у Ruby и Python их недостаточно, чтобы быть очень хорошей средой для FP. Вот мой личный контрольный список, в порядке важности:
Необходимость (1) должна быть очевидна - функции высшего порядка чрезвычайно сложны без функций первого класса. Когда люди говорят, что Ruby и Python являются хорошими языками для FP, они обычно говорят об этом. Тем не менее, эта особенность необходима, но не достаточна, чтобы сделать язык хорошим для FP.
(2) была традиционная необходимость в FP с тех пор, как была изобретена схема. Без TCO невозможно программировать с глубокой рекурсией, которая является одним из краеугольных камней FP, потому что вы получаете переполнение стека. Единственный «функциональный» (по общему определению) язык, который не имеет этого, - это Clojure (из-за ограничений JVM), но у Clojure есть множество хаков для имитации TCO. (К сведению, Ruby TCO зависит от реализации , но Python специально не поддерживает его .) Причина, по которой TCO должен быть гарантирован, заключается в том, что если это зависит от реализации, глубокие рекурсивные функции будут порваться с некоторыми реализациями, поэтому вы не сможете по-настоящему использовать их на всех.
(3) еще одна важная вещь, которую современные функциональные языки (особенно Haskell, Erlang, Clojure и Scala) имеют, чего нет в Ruby и Python. Не вдаваясь в подробности, гарантированная неизменность устраняет целые классы ошибок, особенно в параллельных ситуациях, и допускает такие аккуратные вещи, как постоянные структуры данных . Этими преимуществами очень сложно пользоваться без поддержки на уровне языка.
(4) для меня самая интересная вещь в чисто функциональных языках (в отличие от гибридных). Рассмотрим следующую чрезвычайно простую функцию Ruby:
Это похоже на чистую функцию, но из-за перегрузки оператора она может изменить либо параметр, либо вызвать побочные эффекты, такие как печать на консоль. Маловероятно, что кто-то перегружает
+
оператора, чтобы иметь побочный эффект, но язык не дает никаких гарантий. (То же самое относится и к Python, хотя, возможно, не с этим конкретным примером.)В чисто функциональном языке, с другой стороны, существуют гарантии уровня языка, что функции прозрачны по ссылкам. Это имеет многочисленные преимущества: чистые функции легко запоминаются; их можно легко протестировать, не полагаясь ни на какое глобальное состояние; и значения внутри функции могут оцениваться лениво или параллельно, не беспокоясь о проблемах параллелизма. Haskell в полной мере использует это, но я не знаю достаточно о других функциональных языках, чтобы знать, делают ли они.
При этом можно использовать технику FP практически на любом языке (даже на Java). Например, Google MapReduce вдохновлен функциональными идеями, но, насколько я знаю, они не используют никаких «функциональных» языков для своих больших проектов (я думаю, что они в основном используют C ++, Java и Python).
источник
Языки, которые вы упоминаете, очень разные.
В то время как Python и Ruby являются динамически типизированными языками, Haskell статически типизирован. Erlang - это параллельный язык, использующий модель Actor, и он сильно отличается от всех других языков, которые вы упоминаете.
Python и Ruby имеют много императивных конструкций, в то время как в более чистом функциональном языке, таком как Haskell, все возвращает что-то или, другими словами, все является функцией.
источник
Опоздал на вечеринку, как обычно, но все равно собирался что-то сказать.
Функциональный язык программирования не является языком, который допускает функциональное программирование. Если бы мы следовали этому определению, то практически любой язык в любом месте является функциональным языком программирования. (Кстати, то же самое относится и к ООП. Вы можете писать в стиле ООП на С, если хотите. Таким образом, согласно вашей логике, С является языком ООП.)
Что делает функциональный язык программирования не тем, что позволяет вам программировать, а тем, что позволяет вам легко программировать . Это ключ.
Итак, в Python есть лямбды (которые являются невероятно анемичными, похожими на замыкания) и предоставляет вам пару библиотечных функций, которые вы увидите в функциональных библиотеках, таких как «map» и «fold». Однако этого недостаточно для того, чтобы сделать его функциональным языком программирования, потому что трудно или невозможно последовательно программировать в надлежащем функциональном стиле (и язык, безусловно , не применяет этот стиль!). По своей сути Python является императивным языком, связанным с операциями манипулирования состоянием и состоянием, и это просто противоречит семантике выражения и оценки выражения функционального языка.
Так почему же у нас есть функциональные языки программирования, когда Python (или Ruby (или вставьте язык по вашему выбору)) может «заниматься функциональным программированием»? Потому что Python и др. Не могут делать правильное функциональное программирование. Поэтому.
источник
Вы можете заниматься функциональным программированием на Java (см., Например, http://functionaljava.org/ ). Вы также можете заниматься объектно-ориентированным программированием на языке Си . Это просто не так идиоматично.
Так что на самом деле нам совершенно не нужны Erlang, Haskell, Scheme или какой-либо конкретный язык программирования, но все они представляют разные подходы и различные компромиссы, что делает некоторые задачи проще, а некоторые сложнее. Что вы должны использовать, зависит от того, чего вы хотите достичь.
источник
Этот вопрос может быть применен к бесконечному количеству языков и парадигм.
Большинство, если не все языки существуют по определенной причине. Они существуют, потому что у кого-то была потребность в том, чтобы ни один текущий язык не заполнялся или заполнялся плохо. (Это, конечно, относится не ко всем языкам, но я чувствую, что это относится к большинству известных языков.) Например, python изначально был разработан для взаимодействия с ОС Amoeba [ 1 , 2 ], а Erlang был создан, чтобы помочь в разработке приложений телефонии [ 3 ]. Итак, один ответ на вопрос «Зачем нам нужен другой функциональный язык?» может быть просто потому, что [insert-name-of-the-кто-то-кто-знает-как-к-дизайн-языкам] не понравилось, как это сделал python.
Это в значительной степени подводит итог того, что я думаю, ответ. Хотя вы можете делать с Python все, что вы можете делать с функциональным языком, вы бы действительно этого хотели? Все, что вы можете делать в C, вы можете делать в сборке, но хотите ли вы? Разные языки всегда будут лучше всего делать разные вещи, и так и должно быть.
источник
Функциональное программирование - это не только парадигма дизайна, но и специфические особенности языка. Или, другими словами, лямбды и функция карты не являются функциональным языком программирования. Python и Ruby имеют некоторые функции, вдохновленные функциональными языками программирования, но вы все равно обычно пишете код очень настоятельно. (Это похоже на C: вы можете написать OO-подобный код на C, но никто серьезно не считает C языком OO.)
Посмотрите: функциональное программирование - это не только лямбда
map
-функции или функции высшего порядка. Это о дизайне . Программа, написанная на «истинном» языке функционального программирования, решает проблемы посредством композиции функций. Хотя программы, написанные на Ruby или Python, могут использовать функции, подобные FP, они обычно не читаются как набор составных функций.источник
Каждый упомянутый вами функциональный язык вполне вписывается в определенную нишу, и идиоматические шаблоны, которые каждый поощряет, делают их очень хорошо подходящими для определенных задач, которые было бы невозможно выполнить в Python, если бы вы не создали огромную библиотеку вспомогательных модулей. Самым очевидным из примеров такого превосходства является модель параллелизма Эрланга. У других также есть подобные сильные стороны.
источник
Каждая концепция, доступная в лямбда-исчислении, LISP и Схеме, доступна в Python, так что, да, вы можете выполнять в ней функциональное программирование. Если это удобно или нет, это вопрос контекста и вкуса.
Вы можете легко написать интерпретатор LISP (или другого функционального языка) на Python (Ruby, Scala) (что это значит?). Вы можете написать интерпретатор для Python, используя чисто функциональный, но это займет много работы. Даже «функциональные» языки в настоящее время являются мультипарадигмой.
Эта старая и красивая книга содержит большинство (хотя и не все) ответов о сущности функционального программирования.
источник
eval()
функцию, которая необходима для того, чтобы код представлял собой данные , но он идет дальше: он позволяет вам изменять большую часть среды выполнения, как в LISP.eval()
- это метапрограммирование во время выполнения. Иногда это полезно, но это чрезвычайно дорого. Макросы Lisp разные, это метапрограммирование времени компиляции. Он не доступен в Python в любой доступной форме.Потому что Python также может программировать в нефункциональном стиле, и этого недостаточно для FP-пуриста. Более прагматичные программисты, тем не менее, могут пользоваться преимуществами функционального стиля, не будучи догматичными по этому поводу:
- Джон Хьюз, Почему функциональное программирование имеет значение
источник
goto
ужасен.call-with-current-continuation
.