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

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

  1. А почему, собственно, непроверяемые исключения не должны заворачиваться в контейнер?

  2. Зачем вообще контейнер, можно же просто пробросить отловленное исключение через, полагаю, всем давно известный хак с автовыведением и стиранием типов.

public static <E extends Throwable> void sneakyThrow(Throwable e) throws E {
    throw (E) e;
}

  1. Можно потерять или замаскировать NullPointerException, IllegalArgumentException и множество других багов. Но окончательное решение за Вами, я обрисовал лишь общую схему.

  2. При пробросе исключения при помощи sneakyThrow обработка потока завершится на первом "плохом" URL. А мы хотим обработать все URL-ы. Так то так.

  1. В смысле потерять? Оно же будет в Result-е лежать.

  2. Так и в Вашем варианте при первом RuntimeException-е обработка стрима завершится.

  1. Да, будет лежать в Result. Но нет гарантий что на исключение посмотрят/извлекут. В этом смысле я говорил про потерю исключения.

  2. Некоторая разница имеется - в Вашем варианте обработка стрима завершится на первом "плохом" URL, у меня при первом NullPointerException или другом не-проверяемом исключении.

Хотя я с Вами соглашусь, что перехватывать не-проверяемые исключения иногда необходимо.

Скептически я отношусь к этим выкрутасам с функциональщине. Лучше "бойлерплейт" код, который понятен, что он делает и в чем смысл кода, чем глухонемой код, который непонятно что делает.

map-flatmap-toList

map-flatmap-toList

map-flatmap-toList

Одно и то-же. Код везде делает совершенно разные вещи. Но выглядит одинаково. Чтобы разобраться, что же он делает, нужно буквально в голове декомпилировать эту трахомудию и восстанавливать, что же именно изначально задумывал программист.

>Одно и то-же.
Так он и делает одно и то же. С вашей точки зрения это разные вещи, а с точки зрения типов — одинаковые. И нет, не надо в голове все прокручивать — достаточно понять, что внутри у map — и эта функция проще, чем все в целом (в том числе и тем, что ее можно автономно протестировать, понять, отладить). И если у вас такое повторяется в коде — то такие повторяющиеся куски можно легко зарефакторить в один метод, в отличие от того кода, который вам очевидно нравится, но который содержит побочные эффекты. И который как раз надо понять весь целиком, потому что его нельзя декомпозировать так, как map-flatMap.

Лучше "бойлерплейт" код, который понятен

С этим сложно спорить, но при чем здесь ФП? Если вам непонятен нормальный ФП код, то возможно дело не в коде, а в том, что вы не поняли этот подход / не хотите понимать, так как он другой?

Давайте не будем переходить на личности. Все мне понятно и в ФП, и в реакте. И я, разобравшись, прекрасно вижу, где плюсы и где минусы. Мифические "плюсы" - "краткость" кода, неблокируемая работа. Минусы - для понимания реактивного кода, насыщенного лямбдами, требуется реально больше времени, чем простой, очевидный, классический код (который презрительно называют "бойлерплейтом").

Реактивный код двуслойный: сверху бесконечные map-flatmap-toList, внутри него "зашит" собственно бизнес-код, ваша задумка по требованиям. Причем этот код приходится "раздирать" и "утрамбовывать" в рамки методов map-flatmap-toList.

Семантика map-flatmap-toList реально отлично работает, и эту концепцию стоит применять только для одного вида обработки - взять массив сложных элементов, преобразовать (или извлечь инфу) его в другой вид, вычислив что-то поэлементно, расширить или сжать этот массив, упаковать в нужный контейнер или вычислить групповую операцию. Все! Все остальные применения, как в данном посте - суть ненужные извращения, расчесывание ЧСВ (я сам был молодым и знаю, что это такое) и томление духа.

а потом этот boilerplate с сотней строк и множественным дублированием прилетает кому то на поддержку. Язык развивается и то что было модно-молодёжно во времена вашей молодости уже имеет новую реализацию

Не очень понятен смысл подобных статей в 2022 году, когда в мире существует больше одной готовой реализации Try. Которые можно просто открыть в гитхабе да посмотреть на реальный боевой код, проверенный сотнями пользователей за много лет. Было бы гораздо полезнее именно что взять реальный код того же vavr.io, и рассмотреть — тем более что он не такой уж и большой. При этом вполне можно и предложить какие-то улучшения, если у автора есть мысли, как это сделать.

В своей статье автор хотел

  • неявно выразить свою мечту о том что-бы простейшие функциональные примитивы (Try, Either и м.б. др.) были в составе стандартной библиотеки Java

  • явно указать на простой и ясный способ обработки исключений без использования внешних зависимостей, таких как vavr и других.

Ну, это вполне логично, как мотивация. Я немножко не про это.

Правда не очень понимаю, зачем вам это в стандартной библиотеке? Вот спринг, к примеру, не там — и вас это сильно напрягает каждый день? Или допустим, JDBC драйвер для базы данных Oracle 19 — его там тоже нет, ну так и что? Добавили в pom.xml, или что там у вас, одну зависимость — и оно уже в стандартной библиотеке (я намеренно упрощаю, но в реальности все обычно не сильно сложнее).

Если что, это была не столько критика, сколько предложение на тему, как бы я написал такой текст. То есть, взять небольшой кусок vavr, и на его примере рассмотреть, как это практически сделано, почему так, и как можно было бы иначе. Против самой идеи у меня вообще никаких возражений нет, у меня весь проект нынче так построен (и это уже второй такой).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории