Comments 8
Добро пожаловать, вы изобрели errgroup
Гоферы изобрели callback-hell ))
Принесли какой то хаскель в го и испортили и то и другое. Зачем?
Простите, но это не CPS. В CPS после вызова продолжения нет возврата в вызывавшую функцию, а у вас это везде. Т.е. tail call в продолжение - это не опциональная вещь, а обязательная. И defer тоже противоречит CPS.
CPS - это прежде всего способ либо промежуточного представления кода для оптимизации (доказано, что он эквивалентен SSA представлению), либо способ развертки синхронного кода в асинхронный (поищите CPC - Continuation Passing C).
Ещё, например, Chicken Scheme реализован через CPS: код Scheme транспиллится в C функции оригинального вида - функции всегда оканчиваются tail call в continuation и никогда не зовут return. Стэк растёт «бесконечно». А вернее, он параллельно используется как eden generation в GC, т.е. для аллокации объектов. И когда размер стэка доходит до предела, live объекты с него копируются в кучу, а стэк обрезается под корень (через longjmp). Не устаю восхищаться этим трюком.
Кстати, в Go тоже можно было бы реализовать через panic+recover. А в кучу Go и сам скопирует что нужно.
Код станет нечитаемым, и поэтому не надёжным :-)
Читаемый код "плосский",
а не как у вас: Функция в функции в цикле функции функции функции
(последний пример кода) -
даже линтер такое не пропустит - 6 уровней вложенности в одной функции
Поддержу. Один мой коллега любит так делать: размажет простую задачу по десяти вызовам и сиди потом, гадай, что там происходит. Понимать это очень тяжело, поддерживать невозможно, поэтому впоследствии такой код просто переписывается в нормальном виде.
Это не размазывание, это называется чистый код. При правильном нейминге гадать ничего не надо потому что метод делает то что написано в его названии. Если обратно собрать из десяти методов одну портянку на 200..300 а то и 500 строк, то это как минимум нарушает Single Responsibility.
Вы ретроспективу проводите, анализируете причины снижения читаемости? Или ревью проходит под лозунгом "мне не нравится, значит код неправильный". Можете привести пример когда структурированный код читается плохо, а полотно на 3 экрана читается хорошо?
Применения Continuation-passing style в Go