Книга «Grokking Simplicity» — отличное введение в функциональное программирование

Закончил чтение книги Grokking Simplicity: Taming complex software with functional thinking. Очень советую ее прочитать всем. Это одна из тех книг, которые относятся к категории концептуальных книг.

Книга очень подробно излагает на примерах концепции и идеи функционального программирования. Мне понравилось то, что в книге концепции эти подаются очень взвешенно, постепенно и подробно объясняются с помощью иллюстраций, схем и кода.

Для примеров используется код, написанный на JavaScript. Автор выбрал именно этот язык потому что а) его практически все программисты знают, а те, кто не знает, легко его поймут б) в нем отсутствуют многие инструменты функционального программирования, которые присутствуют в других языках уже изначально. Поэтому из главы в главу постепенно вместе с автором мы создает инструменты-элементы функциональных программ, которые в других языках мы получаем «из коробки». Автор считает что, так мы лучше понимаем, как эти элементарные инструменты работают изнутри.

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

Actions, Computations, Data

Мне очень понравилась идея автора, что весь код в программах делится на действия (actions), вычисления (computations) и данные (data).

Вычисления — это по сути чистые функции (pure functions). Их выполнение не вносит никаких побочных изменений (side effects), а при выполнении в любое время с одними и теми же исходными аргументами мы всегда получаем один и тот же результат.

Действия — это функции с побочными эффектами. Когда мы вызываем функцию sendEmail, происходит отправка почтового сообщения. Вызываем функцию — saveUser, происходит запись в базу данных.

Невозможно написать программу, которая не будет производить вообще никаких изменений (ну разве что чисто вычислительная задача). Чем крупнее задача, тем сложнее ее код. Тем труднее его читать и понимать что в данный момент произойдет, если данный конкретный участок кода будет выполнен.

Мы как серьезные программисты должны постоянно стремиться к уменьшению сложности программной системы, и упрощения чтения кода. Конкретно же задача состоит в том, чтобы как можно больше разделить вычисления и действия, как можно больше вычленить из действий вычисления. Чем больше в вашем коде будет чистых функций, тем легче вам (и другим программистам) будет судить о коде, так как как при исполнении кода чистых функций совершенно понятно, что вычисляется только результат, и ничего больше не изменяется: не вносятся никакие изменения в аргументы, не меняются глобальные переменные, не вызываются никакие сторонние процедуры.

Stratified Design

В следующих главах книги автор представляет идею слоистого дизайна (stratified design). Вкратце, идея заключается в том, чтобы разделить код на слои. Разделить слой более общих абстракций (манипуляции с корзиной, товарами, ценами) от конкретных технических деталей — слоя, где все эти манипуляции переводятся в работу со структурами данных: массивами, хэш-таблицами, циклами и т.д.

Copy-on-write

Разделяя код на actions и computations мы в конце концов достигнем предела. У нас все равно останутся в программе процедуры, которые являются действиями (actions). И их может быть достаточно много, как не выделяй из них вычисления (computations). Так вот в следующих главах автор приводит приёмы, с помощью которых действия (actions) можно превратить в вычисления (computations).

Посудите сами, если наше действие не меняет переданных ему исходных данных (массив, список, хэш-таблицу, объект) , то оно по сути является вычислением (computation). Так нас автор подводит к идеям «copy-on-write» и «defensive copying». С их помощью все наши структуры данных становятся неизменяемыми (immutable data structures). Мы просто делаем копию с этих данных и возвращаем из процедуры копию с изменениями, а исходная структура остается неизменной. Здесь же автор нам подробно расскажет о том, чем shallow copying отличается от deep copying.

Инструменты функционального программирования

Все вышеизложенные идеи применимы и в обычном программировании, скажем — структурном или объектно-ориентированном. Но цель автора была подготовить нас к функциональному программированию. Поэтому в следующих главах он подробно излагает инструменты функционального программирования, которые позволяют нам писать код в функциональном стиле, при этом оставаясь в рамках чистых функций, вычислений, computations и неизменяемых data.

Представлены основные инструменты функционального программирования: map(), filter(), reduce(). Связывание (chaining) всех эти инструментов в цепочки. И множество других концепций из этого вытекающих, например, event sourcing.

Итоги

К освоению функционального программирования ведет множество путей. Мне понравился путь этой книги. Все изложенные идеи и концепции прекрасно ложатся на современную Java. Становится понятным, что новые функциональные классы и интерфейсы, добавленные в в Java 8, появились не просто так, а отражают общий подход (хотя конечно и не полный), принятый в других функциональных языках программирования — Scheme, Haskell, Clojure.

Честно говоря после прочтения этой книги стало понятно, что же именно хотели сказать в своей книге Structure and Interpretation of Computer Programs достопочтенные Абельсон и Сассманн. Например, именно там представлена идея слоистого дизайна (stratified design), но она так глубоко закопана, что ее легко пропустить.

Короче, очень рекомендую эту книгу. На меня она произвела хорошее впечатление. У автора Эрика Норманда (Eric Normand) книги есть свой YouTube канал, где он продолжает излагать свои идеи. Как фанат языка Clojure он написал еще одну книгу: The Ultimate Guide to Clojure Concurrency, которая продается только в Kindle версии.

Летом 2022 года должна выйти книга Grokking Functional Programming, которая наверное изложит те же самые концепции другим способом. Вообще, вся серия Grokking … весьма оригинальна, хотя некоторые книги серии вызывают нарекания.

Пишите в комментариях свое мнение об этой книге.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s