-
Notifications
You must be signed in to change notification settings - Fork 449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Raise accumulating/zip DSL #3436
Conversation
Kover Report
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love it! Amazing. I am trying to think of a better name than nel
. accumulate
might be an option, like Iterable.mapOrAccumlate
and it fits with the SAM.
I've tried a few new names. I've also realized that every "runner" ( |
I am willing to sink time into the IntelliJ plugin to provide a project wide refactor if you can help me get running. I am willing to do that for every breaking change we make between the last patch and 2.0.0! So please review all APIs again in whatever way you think makes sense. If you see a good opportunity to split things of to smaller modules, that are like extremely tiny and make sense like EDIT: couldn't sleep, wrote some silly code. Closed it, will do it properly after resting 😅 |
After thinking about this a bit more, the delegation is what forces to first split into a declaration, right? To prevent: Person(
accumulating { ensureNotNull(name) { "Null name" } },
accumulating { ensure(age => 18) { "Not an adult" } },
) That is not possible with proper accumulation, right? So, the following test case. @Test fun raiseAccumulatingTwoFailures() {
accumulate {
val x by accumulating { raise("hello") ; 1 }
val y by accumulating { raise("bye") ; 2 }
val xy = x + y
val z by accumulating { raise("BOOM"); 3 }
xy + z
} shouldBe nonEmptyListOf("hello", "bye").left()
} |
About accumulation, yes, the delegated property trick is what makes it "wait" until the moment the value is actually needed for the next step, while accumulating the rest. In the last commit I've merged |
arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt
Show resolved
Hide resolved
public abstract val result: A | ||
public operator fun getValue(value: Nothing?, property: KProperty<*>): A = result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do all these need to be public
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getValue
has to be public for by
to work. I added value
just to allow using the Value
on its own (some people don't like delegation), but it can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would initially hide whatever is possible, we can always make it public afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
This looks very nice! I played around on my own trying to get something like this to work, but I couldn't get anything I was happy with. It's great that we're finally going to be avoid multi-lambda syntax and the n-arity duplications. |
3999fb9
to
f7d1784
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me! Thank you for these DSL initiatives Ale 🙏
This PR introduces a mini-DSLs for "zip" operations in
Raise
. The idea is to extendzipOrAccumulate
to any amount of arguments, and make the code a bit more linear, by using the power of property delegation.These are two tests that showcase the functionality: you use
accumulating
to mark those parts which should "add" to the errors, instead of merely using fail-first, and using delegation you don't need to remember anything else. If you use araise
outside anaccumulating
, all the errors accumulated until that moment are added to the other one.