it’s very javascripty in that you have to go back ...
# coroutines
p
it’s very javascripty in that you have to go back and forth with reference comparison and unchecked casts to make it work, with performance as a big tradeoff compared with a sealed class or a nested Option
l
I don't think there's any big performance tradeoffs there at all, quite the contrary in fact.
p
reference check vs instaceof virtual dispatch. Maybe @[removed] knows something that we don’t 😄
l
There's no
instanceof
nor
is
check here. Reference equality and unchecked casts are used, and these are way cheaper than any complicated
Option
type you can come up with and nesting it.
p
there’s any big performance tradeoffs there at all
I thought you meant compared to sealed classes, which depending on implementation may be a direct call into one of the branches instead of doing the ifcheck
Copy code
sealed class Tristate<A> {
  fun <B> fold(fu: () -> B, fn: () -> B, fa: (A) -> B)

  object Uninitialized: Tristate<Nothing> {
     override fun <B> fold(fu: () -> B, fn: () -> B, fa: (A) -> B) = fu()
  }

  object Nullish: Tristate<Nothing> {
     override fun <B> fold(fu: () -> B, fn: () -> B, fa: (A) -> B) = fn()
  }

  data class Option<A>(val a: A): Tristate<A> {
     override fun <B> fold(fu: () -> B, fn: () -> B, fa: (A) -> B) = fa(a)
  }
}
That isn’t even an instanceof check as a when would do, it’s just a virtual call, I believe. May be wrong.
still more expensive than reference checks, for sure
you’re trading off strict types for some perf, which is what I mean by “going javascript” where everything is
Object
like in a dynamic language
we use it on Arrow too, but it’s not to avoid a tristate but to interpret the function calls captured by IO where we’d need to match parameter types with function objects on a recursive loop and that’s just not feasible 😄 https://github.com/arrow-kt/arrow/blob/master/modules/effects/arrow-effects-data/src/main/kotlin/arrow/effects/IORunLoop.kt#L12-L15
l
Comparing a reference check to JavaScript is a bit excessive IMO. Reference check to an internal object is a usual light pattern that is also used in stdlib's
lazy
FYI.
p
Comparing a reference check to JavaScript is a bit excessive IMO.
Not reference check, going down to
Any?
to store a value on a variable so the variable can contain an arbitrary value of an unrelated type. So, dynamic typing of variables 😄
l
Well, that happens to a lot for generic containers, and as long as that doesn't spread everywhere like it does in JavaScript, I don't think it's a bad thing. The public API is still typesafe, and its behavior is tested.
v
instaceof virtual dispatch
Virtual dispatch is not an issue here. But allocations of
Option
on each value and lambdas for
fold
are. One could think of
Result
-like
inline
class, but then boxing kicks in 😞
d
Also used in coroutine intrinsics to indicate suspension. Not sure why it's compared to js or sealed class for performance. It's implementation detail.