Автор начитался eo и придумал следующий бред

Иммутабельные обьекты это хорошо, но иногда очень хочется иметь мутабельный обьект. Например, в паттерне Builder, чтобы делать что-то подобное:

new StringBuilder()
    .add("a")
    .add("b")
    .add("c")
или что-нибудь более осмысленное:
new Graph()
    .vertices(10)
    .edges(edgesList)
    .directed(false)
а так же в принципе Fluent interface, используемый не только для паттерна Builder:
ids
    .map(getUserByID)
    .map(User.getName)
    .mapConcat(User.getFriends)
    .filter(me.isFriend)
С мутабельными обьектами все просто. Сделаем пример на основе StringBuilder с одним методом add, для других случаев все аналогично:
class StringBuilder {
    val text = "";
    constructor() {}
    StringBuilder add(String value) {
        text += value;
        return this;
    }
}
Как сделать это мутабельным? На самом деле мы можем вынести изменение состояния билдера в отдельную чистую функцию, которая будет эндоморфизмом StringBuilder -> StringBuilder:
class StringBuilder {
    val text;
    constructor(text) {
        this.text = text;
    }
    String getText() {
        return this.text;
    }
    }
    StringBuilder addTo(StringBuilder sb, String value) {
        return StringBuilder(sb.getText() + value);
    }
}
Теперь StringBuilder стал иммутабельным. Однако решив одну проблему мы получили три: - StringBuilder стал эквивалентен классу String, а значит не нужен - потеряли Fluent interface - теперь используется чистая функция, которая не очень хорошо вписывается в ООП Зато мы получили изменение состояния с помощью наращивания списка эндоморфизмов и можем гордиться, что функциональное программирование хоть где-то пригодилось. Но мы тут занимаемся ООП, а не ФП, поэтому вспоминаем( https://vk.com/wall-187839235_972 ), что эндоморфизм есть декоратор, поэтому делаем декоратор для добавления строки в StringBuilder (см. диаграмму 1). Думаю реализация метода getText в обоих случаях очевидна. Класс StringBuilderAdded является тем самым декоратором. Теперь построение осуществляется как-то так:
new StringBuilderAdded(
    new StringBuilderAdded(
        new StringBuilderAdded(
            new StringBuilderSimple(""), "a"
        ), "b"
    ), "c"
);
Что выглядит как рекурсия, которую не очень удобно писать и напрашивается do-нотация (если уж не reduce с списком конструкторов декораторов), но мы отгоняем от себя мысли все сделать функциональным и вспоминаем, что мы решили две проблемы из трех. Остался Fluent interface. Очевидно, что самое место ему в StringBuilder, чтобы им можно было пользоваться, как было описано в начале поста, поэтому следующая реализация будет такой, как на диаграмме 2. Реализация отличается тем, что вместо рекурсивной вложенности, как выше, теперь построение StringBuilderAdded помещается в реализации add. Теперь все идеально: мы получили иммутабельные обьекты с Fluent interface-ом и полностью в ООП-е. Что еще можно сказать, так это то, что кажется, что такая реализация неэффективна: создается много обьектов и при вызове getText будет длинная рекурсия. С этим, кажется, что несложно справиться, сделав более эффективную реализацию декоратора, который использует какой-нибудь Visitor с более быстрым соединением строк и без рекурсии или возвращать не String, а поток символов и соединять потоки символов. В общем, проблема решается без ломания полученной парадигмы.

P.S. Кстати похожая штука с эндоморфизмами используется в библиотеке Redux, которая получила название от известного катаморфизма reduce, суть которого в том, что

reduce(init = StringBuilder(), list = [addEndomorphisms])
дает изменение состояния StringBuilder до нужного. Только в Redux вместо StringBuilder-а меняется глобальное состояние приложения и эндоморфизмы называются reducer-ами.

P.P.S. Если поехало форматирование, я не виноват.