Функциональное программирование |
Функциональное программирование всегда привлекало меня в противопоставлении к императивному.
Я очень часто обсуждаю различные аспекты функционального программирования на различных ветках на Базарной площади.
Но хотелось бы собрать всех заинтересованный этой темой в одной ветке.
Я думаю что настало время открыть такую тему. И вот почему.
Исторически функциональное программирование появилось практически вместе с императивным.
Вторым языком после фортрана был лисп.
Но увы, функциональное программирование надолго было уделом исследовательских институтов или специализированных приложений (Искусственный Интеллект)
Конечно не надо считать весь мир дураками из за того что развитие пошло по пути языков Алгол семейства.
Для этого были вполне обьективные причины. Функциональные языки слишком близки к человеку и слишком далеки от машины.
Они сьедают в десятки раз больше рессурсов чем императивные языки.
Вспомните претензии, предявляемые к java - первому императивному языку с виртуальной машиной и сборщиком мусора, толкаемому большими корпорациями в mainstream.
Жутко тормозит, и жрет всю память какая есть. А ведь функциональные языки (далее ФЯ) все без иключения имеют сборщик мусора, виртуальную машину.
Многие из них (семейство лисп) еще и динамические, что только усугубляет положение.
Вполне естественно что появившись более полусотни лет назад они надолго опередилли свое время.
Для широкого распространения ФЯ нужны гигабайты дешевой памяти и гигагерцы дешевых процессоров.
Прошло более 50 лет, прежде чем такие требования к железу стали реальностью.
Это время наступило. СЕЙЧАС.
Добро пожаловать в новую эру программирования.
Jack Of Shadows
Всего в теме 5502 сообщения
Добавить свое сообщение
Отслеживать это обсуждение
- Средства разработки. Языки программирования.
- Delphi 4 or Delphi 5
- Что приобрести в качестве средства разработки?
- Delphi6
- Delphi vs PowerBuilder
- Сравнение компиляторов
- Вот и вышла Delphi 7... Вы рады?
№ 2292 29-03-2007 09:29 | |
Ответ на »сообщение 2290« (Geniepro)
___________________________
>>>Find the sum of the digits in the number 100!
Опять за рыбу гроши.
Никто и не отрицает, что на простеньких математических задачках ФП очень эффективный инструмент. Опять идет сравнение с процедурным программированием.
Компонентное и объектное программирование появились для борьбы с растущей сложностью программных систем и решаемых задач. Только там и имеет смысл сравнение с Обероном или ОО языками.
Впрочем и на этом примере все не так однозначно. Может быть я и не буду непосредственно вкладывать друг в друга 4 функции, но принципиальных отличий в алгоритме естественно не будет. Библиотека арифметики для длинных целых найдется практически в любой реализации любого языка, равно как и списки, массивы и т.д. Так что придется написать только алгоритм подсчета суммы цифр, такой функции скорее всего в стандартной библиотеке не найдется. Если в хаскеле есть такая стандартная функция, то это конечно большой плюс :)
>>>Ну вот что тут непонятного в этом коде? :о))
Ну что может быть непонятного в решении такой задачки?
Я уже предлагал упрощенно показательную задачу моделирования движения бильярдных шаров. Боюсь, что даже на такой, в общем простенькой задаче, решение на ФЯ будет и не компактнее и не понятнее, чем в ОО языке. Давайте еще упростим и не будем учитывать трение, требуется найти положение шаров через время T после удара. Лишь бы в задаче присутствовало время и события.
№ 2291 29-03-2007 08:57 | |
Ответ на »сообщение 2273« (Geniepro)
___________________________
Ответ на »сообщение 2265« (info21)
___________________________
А как же по-Вашему x86 реализует вычисление функции Аккермана?
Известно как - с помощью рекурсии.
А как силикон реализует рекурсию?
Эх-хе-хе...
№ 2290 29-03-2007 08:32 | |
Ответ на »сообщение 2279« (Илья Ермаков)
___________________________
Но не обязательно к ФП в смысле перечисленных чуть ранее "наворотов" :-)
Илья, те вещи, которые я перечислил в »сообщение 2260« , являются стандартными составляющими современного ФП. Без них язык низводится до уровня функционального ассемблера...
Вы же не пишите программы на ассемблере? Предпочитаете гораздо более высокоуровневый Оберон?
Так же и работать на ассемблере ФП не стоит, если есть полноценные ФЯ.
Несмотря на то, что Оберон - хороший ассемблер ООП, он, тем не менее, не может быть даже ассемблером ФП (из-за отсутствия главных пунктов в этом списке - лямбд и возврата процедур в качестве результатов других процедур).
Я подозрительно отношусь к усложнениям инструмента.
Мне очень понравилась статья Пола Грэма (Paul Graham) "Краткость - сила" , где он обосновывает своё мнение о том, что чем выше уровень языка и чем он удобнее, тем короче программы, на нём записанные.
Перечисленные мною элементы ФП необходимы для полноценной, удобной и быстрой работы на ФЯ, только и всего. Так же как и для Вас циклы и ветвления необходимы и более удобны, чем операторы условного перехода GOTO (типа jnz и прочее), которыми всё это реализуется на самом нижнем уровне...
Вот сравните решение задачки №20 с Project Euler :
Problem 20
n! means n * (n - 1) * ... * 3 * 2 * 1
Find the sum of the digits in the number 100!
sum $ map (\c -> read [c]) $ show $ product [1..100]
с кодом решения на Оберонах - какой вариант выиграет в понятности, читаемости, надёжности, лёгкости написания?
Учитывая, что Вам ещё придётся создать библиотеку арифметики больших чисел... Слабо Вам решить эту простейшую задачку? :о))
Кстати, в этом хаскеллевском коде используются именно "навороты" в Вашем понимании или просто базовые понятия ФП, такие как list comprehension [1..100], лямбда-абстракция (\c -> read [c]), ФВП map, полиморфные функции sum, show, read и product, ну и ещё удобный комбинатор функций $. Ну вот что тут непонятного в этом коде? :о))
№ 2289 29-03-2007 06:57 | |
>>>Как это "без рекурсии"? Есть тама рекурсия! Вы её СЭМУЛИРОВАЛИ! :о)
О том и речь! Любую рекурсию можно устранить из алгоритма, эмулировать ее с помощью итераций (циклов). Так же и наоборот - любой итерационный алгоритм можно заменить на рекурсивный. Эквивалентность рекурсии и итерации - это, по сути, эквивалентность алгоритмической системы Черча (рекурсивные функции) и машины Тьюринга (итерации). И эта эквивалентность математиками уже давно не подвергается сомнению.
Есть хороший материал на эту тему из книги Рода Стивенса, глава "Рекурсия":
http://am.rusimport.ru/MsAccess/topic.aspx?ID=266
Обратите внимание на следующий фрагмент:
"И хотя любой алгоритм можно переписать так, чтобы он не содержал рекурсии, многие алгоритмы сложнее понимать, анализировать, отлаживать и поддерживать, если они написаны нерекурсивно. В следующих разделах приведены методы устранения рекурсии из любого алгоритма".
Что это? Автор не понимает, о чем пишет? Или рецензенты пропустили ляп?
№ 2288 29-03-2007 06:29 | |
Ответ на »сообщение 2282« (Jack Of Shadows)
___________________________
1. Данные (глобальные обьекты), которые хранят состояние. Неважно в памяти или в БД
2. Код реагирующий на события (events)
3. Код преобразующий данные.
4. Код сохраняющий изменения.
В зависимости от соотношения сложности этих частей и нужно выбирать язык. Какая часть наиболее сложная и наиболее нуждается в синтаксической поддержке языка.
ФП предполагает полное разделение этих слоев, тогда как ООП основан на декомпозиции сначала на объекты, и уже для каждого объекта по этим слоям.
Для ФП очень подходят задачи пакетной обработки: ввод->обработка->вывод.
>>>Код реагирующий на события...в чистых ФЯ помечен IO
Т.е. ввод-вывод. Опять предполагется, что события появляются только извне. Тогда как во многих задачах события генерируются различными частями программы.
№ 2287 29-03-2007 02:42 | |
Ответ на »сообщение 2262« (Q.Werty)
___________________________
>>>Функция Аккермана тому пример.
Увы! Функцию Аккермана можно вычислить и с рекурсией и без нее. Поэтому этот пример не проходит.
собственно говоря, рекурсия реализуется с помощью стека, что вы и продемонстрировали
№ 2286 29-03-2007 02:33 | |
Ответ на »сообщение 2282« (Jack Of Shadows)
___________________________
Ответ на »сообщение 2281« (AVC)
Чем отличается
myObject.DOSomething
от
myObject <- DoSomething(MyObject)
В плане сложности реализации ?
Но MyObject-то всплывает наверх! Для ряда задач в этом есть свои плюсы - все состояние наверху, "кучей". В других случаях это противоестественная архитектура. Для системного программирования естественно, что каждый блок программы имеет свое состояние. В Обероне, например, блоки - это модули, АТД ("микромодули") и активации процедур. Блоки связываются различного рода шинами, по которым передаются сигналы (при этом переменные выполняют роль "припоя" на разъемах).
№ 2285 29-03-2007 02:30 | |
Ответ на »сообщение 2282« (Jack Of Shadows)
___________________________
2. Код реагирующий на события.
Опять же в обоих случаях совершенно одинаковый. Небольшая разница в том что в чистых ФЯ такой код помечен IO . Но как вы пишите этот код совершенно не отличается от ИЯ.
Разница в том, что функциональщики (точнее, их радикальное крыло -- хаскеллисты :) ) подают этот код как "чистый ФП".
Мол, монады позволяют все реализовать с помощью чистого ФП.
И пока ты потираешь лисыну в раздумье над присвоением, которое, однако, остается чистым ФП, они вполголоса переговариваются между собой, кто из них еще какие монады знает, -- делятся опытом.
В ФЯ чистые функции не имеют доступа к изменяемым данным, а потому эти данные надо передавать им явно.
То есть
MyObject <- DoSomething(MyObject);
Как видите чистая функция не только не имеет доступа к изменяемым данным, но и не может ничего наружу записать. Может только вернуть результат.
Уже снаружи этой функции происходит запись данных в переменную. То есть императивная операция.
Так где же (цвай таузенд тойфель!!) эта запись все-таки имеет место быть?
Где -- снаружи?
Снаружи ведь еще одна функция, которая также не может писать в "глобальные данные".
К тому же, писать данные где-то "снаружи", а не с помощью метода объекта, -- выглядит как нарушение инкапсуляции.
№ 2284 29-03-2007 02:15 | |
Ответ на »сообщение 2283« (Рэйлвэй Каген)
___________________________
И разрешить еще собственные либы подтягивать 8))
Обязательно. Но только с условием. Все opensource.
Это приведет к тому что из года в год инструментарий которыми пользуются команды будет общедоступным и будет развиваться. Что на пользу всем.
№ 2283 29-03-2007 02:02 | |
Ответ на »сообщение 2101« (Jack Of Shadows)
___________________________
...разница в размере кода новичка-хаскелиста и зубра-оберониста практически в два раза, показывает что в условиях соревнований у хаскелистов будет колоссальное преимущество в скорости.
Что опять таки утверждает меня в моем мнении что разреши в соревнованиях хаскель, окамл, лисп - и о гегемонии ИЯ на соревнованиях можно забыть.
Проигрывать то никому неохота :))
И разрешить еще собственные либы подтягивать 8))
Раз уж языки ФП имеют встроенные алгоритмические реализации, то будьте справедливы - дайте всем претендентам одинаковые тапки. Иначе получается соревнование "пианиста с бумбоксом". Кто есть ху, уточнять в данноми случае не стОит, важен сам подход.
Особенности реализации, скрываемые компилером в ФП, безусловно, повышают наглядность программы. При этом появляется полная зависимость от реализации самого компилера; и при неизбежном (и бесконечном) в рамках ФП расширении синтаксиса языка приходится тащить груз совместимости с предыдущими его спецификациями. Польза для дела конечно есть - производитель компилера профессионально занимается всей этой совместимостью "внутренней ботвы". Любой стартап спасибо скажет за такое облегчение.
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|