https://kotlinlang.org logo
Title
k

kioba

10/14/2020, 5:17 PM
I am playing with
DelimitedScope
to implement
option {}
continuation and I realised that
DelimContScope
can not manage
null
as a
shift
return value. the implementation already using nullable to show that the block is done. I replaced the nullable type with a quick GADT to represent empty state and allow nullable value:
private val nextShift = atomic<Shift<(suspend () -> R)>>(Empty)
is there any better way to avoid constant boxing for the return values of shifts?
j

Jannis

10/14/2020, 5:30 PM
Yes, you could use a custom object and use any. Same principle as null just fixed to an internal. Still doesn't allow nesting but allows null
☝️ 1
👍 2
I used null simply as convenience cause at the time of writing most of that package was experimental^^ also feel free to ask me if anything in there is unclear 😅
r

raulraja

10/14/2020, 6:56 PM
@kioba there will be an option continuation as well so this one should be named nullable for consistency
👍 1
All computation expressions are now named after the data type decapitalized
k

kioba

10/14/2020, 10:18 PM
sorry @Jannis didn’t mean to criticise, the implementation is super great 🎉 I have only a limited understanding of the DelimitedScope and don’t want to make any changes which could impact the performance on a bad way. @raulraja thanks, I will rename it 👍 naming makes sense especially to have both of them 🙂
j

Jannis

10/14/2020, 10:44 PM
@kioba no worries and please do criticise^^ What I meant was more along the lines of "everything is pretty hacky and not all that well tested so any improvement or found bug is great!" anyway 🙈 Either way, the atomic containing the result needs to allow nullables to work properly in a generic setting. Best is probably a singleton object for which we check with reference equality since we don't need to be concerned with nesting here.
k

kioba

10/15/2020, 12:03 AM
you mean a separate atomic variable l to keep track of the end of the block?
create a draft PR to be able to show the current implementation. https://github.com/arrow-kt/arrow-core/pull/251 Added a few questions regarding the code arrangement but happy to take any feedback regarding these changes if you have time 🙂 👌
👏 1
s

simon.vergauwen

10/15/2020, 7:24 AM
@kioba this is the trick @Jannis is referring to. It's comming in a lot of Kotlin generic code when not using
Option
to optimise over allocations in hot-spot areas like this. It sadly requires
Any?
and thus also casting in some places.
private object MY_NULL

class Generic<T>(val value: T) {

    val atomicValue: Any? = value

    fun isMyNull(): Boolean =
        atomicValue === MY_NULL
}
😲 1
☝️ 2
k

kioba

10/15/2020, 7:50 AM
this is definitely a neat trick! Reminds me the old days for C++ boolean bitwise 😅. thanks guys for teaching this 👨‍🎓 I will go and apply the changes today 👍
🙌 1
s

simon.vergauwen

10/15/2020, 7:51 AM
No problem, it's a bit dirty but a good way to optimise low-level code to support generic
?
🙂
j

Jannis

10/15/2020, 8:49 AM
It has the same nesting problems as nullables but since it uses a different reference it doesn't lead to nested null cases^^ Sadly we can't do this in general for option because of those drawbacks
👍 2