LINUX.ORG.RU

Функциональная парадигма

 , ,


2

7

Что-то в последнее время начали хайпить функциональное программирование. Мол, стиль со взглядом в будущее, распараллеливание, оптимизация, замена устаревшему ООП, который не способен идти в ногу с современными процессорами. Есть ли здесь люди, которые пишут на Haskell или тому подобных языках? Есть ли профит переходить на ФП? Или мультипарадигмость С++ и Java исправят ситуацию?


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

опять из того топика

sin_a

Сравнение ЯП с естественными языками интересно в первый момент. У них разные задачи. Язык программирования это язык инструкций. Разговорный язык это язык описания. После понимания этого, интерес к такому сравнению полностью пропадает. И сопоставление этих двух предметов более ничего не даст.

нет, это языки из разных логик. ЯП — это логика описания алгоритмов. а ЕЯ — это декларативное метаописание символических вычислений, интерпретируемых по контексту (в модели треугольника Фреге: знак-денотат-концепт, означаемое-означающее-смысл,идея).

конкретно это логики: алгоритмов — это linear logic, linear temporal logic, презентация, а ЕЯ — это скорее, substructural logic (помнишь у Стругацких про «структуральнейшего лингвиста» :-) ?)

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

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

оценивать выражения на ЯП можно скорее всего качественно, а не количественно.

в ЯП структура имеет значение, но и порядок выражений — тоже. то есть, структурный ЯП — это 4 выражения (следование;цикл;альтернатива; и выражение, включая вызов функций) — то есть, рекурсивное. эти выражения упорядодочены, развёрткой DAG графа AST или графа вызовов.

то есть, оцениваются количественно, а не качественно.

вывод: ЯП описывается «математической структурой», решёткой — частично упорядоченным множеством. с количественной мерой (одной или несколькими) на этой решётке.

в ЕЯ же структура неявная, скорее всего — качественная (квалиа и т.п.). то есть, для вычисления количественных из качественных можно использовать нечёткую логику, лингвистические переменные, классификаторы, вот это всё.

ну или символьные вычисления (в которых денотат и концепт как раз и зависят не только от «знака», но и от точки зрения, истории выполнения, «законов причинностей» и т.п.)

а ты вообще какой вопрос хотел задать? сформулируй его кратко, ёмко.

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

anonimus>

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

via:

-В одном вы все же правы, господин артиллерист Тринли. Если этих людей заставить заниматься арифметикой или сортировкой строк, это было бы глупой шуткой. Самый мелкий процессор в колечке на пальце такие вещи делает в миллиард раз быстрее человека. Но ты слышал, как разговаривают зипхеды? [...] Это внутренний жаргон; они его очень быстро вырабатывают, если мы ставим их работать командой. Но смысл в том, что они не выполняют машинных функций низкого уровня. Они используют компьютерные ресурсы. Понимаешь, для нас, эмергентов, зипхеды – это следующий слой над программным уровнем. Они могут применять человеческий интеллект с терпением и настойчивостью машины. И вот еще почему важны не-Фокусированные специалисты – особенно техники вроде меня. Фокус бесполезен, если нет нормальных людей, которые направят его и найдут необходимое равновесие между железками, программами и Фокусом. Если эта комбинация правильно составлена, получается такое, что вашей Кенг Хо и не снилось.

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

sin_a> Трансляция нужна не в инструкции, в этом и дело. Трансляция нужна в структуру данных, если можно так выразиться. И это возможно, но сначала надо эту структуру данных создать.

ну например, в глобальную «гипер"структуру: объединяющую инструкции, данные и метаданные. символически метаданные вычисляются в (порождают) данные, и инструкции (обобщённый метациклический вычислитель)

проблема, которую это должно было решать, так и не озвучена

> в данном случае это решает массу проблем. Например, это практически устранит callback-hell, коллбеки можо будет использовать многократно, причем в разных промисах, и тд Но это решает и более глубокие проблемы — проблемы проектирования, декомпозиции, построения абстракций.

В очередной раз прошу внятный правдоподобный пример.

опять-таки, проблема не озвучена. в чём проблема, как она решается сейчас, что предлагается, почему это решение лучше — ХЗ ???

но придумаю свой вариант за тебя: вот например, на языке Converge написан конечный автомат с „global state machine“, как трансляция DSL: DSL использование

вполне себе человекопонятные примеры использования:

 // Get the account number.
transition reading_card from Waiting to Read_Card: / card_num := read_card()
transition getting_balance from Read_Card to Get_Balance: [card_num != -1] / balance := get_balance(card_num)
transition invalid_card from Read_Card to Waiting: [card_num == -1] / error("Unknown account")
// Get the balance of the account, and then ask what the user wants to do.
transition goto_menu from Get_Balance to Display_Menu
transition get_action from Display_Menu to Get_Action: / action := get_action()
transition invalid_action from Get_Action to Display_Menu: [ action != "W" and action != "F" ]
// Try to withdraw money.
transition withdrawing from Get_Action to Withdraw_Ask: [ action == "W" ] / amount := get_amount()
transition do_withdraw from Withdraw_Ask to Withdraw: [ balance - amount >= 0 ]
transition fail_withdraw from Withdraw_Ask to Display_Menu: [ balance - amount < 0 ] / error("Trying to withdraw too much")
transition withdraw from Withdraw to Display_Menu: / balance := withdraw(card_num, amount)
// Finished working on this account; reset the card number and go back to reading account numbers.
transition withdrawing from Get_Action to Waiting: [ action == "F" ] / card_num := -1

это код. Converge — это потомок SNOBOL, Icon с синтаксисом Python-а и семантикой Template Haskell. там есть AST, квазицитирование, сплайсы и в примерах довольно легко построить свой DSL.

вот такой существующий проблем и способы его решения.

теперь, что именно ты предлагаешь в том топике? какую проблему решать? каким способом? почему этот способ — лучше? для кого лучше? в чем недостатки предложенного тобой способа?

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

отличная шутеечка, брат, сейчас живот лопнет

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

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

Если логирование дебажное, то не нужно.

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

оно и есть?

Есть, но это не тру. И дока говорит не использовать такое в продакшене.

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

можно просто заюзать глобальную переменную

Так ведь это отстойное решение. А способа делать такие вещи менее болезненно есть и в хаскеле. Но сразу скажу, что меня и самого все эти заморочки напрягали и хаскель так и не полюбил.

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

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

В haskell можно создать глобальную переменную через unsafePerformIO и прагму NOINLINE. Иногда так и делают, но это не комильфо

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

покажешь, как ты на жаве hot reload сделаешь

man deopt события в HotSpot. Даже небо, даже аллаха, скомпилированного JITом неделю назад, можно налету перегрузить и новая версия корректно сJITится. Главное HotSpot это умеет, а тулинг человеческий появится. Вот модули допилят в java9 - будет что перегружать, с отдельными классами муторно пока.

у тебя Out of PermGen space

С разморозкой, PermGen последний раз был в java7, у которой публичная поддержка кончилась в апреле 2015 года.

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

отчего же, вполне себе может быть. только ленивость это как фекспры — позволяет отложить вычисление аргументов, создать свой порядок вычисления аргументов, то есть, строительные блоки для DSL. чисто функциональный eager, not lazy менее полезен ибо промисы, future и прочие продолжения с замыканиями там сделать будет более сложно. причём отложить можно и порядок вычисления алгоритмов (те же промисы, future) и порядок вычисления данных (продолжения, замыкания, мемоизация, рекурсивные/бесконечные структуры данных, бесконечные списки, list comprehension/pattern matching на таких списках, катаморфизмы на деревьях и т.п.)

ибо lazy evaluation это фактически call-by-need, а strict/eager/greedy evaluation — call-by-value/call-by-reference/call-by-sharing, а хотелось бы наиболее мощного call-by-name/call-by-macro-expansion.

не считая call-by-future и future/promises. или генераторов корекурсивных ковыражений (например,как в Icon — всё (ко)выражение, и goal oriented execution).

в общем, наиболее мощная штука — ленивость и фекспры. позволяет конструировать из строительных блоков всё остальное.

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

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

ну то есть, и там можно воткнуть свой pattern Interpreter или там продолжения или целую «let over lambda», однако ж никаких бесконечных списков с катаморфизмами. скукота же.

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

в общем, callback-hell возникает. или сопрограммы с ковыражениями, или замыкания с продолжениями, или целая «let over lambda», lambda over let over lambda и т.п. с лексическими окружениями и лямбдами, и т.п.

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

вот например: А. Лазаревич в повести «Технокосм» предложил

2.5 Универсальный язык интрагалактического общения (Интрагалакт)

Это действительно абсолютно прозрачный перевод. Но как вам это удается? Как это все работает? Неужели у Вас есть словари которые устанавливают полное соответствие между словами любой пары языков, существующих в Нашей Галактике?"

_ «Разумеется нет. Перевод идет через язык-посредник - Универсальный язык интрагалактического общения (Интрагалакт). И у нас есть „словари“, позволяющие переводить с любого местного языка на Интрагалакт и обратно. Как только мы находим новую цивилизацию, мы строим модели сознания местных жителей и модели их культурной среды, затем анализируем эти модели и создаем модули перевода языковых сообщений и культурно-социальных ситуаций этой цивилизации на Интрагалакт и обратно. Выражение „модуль перевода“ более корректно чем „словарь“, поскольку слов как таковых в Интрагалакте нет.

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

[..] При переводе с одного языка на другой Переводчик анализирует всю коммуникативную ситуацию в целом и записывает ее на языке Интрагалакт. Интрагалакт - это язык описания коммуникативных ситуаций построенный по принципу иерархического дерева с неограниченной глубиной ветвления».

то есть, бесконечные списки с list comprehension и катаморфизмами для обхода.

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

- «Простите?!»

- «Все очень просто. Верхний уровень иерархии абсолютно идентичен у всех сообщений и состоит из двух элементов: то о чем сообщается, и что о нем сообщается. По вашему - подлежащее и сказуемое, или субъект и предикат. Это основа любого сообщения, поскольку любое сообщение сообщает нам что-то о чем-то.

Следующий уровень иерархии уточняет наиболее существенные признаки того, что описывается. Например, если необходимо перевести с Вашего языка сообщение „книга лежит на столе“ субъект „книга“ описывается на втором уровне иерархии переведенного сообщения как „материальный объект“, а предикат „лежит на столе“ как „устойчивое во времени пространственное отношение с другим материальным объектом“.

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

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

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

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

- «Однако получается очень длинное сообщение».

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

опять же: бесконечные рекурсивные структуры данных (recursive data type) как деревья для единицы представления знаний, и обработка таких структур лениво, по требованию — уточняя следующий уровень рекурсии, только если непонятен предыдущий, с мемоизацией.

а уровней таких бесконечно много. но рекурсия с «суперпозицией» (whatever) когда-нибудь обрывается — когда достигнута качественная, не количественная мера понимаемости сообщения.

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

эти уровни, ветвления похожи на категории.или категории категорий. теория категорий в животноводстве:

Под мудрым руководством категории категорий идёт строительство абстрактных фабрик паттернов.

но это может быть и произвольная структура понятий, онтология как recursive data types/ high kinded types.

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

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

вот тогда и пригодится функциональщина.

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

Эммм, я думал тут всем очевидно, что чистота, иммутабельность и т.п. ортогональны функциональности языка. Да, приходим к основному вопросу философии - что есть ФП?

Нет тут никакого философского вопроса, есть четкое определение ФП с точки зрения CS как чисто подстановочной модели вычислений, все остальные инсинуации

про основной вопрос философии:

!Ъ:

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

Материализм — абсурден."

:-))))

поэтому философия не наука, а просто мировозрение/миропонимание/рефлективная система мира.

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

То есть, не может быть чисто-функциональных не ленивых языков?

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

А с другой стороны, ленивость дает много плюшек, привыкнув к которым уже не хочется ничего другого (ни Scala, ни F#, хотя Scala использую на работе). Правда, ленивость имеет свои недостатки, о которых надо знать.

dave ★★★★★
()
Последнее исправление: dave (всего исправлений: 3)
Ответ на: комментарий от DarkEld3r

По-моему существуют, но не так популярны, как хаскель

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

Не знаю, почему некоторые личности на лоре из года в год продвигают это мнение. Могут быть такие языки. Если общая предсказуемость поведения программы важнее некоторых весьма и весьма синтетических преимуществ типа «бесконечных» структур данных и способа написания комбинатора неподвижной точки, то ленивость скорее нежелательна.

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

И этих языков особо не видно, потому что ленивый хаскель офигенно быстрый!

Вот, только сейчас замерял скорость для практически эквивалентного кода на Haskell и F# (который генерирует довольно качественный код IL). Haskell оказался значительно быстрее, чем Mono, и заметно быстрее, чем .NET Framework на моих тестах.

И это ленивый язык! В коде довольно много вычислений, и много выделений памяти.

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

Вот, только сейчас замерял скорость для практически эквивалентного кода на Haskell и F#

Я слишком слабо ориентируюсь в теме, чтобы оценить честность такого сравнения.

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

Я знаю. В тестах использовал имитационные модели с увеличенным временем имитации. Метод реализации почти один и тот же.

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

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

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

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

Ivana
()

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

В узких кругах, а так не особо и заметно, в том числе и здесь, на ЛОРе.

замена устаревшему ООП, который не способен идти в ногу с современными процессорами.

В чем ФП-парадигма шагнула дальше ООП? В ногу должны идти конкретные специалисты с конкретными стеками технологий.

Есть ли профит переходить на ФП?

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

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

Ну java- не совсем функциональный,

Не совсем?! Мм, яснопонятно... Сразу уж scala бы и писал, че позориться-то.

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

Вот опять, вопрос попахивает фанатизмом.

Правильный ответ - есть места где лямбды возможны и нужны, есть места где они уродуют код.

На счет эффективности - есть такой Stream API, который может гонять обработку коллекций на Fork-Join Pool. Этот API весь функциональный и там нужно использовать либо лямбды, либо method reference-ы. И да, на больших объемах данных оно СИЛЬНО эффективнее, потому что предлагает прозрачное распараллеливание.

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

Я понимаю, что тебе тоже захотелось подколоть. Попытка провалилась

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

а про твои контексты из того потика так скажу: прочитай уже наконец «let over lambda»

Автор данной книжки безграмотен, пишет о том, в чем не разбирается, и делает банальные фактологические ошибки. Так что читать ее не просто не надо - это вредно.

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

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

Вообщето в строгих языках нету никаких проблем в том чтобы откладывать вычисления.

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

Так программа на хаскеле ничего и не пишет. Она возвращает IO (), то есть State World (), а это ни что иное как обычная функция World -> (90, World)

То есть программа на хаскеле возвращает функцию. Именно эта функция, по идее, уже и должна делать read/write, но поскольку никто этой ф-и не запускает (с точки зрения семантики хаскеля) то и проблем никаких нет.

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

Метод реализации почти один и тот же.

Но проблема может быть в F# или в том, что .NET плохо под такое заточен, а совсем не в том, что хаскель выигрывает из-за ленивости.

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

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

Посыл в том, что у хаскелевского GHC очень эффективный run-time. На мой взгляд даже чуточку лучше, чем у .NET Framework, хотя я дотнетчик со стажем (да и плюсовщик тоже). Сравнение проводил в задачах с сопоставимой алгоритмической реализацией с минимальным использованием внешних библиотек.

Причем, я как-то гонял этот хаскелевский run-time на своих моделях, где использовалось много, очень много «слабых» ссылок, система уходила почти в своп, и все равно был очень впечатлен результатами.

Да и если верить интернету, довольно многие замечают, что хаскель достаточно быстр.

А примеры типа quicksort, конечно, отличаются краткостью, но я бы этот пример назвал worstsort, ибо у новичков складывается совершенно ошибочное представление о языке. Вот, primes как пример вполне ничего) Многих путает чистота, и они не знают, что с ней делать)

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

Ок.

Тогда и ввода-вывода в реальном железе нет. Клавиатура, сетевая карта и т.д. являются частью компьютера. А не внешней средой.

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

Вообщето в строгих языках нету никаких проблем в том чтобы откладывать вычисления.

yep. Просто тот же алгоритм в строгом языке с эмуляцией отложенных вычислений будет в 10-1000 раз медленнее работать, чем в ленивом.

utf8nowhere ★★★
()

Лямбды - это новомодный хипстерский хайп. Где-то в 2013 появился. А ООП был всегда. За ним будующее!!111

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

Они об этом молчат. Но не потому что им стыдно, а потому что никому до этого нет дела. И они об этом знают.

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

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

А ООП был всегда. За ним будующее!!111

В такой интерпретации согласен полностью ))

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

Что «мда»? ЛОР этим и прославился, уникальными мозговыносящими тредами. К сожалению, мракобесие тут победило задолго до Мизулиных и Яровых.

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

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

С чего ему быть медленнее?

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