| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Религиозные войны > Функциональное программирование |
| Автор: Void 12.10.2005, 20:15 |
| По мотивам ветки http://forum.vingrad.ru/index.php?showtopic=58253, я решил нарушить первую заповедь флеймера – "не создавай свои провокационные топики – используй чужие" Налицо расхожее мнение, что функциональные языки являются чисто академическими инструментами, непригодными для решения практических задач, и вообще, все, для чего они нужны – это заваливать нерадивых студентов на экзамене Почему так? Наверное, тут можно выделить несколько наиболее часто встречающихся (и взаимно пересекающихся) доводов: 1) Не нужны они, и все тут. XXX вполне справляется со своими задачами. 2) Программистов, знающих такие языки, очень мало; и, в отличие от, скажем, перехода Java ->C#, пересадить C++-ника на Haskell быстро не получится. И вообще, нормальному человеку надо вывихнуть мозги, чтобы понять такие вещи. 3) Все прекрасно, но у таких языков нет коммерческой поддержки, нормальных средств разработки, и т. д. Все это в какой-то мере правда… Но: Не рассматривая собственно ФЯ, как самоцель, многие вещи, широко распространенные среди ФЯ (и, увы, мало популярные в мэйнстриме), кажутся мне весьма полезными, облегчающими и ускоряющими процесс разработки. Например:
(Пример языка, попытавшегося совместить это все с классическим императивным и ОО подходом на базе платформы .NET – http://www.nemerle.org/. По первым впечатлениям, очень приятная штука. Другой распространенный функциональный язык – http://caml.inria.fr/, также не является чисто функциональным и позволяет использовать императивный и ОО стиль.) Вопросы, на которые мне хотелось бы получить ответ: Считаете ли Вы функциональные (и вообще, нетрадиционные) языки применимыми в промышленном программировании, и почему. Считаете ли Вы полезным движение некоторых современных мэйнстримных языков (например, http://rsdn.ru/forum/Message.aspx?mid=1382740&only=1) в сторону ФЯ. Грубо говоря, нужны ли вам эти фичи? Попробую побыть адвокатом дьявола… тьфу, то есть ФЯ Пока все. Жду помидоров |
| Автор: LSD 12.10.2005, 20:18 | ||
Для .NET есть компилятор ML-я от MS. |
| Автор: Void 12.10.2005, 20:23 | ||
Знаю, знаю и про SML.NET, и про F#. У Nemerle своя специфика (в частности, ИМХО, гораздо более удобная, чем CamlP4, система макросов. Впрочем, я с ним только только начал разбираться). |
| Автор: Mayk 16.10.2005, 09:57 | ||
Пощупал вчера ocaml чуток. hello world вывел
Первые три пункта слабо понял вообщем |
| Автор: Void 16.10.2005, 13:01 | ||||||||||||||||||||||
| Mayk ОК, поехали по пунктам:
Это означает, что язык не делает принципиальных различий между функциями и значениями; ф-ции можно передавать в качестве аргументов другим ф-циями, возвращать и т. д. Указатели на ф-ции в C++ не обеспечивают подобной функциональности. Что-то подобное можно делать в C# 2.0, используя делегаты, анонимные методы и дженерики, но громоздкость синтаксиса оставляет желать много лучшего. Это становится понятно при попытке определить такую элементарную вещь, как композиция ф-ций:
Причем вывод типов для аргументов Compose работать не будет, и придется каждый раз явно указывать список дженерик-параметров. Что нужно наворотить на C++, чтобы записать композицию ф-ций, я боюсь даже представить.
Ф-ции, примененная к части своих аргументов, возвращает ф-цию с меньшим числом аргументов - уже заданные фиксированны как константы.
Предыдущий пример можно переписать с использованием карринга:
identity будет иметь тип float -> float - ф-ции принимающей float, и возвращающей float. Аналогично можно записать оператор дифференцирования:
Стоит обратить внимание на специфическую запись операторов - с точкой. За все надо платить, и за вывод типов тоже - в OCaml нет перегрузки ф-ций и операторов. Поэтому даже оператор сложения имеет разную форму для целых ("+") и действительных ("+.") чисел. С другой стороны, позволено объявлять любые собственные операторы.
...или pattern matching. Грубо говоря, pattern-matching - это некий аналог switch, способный оперировать не только над целыми числами или строками, а над любыми типами вообще. В сочетании со способностью OCaml к простому и элегантному объявлению сложных структур данных, получается средство для очень наглядной записи массы алгоритмов. Тот http://forum.vingrad.ru/index.php?showtopic=58253&view=findpost&p=537291 со вставкой в бинарное дерево использует именно сопоставление с образцом. Вот простой пример, демонстирующий, что switch лекго изображается средствами pattern-matching:
эквивалентно
Можно привести пример с определением типа AST арифметического выражения, и вычисления его значения:
Кстати, простейший калькулятор на OCaml пишется строчек в 30. Как мог, попытался объяснить. При необходимости готов разъяснять и проповедовать дальше |
| Автор: Mayk 16.10.2005, 13:16 | ||||||||||
.net 2.0 не видел. но примерно ясно
compose(f,g) = f(g,x)
Ага, понятно
Ага. Интересно читать |
| Автор: Sardar 16.10.2005, 14:47 | ||||||
В JS тоже можно, но механизм немного другой - closures.
Используеться тот же механизм closures
Свитчь есть везде. А вот есть ещё вещь интересная для аргументов если я правильно понял, например: факториал(0) = 1 факториал(n) = n * факториал(n-1); В результате функция вычисляет факториал, принимая аргумент число. При нулевом аргументе берёться первое действие, иначе второе. Нa счёт closures в JS, интересная вещь, например здесь активно используеться: http://forum.vingrad.ru/index.php?showtopic=67475 Для Java можно встретить в таких языках как Groovy, полученный байткод затем исполняеться в обычной JVM. |
| Автор: Mayk 16.10.2005, 15:23 | ||
Такое можно и на плюсах в compile-time высчитать |
| Автор: Void 16.10.2005, 16:04 | ||||||||||
Э-э... ты это к чему?
Весьма рад
Кстати, да. Замыкания - фактически непременный атрибут ФЯ, но их эксклюзивной привелегией не являются. Python и Ruby тоже позволяют так обращаться с функциями.
Примерно так и определяются ф-ции в Haskell. А в OCaml оно будет так:
Практически дословная запись математического опредления факториала |
| Автор: Mayk 16.10.2005, 16:06 | ||
Упс. да так. пробовал вместо g и f написать asin и sin. Пару строчек недоудалял... |
| Автор: Void 21.10.2005, 20:52 |
| Ссылка в тему: http://www.softcraft.ru/paradigm/fp/whynotfp.shtml И заодно UP темы |
| Автор: LSD 21.10.2005, 22:40 |
| Функциональное программирование имеет место быть, но широкого распространия ему не получить никогда (мое ИМХО). Обосную чуть погодя. |
| Автор: setq 22.10.2005, 08:02 |
| тема-то интересная, а сказать нечего |
| Автор: Sardar 22.10.2005, 14:00 |
| Ну вот, теперь флеймить начнём Сам изучал для себя Haskell и Lisp. Мощно, хотя синтаксис явно накурившись придумывали Одна проблема, я не могу придумать решениния на функциональном языке, почитав пример, получаеться повторить приём, но самому что то новое - туго... В то же время на Java/PHP5/JS любая задача в общих чертах решаеться за пару минут. Это не опыт и не база отработанных шаблонов, почти с каждой програмой придумываю новые, ранее не использованные пути. Вывод: может какие другие участки мозга задействованны, что с детства тренировать нужно, а то туго... |
| Автор: Void 22.10.2005, 16:54 | ||||
| Sardar Может быть, просто задачи такого рода попадаются? Действительно, многие задачи на ФЯ решаются даже сложнее... Но вот, скажем, для задач синтаксического анализа и символьных вычислений, я ничего подобного OCaml не видел.
Синтаксис LISP делался для того, чтобы было легко транслятору, а не программисту LSD
Ждем-с. |
| Автор: LSD 1.11.2005, 22:59 |
| Моя ИМХА, почему функциональные языки не получат широкого распространения. 1. Традиционное мышление. Написание задачи на функциональном языке требует от человека перед тем как начать писать код четко, формально сформулировать задачу. Функциональное программирование пошло от математики, а императивное от техники. Для функционального программирования надо мыслить абстракциями, а в императивном можно более конкретными вещами. Пример написать текстовый редактор аля блокнот. В современной RAD среде быстро накидывается формочка, а затем к ней прикручивается функциональность (открытие документа, сохранение и т.д.). А вот много ли программисто смогут описать этот же редактор в терминах функций? Я помню с каким трудом я учился писать на ML, желание применять наработанные методы было непреодолимо, но они не работали, приходилось ломать себя и искать новые пути решения 2. Производительность. Да развитие современной техники позвляет не заниматься оптимизацией на уровне комманд ассемблера, но это не значит что требования к производительности приложения можно совсем отбросить. Для компилятора это может быть приемлемо, или для системы поддержки принятия решений (и то не всегда). А для системы реально времени это не приемлемо совершенно, равно как и для системы взаимодействующей с пользователем. стали бы вы пользоваться текстовым редактором, в котором после ввода каждого слова следует секундная задержка на проверку орфографии? 3. Мелочевка. Серьезные конторы не вкладывают деньги в развитие таких языков, в основном это все университетские проекты. Отладка в функциональных языках затруднена. Самое главное: не видно особо сильных преимуществ функциональных языков, для того чтобы развернуть всю отрасль разработки ПО. А без этого ничего не будет, слишком много сил, денег и знаний вложено в традиционные языки. |
| Автор: setq 1.11.2005, 23:41 | ||
а на императивном? |
| Автор: Sardar 2.11.2005, 01:44 | ||
Не всегда, особенно в ООП часто просто определяешь пару основных интерфейсов, а затем пишешь прогу по кускам, порой совсем не зависимых друг от друга, благо ООП подход силён в этом. Сильно добивает в функциональных языках(по крайней мере в тех что я видел), так и в Питоне, это кривые названия функций/обьектов. Ужать имя до нескольких согласных могут все, а вот помнить это и с лёгкостью после читать код - не каждый. |
| Автор: setq 2.11.2005, 09:24 |
| может не полениться и потратить время на решение какой-нибудь задачи на одном из императивных и на одном из функциональных языков? почему бы нам не сравнить потом эти программы по 1) скорости написания 2) производительности 3) читаемости 4) красоты кода :-D 5) наличию багов 6) и прочее |
| Автор: Void 2.11.2005, 17:37 | ||||||||||||||
LSD
Думаю, из этого следует только один вывод - для написания текстового редактора ФЯ мало подходят
Вот как раз с этим пунктом проблем все меньше. Ряд языков имеют весьма эффективные компиляторы в нативный код, ряд генерируют байт-код управляемых платформ, на скорость которых тоже вроде не особо жалуются. У меня есть сильное подозрение, что во многих современных приложениях основная причина недостаточной производительность - не в языках/платформах на которых они пишутся, а в дизайне самих приложений.
Телефонные коммутаторы - это системы реального времени или нет? Кстати, вот еще один очень полезный атрибут ФЯ - легкость распараллеливания программ.
Я бы не сказал, что это мелочевка... Это очень важный фактор, противодействующий распространению ФЯ. Я вот с интересом смотрю на MS: ну ладно, F# и SML.NET - это все-таки исследовательские проекты. А вот то что поддержка функционального стиля была заявлена едва ли не как основная цель в C# 3.0 - "это ж-ж-ж неспроста"
Ну разве что в ленивых. А для остальных - проблема скорее просто в том, что никто не торопится писать отладчики (да и вообще сопутствующий инструментарий).
Да кто ж предлагал разворачивать индустрию? Речь идет не о замене императивного стиля функциональным, а о внедрении второго там, где он действительно нужен. К тому же в современных языках эти две парадигмы явно идут на сближение. setq
Пусть народ предлагает задачи. Может, удастся и сравнить |
| Автор: LSD 2.11.2005, 17:37 | ||||||||||
Запросто, особенно на всяких современных RAD средах. У нас была одна программа, программа взаимодействовала с некой аппраратурой, принимала сигналы от нее, обрабатывала, вообщем управляла процессом и плюс взаимодействовала с оператором. Программа была написанна на C++ Builder, а когда захотели перенести ее на Visual C++, выяснилось, что код настолько плотно завязан на C++ Builder, что выдрать его отуда практически нереально. Т.е. не было никакого разделения классов по функциям, визуальная чать отдельно, логика работы с аппаратурой отдельно, все было в перемешку. Вообщем в итоге бросли ее и стали писать заново.
У нас как раз открылся раздел тестов, предложи эту идею там. Добавлено @ 17:44
Капля в море. В любом случае языки которые идут от аппаратуры, будут потенциально более эфективнее, чем языки которые идут от задачи.
У нас уже был спор можно ли считать SQL языком программирования (я считаю что да), и если это так то почему для него нет отладчиков?
И где он действительно нужен? |
| Автор: Void 2.11.2005, 18:12 | ||||||
Были упомянуты системы реального времени и проблема эффективности. Я показал, что эти понятия ФЯ не противоречат. Думаю, в Ericsson умеют считать деньги и используют Erlang не ради собственного удовольствия.
Потенциально... Мне почему-то кажется, что эффективность инструментов проверяется только на практике. Не забываем и про стоимость разработки. Понятно, что, к примеру, на ассемблере можно выжать из железа все, что возможно, только софт золотым становится.
Я же сказал, проблемы возникают для ленивых языков, т. е. языков, в которых порядок вычислений не определен. "Жадные" языки прекрасно отлаживаются. Для того же OCaml (уж извините, что везде вставляю, но я только с ним знаком достаточно хорошо) есть ocamldebug, правда невизуальный (а-ля gdb) и только под *nix/Cygwin. Кстати, а как может выглядеть отладчик для SQL? |
| Автор: LSD 2.11.2005, 18:20 | ||||||
А зачем все приложение писать на ассемблере, только критическую часть, да и вообще Cи с этим неплохо справляется.
Вот и мне интерестно
Насчет Erlang ничего не скажу, я его не видел. Но при отладке SQL приходится забывать о всяких возвышенных вещах (типа оперирования множествами), и анализировать именно то как работает конкретная реализация SQL, на конкретной машине. |
| Автор: Void 2.11.2005, 18:43 | ||||
Для некоторых задач Си по сравнению с некоторым языками от ассемблера недалеко ушел Почему бы не применить ту же логику уровнем выше: критичная к производительности (или тесно взаимодействующая с железом/ОС) часть на C++, а остальное - на высокоуровневом, пусть и несколько более медленном языке? Впрочем, могу сам же частично и ответить: хлопотное это занятие, интеграция мало похожих языков. Если для скриптовых языков (Python, Lua) существуют библиотеки, обеспечивающие удобное взаимодействие с C++ кодом, то с ФЯ дело обстоит гораздо печальнее.
Если я правильно понял, речь идет скорее не об отладке, а о профилировании. |
| Автор: LSD 2.11.2005, 20:39 | ||
Да, я не совсем правильно выразился. |
| Автор: LSD 11.2.2008, 16:45 | ||||||
Поправочка - некрофил
Проверенный кем и на ком?
Да распаралеливание нужно в единицах задач. Мне вот больше 5-8 поток ни в одном моём приложении создавать не приходилось. Да и то, в основном потоки занимались тем что ждали данные от внешних источников (сеть, com порт и т.п.). А по поводу ручное vs автоматическое управление многозадачностью, http://forum.vingrad.ru/forum/topic-194597.html уже был один жаркий спор. А вот что нужно на самом деле и чего нет ни у одного ФЯП (слово то какое
Как все красиво звучит в теории |
| Автор: Void 11.2.2008, 17:24 | ||||||
Ну-у, в принципе, ни для одного языка программирования сложность не была оценена объективно. Тем не менее, никто обычно не спорит, что, скажем, plain old Pascal проще, чем C++. Эрланг, в отличие от Паскаля с Сями, мало кому известен, но ежели кто осилил туториал, то не согласиться с тем, что толковый разработчик разберётся с языком за пару недель, будет трудно.
Sic! Это потому что у тебя парадигма неправильная
Некоторые особо хитрые товарищи (см. Scala, Nemerle) взяли, и присосались к JVM и .NET FW В остальных, да, фреймворков нет. Есть, конечно, OTP, который могуч и ужасен, но «страшно далёк от народа» в своём телекомовском великолепии. |
| Автор: LSD 11.2.2008, 18:04 | ||||
И получили все прелести взаимодействия с императивными языками (типа side-efects)
А вот тут и возникает вопрос, что есть процесс в Эрланге? Если это просто некая обёртка над процессами ОС, то это просто ужас. Т.к. в мейнстримовых ОС, процесс штука очень ресурсоемкая и создание его весьма длительно. |
| Автор: Mayk 11.2.2008, 18:14 |
| в сторону. Нашёл "The implementation of functional programming languages" написанную Peyton'ом Jones'ом. ыыыыы. Любопытные вещи валяются в ed2k. |
| Автор: Void 11.2.2008, 18:17 |
Ни в коем случае. Это сущность виртуальной машины со своим планировщиком. Процессы очень легковесные, их можно держать столько, сколько влезет в память, то есть десятки и сотни тысяч на типичном десктопе. Процессы взаимодействуют только через асинхронный обмен сообщениям, никаких разделяемых данных, никакой синхронизации. Экземпляры виртуальной машины могут быть запущены на разных узлах и сети, и по сети могут прозрачно ходить сообщения. Т.е. всё это добро очень неплохо натягивается и на SMP, и на кластеры. |
| Автор: LSD 12.2.2008, 12:51 | ||||
И все это удовольствие может работать поверх обычной VM (я про JVM или .NET runtime)?
Наверно это хорошо. Только вот насколько это востребовано бывает. |
| Автор: Void 12.2.2008, 15:19 | ||
Нет, там своя виртуальная машина, с софт-реалтайм планировщиком и сборщиком мусора. Наверное, можно изобрести что-то подобное поверх JVM или CLR, но насколько близко будет по характеристикам, трудно сказать. С другой стороны, JIT в Эрланге нет, только прямая интерпретация байт-кода или прекомпиляция (HiPE), которая в зависимости от кода даёт прирост скорости в 2-3 раза. То есть в однопоточном коде Эрланг будет медленнее Джавы, где-то на уровне Питона. Но можно подцепить модуль на Си или посадить в Эрланг-кластер узел на Си или Джаве — соответствующие библиотеки есть. Оно востребовано для того, для чего создавалось: телеком, всякого рода high-load системы. |
| Автор: Shaggie 13.2.2008, 08:13 | ||
Одерски сотоварищи внедрили в scala механизм actors наподобие Эрланговского. Руки ещё не дошли, но везде где пишут о scala - громко хвалят систему actors, по большей части за несравненне удобство в работе с ними. Работает оно как раз на JVM, поэтому байт-код итоговый получается один-в-один с обычным Джавным, а значит, предел мощности ограничен несколькими сотнями потоков. Вам решать, много это или мало. С другой стороны, выгодно смотрелся бы симбиоз потрясающей легковесности Эрланговской мнгопоточности вкупе с привычной императивностью и простотой обработки программной логики на Джаве... и такие эксперименты уже ведутся, подробнее можно прочитать http://www.theserverside.com/tt/articles/article.tss?l=IntegratingJavaandErlang. |
| Автор: Void 13.2.2008, 11:38 | ||
Нельзя назвать это экспериментами, jinterface в составе OTP уже чёрт знает сколько, бери и пользуйся... Cyberax http://rsdn.ru/forum/message/2798767.1.aspx на RSDN примером более удобной интеграции Java и Erlang. Обещают в скором времени отдать в open source. |
| Автор: LSD 15.2.2008, 13:45 | ||
"Узок их круг и страшно далеки они от народа" (это к вопросу о причинах малой распространённости) |
| Автор: Void 15.2.2008, 16:20 |
| LSD, да собственно никто не спорит уже. Для задач, которыми занимается большинство программистов, жабошарпов с избытком хватает |
| Автор: LSD 15.2.2008, 16:35 |
| Amazon - тоже мне пример, эти маниаки на чем только не пишут |
| Автор: Void 15.2.2008, 16:53 |
| Или вот IBM http://damienkatz.net/2008/01/new_gig.html разработчика http://couchdb.com/ Примеров можно насобирать прилично, маньяки есть везде |
| Автор: Амортизатор2 14.3.2008, 23:35 | ||||
Насколько я понял, эти акторы - по сути реализация на Scala спецификации JTA.
Уже не хватает. Собственно, сегодня старые парадигмы доживают последние дни. Будущее - за асинхронностью и параллелизмом. Закон таков - алгоритм, который может быть распараллелен, должен быть распараллелен, причем это должно происходить автоматически. Собственно, сегодня можно вовсю наблюдать, как куча хардкорщиков занимается тем, что тупо добавляет в свой софт "поддержку еще одного ядра" , а потом бьет пяткой в грудь - мол, у нас используется аж 2 ядра. Эти убогие поделия не более масштабируемы, чем их однопоточные оригиналы. Не сегодня-завтра появятся процессора с сотнями ядер, хотел бы я посмотреть, как они будут параллелить ручками... в общем, java и c# на свалку истории... |
| Автор: LSD 15.3.2008, 15:05 | ||
Ага формочка которая показывает бухам их годовые отчеты, просто обязана использовать не менее 10 потоков |
| Автор: Sardar 15.3.2008, 15:30 | ||
А события с клавы, мыши и другие действительно удобно в своих короткоживущих тредах (асинхронных сообщениях) выполнять Гуй, это одна из областей где fine grained распараллеливание воспринимается на ура. |
| Автор: LSD 15.3.2008, 15:43 | ||
А нынешняя парадигма обработки событий уже успела стать неудобной? |
| Автор: Sardar 15.3.2008, 16:11 |
| Ну там где есть closures/inner classes, т.е. где "решение проблемы" можно описать сразу же на месте - то да, не отвратно. Но приходиться помнить, что в обработчике много не делаем, ставить worker threads, заполнять очереди pending operations - и всё это ради быстрого отклика от гуя. Многие забивают на это, получаем "тормознутый" софт. |
| Автор: Амортизатор2 15.3.2008, 19:27 | ||||||
Хоть 10000, если потребуется. Сколько потоков использовать - решает рантайм, и никто другой. Твоя задача - программировать так, чтобы позволить рантайму произвести потоковую оптимизацию.
Истинно так. Кстати, это - уже сегодняшний день. Посмотрите на любой веб-фреймфорк для ui (ext, gwt) - там все построено на асинхронных сообщениях. Какая нынешняя? Если ты имеешь ввиду стандартный виндовый способ программирования, когда UI работает в одном потоке с основной программой, то это всегда было не лучшим решением. Добавлено через 4 минуты и 37 секунд LSD, ты не совсем правильно меня понимаешь. Вот эти слова
следует воспринимать не по отношению к рйнтайму, а применительно к программированию. Т. е. параллелизм не физический, а логический. ФП - один из способов организации такого параллелизма, далеко не единственный, кстати говоря. |
| Автор: LSD 17.3.2008, 17:42 | ||||
Вот и я о чем. Ты предлагаешь всем переучиваться, мучаться с переписыванием старого софта, ради малоперспективных выгод. Современные GUI приложения не нуждаются в сильном паралелизме т.к. возможностей современного железа хватает за глаза.
Тут конечно бы это пригодилось, но не так уж и часто такие ситуации возникают. И не так уж трудно с этим бороться. |