Функциональное программирование |
Функциональное программирование всегда привлекало меня в противопоставлении к императивному.
Я очень часто обсуждаю различные аспекты функционального программирования на различных ветках на Базарной площади.
Но хотелось бы собрать всех заинтересованный этой темой в одной ветке.
Я думаю что настало время открыть такую тему. И вот почему.
Исторически функциональное программирование появилось практически вместе с императивным.
Вторым языком после фортрана был лисп.
Но увы, функциональное программирование надолго было уделом исследовательских институтов или специализированных приложений (Искусственный Интеллект)
Конечно не надо считать весь мир дураками из за того что развитие пошло по пути языков Алгол семейства.
Для этого были вполне обьективные причины. Функциональные языки слишком близки к человеку и слишком далеки от машины.
Они сьедают в десятки раз больше рессурсов чем императивные языки.
Вспомните претензии, предявляемые к java - первому императивному языку с виртуальной машиной и сборщиком мусора, толкаемому большими корпорациями в mainstream.
Жутко тормозит, и жрет всю память какая есть. А ведь функциональные языки (далее ФЯ) все без иключения имеют сборщик мусора, виртуальную машину.
Многие из них (семейство лисп) еще и динамические, что только усугубляет положение.
Вполне естественно что появившись более полусотни лет назад они надолго опередилли свое время.
Для широкого распространения ФЯ нужны гигабайты дешевой памяти и гигагерцы дешевых процессоров.
Прошло более 50 лет, прежде чем такие требования к железу стали реальностью.
Это время наступило. СЕЙЧАС.
Добро пожаловать в новую эру программирования.
Jack Of Shadows
Всего в теме 5502 сообщения
Добавить свое сообщение
Отслеживать это обсуждение
- Средства разработки. Языки программирования.
- Delphi 4 or Delphi 5
- Что приобрести в качестве средства разработки?
- Delphi6
- Delphi vs PowerBuilder
- Сравнение компиляторов
- Вот и вышла Delphi 7... Вы рады?
№ 2862 14-04-2007 13:00 | |
Ответ на »сообщение 2861« (Руслан Богатырев)
___________________________
Такие далеко идущие выводы на основе озвученного эксперимента вызывают скепсис. Объясню почему:
...
Странно, что у Вас возникли эти вопросы. Вы хоть прочли статью?
4) кто готовил данную статью (их предпочтения и мотивация)?
Авторы статьи - люди, известнейшие в мире Хаскелла, одни из создателей Хаскелла.
Их предпочтения и мотивация очевидны.
1) одинаков ли опыт участников эксперимента в решении подобных задач (сколь равные были условия)?
В статье не указывается, решали ли раньше участники эксперимента подобшые задачи.
Было упомянуто только, что участники - профессионалы в используемых ими языках.
Исключение - выпускник колледжа, сделавший программу (10), он в эксперименте не участвовал; отдельный опыт с ним был проделан втайне от других участников эксперимента (видимо, для контрольного теста Хаскелла).
2) сколь значима выборка (один результат на один язык -- это даже не статистика)?
Об этом судить не могу.
Но могу посоветовать почитать статью Эранна Гата, которую я тут уже как-то упоминал:
Erann Gat, "Lisp as an Alternative to Java"
3) кто оценивал результат (уровень квалификации во всех упомянутых языках и реальная мотивация членов жюри -- "а судьи кто")?
Судьями были независимые эксперты, приглашённые устроителями эксперимента. Конкретно - "computer scientists and software engineers", откуда именно - не указано.
Уровень квалификации по крайней мере в Хаскелле - похоже, не очень высокий. Некоторые из них даже не могли поверить в то, что решение (1) (от авторов статьи) является реальной исполнимой протестированной программой на Хаскелле, а не просто спецификацией программы...
Насчёт их оценок прямо сказано, что они - субъективны.
Мотивация? Ну какая у них могла быть мотивация?
Им предложили оценить прототипы по нескольким параметрам, таким как скорость разработки прототипов, понятность кода и лёгкость модификации, масштабирования, повторного использования и т.д. Главное для этих экспертов было оценить пригодность разных языков программирования для быстрого прототипирования сложного ответственного ПО, вот и всё.
Я понимаю, вы, вероятно, недовольны отсутствием Оберона в списке языков. Ну что ж, в 93-м году, похоже, американские военные мало знали про Оберон, если вообще знали о нём... Жаль, конечно, что Оберон не участвовал в этом эксперименте, но что уж тут поделаешь...
По количественным -- число строк в документации не говорит практически ни о чем (кроме разве что -- чего-то написал участник или же вообще не тратил на это время).
Вообще-то, понятность кода прототипа зависит в том числе и от качества его документации, а этот параметр (понятность кода) был не менее важен для экспертов при оценке прототипов, чем скорость разработки.
Что касается времени разработки: например, в разработке интерактивных программ следует помнить, что время реакции человека не превышает 0,1 сек. Это значит, что есть так называемй порог чувствительности, ниже которого скорость не важна. Т.е. если функция в интерактивной программе будет выполняться в 100 раз быстрее и не за 0,1 сек, а за 0,001 сек -- это практически ничего не даст. Надо знать требования масштабирования.
Вапще непонятно, к чему Вы упомянули про этот порог реакции?
Естественно, эти прототипы были сделаны не за доли секунды... :о)
№ 2861 14-04-2007 11:44 | |
Ответ на »сообщение 2835« (Geniepro)
___________________________
Общий вывод статьи таков: функциональное программирование прекрасно подходит для быстрого прототипирования серьёзного и важного программного обеспечения.
Это интересная информация к размышлению. Не более. Не хочу никак преуменьшать значение подобных публикаций и никого обижать, но..
Такие далеко идущие выводы на основе озвученного эксперимента вызывают скепсис. Объясню почему:
1) одинаков ли опыт участников эксперимента в решении подобных задач (сколь равные были условия)?
2) сколь значима выборка (один результат на один язык -- это даже не статистика)?
3) кто оценивал результат (уровень квалификации во всех упомянутых языках и реальная мотивация членов жюри -- "а судьи кто")?
4) кто готовил данную статью (их предпочтения и мотивация)?
Кроме того, хотел бы обратить внимание, что критерии носили количественный характер (число строк, документация, время разработки) и качественный (оценка судьями). По последнему не вижу даже смысла обсуждать -- за недостатком информации об их квалификации и мотивации.
По количественным -- число строк в документации не говорит практически ни о чем (кроме разве что -- чего-то написал участник или же вообще не тратил на это время). Было бы куда полезнее отделить документирование от реализации (вычесть время и явно его обозначить). Что касается времени разработки: например, в разработке интерактивных программ следует помнить, что время реакции человека не превышает 0,1 сек. Это значит, что есть так называемй порог чувствительности, ниже которого скорость не важна. Т.е. если функция в интерактивной программе будет выполняться в 100 раз быстрее и не за 0,1 сек, а за 0,001 сек -- это практически ничего не даст. Надо знать требования масштабирования.
Что касается числа строк исходного текста, то они важны с двух позиций:
1) если считать, что время затрачиваемое программистом на кодинг (не на программирование) прямо пропорционально количеству строк безотносительно языка, то это выигрыш во времени на получение макета;
2) чем меньше количество строк, тем проще анализировать исходный текст, но при этом не надо забывать, что в этом случае некорректно просто подсчитывать общее количество -- анализ облегчается декомпозицией на блоки -- модули и процедуры/функции (функция на 1 экран предпочтительнее для анализа функции на 3 экрана). Игнорирование этого момента некорректно и потому, что скриптовые языки, равно как и ФП, могут рассматриваться как синтаксическая надстройка над ИЯ-библиотеками (где выделены и поименованы эти блоки).
К чему это я? К тому, что в экспериментально-тестовых задачах, когда проводятся такие эксперименты, необходимо для количественных показателей задавать "диапазоны чувствительности" (когда колебание значения внутри данного диапазона неважно -- т.е. что 10 часов и 15 часов -- суть одно и то же; равно как 85 строк и 300 строк). О таких диапазонах должны быть проинформированы априори и участники "соревнований".
Надо знать, и сколь масштабируема задача макетирования (а это было именно макетирование, т.е. получение неоптимальной действующей модели, дающей требуемый результат) и сколь легко потом превращать/встраивать макет в реальную систему (выдерживая все необходимые требования), иными словами -- не понадобится ли после пересечения финишного створа все выбрасывать и делать уже по-новому и более аккуратно.
Как-то неудобно "поучать" людей, имеющих отношение к вопросам разработки ПО для оборонки, но упомянутые мной моменты имеет смысл знать и понимать. А также иногда озвучивать, чтобы не было недопонимания всей важности результатов и особенно -- выводов.
№ 2860 14-04-2007 10:52 | |
Ответ на »сообщение 2859« (Max Belugin)
___________________________
Вот оно так и есть:
Это главный цикл из простой игры Asteroids (Haskell in Space). Пожалуй, Вы правы - для объяснения основ построения интерактивных игр на Хаскелле это пример - один из лучших.
И мне кажется, везде так и есть.
В более сложных OpenGL'ных играх уже чуть посложнее.
Функция mainLoop находится уже внутри библиотеки OpenGL и программисту просто так не доступна. До запуска этой функции нужно настроить обработчики разных событий от клавиатуры, мышки, таймера, прорисовки экрана, настроить реакции, в общем. Ну а дальше уже крутить цикл типа loop w s, пока не произойдёт выход из игры...
Только поверх этого могут быть нафёрнуты всякие монады. Фактически, насколько я понял, монада IO есть способ комбинирования таких функций
Монада IO - однопоточный ввод/вывод. Для многопоточного ввода/вывода можно использовать, например, Arrows.
А всякие монады тут вообще ни причём. Списки, в конце концов, тоже монады.
№ 2859 14-04-2007 09:54 | |
Ответ на »сообщение 2858« (Geniepro)
___________________________
Например (это, конечно, мои глупые фантазии) так: основной цикл программы моделирования реализован в виде хвостовой рекурсии, а (измененное) состояние передается между итерациями в качестве аргумента этой рекурсивной функции основного цикла.
Вот оно так и есть:
loop w s =
do setGraphic w (drawState s)
getWindowTick w
evs<- getEvs
s<- nextState evs s
g<- newStdGen
if (end s) then (closeWindow w)
else if ((shipDes (ship s)) && not godmode && (rsCnt s) > 0)
then loop w s
else if ((shipDes (ship s)) && not godmode)
then loop w (initialState (randomRs ((-astSpd),astSpd) g) (randomRs (1,8) g) (randomRs (0,12) g))
else loop w s
И мне кажется, везде так и есть. Только поверх этого могут быть нафёрнуты всякие монады. Фактически, насколько я понял, монада IO есть способ комбинирования таких функций
№ 2858 14-04-2007 09:43 | |
Ответ на »сообщение 2851« (AVC)
___________________________
Что такое ООП? Каждый может ответить по-своему.
Назову некоторые черты ООП: децентрализация, косвенность и обобщение.
Это настолько общие черты, что их можно легко увидеть и в ФП.
Например (это, конечно, мои глупые фантазии) так: основной цикл программы моделирования реализован в виде хвостовой рекурсии, а (измененное) состояние передается между итерациями в качестве аргумента этой рекурсивной функции основного цикла.
Или, что вероятнее, используется какой-то другой способ.
Вариантов может быть множество, и Вы только что назвали один из вариантов.
Но конкретно в таких задачах, как интерактивные игры типа Квейка или бильярда, в ФП следует применять ФРП, реализованное с помощью библиотек типа Yampa для Хаскелла. К сожалению, у меня нет больщого опыта в игростроении, тем более с помощью ФП, но основное направление в принципе ясно...
Я бы порекомендовал посмотреть презентацию Paul Hudak, "Arrows, FRP, and Functional Reactive Programming" и статью Paul Hudak et al., "Arrows, Robots, and Functional Reactive Programming", но там. правда, уже надо хоть как-то разбираться в монадах, так как ФРП построено на обобщении монад, Arrows...
Вместо того, чтобы отсылать спрашивающего к 345KB очередного чуда криптографии, вполне можно, IMHO, объяснить принцип на словах.
Ну если заранее настраивать себя на то, что ФП - лишь криптография, что ж... Боюсь, тысяч слов будет недостаточно, что бы объяснить хоть какие-то принципы...
Кстати, а не попробуете ли Вы сделать Квейк на Обероне? Интересно, насколько криптографичным будет Ваш код. Боюсь, не меньше, чем на Хаскелле.
Вот как Вы бы организовали обработку событий? С помощью шины сообщений? С помощью активных объектов? Как-то ещё? А что мешает эти же принципы использовать в ФП?
А вообще, забавная ситуация: Вы хотите, что бы Вам в нескольких словах объяснили принципы Функционального Реактивного Программирования, но при этом у Вас, похоже, нет особого желания разбираться с просто Функциональным Программированием.
Интересно, если бы к Вам обратился кто-то с просьбой объяснить в нескольких словах сущность event driven OOP, но при этом не желал бы разбираться и изучать простое Императивное программирование, сумели бы Вы выполнить его просьбу? Ну попробуйте... :о))
№ 2857 14-04-2007 09:41 | |
Ответ на »сообщение 2853« (pepper)
___________________________
Я не очень понимаю, чем оберону поможет r/o импорт, если любая импортируемая процедурная переменная (пусть даже сама по себе и r/o) может сделать все что угодно с "состоянием" какого угодно модуля.
Импорт с ограничениями (не только на чтение) может помочь не языку Оберон, а программисту. Что касается процедурной переменной, то она выступает в двух ипостасях -- как переменная (которая хранит ссылку на процедуру) и как полноправная процедура. Импорт с ограничениями в первом случае накладывает запрет на изменение ссылки. Во втором случае существуют те же средства контроля, как и для обычных процедур: способ/характер/режим передачи параметров (это уже подробно разбиралось).
Например, квалификатор const в C++ гарантирует лишь то, что пользователь такого объекта никак не может его модифицировать, но сам константный объект может меняться как угодно (в том числе и кем-то третьим, для которго он не const).
Я пояснял, что переменная, импортированная на чтение (равно как и экспортированная на чтение) -- это не константа. Она может постоянно меняться (например, другим процессом). Просто ее запрещено изменять сущностями данного "государства".
№ 2856 14-04-2007 05:29 | |
Ответ на »сообщение 2842« (Jack Of Shadows)
___________________________
Ответ на »сообщение 2841« (Сергей Перовский)
___________________________
Что из себя представляет такая вот методика построения архитектуры ?
Бетон видели как делается ?
В форму укладываются длиннющие и очень крепкие железные пруты, арматура.
Затем все это заливается цементом.
Как цемент прихватило, поздно уже что то менять. Только ломать и заново строить.
Из Ваших рассуждений следует, что строить из железобетона невозможно :(
Jack, оглянитесь вокруг: все крупнейшие постройки мира железобетонные.
Просто в архитектуре и строительстве проектирование от строительства отделено законодательно: пока не будет готов проект никто не позволит "написать ни строчки кода".
Ваше предложение с быстрым моделированием напоминает сборку модели из конструктора лего: быстро, наглядно но ничего не отображает и не доказывает.
Ни один архитектор не работает в песочнице, у него есть бумага (теперь компьютер), у него есть расчетные методики. Ни одной железячки и ни грамма бетона он не увидит пока не закончит работу - только в процессе авторского надзора.
И только фундамент под избушку можно сделать "по месту". Но мы же рассматриваем программные системы, а не программульки.
Надо заметить, что аналогия очень хорошая: строительные объекты очень разнообразны, работа архитектора нисколько не более стандартна, чем работа программиста. То, что здания падают гораздо реже программ, дает повод думать, что знание строительной механики полезнее возможности построить натурную модельку, а разделение проектирование и реализации разумный подход к делу.
№ 2855 14-04-2007 03:46 | |
Ответ на »сообщение 2842« (Jack Of Shadows)
___________________________
Посмотрите, во всех до единого книгах по ООП, говорится. что раз построив модель, иерархию классов и их взаимосвязей, переделывать ее уже невозможно (слишком дорого)
Это Вы наверное не читали книг Кента Бека. :)
Джек, не нужно путать традиционные подходы к проектированию и ООП, ведь то же XP *призывает* к рефакторингу.
№ 2854 14-04-2007 03:46 | |
Ответ на »сообщение 2852« (Jack Of Shadows)
___________________________
Давайте возьмем другой пример - пианист.
Он может пройти прекрасную школу, иметь более десяти лет опыта.
Но он не может основываясь на все свои знания и весь свой опыт, просто взять новую незнакомую партитуру, выйти на сцену и сходу ее забацать.
Ему требуется тренировка.
Да, он сможет разобрать эту партитуру за неделю. В тысячи раз быстрее чем любой неподготовленный человек.
Именно из за своих знаний и опыта по переносу этих знаний на новые ситуации.
Но никакие знания и никакой опыт не освобождают от необходимости каждую ситуацию изучать заново.
И у шахматистов то же самое.
<...>
Да, может быть в тысячи раз быстрее и эффективнее нешахматиста.
Но тем не менее, изучать новую ситуацию вам придется. Чтобы потом по настоящему сыграть всего один лишь раз.
Я выделил пару мест в Вашем тексте, подтверждающих, IMHO, что перенос опыта существует.
Бесспорно, думать при этом все равно приходится. Нам требуются и мышление, и опыт.
Более того, мышление именно и занимается тем, что применяет накопленный опыт к новым ситуациям. Если бы опыт был совершенно неприменим к новым ситуациям, то мышления не существовало бы вовсе.
Что касается конкретно шахмат, если бы в них не требовалось думать, они не доставляли бы никакого удовольствия (от процесса мышления и инсайта), и тут же были бы забыты.
Посмотрите на все виды деятельности человека, где он каждый раз решает новую проблему.
Вы не найдете ни одной в которой новые проблемы бы решались только на основе некоего обобщенного опыта, сходу.
Jack, Вы спорите с какой-то другой точкой зрения, не с моей.
Я не говорю, что обобщенный опыт дает решение "сходу".
Просто "обобщенный опыт" и "мышление" -- две стороны одной медали, они друг без друга не существуют.
Вот только ООП ставит программистов в идиотскую ситуацию, когда от них требуется решить новую задачу без тренировки вообще, полагаясь только на "способность ума к обобщению и переносу опыта на новые ситуации."
А чем ООП-то виновато?
Что такое ООП? Каждый может ответить по-своему.
Назову некоторые черты ООП: децентрализация, косвенность и обобщение.
Децентрализация означает, что решения принимаются именно там, где требуется и где для этого есть вся достаточная информация, а не в Кремле или Госкомстате. Очень близко, IMHO, той децентрализации, что делает эффективной либеральную экономику (по крайней мере, в некоторых аспектах).
Косвенность означает отделение запроса от его исполнения. Клиент не заботится о деталях исполнения своего запроса. Поэтому возможны и late binding, и late linking. Поэтому возможно повторное использование клиентского кода, возможны фреймворки и т.д. IMHO, уже просто возможность повторного использования кода в ООП говорит о том, что здесь задействованы определенные механизмы обобщения.
№ 2853 14-04-2007 03:14 | |
Ответ на »сообщение 2797« (Руслан Богатырев)
___________________________
Ответ на »сообщение 2793« (Max Belugin)
Если в языке Оберон использовать модули с контролем импорта на чтение, то многие вопросы снимутся сами собой. Для этого нужно ввести понятие read-only import (точнее, импорт с ограничениями) и его контроль на уровне верификатора (который гарантирует, что импортированные сущности не превышают свои полномочия).
Я не очень понимаю, чем оберону поможет r/o импорт, если любая импортируемая процедурная переменная (пусть даже сама по себе и r/o) может сделать все что угодно с "состоянием" какого угодно модуля. Например, квалификатор const в C++ гарантирует лишь то, что пользователь такого объекта никак не может его модифицировать, но сам константный объект может меняться как угодно (в том числе и кем-то третьим, для которго он не const).
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|