169 похожих чатов

Привет! Есть вопросик к коммьюнити: Кто-нибудь хотел бы иметь в котлине что-то

вроде scala-вских for-comprehensions?
Если да, то поголосуйте за тикет про это, пожалуйста.

(знаю, что в чатике есть мощные функциональщики, но сейчас интересует исключительно прагматическая сторона и применение в проде, без упоминая слова монады вообще c: )

Просто известно, что скалисты пользуются ими и в хвост, и гриву, в моем окружении тоже много кто хочет такое, но официально к тикету про это никакого интереса проявлено не было.

P.S. Для тех, кто не слышал про такое, супер-краткий обзор: функциональное программирование на котлине это круто, но часто оказывается, что читать вложенные преобразования данных функциями вида map и flatMap довольно тяжело, а ля callback hell.

Ну, совсем тупой пример еще даже на Java:

results.stream().flatMap(
res -> f(res).flatMap(
res1 -> res1.flatMap(
res2 -> res2.map( /* and so on */ ))));

И вот говоря очень кратко, for-comprehensions это простой синтаксический сахар для такого. Он применим для любых сущностей у которых есть методы вида map, flatMap и filter, например, Optional, List, Future, Flowable, Observable, Spring Stream's Flux и т.д, т.е. у дофигищи повседневных вещей.

И вот если в котлине будут for-comprehensions, то код вида

fun login(oldAuth: AuthToken): SomeContainer<UserModel>> {
credentialService.oauthLogin(oldAuth).flatMap { token ->
securityService.getRole(token).flatMap { role ->
credentialService.getUserDetails(token, role).map { userDetails ->
(token, role, userDetails)
}
}
}
.filter { (token, role, userDetails) -> areValidModelParams(token, role, userDetails) }
.flatMap { (token, role, userDetails) -> computeUserModel(token, role, userDetails) }
...

будет примерно выглядеть как

fun login(oldAuth: AuthToken): SomeContainer<UserModel> =
for {
token <- credentialService.oauthLogin(oldAuth)
role <- securityService.getRole(token)
userDetails <- credentialService.getUserDetails(token, role)
if areValidModelParams(token, role, userDetails)
userModel <- computeUserModel(token, role, userDetails)
}
yield userModel

10 ответов

15 просмотров

По-моему это ужасно. Вообще не понятно, что оно делает. Не говоря о том, что пример плохой, если у вас там там что-то типа Optional, то в котлин оно вообще не нужно из-за нулябельности.

Ну для nullable типов, Result, а также Option, Either и Eval из Arrow есть собственно блоки в самом Arrow: https://github.com/arrow-kt/arrow/tree/main/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/computations (Формально для nullable есть и просто ?. но да, такие блоки помощнее) Для листов иногда хочется в задачах для условного Advent of Code (кстати начался, да), в реальных задачах как-то не сложилось с нуждой лично у меня 🤷‍♀️ Всякие промисоподобные вещи не особо казалось удобным (но тут можно поспорить, да), у реактивщины вроде нету никакого одного flatMap, чтобы так делать Короче какие-то обходные пути и сейчас есть (раньше в Arrow и для листов вроде был, так что наверное и это можно вернуть). Может что-то для упрощения работы с тем же Result/Either было бы приятно иметь из коробки, но непонятно как лучше, как в условном хаскеле/скале или как-то иначе

Посмотрите, как сделано в Arrow: https://arrow-kt.io/docs/0.10/patterns/monad_comprehensions/. Вот пример кода val university: IO<University> = IO.fx { val (student) = getStudentFromDatabase("Bob Roxx") val (university) = getUniversityFromDatabase(student.universityId) val (dean) = getDeanFromDatabase(university.deanId) dean } честно говоря, не вижу причины, зачем ду-нотацию тащить в язык, если её можно реализовать на уровне библиотеки с помощью корутин.

Alexander-Bashkirov Автор вопроса
Ilmir
Посмотрите, как сделано в Arrow: https://arrow-kt....

Кстати, а насколько оно эффективно в байт-коде? Там от рантайма корутин ничего не остаётся, или оно наоборот на него завязано?

Alexander Bashkirov
Кстати, а насколько оно эффективно в байт-коде? Та...

Оно не зависит от kotlinx.coroutines. Единственное, что от корутин требуется - это продолжения. А они оптимизированы донельзя. Плюс на всю цепочку аллоцируется только одно продолжение, а не по лямбде на каждый шаг, если делать через дешугаринг.

Alexander-Bashkirov Автор вопроса
Ilmir
Оно не зависит от kotlinx.coroutines. Единственное...

Любопытно, спасибо! Вот, ещё один козырь в крышку гроба ду-нотации а котлине.

Ilmir
Оно не зависит от kotlinx.coroutines. Единственное...

А разве там не было истории о том, что эрроу использует корутины не так, как вы предполагали, потому вы не можете обещать, что вы их не сломаете? :)

Andrew Mikhaylov
А разве там не было истории о том, что эрроу испол...

Намерено ломать эрроу мы не планируем. И сейчас если ломать корутины, то это будет несовместимое изменение. А на это нужны ооочень веские причины. Так что, вероятность, что мы сломаем эрроу - минимальная.

Кажется надо проголосовать, чтобы это не приняли 😂

Похожие вопросы

Обсуждают сегодня

читать файл максимально быстро? странный вопрос))
zamtmn
53
тоесть, указав return eax, сгенерируется никому ненужная инструкция mov eax,eax ?
Aiwan \ (•◡•) / _bot
24
Приветствуем всех! Устали без проектов? Если вы программист и хотите получать стабильные заказы, компания Elif предлагает вам недельный курс по поиску проектов и их ведению. ...
Elif
1
А чего сейчас в моде вместо Error для эксепшенов? А то я тут внезапно узрел что он не рекомендуется :) У Try::Tiny какой-то совершенно ужасный синтаксис если надо конкретные э...
Denis F
19
а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
63
Привет. Сразу скажу, что на C/C++/Rust я не пишу, но тем не менее возникла потребность дебага C/C++/Rust кода. Суть: есть серверное приложение, которое периодически ведёт себ...
ninekeem 🐳
4
всем привет! углубившись в плюсы и начав изучать реверсинг понял, что без асм'а никуда со своими высокоабстрактными представлениями начал изучать механизмы асма, и не совсем п...
9
Всем привет, после Си стоит учить плюсы или лучше на раст перейти?
Linus
8
или вы считаете муит дает знание?
супер_лох_3000 альфа версия
12
значить например он учился в СДУ то получается он особенный?)
Asets Serikov
11
Карта сайта