hey, can I have this? ``` sealed inline class Tok...
# announcements
g
hey, can I have this?
Copy code
sealed inline class Token{}
object UnixNewline: Token()
object WindowsNewline: Token()
inline class Character(val impl: Char): Token()
it would make one of my tokenizers run a whole lot faster
s
inline classes need a single value parameter, that sealed class doesn’t have one and therefore can’t be inline
g
right but its abstract
s
so what do you expect the inline modifier on the sealed class to actually do?
g
1. erase the type from reflection 2. let me use an
inline class
as a type in a
when
expression with exhaustive coverage
s
you expect an abstract class to be erased from reflection? that’s not realistically possible
a final inline class can be erased by the compiler, because it can be autoboxed and replaced by the thing it’s inlining. if a function takes a
Token
, it requires a value of that type, there’s nothing to inline there
g
presumably we can use the same boxing device as:
Copy code
interface Whatever{}
inline class MyImpl(val char: impl): Whatever

fun myFunc(p1: Whatever){
s
yes, but
Whatever
can’t be inlined, and if i’m not mistaken, a function accepting
Whatever
has to accept a boxed (i.e.
MyImpl
) value rather than an
impl
g
I mean im not actually concerned with the runtime incarnation of
Whatever
, but if your point is that boxing is going to cause me to see those object allocations regardless then I'm stuck. Presumably if I express my tokenizer as a set of static functions and/or inline functions, then the object allocations go away?
a
Everytime you call a function/method that requires a
Whatever
, auto-boxing is involved
g
That wouldn't be erased by either an optimization pass nor the jitter?
Copy code
interface Whatever {}
inline class Impl(val value: Char)

inline fun Whatever.doSomething() = when(this) {
  is Whatever -> value
  else -> '0'
}

fun something(){
  val x: Impl = Impl('1')
  val y = x.doSomething()
}
is going to involve allocating a boxed
ImplAsWhatever
?
s
Whatever.doSomething()
might have to cast to
Whatever
, meaning yes(?)
g
You'd need a pretty sophisticated compiler optimization to remove it, and I dont think the jitter would be willing to assume that the object allocation chain (which to it is of course quite large) wouldn't cause some other behaviour somewhere (static initialization of
Whatever
for example?).
Jetbrains really has torn off a huge chunk of JVM performance-ee things with this
inline class
concept.
s
just decompiled the example you gave, it boxes before calling
doSomething
😩 1
g
whats the decompilation tool your using? I saw somebody posting a plugin for intelliJ that looked pretty good.
s
just the basic one in IntelliJ
something
compiles down to this:
Copy code
public static final void something() {
      char x = Impl.constructor-impl('1');
      Whatever $receiver$iv = Impl.box-impl(x);
      int $i$f$doSomething = false;
      if ($receiver$iv instanceof Whatever) {
         $receiver$iv.getValue();
      } else {
         boolean var10000 = true;
      }

   }
🤔 1
g
thanks @serebit!
s
👍🏿 no problem