Обновить
99
0.1
Роман Смирнов @Source

Head of Elixir at Ecom.tech

Отправить сообщение

Я возможно Вас слегка расстрою, но утиная типизация — это часть парадигмы обобщённого программирования, к ОО-парадигме она никаким боком не относится :-)
Метапрограммирование — это тоже не ООП, строго говоря. Вообще рекомендую ознакомиться со списком парадигм программирования, там много интересной информации.


Что касается ООП, попробуйте хотя бы для себя, абстрагируясь от привычек, ответить на вопрос: при каких условиях неудобно применять ООП?

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

Мне кажется, проблема статьи в том, что большинство читателей ещё не познакомились с Elm. Лучше про сам язык расскажите и в чём преимущество его использования по сравнению с другими технологиями типа AngularJS, ReactJS и т.д..

Нет, это будет называться ФП на ОО-языке. Нужно, если у Вас задача идеально подходящая для ФП, а язык проекта позволяет только ООП.

Само по себе ООП — не решение. Важно то, как оно реализовано в конкретном языке.

Насколько я помню, есть всего 3 реализации ООП — на основе классов, на основе прототипов и на основе акторов.
C# ранних версий — это шикарный пример реализации ООП на основе классов, а вот начиная с 3-й версии туда начали добавлять ФП и прочие не ООП-концепции.
Из различий реализаций ООП на основе классов, Вы упомянули только множественное наследование, которое по холиварности не уступает goto, поэтому в большинстве реализаций отсутствует )))


сколько абстракций он держит в той же Джанге, и, наверное, в этих ваших рельсах…

А задумайтесь сколько из этих абстракций реально нужны, чтобы обработать запрос? именно из-за усложнения простых вещей "за долю секунды происходит столько всего, что в голове не удержишь". Вы догадываетесь сколько объектов создаётся для обработки тривиального GET /page/permalink? Хотя по сути Вам нужен 1 объект класса Page и то он сам Вам нафиг не нужен, Вам нужны данные из БД, но как же, без ORM никуда..

@Cryvage пишет о том, что можно ОО-язык использовать в функциональном стиле. Т.е. данные о состоянии объекта передавать только конструктору и объявлять на них только геттеры, чтобы даже у методов объекта не было возможности повлиять на его состояние. Тогда получится своеобразное замыкание как в ФП.
Но чтобы так писать на ОО-языке всё равно надо уже расширить своё мышление функциональной парадигмой :-)

Вы во многом правы, но не считаете ли Вы, что функциональные примеси в ООП демонстрируют слабость ОО-парадигмы? По сути даже создатели языков программирования, признают чистое ООП недостаточно удобным. Остался ли хоть один современный ЯП, в котором есть только чистое ООП и ничего больше? Так чтоб никаких лямбд (только Strategy), никаких foreach (только Iterator) и т.д.

Но он далек от серебрянной пули и уж точно не замена ООП

Что Вы как ребёнок всё в серебряные пули верите…
ФП — это парадигма программирования и она предоставляет свои инструменты для решения задач. ООП — другая парадигма, в идеале их области применения могли бы не пересекаться, но на практике одну и ту же задачу можно решать в рамках и той и другой парадигмы.
Мы тут обсуждаем конкретно веб-разработку, а не всё подряд. Если вспомнить как ООП попало в веб-разработку, то очевидно, что это было мотивированно больше всего модой на ООП, т.к. весь практический смысл этой парадигмы теряется для программ, которые отрабатывают за долю секунды.

А чего его представлять то, на самом деле полно мультипарадигмальных языков.
Особо отличился Oz — он одновременно поддерживает 7 парадигм программирования :-)
И Вы правы, разные парадигмы не должны мешаться друг с другом, но их можно использовать в разных частях программы.

Ну что ж, возможно в Django мире с многопоточностью чуть получше, чем в Rails мире, где Puma ещё только набирает популярность.


Удачи с ФП :-)

Django поддерживает многопоточность.

Rails сам по себе тоже поддерживает многопоточность, ещё с 2008 года. А толку то? Вопрос в том какой процент людей пишет сторонние библиотеки и свои приложения в расчёте на многопоточность.


Так что это не преимущество ФП, а недостаток конкретного ОО языка.

Могу с Вами поспорить на эту тему… проблема именно в ООП, а языки подстраиваются, тупо встраивая некоторые паттерны непосредственно в синтаксис. Классический пример — паттерн Iterator от GoF, сейчас уже сложно найти язык в котором не ввели его поддержку на уровне синтаксиса. Что касается, Python, то он, как и Ruby, не является строгим ОО-языком, а поддерживает множество парадигм. Поэтому Вы можете решать на нём задачи в том числе и в функциональном стиле (возможно даже не подозревая об этом). Чисто ОО-подход — это применение паттернов: GoF, PoEAA, Applying UML and Patterns и т.д.


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

это в Lisp-подобном языке то? там в принципе нет разделения на код и данные by design :-)


Но одно поверхностное знакомство с Erlang ошарашило меня таким количеством фич, что сложно ожидать простоты.

Erlang простой, но весьма непривычный язык. Elixir выглядит привычнее, поэтому и осваивать легче.


Может просто взять любимый Python и нелюбимый JS, и программировать на них в функциональном стиле? :)

Почему бы и нет, они это позволяют )))


С примерами не всё так просто… Чтобы ОО-пример был нечитабелен, он должен быть достаточно большой по размеру. Т.е. по-хорошему в качестве примера нужен какой-то OpenSource проект или хотя бы ощутимый кусочек проекта, который переписали с ООП на ФП. К тому же чтобы код на функциональном языке стал для Вас читабельным, надо всё-таки привыкнуть в определённым нотациям.
А то с непривычки даже тривиальный вызов стратегии


(&Strategy.add/2) |> Context.execute(3, 4)

может сложночитаемым оказаться по сравнению с привычным


Context context = new Context();
context.setStrategy(new ConcreteStrategyAdd());
context.executeStrategy(3, 4);

Картинка, кстати, не моя, она как раз из презентации Functional Programming Patterns

Фанатизм везде плох. Делать из ФП культ — так же плохо, как делать культ из ООП или из Rails :-)


О какой потокобезопасности может идти речь в классе Message, предназначенном исключительно для однопоточной работы с объектами с коротким жизненным циклом.

При разработке на Rails по факту всё подгоняется под однопоточную работу.
Хочешь параллельно обрабатывать запросы — запусти N инстансов однопоточного unicorn, хочешь фоновые задачи — запусти ещё 1 инстанс для sidekiq и т.д. Не знаю, как обстоят дела в Django, но что-то мне подсказывает, что аналогично.


А Вы имеете опыт работы с ООП?

Конечно, 10 лет… А разве сейчас бывают программисты без опыта работы с ООП?
Преимущество ФП ещё в том, что оно проще. В ООП частенько за деревьями не видно леса. Потому что кругом паттерны, замудрённые абстракции и т.д., а что по факту делает код понять сложно. В ФП программу рассматривают как своеобразный конвеер по преобразованию данных, где каждый этап конвеера — это просто функция.
FP pattens
Это очень непривычно после ООП, но когда начинаешь въезжать в идею, понимаешь, что большая часть ОО-паттернов — это костыли, подпирающие изначально непродуманную парадигму.
Чем меньше концепций заложено в код, тем он проще, а значит и надёжнее. Это не значит, что ООП теперь нельзя использовать, просто если Вы можете представить задачу, решаемую вашим кодом, в качестве конвеера по преобразованию данных, то в функциональном стиле ваш код будет гораздо легче и понятнее.

Вы же предлагаете всю предметную область положить в AR

Я в этом треде вообще ничего не предлагаю. Я просто констатирую определение этого паттерна и прямые следствия из него.
А то, что Вы по факту не используете паттерн Active Record — это даже хорошо. Путаница возникает из-за того, что Вы думаете, что Вы успешно и повсеместно применяете данный паттерн, хотя по факту отходите от него безумно далеко, и при этом пытаетесь других убедить, что 2+2=5.

И это не усложнение, это — напротив — упрощение

Это упрощение кода, но усложнение понятий. Паттерны хороши тем, что дают названия вместо длинных определений. Вместо того чтобы говорить "Каждый класс соответствует одной таблице в БД. Строка таблицы соответствует объекту класса. Логика работы с БД помещена в модель предметной области.", мы говорим одно название — ActiveRecord. И всем понятно, о чём это и чем это плохо в нетривиальных случаях. Когда Вы вводите свою интерпретацию понятия ActiveRecord вместо общепринятого определения, и пытаетесь строить свои выводы на ней, это выглядит очень странно.

Я не вижу тут диррективы: «все должно быть так и только так»

Такой директивы нет ни у одного паттерна. Но если что-то не совсем так, то это уже не этот паттерн. Всё просто, в AR нет никаких Service, по сути AR — это и есть fat models. Всё остально — это не AR. Не усложняйте.

Мне кажется, Вы излишне усложняете… Основная претензия к ООП, касаемо состояний, состоит в том, что состояние спрятано внутри объектов. Соответственно, каждый класс должен сам обеспечивать потокобезопасность. Иначе привет race condition. В ФП потокобезопасность заложена by design, включая защиту от случайных мутаций. Проще говоря, чтобы написать на ОО-языке надёжную программу, которая будет работать в многопоточном режиме, Вам придётся писать в функциональном стиле, просто это будет неудобно. Если Вам самому ещё не приходилось так делать, то понять преимущества ФП сложнее.
Ну а чистые функции — это хорошо, их должно быть большинство, но никому не нужна программа из одних чистых функций, которая не сможет записать результат вычислений ни в БД, ни в файл, ни вывести на экран.

AR — это когда логика сохранения данных помещена в модель предметной области, в ту самую в которой бизнес логика. Тупо по определению:
"An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data."
"Active Record uses the most obvious approach, putting data access logic in the domain object"

Хм, странный эпиграф к статье… Как-будто автор не понял, что юзер реддита имел в виду нашумевшую историю с автором ReiserFS


А по сути статьи — круто! Восхищаюсь вашим упорством и целеустремлённостью.

Это, конечно же, предохраняет от случайных мутаций. Но не там, где они являются дизайном.

Где это случайные мутации являются дизайном?

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


Отправка сообщения актору — это, к сожалению, тоже сайд-эффект

Вы уже в шаге от определения сайд-эффекта через нагрев процессора… А если серьёзно, то отправка сообщения актору — это то же самое, что вызов метода объекта в ООП. Да и, в принципе, Erlang/Elixir реализуют ООП согласно определению Алана Кея.

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

Ну вообще-то это следует напрямую из определения паттерна. Просто у Вас своё оригинальное видение ActiveRecord… поэтому мы тут тёплое с мягким сравниваем.

Информация

В рейтинге
4 056-й
Откуда
Россия
Зарегистрирован
Активность