Привет! Конференция ФПКонф в эту субботу нас уже 160 человек и еще не поздно прыгнуть в последний вагон.
Постановка на учет - здесь .
И вот накануне мы решили задать нашим спикерам один довольно неоднозначный вопрос.
Публикуем ответы, ваши варианты в комментариях приветствуются!
В объектно-ориентированных языках существует хорошо известный список шаблонов проектирования «Банды четырех».
В функциональных языках такого известного списка не существует. С вашей точки зрения, почему это так? Неужели такие паттерны не нужны при программировании на функциональных языках или просто их канонический список еще не сформирован? Антон Холомьев, Haskell Для Haskell такой список есть, но он называется по-другому и существуют другие шаблоны, в стиле ФП.
Здесь Сергей Лобин, Scala На мой взгляд, паттерны — это принципы ФП, которые можно использовать как кубики для сборки красивых программ :) Сергей Тихон, F# По вопросу о шаблонах языка программирования я согласен с Питером Норвигом, который сказал: «Шаблоны проектирования — это отчеты об ошибках в вашем языке программирования».
Большинство задач, которые решались классическими паттернами из «Банды четырех», уже в той или иной форме решены в функциональных языках.
«Функциональные паттерны\абстракции» есть и будут появляться (например, Монады) как набор общих подходов к управлению сложностью разрабатываемых приложений.
Возможно, со временем появится один общий список, который мы все признаем каноническим, но это будет вызвано заметным увеличением сложности задач, которые позволят решить функциональные языки.
Александр Гранин, Haskell Вопрос очень коррелирует с темой моего доклада.
И я несколько раз поднимал этот вопрос на наших встречах в LambdaNsk. Шаблоны проектирования в ООП — это искусственные конструкции, которые решают ту или иную техническую проблему, которую невозможно решить естественным путем — с помощью синтаксиса языка, идиом высокого уровня или концепций.
Значительная часть паттернов (если не все) оперируют понятиями ООП «наследование», «полиморфизм» и «абстракция», при этом ни эти понятия, ни какая-либо другая специфическая синтаксическая структура языка ООП не решают проблему напрямую.
При этом в функциональных языках эти паттерны либо вырождаются (Visitor), либо просто становятся ненужными (Command) — из-за того, что в самом ФП есть понятия, способные напрямую решить задачу: FVP, лямбды, сопоставление с образцом , первоклассные функции, неизменяемость, композиция, ленивость и многое другое.
Например, Visitor легко заменяется сопоставлением с образцом и PDF, а Command просто заменяется первоклассными функциями.
В ООП шаблоны — это сложные конструкции, не присущие самому языку ООП.
То есть для решения задачи недостаточно языка ООП и его элементов: нужно из этих элементов составить тот или иной механизм.
И многие подобные механизмы в конечном итоге обобщаются в шаблоны ООП.
Напротив, для решения задачи в ФП достаточно только языковых конструкций, а зачастую достаточно просто создать тип функции.
Если тип есть, реализация функции будет простой.
В то же время в ФП есть свои «паттерны», хотя я предпочитаю называть их «идиомами».
Вы о них слышали: различные монады, комонады, функторы, стрелки, аппликативные функторы, комбинаторы, преобразователи.
Кроме того, у ФП есть такие модели, как FRP, STM, линзы.
В чем, на мой взгляд, разница между паттернами ООП и идиомами ФП? Паттерн ООП — это решение проблемы «извне» с использованием императивного подхода.
Шаблон ООП обращается к сущностям и их изменяемым взаимодействиям.
Шаблон ООП описывает, «как» работает система.
Существуют шаблоны ООП, которые нужны только для реализации функциональной идиомы, отсутствующей в языке (Посетитель — сопоставление с образцом и FVP).
Идиома FP — это решение проблемы «изнутри» с использованием функционально-декларативного подхода.
Идиома FP касается свойств и их неизменяемого преобразования; Идиома FP описывает, «что» представляет собой сущность, какими неразделимыми свойствами она обладает. О каких свойствах мы говорим? Например, если у вас есть функциональный список, то он изначально, даже без вашего ведома, является монадой.
А если у вас есть игра «Жизнь», то ее клеточное поле — это уже комонада.
Из этого, кстати, следует, что программист ФП не просто конструирует решение задачи, он ищет скрытые характеристики и свойства в предметной области и на основе этих знаний решает задачу, используя ту или иную идиому ФП.
.
Такой код, построенный на свойствах и преобразованиях, будет идиоматическим функциональным кодом.
А вот тема проектирования больших приложений на функциональных языках, конечно, пока малоизучена — из-за малой распространенности этих самых языков.
Соответственно, литературы мало.
В своем докладе я собираюсь затронуть этот важный вопрос.
Ссылки по теме * Заменяет ли FP шаблоны GOF? * Шаблоны проектирования в Haskell * Шаблоны проектирования в FP * Идиоматический функциональный код (презентация из моего выступления на LambdaNsk) * Идиомы в Haskell и FP: 1 И 2 Денис Редозубов, Haskell +1 к предыдущему ответу.
Николай Рыжиков, Clojure Не все шаблоны GOF одинаковы.
Некоторые из них слишком низкого уровня — например, Iterator. У FP есть свой (более выразительный) арсенал для таких задач: карта, уменьшение/сложение, ходок.
А также ряд чисто функциональных низкоуровневых шаблонов: монады, зипперы, преобразователи.
Однако значительная часть шаблонов представляет собой конструкции высокого уровня, полезные и понятные опытным программистам, позволяющие структурировать и описывать программу в целом.
И они вполне могут использоваться в ФП, иногда с немного отличной от оригинала реализацией.
Например, Chain of Responsibility можно выразить через HOF как украшение функций (для доступности мы используем js:):
Поэтому я думаю, что нам следует просто перевыпустить шаблоны проектирования для FP. Возможно, именно вы напишете эту книгу :) Никита Прокопов, Clojure Есть закономерности и здесь, и там.function handler1(next_handler) { return function(args){ if (exp){ // some logic next_handler(args); //pipe to next handler } else { return some_responce; //intercept } } } var stack = handler1(handler2(handler3)) // build chain (stack) stack(args); // process chain
Язык ООП говорит вам: вот объекты, делайте что хотите.
Свобода, но не конструктивная.
Паттерн – это «если спроектировать предмет по этому шаблону, его можно будет использовать для таких-то целей».
Спецификация.
Поэтому я бы не стал приписывать языкам ФП какие-то особые свойства, отменяющие шаблоны.
Шаблон — это просто классификатор часто встречающихся «форм кода».
Специфические шаблоны ООП из GoF не нужны, поскольку объектов нет. Но шаблоны ФП необходимы.
Как-то ведь код ФП прописан, и он не типа уникален для каждого человека.
Ну общеизвестного списка нет, потому что его еще никто не составил.
Неофициально оно существует, оно просто передается неявно.
Плюс скорее всего для разных языков он будет сильно отличаться, как минимум для типизированного ФП и для нетипизированного.
Я бы предположил, что для типизированных необходимость в шаблонах выше, потому что.
им нужны рецепты, как «обернуть» типы, чтобы обойти ту или иную проблему.
Такие рецепты очень быстро становятся нетривиальными, и дойти до них собственным умом становится все сложнее.
Так что с образовательной точки зрения «типизированные шаблоны ФП» пользуются большим спросом.
Михаил Лиманский, Scala Функционалистам не нужны шаблоны, потому что мы творческие люди, а не ремесленники.
А если серьезно, то в ООП шаблоны порождаются сложностью самой объектной модели.
Все, что у вас есть, — это инкапсуляция, наследование и полиморфизм, но в языке нет смысла, как их использовать.
Те.
знания языка и принципов ООП недостаточно, чтобы не выстрелить себе в ногу и не превратить код в сумасшедшую кашу.
Именно для этого и нужны шаблоны (ну, а когда шаблоны не помогают, на помощь приходят трактаты по рефакторингу).
В ФП мы, наоборот, идем от поведения — от классов типов, которые уже являются частью языка.
Оказывается, это своего рода способ программирования в Unix: небольшой класс типов решает одну небольшую проблему и делает это хорошо.
Арсений Жижелев, Scala «Банда четырех» «застолбила» список шаблонов, существовавших на тот момент и казавшихся универсальными и широко применимыми.
Со временем появлялись новые паттерны, а в старых обнаруживались недостатки (например, внедрение зависимостей заменило фабрику).
Как уже говорилось выше, в функциональных языках тоже есть наборы хороших практик, но ни один из наборов пока не стал общеизвестным и популярным.
Это открывает возможность включения в такой список новых подходов и библиотек, их реализующих.
Об одном из интересных способов использования функциональных языков пойдет речь в моем докладе о библиотеке SynapseGrid, реализующей подход функционального реактивного программирования в Scala. УПД.
Утром мы получили ответ от Эdward и решили его опубликовать.
отдельный пост Новости от других участников и спикеров конференции — в комментариях.
Увидимся в ФПКонф! Теги: #Функциональное программирование #шаблоны проектирования #ООП #fp #scala #erlang #clojure #scala #Функциональное программирование
-
Итак, Менеджер По Продукту Или Проекту?
19 Oct, 24 -
Топ-10 Докладов Dotnext 2021 Москва
19 Oct, 24 -
10 Принципов Разработки На Java
19 Oct, 24 -
Чип 555. Практика
19 Oct, 24 -
Веб-Api Google Больше Не Поддерживается.
19 Oct, 24