CLOVIS
11/24/2023, 4:04 PMearly {}
DSL with a Raise<Unit>
, so you can use ensure
etc for early-returns without any error message?Youssef Shoaib [MOD]
11/24/2023, 4:18 PMRaise<Unit>
and hence don't require an ugly empty block?CLOVIS
11/24/2023, 5:08 PMnullable
, but for "purely impure functions" (those that do only side effects)Youssef Shoaib [MOD]
11/24/2023, 5:09 PMYoussef Shoaib [MOD]
11/24/2023, 5:10 PMCLOVIS
11/24/2023, 5:12 PMfun MutableSet<AccessRight>.addRightsForUser(user: User) = early {
ensure(…)
ensure(…)
add(AccessRight(…, user))
}
I don't know if it's useful enough to warrant its own builder, but it's kinda ugly to have to go back to if (!condition) …
in these cases
Name candidates:
• early
(it uses Raise as an early return)
• do
(it's just a block of code, and run
is already taken)
• unit
(it returns Unit
)CLOVIS
11/24/2023, 5:13 PMI think that's what nullable does for the same reasons,I remember the same
CLOVIS
11/24/2023, 5:14 PMNullableRaise
under the hood? Raise<Nothing?>
and Raise<Unit>
are isomorphic, they're both raising a singleton, so all utilities are probably the sameCLOVIS
11/24/2023, 5:14 PMensure
, the ignoreErrors
helper, etcYoussef Shoaib [MOD]
11/24/2023, 5:14 PMbreakable
CLOVIS
11/24/2023, 5:16 PMbreak
keyword. Maybe raisable
? But that might be confused as "the primary way to use Raise
, since it shares the name", whereas it's really a narrow use-caseCLOVIS
11/24/2023, 5:16 PMimpure {}
?Youssef Shoaib [MOD]
11/24/2023, 5:16 PMNullableRaise
would change much. The only reason we need it is so that we can define those utils without needing context receivers, but other than that NullableRaise
doesn't have any custom behaviourYoussef Shoaib [MOD]
11/24/2023, 5:18 PMimpure {}
is interesting because this builder will be returning Unit anyways, so this makes it clear that we're only performing side effects that can also fail and end the computation earlyCLOVIS
11/24/2023, 5:19 PMinline fun unit(block: NullableRaise.() -> Unit): Unit =
fold({ block(this) }, recover = { Unit }, transform = { Unit })
Youssef Shoaib [MOD]
11/24/2023, 5:20 PMUnitRaise
, the implementation is then:
inline fun unit(block: UnitRaise.() -> Unit) = merge(block)
CLOVIS
11/24/2023, 5:20 PMNullableRaise
doesn't have any custom behaviour
It already has lambda-less ensure, ignoreErrors etc, and these would be useful for the same reasonsYoussef Shoaib [MOD]
11/24/2023, 5:21 PMNullableRaise
as an implementation detail won't give us anything reallyCLOVIS
11/24/2023, 5:21 PMUnitRaise
, you have to duplicate them, right?Youssef Shoaib [MOD]
11/24/2023, 5:23 PMraise(Unit)
and 2) not give any special behaviour to nullsYoussef Shoaib [MOD]
11/24/2023, 5:23 PMNullableRaise
Youssef Shoaib [MOD]
11/24/2023, 5:24 PMOptionRaise
exists as well, even though it could be implemented in terms of NullableRaise
, but that's because we want the available utils to be slightly differentCLOVIS
11/24/2023, 5:25 PMraise(null)
is weird here.CLOVIS
11/24/2023, 5:26 PM@clovis-ai
on GitHub)Youssef Shoaib [MOD]
11/24/2023, 5:32 PMNullableRaise
and OptionRaise
in their types. I think in a context receivers world we'd just have nullable, impure, and option all giving us a context(Raise<Null>, Raise<None>, Raise<Unit>)
and we'd have the same utilities thus for each one, with the only difference being the ultimate return type at the end.
I'll make a PR for impure, and we can continue the discussion thereCLOVIS
11/24/2023, 5:35 PMYoussef Shoaib [MOD]
11/30/2023, 2:58 AM