Представьте, что вы задремали в кулуарах railsclub, но вдруг мимо вас пробежал Николай Рыжиков во второй зал.
Он представился художественным руководителем команды Health-Samurai, которая уже лет 8 занимаеться Health IT. Он шептал какие-то странные слова - ФП, персистентные структуры данных. И вы не подумав про последствия побежали за ним и ... провалились в кроличью нору (хотя Ярослав вас предупреждал:).
Толи нора была слишком глубокой, толи ... Николай слишком долго говорил. Но на 40 минут вы попали в страну Функционального программирования.
Вокруг все было похожим на привычную обстановку, но все было каким-то странным.
Во прервых все было сделанно из функций и данных. Да-да все было на оборот - мы стемимся связать поведение и данные в аккуратненькие объекты, а у них проводилась четкая грань между ними. Функции чем-то напоминали наши методы, лябмды и блоки, но тоже были странными. И почему-то по близости практически не было никаких объектов и классов.
Почему-то вокруг все говорили не "передать аргументы в функцию", а применить функцию к значениям (так там называли данные).
Толи потому-что функции за собой ухаживали, но они считали себя "чистыми" и вели они себя
необычно. Напимер, функция inc`` применялась к единичке и возвращала двойку, но единичка тоже никуда не исчезала. У нас тоже есть операторы над примитивными типами, они ведут себя так же. Но здесь, даже такие с виду знакомые функции как
pushэлемента в массив ничего не делали с оригинальным массивом и элементом, а возвращали новый массив содержащий элемент (как будто делали копию). Также вела себя функция добавления нового ключа в
hash``.
Здесь вообще нельзя было поменять что-нибудь в данных, при любой попытке мы получали каждый раз новую измененную копию, но и старые данные тоже оставались на своих местах. Возможно поэтому функции называли чистыми, а данные значениями.
Мы попробовали несколько раз применить функцию к тем же саммым значениям, но результат был всегда одним и тем же (даже не интересно). Вне зависимости от того, что происходило вокруг, эти "чистые" функции постоянно, как автоматы, возвращали тоже самое. Хоть не вызывай их второй раз с теми же аргументами, а просто замени предыдущим результатом. За такое поведение они считали себя ссылочно-прозрачными - те во всех местах и в любое время можно было заменить вызов функции с одинаковыми параметрами, тем что они возвращают - и ничего бы не поменялось.
Эти фунции подозрительно легко склеивались, достаточно было выход одной функции соединить с входом другой (если подходили разъемы) и мы получали новую функцию, которая опять оказывалась чистой.
Вообще все программы строились как дерево соединенных подобным образом функций (у нас это обычно граф объектов). Стоило передать в такое дерево входные данные, они начинали передаваться вверх достигая листиков, а потом листики начинали схлопываться в данные. И когда все листики на веточке схлопывались, веточка превращалась в листик и тоже начинала схлопываться. И в итоге от дерева оставалось только значение. Они называли это evaluation. Причем оказывалось не очень важно в каком порядке схлопываются веточки - поскольку в результате все равно получалось тоже самое значение.
У них была своя абстактократия, некоторые функции могли принимать на вход другие функции или производить новые функции - их называли функциями высших порядков.
....
Например, была функция Fold (или reduce) при помощи, которой можно было выполнить практически любые операции с коллекциями - получить сумму, произведение, смапить, отфильтровать. Похожие функции были для работы с деревьями, они уже принимали по-несколько других функций. Ну у нас есть нечто похожее, иногда называют потоками.
Были еще забавные функции, которые могли оборачивать другие функции - те они принимали функцию - возвращая новую функцию. Это чем-то напоминало наш паттерн декоратор. Из подобных функций можно было собрать новую, нанизывая их друг на друга и добавляя новую функциональность, а потом применять ее к значениям.
Например у нас на глазах, для последовательного применения различных операций к коллекциям, вместо того чтобы приминять каждую операцию оббегая коллекцию каждый раз - они вначале собрали из таких декорирующих функций новую, содержащую все нужные операции, и лишь потом применили ее к коллекции за один проход. Им даже не понадобились ленивые коллекции, чтобы сделать это. Некоторые называли эти странные декорируемые функции для работы с коллекциями - трансдюссерами.
Еще кстати там были изменяемые данные и всякие вводы-выводы, но их считали дикими и опасными и поэтому изолировали от общества чистых функций и данных-значений. Они сидели в клетках, которые называли SТМ или IO монады, трогать их можно было только в тразакции изолированной от остального мира, ну или вообще нельзя было.
Когда несколько функций начинали работать одновременно, они вообще друг другу не мешали, поскольку у каждой были свои копии игрушек. А если им нужен был доступ к зверям - то под чутким контролем STM почему-то не удавалось устроить им гонку, или не консистентное чтение или дедлок. Так что было даже не интересно, никакого риска и адреналина.
Мы как веб-программисты, конечно же отправились туда где из этих функций делают веб-приложения.
Веб сервер Роутинг Вью Генерация SQL Сервисы и контроллеры Весь стэк