LINUX.ORG.RU

[капитан][ФП] Чистые функции не такие чистые


0

4

http://www.johndcook.com/blog/2010/05/18/pure-functions-have-side-effects/

Ъ: У чистых функций всегда есть side-effects, которые выражаются в пожирании памяти и CPU.

Очевидно конечно, но почему об этом не орут на первой странице каждой книги по функциональному программированию?

★★★★★
Ответ на: комментарий от Harald

круто, дополнительный аргумент для троллинга в ФП-сраче :)

У бородатых штангистов будет дополнительный аргумент считать тебя убогим.

mv ★★★★★
()
Ответ на: комментарий от vertexua

Все потому что лисперы орут что Лисп не ФП язык

Они орут, что Лисп (Коммон который) - это не чистый ФЯП, но многие разницы не видят.

mv ★★★★★
()
Ответ на: комментарий от archimag

Python поддерживает ФП в ничуть не меньшей степени, чем CL.

В питоне операторы (statements) или выражения? Для хорошей поддержки ФП нужно, чтобы были выражения. Например, IF в лиспе - это выражение, возвращающее значение. В питоне - нет.

dave ★★★★★
()
Ответ на: комментарий от Zorn

CL, вон, вообще больше ООП, чем ФП

Значит, не зря некоторым Scala в кошмарах снится :)

dave ★★★★★
()
Ответ на: комментарий от mv

вот мне не пофиг, кого убогие считают убогим

Harald ★★★★★
()
Ответ на: комментарий от dave

Например, IF в лиспе - это выражение, возвращающее значение. В питоне - нет.

Не очень удачный пример %)

foo = bar if baz else yuk

Но, конечно, жаль, что Python не expression-oriented

tailgunner ★★★★★
()
Ответ на: комментарий от quasimoto

Хорошо написал. Даже я почти понял, о чём идёт речь :-).

Virtuos86 ★★★★★
()
Ответ на: комментарий от Zorn

CL, вон, вообще больше ООП, чем ФП

А как одно мешает другому?

ovk48 ★★★
()
Ответ на: комментарий от Virtuos86

1. Нужно рожать лабы в универе со скоростью света, так как совмещение работы и учебы

2. Пришлось писать высокопроизводительный и durable сервер. Итого persistent data structures, иммутабельность, отсутствие синхронизации

Scala выручила, одно удовольствие программировать

vertexua ★★★★★
() автор топика
Ответ на: комментарий от Virtuos86

Но тут говорят, скала это больше ООП, врут?

Народ, ну вы правда задрали с этим «больше ООП, чем ФП». Даже хаскель бывает ООП.

ovk48 ★★★
()
Ответ на: комментарий от Virtuos86

Да блин, чем ООП мешает ФП? Или наоборот, чем ФП мешает ООП?

PS. Скала разве экспрэшн-ориэнтид?

Deleted
()
Ответ на: комментарий от Virtuos86

Scala просто очень хороший язык. Я бы сказал оптимальный с точки зрения многих параметров. Авторы Scala, в основном Мартин Одерски, достаточно адекватные люди, которые смотрят на мир реально, и просто хотят сделать хороший гибкий и масштабируемый для любых задач язык. На Scala приятно писать код, концепции мощные и удобные. Это единственныей язык JVM, который иногда работает быстрее Java, но при этом достаточно выразительные чтобы соорудить самый причудливый DSL. Что я вынес углубившись, так это то, что очень верится что лет через 10 ЯП будут именно такими, по крайней мере так хочется. Отличное ООП, отличное ФП, прекрасный параллелизм, полный набор иммутабельных и мутабельных коллекций, параллельные коллекции, актеры, возможность писать с любой степенью заумности, от простой императивщины до монад. У них своя надстройка над Swing, позволяющая элементарно строчек в 100 в одном файле нагородить что-то делающее приложение. О 100 строчках, меня наверное мотивировало изучать Scala, лабораторная в <100 строчек, которая решала системы линейных уравнения.

Относительно JVM, то это приятный плюс, так как из-за eden написание алгоритмов с иммутабельными данными достаточно дешево и есть 100500 библиотек высшего качества.

vertexua ★★★★★
() автор топика
Ответ на: комментарий от Deleted

Скала ведь не функциональная, а мультипарадигменная все-таки, поэтому и спрашиваю.

Если кратко, то да.

mv верно подметил выше про CL. Тоже относится и к Scala. Да, не чистая. Да, гибридная. Да, развитое ООП. Но по-прежнему функциональная. Вы, что в массовом порядке решили записаться в ряды ортодоксальных хаскелистов, не признающих ничего, кроме самого хаскеля?

P.S. «Ортодоксальный» в дословном переводе с греческого: «православный».

dave ★★★★★
()
Ответ на: комментарий от dave

Читать так: «Если кратко, то да. Scala - экспрешен-ориентид.»

dave ★★★★★
()
Ответ на: комментарий от dave

Все функциональные языки экспрешн-ориэнтид.

Если говорить о ФП на Python, то это всего лишь небольшое неудобство, никаких принципиальных или практически значимых проблем не создает.

archimag ★★★
()
Ответ на: комментарий от dave

Вы, что в массовом порядке решили записаться в ряды ортодоксальных хаскелистов, не признающих ничего, кроме самого хаскеля?

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

Да, не чистая. Да, гибридная. Да, развитое ООП.

Это же одни плюсы! Почему звучит, как какое-то оправдание?

Deleted
()
Ответ на: комментарий от dave

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

Deleted
()
Ответ на: комментарий от archimag

Ну, в общем-то, многие современные языки, в том числе питон, взяли очень многое из мира функциональных языков. Конвергенция. Границы нечетки.

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

dave ★★★★★
()
Ответ на: комментарий от Deleted

Где я сказал другое? Я просто сказал, что он не ФП в чистом виде, а мультипарадигменный с элементами ФП

Zorn
()
Ответ на: комментарий от Deleted

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

(Здесь не будем спорить, насколько функциональны циклы. В том же Common Lisp циклы записывается очень декларативно, что становится не совсем понятно, где заканчивается императивное и начинается декларативное программирование)

dave ★★★★★
()
Ответ на: комментарий от dave

Первоначальный смысл термина «язык функционального
программирования» утерян и заменен более ортодоксальной версией

Ну вот и получается, что все холивары сводятся к терминологии, ибо реальный смысл термина размыт. Мне нравится «ортодоксальный» вариант, ибо он претендует на что-то концептуально чёткое и обособленное, а все остальные трактовки имели смысл в 80-ые, но в текущий момент применимы к слишком большому количеству совершенно различных языков.

archimag ★★★
()
Ответ на: комментарий от Deleted

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

Хаскель - бесспорно интересный язык. Своеобразный. Мне он нравится. Насколько практичен? Думаю, сильно зависит от задачи. Если детерминированная задача, то все прекрасно. Как начинается недетерминированность, то сразу появляется IO, от которого так просто не избавишься.

Лисп - сложный язык (CL). Безусловно практичный. Но ему надо много учиться, хотя основы просты.

Это же одни плюсы! Почему звучит, как какое-то оправдание?

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

dave ★★★★★
()
Ответ на: комментарий от archimag

Ортодоксальный вариант установился много позже того времени, когда я впервые узнал о самом термине. Я привык к старой трактовке. Наверное, лично мне будет очень трудно привыкнуть к новому варианту :)

К тому же, в рядах хаскелистов тоже нет единого мнения. Есть одна уважаемая книга «Programming in Haskell» (2005), где приводится очень свободная трактовка термина, совершенно лишенная ортодоксальности.

dave ★★★★★
()
Ответ на: комментарий от dave

Если заменить «язык функционального программирования» на «объектно-ориентированный язык» и «лисп» на «смолток», то смысл не изменится ;).

Virtuos86 ★★★★★
()

Очевидно конечно, но почему об этом не орут на первой странице каждой книги по функциональному программированию?

Потому что функциональщики отнюдь не возражают против сайд-эффектов. Им нужен КОНТРОЛЬ над сайд-эффектами, который в чистом языке лучше. Вот и всё.

Miguel ★★★★★
()
Ответ на: комментарий от malbolge

Говно это. Они там сборку мусора не осилили ещё? Хотя не, если он мелкий, можно на какой-нибудь AVR микроконтроллер впихнить)

Zorn
()
Ответ на: комментарий от Zorn

Все же кричат: «Лишп, лишп!»!

Да здесь кричат-то так раз в месяц, от силы два. Так что можно и потерпеть. :)

DeVliegendeHollander ★★
()
Ответ на: комментарий от Deleted

Они это как фичу ещё представляли.

Был где-то тред или тут, или на lisper.ru

О:

Мне кажется, очевидно, что это очень и очень плохо. Идиотский способ управления памятью — не GC (как в лиспе, яве), не подсчет ссылок (как в питоне и vala), а некое свое one reference only (http://www.newlisp.org/MemoryManagement.html).

http://lisper.ru/forum/thread/128

Zorn
()

У чистых функций всегда есть side-effects, которые выражаются в пожирании памяти и CPU.

Да, да. А жизнь — форма гниения белковых тел.

Macil ★★★★★
()
Ответ на: комментарий от vertexua

Я бы сказал оптимальный с точки зрения многих параметров.

А я бы так не сказал. Скалу юзают там, где JVM безальтернативна. И зачастую в режиме явы-на-стероидах.

Macil ★★★★★
()
Ответ на: комментарий от quasimoto

В чистом языке со статической типизацией (Haskell, Clean) умозрительным будет понятие тотальности, но при этом все конструкторы термов не будут выполнять I/O операции, поэтому все сложные (индуктивно составленные) термы тоже не будут иметь побочных эффектов. В этом смысле чистота будет индуктивной. Операции I/O при этом могут быть составлены чистыми функциями как некая спецификация для выполнения рантаймом

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

anonymous
()
Ответ на: комментарий от quasimoto

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

Ой. А что такое функция? :)

anonymous
()
Ответ на: комментарий от anonymous

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

Например? Я когда смотрел понял только, что придётся таскать *тип вот так:

foo :: !*File !X -> *File
foo f x
  | somePred x = foo (fwrites (someData x) file) (soneNext x)
  = file

вместо:

foo :: Handle X -> IO ()
foo f x
  | somePred x = do
    hPutStr f (someData x)
    foo f (soneNext x)
  | otherwise  = return ()

или

foo :: Handle X -> IO ()
foo f x = unless (somePred x) $ hPutStr f (someData x) >> foo f (soneNext x)

А что такое функция?

Что такое функция на x86? Что-то определённое для данной архитектуры - после того как мы выбрали архитектуру и определили для неё понятие функции/процедуры, уже можно рассуждать о пространственной и временной сложности, побочных эффектах и т.п. А то или иное ограничение такой функции/процедуры уже может совпадать с математическим понятием чистой и терминируемой функции.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Ещё можно передавать само действие:

foo :: IO () -> Handle -> X -> IO ()
foo io h x = io >> unless (somePred x) (foo (hPutStr h (someData x)) h (soneNext x))
quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Например?

Ну, грубо говоря - допустим, у нас монада IO реализована через протаскивание World. В хаскеле мы никак не сможем статически гарантировать, что при использовании такого IO все будет «хорошо», т.к. мы всегда можем вытащить этот World и сделать с ним все, что душе угодно (чистота в хаскеле системой типов и не гарантируется). С другой стороны, объявив в Clean World уникальным, мы получаем статические гарантии.

foo :: !*File !X -> *File

Зачем !?

Что такое функция на x86?

Интересный вопрос :)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.