Функциональное программирование: семь раз отмерь, один раз отрежь -1


Добрый день! Последнее время я очень часто слышу о том, что пришел закат ООП. Сегодня все больше людей переходят на функциональную парадигму. Скоро людей, которые пишут на C++/C#/Java, вообще не останется. Так ли это? Не думаю. На мой взгляд, бездумное использование ФП (функциональное программирование) может стать затратной по времени и лишней головной болью, которая совершенно не сочетается с текущими проектными решениями. Давайте убедимся в этом!

image

Я хочу заметить: речь пойдет не о лямбда выражениях в Java/Python, а о более продвинутом ФП, типа Haskell или Scala с cats/scalaz.

Итак, я утверждаю, что:

  1. ФП далеко не везде применимо.
  2. Приносит головную боль при интеграции с готовыми решениями.
  3. Тратить время на ФП не всегда разумно.

Разберем эти пункты более подробно и оценим масштаб трагедии.

1. ФП далеко не везде применимо


Это кажется удивительным, но далеко не все это понимают. Более того, такие языки, как С, очень далеки от своего заката. Гораздо дальше, чем Haskell или Scala. Взгляните на любой игровой движок. С вероятностью 90%, большая его часть написана на С. Взгляните в прошивку любого бытового устройства в своей квартире. Скорее всего, это снова С! Операционные системы? Конечно, С.

Почему же так происходит? Дело в том, что все вышеперечисленное работает напрямую с железом. Железо не знает никаких функций высшего порядка. Железо — это набор регистров (что уже является изменяемым состоянием), прерываний (опять же, которые изменяют состояние) и команд, которые переносят нули и единицы из одной ячейки в другую.

Конечно, можно воспользоваться абстракцией и забыть про все эти железные штуки. Но во-первых, это не всегда разумно. Если наша программа достаточно простая, то нет смысла закрываться какими-то слоями абстракции. Во-вторых, часто в таких программах скорость работы ставится на одну из ключевых позиций. Поэтому дополнительные затраты на “объяснение” железу ФП полностью погубит пользу вашей разработки. ФП здесь проявить себя не может.

2. Приносит головную боль при интеграции с готовыми решениями

В каждом уважающем себя языке программирования есть большое количество готовых решений. В С# — это, например, Entity Framework и .Net. В Java — это Hibernate и Spring. И почти каждый фреймворк нацелен на работу в привычном нам ООП стиле. Почти всегда эти решения имеют изменяемые состояния и совершенно не пригодны для работы с чистым ФП.

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

  1. Почти всегда такие решения приводят к boilerplate коду.
  2. Мы теряем огромный пласт функционала. Конечно, мы можем взять готовую библиотеку для работы в функциональной парадигме. Но почти всегда такое решение гораздо менее популярно, а значит не может предложить и половины всех возможностей популярных решений.
  3. Готовые продукты, которые используют такое решение, надо будет почти полностью рефакторить.
  4. Мы теряем хорошо протестированное и отлично детерминированное решение. Вместо этого мы идем в сторону неизвестности. Есть ли в популярных решениях проблемы? Конечно! Но о них, как правило, уже все давно известно. В нашем новом подходе такого точно не будет.

На самом деле список можно продолжать еще долго. На мой взгляд, совокупность потерь делает ФП, как минимум, не везде и не всегда пригодным.

3. Тратить время на ФП не всегда разумно

Что удивляет не менее, часто программисты не видят, что стоит за кодом. Не всегда язык программирования и парадигма определяет качество продукта. На бэке все идет к контейнеризации. Уже почти не важно на чем вы пишете: Python, Java, Scala. Код на любом из этих языков можно обернуть в образ и поставлять контейнером.

В таком мире не столь важно, что внутри контейнера, если оно отвечает всем поставленным требованиям. Здесь более важно, как организована система целиком. Возникает вопрос: вы действительно уверены, что ваше время стоит вкладывать в изучение ФП с его теорией категорий? Возможно стоит вложиться в развитие общей архитектуры системы. К тому же, найти людей без знания ФП, которые готовы предоставить вам такие контейнеры, гораздо легче.

Представьте себе такую ситуацию. Вы сидите ночами и изучаете всю теорию. Вы смотрите ролики на YouTube, читаете книги, вникаете в математические выкладки. Со временем вы уже можете построить небольшое приложение, но еще не все понятно. Вы начинаете практиковаться дальше: берете более продвинутые книги, ходите на митапы, ведете с коллегами разговоры о высоком. Но вот появился реальный проект. С вашими знаниями вы попадаете на лидирующую роль в этом проекте. Жизнь удалась! И вот вы написали просто идеальный сервис. Остается всего одна проблема. Что с ним делать дальше? Как настроить процесс автоматизации? Как настроить “умную” балансировку? Как другим сервисом найти ваш? На эти вопросы ответа у вас может просто не быть! Вы еще уверены, что ФП вам так необходимо?

Выводы


На самом деле, я отношусь к ФП крайне положительно. Все, что я хочу сказать: это инструмент, который подходит далеко не всегда и везде. На мой взгляд, инженер не должен мыслить категориями нравится/не нравится. Вместо этого должны быть максимально объективные причины для использования того или иного решения.

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

Спасибо за внимание!




К сожалению, не доступен сервер mySQL