Как стать автором
Обновить

Преимущества функционального программирования на примерах C#

Время на прочтение7 мин
Количество просмотров7.6K
Всего голосов 13: ↑6 и ↓7+2
Комментарии9

Комментарии 9

На столько быстро пролистал, что не увидел рекламы новой книги?

За такую реализацию ParallelSum автора конечно нужно бить палкой по пяткам…

Рассмотрим пример на C#, демонстрирующий преимущества функционального программирования для качества кода:

Вижу обычный, стандартный шарповый код.

А есть какой-то пример, который являлся бы, по-вашему, не функциональным, но выполнял бы все те же самые действия? Лишенный, так сказать, "всех преимуществ".

Преимущества функционального программирования в связке с конкатенативным и некоторым применением DSL на примере Factor языка.
A panoramic tour of Factor


Вы можете задаться вопросом, почему вы должны так интересоваться Factor, чтобы прочитать это руководство?
Factor имеет несколько существенных преимуществ перед другими языками, большинство из которых связано с тем, что он практически не имеет синтаксиса:

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

P.S. Внушительное количество решённых задач на Factor с площадки rosettacode.org


По рейтингу популярности на rosettacode он на 24-ом месте

Не очень понятно где тут функциональное программирование

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

Высокомодульный и многократно используемый фрагмент кода ?

// Сцепляем имена с использованием функционального подхода
string functionalConcatenatedNames = string.Join(" ", names);

Есть метод, реализованный программистами MS. В программе вызван этот метода. Не понимаю: в чём тут скрыт "функциональный подход"? Пожалуйста, поясните.

Не надо говорить о преимуществах функционального программирования на примере C#: C# для этого плохо подходит. Потому что C# на уровне языка не позволяет гарантировать, что "чистые функции" (на самом деле — делегаты) действительно не имеют побочных эффектов. Так что в C# вполне можно сделать несколько последовательных композиций "функций"(то есть, делегатов) в совершенно разных местах кода, взяв где-нибудь в одном месте делегат с побочным эффектом — и ни компилятор вас не предупредит, ни проверить это без анализа всего этого кода невозможно. Что-то подобное я видел в реальности — в коде, вызывающем метод Configure Startup-класса в части инициализации веб-приложения, сделанного по шаблону Generic Host. Там была композиция (т.е. цепочка вложенных вызовов — иначе в C# композицию не реализуешь) из нескольких делегатов, а самый глубоко вложенный делегат имел побочный эффект — запись извлеченного значения в кэш. Но так как кэш на практике уже записан более ранним вызвовом, а инициализация — процесс однопоточный, то этот побочный эффект ни к чему плохому не приводит. Однако, по факту, это называется "повезло" — а ведь может и не повезти.
Потому к элементам функционального программирования конкретно для C# лучше всего подходит слово "функциональщина": пользоваться можно, но — без гарантий, которые может дать настоящий функциональный язык.

Кажется, автор не до конца понимает смысл функционального программирования :\
ФП - это про иммутабельность и предсказуемое поведение методов, которые при одинаковых параметрах будут возвращать одинаковые результаты, а не внезапные исключения. А в данной статье всё описывается так, будто для ФП достаточно каждую операцию в отдельный метод, чтобы потом "переиспользовать этот модуль"

В пункте "Сглаживание побочных эффектов" можно заменить

int y = AddFive(x);

на

int y = x + 5;

при этом "функциональность" кода (а именно метода Main()) не потеряется. А пока всё это выглядит как утка в зайце: давайте вынесем +5 в метод, чтобы стало функционально.

Пункт про параллелизм я вообще не понял. В угоду распараллеливания автор жертвует иммутабельностью и переписывает значение одного и того же объекта.

Ну и в пункте Модульность и возможность повторного использования автор говорит о том, что цикл - не круто, а вот Enumerable.Aggregate - топ, хотя на функциональность метода Product() это никак не влияет..

Зарегистрируйтесь на Хабре, чтобы оставить комментарий