Just putting on your radar that I've made 2 separa...
# arrow-contributors
y
Just putting on your radar that I've made 2 separate PRs (#2950 and #2951) for a
value class Option
. From the benchmarks (included in the PRs), it seems as though there is marginal benefits of turning Option into a value class, but tangible benefits were seen when taking the more intrusive approach (in #2950) of optimizing nested Options. All the data and extensive commentary about upsides and downsides is available in the PRs. Perhaps my benchmarks are flawed as well, so if you have any suggestions for more representative benchmarks please let me know. All feedback is welcome!
c
Why is the use of
inline reified
so bad? I’m asking because I have a small library that makes use of it and I’d like to understand more about its drawbacks.
Copy code
inline operator fun <reified A : Screen> Store.invoke(f: context(A)(Action.() -> Unit) -> Unit): Unit =
    when (val screen = state.value.screen) {
        is A -> f(screen, ::dispatch)
        else -> Unit
    }
here a little helper function
y
It's more about the proliferation of it in the codebase. First of all, inlining any significantly big functions will result in duplication of bytecode since inline functions are, well, inlined into the bytecode. You can actually observe this for yourself with this code:
Copy code
inline fun test(block: () -> Unit) {
    block()
    block()
}
 
fun main() {
    test { test { test { test { test { test { test { test { test { test { Unit }}}}}}}}}}
}
Yes that is an artificial example and it inlines the lambda twice, but it shows that inlining isn't always desirable
Second of all, reified types obviously don't work when you don't know the type. For instance, if you're in a generic class, you can't use a type parameter as a reified type. This limits the extent of what you can do with those functions, and in fact in some cases it pushes developers to just use
Any?
As the reified type, which, in the case of that PR, would actually result in incorrect behaviour (I was very aware of that since I designed the code in that way and yet I fell for that and had to fix a resulting bug). Also, `Nothing`and
Nothing?
Can't be used as reified types, and so in the PR when I tried to create a
Some(null)
, I had to do
Some<Any?>(null)
A helper function like
Store.invoke
there is a perfectly valid use of
reified
. The issue with the PR is that the whole Option API would now be based on
reified
, with no intuitive reason as to why. The reason, if you're curious, is that I was using reified types to prevent boxing of nested Options by unravelling an
Option<Option<T>>
, and I'd only rebox the Option if the user was trying to access the value as an
Option
(thus relying on reified types to achieve that). It's a very hacky implementation, but it works. In your case, the reified type is clearly used for an
is
check, and the reification is limited to a few functions on the surface. Do note that this PR is suggesting a change to a pre-existing API, and thus it'll have to stand more to scrutiny vs if it were a new API
c
I have a much clearer understanding of all the implications this implementation entails. It’s a pleasure learning with you all 🙂
y
Don't hesitate to ask any more questions lol! If there's anything unclear to you then it's likely to be unclear to others as well.