Я говорю — попробуйте решить задачу с ограничением времени в O(n). Можно даже амортизацию применять. Я находил функциональные алгоритмы с временной сложностью O(n*log(n)). Принципиально медленнее.
Извините, но не буду тратить на это время. За 10 лет практического опыта, мне эту задачу ни разу не приходилось решать для реального проекта. Поэтому лично мне вообще не интересно какая у неё алгоритмическая сложность.
Если Вы в каждодневной работе часто сталкиваетесь с подобными задачами и сложность функциональных алгоритмов Вас не устраивает, то возможно под Ваши задачи лучше подойдёт С++.
Ну а в чём проблема то? Берём Elixir или Erlang, пишем GenServer Teapot. У которого есть состояние(наличие и температура воды) и кто угодно может послать ему сообщение и узнать актуальное состояние в любой момент времени.
ООП вообще на акторах реализуется даже лучше, чем на классах. И мутабельность для этого не нужна.
В плане практических бизнес-задач у ФЯП проблем никаких нет.
Единственная проблема в ФП — реализовывать алгоритмы, построенные на базе мутабельности и массивов. Какие-то из них может даже не получиться реализовать за ту же сложность. Но, это довольно узкий класс задач… вспомните, когда Вы прошлый раз Кнута перечитывали?
Я про языки не писал… В функциональном подходе традиционно используется только хвостовая рекурсия, соответственно переполнение стека исключено.
Насчёт ограничений и языков… у всех по разному, у Erlang, например, глубина нехвостовой рекурсии ограничена только объёмом RAM.
переполнение стека из-за недооценки глубины рекурсии
ну вот, ещё одну проблему императивного подхода вспомнили, которая при функциональном подходе отсутствует )))
Программирование — это не математика, поэтому математически корректный алгоритм, который во что-то упёрся, с точки зрения программирования такой же ошибочный, как с NPE.
Функциональный язык — тот, в котором основная парадигма функциональная. Языков, в которых совсем невозможно ФП, по-моему, уже и нет, даже Java не устояла. С ООП то же самое, ООЯП — тот, в котором основная парадигма объектно-ориентированная. Но языков, в которых невозможно ООП, тоже практически нет.
Другими словами, вопрос только в качестве, удобстве и полноте поддержки той или иной парадигмы в языке.
Попробуйте реализовать построение суффиксного дерева на функциональном чистом языке за линейное время. Я вот ещё ни одной реализации не встречал. А на императивных «грязных» языках — запросто.
Я уже несколько раз тут в комметах писал… не надо пытаться реализовывать императивные алгоритмы в функциональном стиле. Ничего хорошего из этого не получится. И это ни разу не аргумент против ФП.
Я не улавливаю Вашей логики, честно говоря. В научных расчётах много чего используется, в том числе и ФП. Только какой от этого практический толк, если, допустим, Вы не занимаетесь научными расчётами?
Мне вот интереснее применение ФП для таких проектов как WhatsApp, Twitter и т.д.
Ok. Я просто когда-то давно тоже программировал на Delphi, но практически все, кого я знал, перешли на C# в районе 2007-2009 годов. Хотя, косвенно hh.ru это подтверждает, по тому же C# почти в 8 раз больше вакансий )
Вообще-то, конкурентность и параллелизм — это совсем разные понятия. Параллелизм тоже можно устроить на ФП, но я это не имел в виду в начальном сообщении.
Про программирование на GPU я Вам не подскажу, т.к. не интересуюсь этой темой. Если Вы хотели подколоть на тему, что для параллелизма есть инструменты получше, то вспомнили бы лучше Lambda- и Kappa-архитектуры. А то параллелизм числовых данных на GPU — это насколько узкая тема, что кроме учёных и любителей криптовалют, имхо, никому не интересна.
Так кривая ленивость — это тоже ошибка алгоритма, просто другого плана. Неведомой магии вообще в программировании не бывает, бывают неочевидные особенности )
Про Delphi — это тонкий троллинг или Вы до сих пор его в разработке используете?.. Честно говоря, ничего не знаю, про компонентно-ориентированное программирование или GUI на функциональных языках… Меня лично больше интересует область бэкенда для всяких веб- и mobile-приложений.
Скорость написания примерно такая же, как и на императивных языках, после того как осознаёшь функциональную парадигму и перестаёшь пытаться перетянуть туда императивные привычки.
И насколько углублённое знание лямбда-исчисления и прочей математики требуется чтобы писать быстро?
Просто не лезьте в Haskell и такие вещи как лямбда-исчисление, монады, функторы и т.д. Вас не потревожат )))
Т.е. ответ по существу — Вы можете вообще не знать что такое лямбда-исчисление и теория категорий, и прекрасно себя чувствовать на функциональных языках типа Elixir или Clojure, а также и на гибридных типа F#. Из ребусов только некоторые особенности записи могу вспомнить, но они скорее непривычные, чем сложные, и довольно легко осваиваются.
Когда Вы можете передать функцию в качестве параметра другой функции, или вернуть функцию из функции — это, безусловно, часть ФП, так как только в этой парадигме существуют функции высшего порядка.
Отвечу вместо nehaev… Использование ФП на 100% оправдано, когда вам нужна высококонкурентная программа с высокой степенью надежности и отказоустойчивости.
В таком случае вы либо будете использовать готовый ФЯП, либо переизобретёте большую часть ФП на своём любимом ЯП, либо будете страдать на каждом углу от race conditions, dead locks, гейзенбагов и прочих весёлых вещей.
А вот в императивных языках — как написал, так и работает.
Вы уверены, что это в императивных языках, а не в Ваших фантазиях? )
Откуда ж берутся null pointer exception, GIL и ещё 100500 подводных камней, когда работает совсем не так, как написал… Проблемы везде есть, и в императивных языках их совсем не мало. Но можно найти проблемы и в Прологе и в Хаскеле, тут никто не спорит. А если пытаться на них в императивном стиле программировать, то вообще феерический ппц будет, о чём и статья.
Ok, мутабельный, так мутабельный… Но это не отменяет того факта, что Вы сравниваете 2 совершенно разных алгоритма и удивляетесь, получив вполне ожидаемый результат. Чтобы сравнение было уместным, возьмите LinkedList добавьте в него строки через AddLast, а потом превратите в строку с помощью Join (желательно найти тот, который без лямбд). Хоть StringBuilder работает не так, но это по крайней мере алгоритмы одной сложности.
Сейчас клиенты пишут либо под браузер, либо под мобильники. И там и там можно использовать ФП, но на, мой взгляд, оно как раз больше для высоконагруженного сервера подходит. На клиентах выигрыш от ФП как-то неочевиден.
По определению, массив — структура данных, оптимизированная для произвольного доступа по индексу. Список — структура данных, оптимизированная для последовательного перебора.
А с точки зрения логики, если бы реализация этих структур принципиально не отличалась, то достаточно было бы одного названия )
Я умею работать с массивами, даже знаю пару алгоритмов на базе массивов. Где тут в вашем ФП массивы? Как нет? А что есть? А, списки… в моём любимом языке класс массива называется ArrayList, значит список — это типа массив такой. Сейчас как напрограммирую… Ой, а почему всё так тормозит? Как это нельзя к списку по индексу обращаться, вот же я обращаюсь и всё работает, тупит правда, но это потому что ФП медленный.
Если Вы в каждодневной работе часто сталкиваетесь с подобными задачами и сложность функциональных алгоритмов Вас не устраивает, то возможно под Ваши задачи лучше подойдёт С++.
ООП вообще на акторах реализуется даже лучше, чем на классах. И мутабельность для этого не нужна.
В плане практических бизнес-задач у ФЯП проблем никаких нет.
Единственная проблема в ФП — реализовывать алгоритмы, построенные на базе мутабельности и массивов. Какие-то из них может даже не получиться реализовать за ту же сложность. Но, это довольно узкий класс задач… вспомните, когда Вы прошлый раз Кнута перечитывали?
Насчёт ограничений и языков… у всех по разному, у Erlang, например, глубина нехвостовой рекурсии ограничена только объёмом RAM.
Программирование — это не математика, поэтому математически корректный алгоритм, который во что-то упёрся, с точки зрения программирования такой же ошибочный, как с NPE.
Другими словами, вопрос только в качестве, удобстве и полноте поддержки той или иной парадигмы в языке.
Я уже несколько раз тут в комметах писал… не надо пытаться реализовывать императивные алгоритмы в функциональном стиле. Ничего хорошего из этого не получится. И это ни разу не аргумент против ФП.
Мне вот интереснее применение ФП для таких проектов как WhatsApp, Twitter и т.д.
Про программирование на GPU я Вам не подскажу, т.к. не интересуюсь этой темой. Если Вы хотели подколоть на тему, что для параллелизма есть инструменты получше, то вспомнили бы лучше Lambda- и Kappa-архитектуры. А то параллелизм числовых данных на GPU — это насколько узкая тема, что кроме учёных и любителей криптовалют, имхо, никому не интересна.
Скорость написания примерно такая же, как и на императивных языках, после того как осознаёшь функциональную парадигму и перестаёшь пытаться перетянуть туда императивные привычки.
Просто не лезьте в Haskell и такие вещи как лямбда-исчисление, монады, функторы и т.д. Вас не потревожат )))
Т.е. ответ по существу — Вы можете вообще не знать что такое лямбда-исчисление и теория категорий, и прекрасно себя чувствовать на функциональных языках типа Elixir или Clojure, а также и на гибридных типа F#. Из ребусов только некоторые особенности записи могу вспомнить, но они скорее непривычные, чем сложные, и довольно легко осваиваются.
В таком случае вы либо будете использовать готовый ФЯП, либо переизобретёте большую часть ФП на своём любимом ЯП, либо будете страдать на каждом углу от race conditions, dead locks, гейзенбагов и прочих весёлых вещей.
Откуда ж берутся null pointer exception, GIL и ещё 100500 подводных камней, когда работает совсем не так, как написал… Проблемы везде есть, и в императивных языках их совсем не мало. Но можно найти проблемы и в Прологе и в Хаскеле, тут никто не спорит. А если пытаться на них в императивном стиле программировать, то вообще феерический ппц будет, о чём и статья.
А с точки зрения логики, если бы реализация этих структур принципиально не отличалась, то достаточно было бы одного названия )