Подтвердить что ты не робот

Существует ли методология программирования для функционального программирования?

Программная инженерия, как ее преподают сегодня, полностью ориентирована на объектно-ориентированное программирование и "естественный" объектно-ориентированный взгляд на мир. Существует подробная методология, которая описывает, как преобразовать модель домена в модель класса с несколькими шагами и множеством (UML) артефактов, таких как диаграммы-примеры или диаграммы классов. Многие программисты усвоили этот подход и имеют хорошее представление о том, как проектировать объектно-ориентированное приложение с нуля.

Новый обман - это функциональное программирование, которое преподается во многих книгах и учебниках. Но как насчет функциональной разработки программного обеспечения? Читая о Lisp и Clojure, я получил два интересных утверждения:

  • Функциональные программы часто развиваются снизу вверх, а не сверху вниз ('On Lisp', Paul Graham)

  • Функциональные программисты используют Карты, где OO-Programmers используют объекты/классы ('Clojure для Java-программистов', говорят Rich Hickley).

Итак, какова методология для систематического (на основе модели?) дизайна функционального приложения, то есть в Lisp или Clojure? Каковы общие шаги, какие артефакты я использую, как мне отобразить их из проблемного пространства в пространство решений?

4b9b3361

Ответ 1

Слава Богу, что разработчики программного обеспечения еще не открыли функциональное программирование. Вот несколько параллелей:

  • Многие шаблоны проектирования OO фиксируются как функции более высокого порядка. Например, шаблон посетителя известен в функциональном мире как "складка" (или, если вы - заостренный теоретик, "катаморфизм" ). В функциональных языках типы данных являются в основном деревьями или кортежами, и каждый тип дерева имеет связанный с ним естественный катаморфизм.

    Эти функции более высокого порядка часто приходят с определенными законами программирования, иначе называемыми "свободными теоремами".

  • Функциональные программисты используют диаграммы гораздо реже, чем программисты OO. Большая часть того, что выражается в диаграммах ОО, вместо этого выражается в типах или в "подписях", которые вы должны рассматривать как "типы модулей". Haskell также имеет "классы типов", который немного похож на тип интерфейса.

    Те функциональные программисты, которые используют типы, обычно считают, что "как только вы получите правильные типы, код практически сам пишет".

    Не все функциональные языки используют явные типы, но Как разработать программы, отличная книга для изучения схемы / Lisp/Clojure, в значительной степени опирается на "описания данных", которые тесно связаны с типами.

Итак, какова методология для систематического (на основе модели?) дизайна функционального приложения, то есть в Lisp или Clojure?

Любой метод проектирования, основанный на абстракции данных, хорошо работает. Мне кажется, что это проще, когда язык имеет явные типы, но он работает даже без него. Хорошей книгой о методах проектирования абстрактных типов данных, которая легко адаптируется к функциональному программированию, является абстракция и спецификация в разработке программ Барбарой Лисков и Джон Гуттаг, первое издание. Лисков частично выиграл награду Тьюринга за эту работу.

Еще одна методология проектирования, которая уникальна для Lisp, заключается в том, чтобы решить, какие языковые расширения будут полезны в проблемной области, в которой вы работаете, а затем используйте гигиенические макросы, чтобы добавить эти конструкции на свой язык. Хорошим местом для чтения такого дизайна является статья Мэтью Флатта Создание языков в Racket. Статья может быть за платной. Вы также можете найти более общий материал по этому виду дизайна, выполнив поиск термина "встроенный язык, специфичный для домена"; для конкретных советов и примеров, кроме того, что охватывает Мэтью Флатт, я, вероятно, начну с Graham В Lisp или, возможно, ANSI Common Lisp.

Каковы общие шаги, какие артефакты я использую?

Общие шаги:

  • Определите данные в вашей программе и выполняемые на ней операции и определите абстрактный тип данных, представляющий эти данные.

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

  • Если вы используете типизированный функциональный язык, используйте проверку типов раньше и часто. Если вы используете Lisp или Clojure, наилучшей практикой является сначала написать контракты функций, включая модульные тесты, - это тестовая разработка с максимальным. И вы захотите использовать любую версию QuickCheck, перенесенную на вашу платформу, которая в вашем случае выглядит как ClojureCheck. Это чрезвычайно мощная библиотека для построения случайных тестов кода, использующих функции более высокого порядка.

Ответ 2

Для Clojure я рекомендую вернуться к хорошему старому реляционному моделированию. Из Tarpit является вдохновляющим чтением.

Ответ 3

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

Мой опыт связан с переходом с Java на Clojure в последние годы.

Некоторые примеры:

  • Понимание вашей бизнес-области/модели данных - не менее важно, планируете ли вы проектировать объектную модель или создать функциональную структуру данных с вложенными картами. В некотором смысле, FP может быть проще, потому что он побуждает вас думать о модели данных отдельно от функций/процессов, но вам все равно придется делать то и другое.

  • Ориентация на обслуживание в дизайне - действительно очень хорошо работает с точки зрения FP, поскольку типичная услуга - это действительно функция с некоторыми побочными эффектами. Я думаю, что "снизу вверх" вид разработки программного обеспечения, иногда поддерживаемый в мире Lisp, на самом деле является просто хорошим сервис-ориентированным дизайном API в другом обличье.

  • Test Driven Development - хорошо работает на языках FP, на самом деле иногда даже лучше, потому что чистые функции очень хорошо дают четкие, повторяемые тесты без необходимости создания среды с сохранением состояния, Вы также можете захотеть создать отдельные тесты для проверки целостности данных (например, на этой карте есть все ключи, которые я ожидаю, чтобы сбалансировать тот факт, что на языке OO определение класса обеспечило бы это для вас во время компиляции).

  • Прототипирование/итерация - работает точно так же с FP. Возможно, вы даже сможете прототипировать вживую с пользователями, если вы очень хорошо разбираетесь в создании инструментов /DSL и используете их в REPL.

Ответ 4

Программирование OO тесно связывает данные с поведением. Функциональное программирование разделяет два. Таким образом, у вас нет диаграмм классов, но у вас есть структуры данных, и вы, в частности, имеете алгебраические типы данных. Эти типы могут быть написаны очень точно в соответствии с вашим доменом, включая устранение невозможных значений по построению.

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

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

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

Теперь у вас есть домен, над которым у вас есть функции, которые составлены в соответствии с хорошо выполненными законами. Простой встроенный DSL!

О, и заданные свойства, вы можете, конечно, написать автоматизированные рандомизированные тесты (ala QuickCheck).. и это только начало.

Ответ 5

Объектно-ориентированный дизайн - это не то же самое, что разработка программного обеспечения. Разработка программного обеспечения связана со всем процессом, как мы переходим от требований к рабочей системе, вовремя и с низкой степенью дефекта. Функциональное программирование может отличаться от OO, но оно не отменяет требований, высокоуровневых и подробных проектов, проверки и тестирования, метрик программного обеспечения, оценки и всего этого другого "программного обеспечения".

Кроме того, функциональные программы демонстрируют модульность и другую структуру. Ваши подробные проекты должны быть выражены в терминах концепций в этой структуре.

Ответ 6

Смотрите мой ответ на другой пост:

Как Clojure aproach Разделение проблем?

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

Ответ 7

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

Ответ 8

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

Здесь несколько ссылок:

http://www.northeastern.edu/magazine/0301/programming.html

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.86.8371

Ответ 9

Честно говоря, если вы хотите рецепты дизайна для функциональных программ, посмотрите на стандартные библиотеки функций, такие как Haskell Prelude. В FP шаблоны обычно захватываются процедурами более высокого порядка (функции, которые работают с функциями) сами. Таким образом, если картина видна, часто функция более высокого порядка просто создается для захвата этого шаблона.

Хорошим примером является fmap. Эта функция принимает функцию в качестве аргумента и применяет ее ко всем "элементам" второго аргумента. Поскольку он является частью класса типа Functor, любой экземпляр Functor (например, список, граф и т.д.) Может быть передан в качестве второго аргумента этой функции. Он фиксирует общее поведение применения функции для каждого элемента ее второго аргумента.

Ответ 10

В "Оксфордском университете" (Великобритания) существует стиль "расчета программы" / "дизайн путем вычисления", связанный с профессором Ричардом Бердом и группой разработчиков алгебры программирования, я не думаю, что это слишком надуманно, чтобы рассмотреть это методология.

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

Ответ 11

Я обнаружил, что Behavior Driven Development является естественным подспорьем для быстрого развития кода как в Clojure, так и в SBCL. Реальный потенциал использования BDD с функциональным языком состоит в том, что я склонен писать много более тонких тестов на зерно, чем я обычно делаю при использовании процедурных языков, потому что я делаю гораздо лучшую работу по разложению проблемы на более мелкие куски функциональности.

Ответ 12

Недавно я нашел эту книгу: Функциональное и реактивное моделирование доменов

Я думаю, что полностью соответствует вашему вопросу.

Из описания книги:

Функциональное и реактивное моделирование домена учит вас думать о модели домена с точки зрения чистых функций и о том, как создавать их для создания больших абстракций. Вы начнете с основ функционального программирования и постепенно перейдете к передовым концепциям и шаблонам, которые вам нужно знать для реализации сложных моделей доменов. Книга демонстрирует, как продвинутые шаблоны FP, такие как алгебраические типы данных, дизайн на основе стекол и выделение побочных эффектов, могут сделать вашу модель более удобной и удобочитаемой.

Ответ 13

Ну,

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

Они становятся все более популярными сейчас, так как ООП испытывает трудности с "парализованным программированием" из-за "состояния". И иногда функциональный стиль лучше подходит для решения проблемы, например, Google MapReduce.

Я уверен, что, когда functioanl ребята попадут в стену [попытайтесь внедрить системы размером более 1.000.000 строк кода], некоторые из них придут с новыми методологиями разработки программного обеспечения со словами buzz:-). Они должны ответить на старый вопрос: как разделить систему на куски, чтобы мы могли "кусать" каждую фигуру по одному за раз? [Итеративный, инкрементальный эволюционный путь] с использованием функционального стиля.

Уверен, что функциональный стиль повлияет на наш объектно-ориентированный Style.We "все еще" многие концепции из функциональных систем и адаптированы к наши языки ООП.

Но будут ли функциональные программы использоваться для таких больших систем? Станут ли они основным потоком? Это вопрос.

И никто не может прийти с реалистичной методологией, не внедряя такие большие системы, делая его - свои руки грязными. Сначала вы должны сделать свои руки грязными, а затем предложить решение. Решения-предложения без "настоящих болей и грязи" будут "фантазией".