Does FIR-K2 account for such potential features? <...
# language-evolution
a
Does FIR-K2 account for such potential features? https://youtrack.jetbrains.com/issue/KT-33693/Aggressively-optimize-comparisons-of-reified-class-literals-after-inline https://youtrack.jetbrains.com/issue/KT-11211/Be-able-to-use-a-reified-type-parameter-on-left-hand-side-of-is I see that
is
is a runtime operator, but what about whens? The idea is the ability to make type arguments have values at compile time (it would be nice if every expression could have values as well), and so optimize code away or at least replace with a boolean value. P.S.: I have no knowledge about K2 FIR, so I don't know about the possibility of it.
Copy code
inline fun <reified T> printfIs(t: T) {
  if (T is Int) println("Int: $t")
  if (T is UInt) println("UInt: $t")
  if (T is String) println("String: $t")
}
inline fun <reified T> printIfEq(t: T) {
  if (T == Int) println("Int: $t")
  // ...
}
inline fun <reified T> printWhenIs(t: T) {
  when (T) {
    is Int -> println("Int: $t")
    // ...
  }
}
inline fun <reified T> printWhenEq(t: T) {
  when (T) {
    Int -> println("Int: $t")
    // ...
  }
}
d
There are no planned features in 2.0 with K2 release (except some improvements in smartcasts calculation mechanism). This decision was made to 1. Simplify migration for users, because there are a lot of (more or less minor) breaking changes comparing to 1.9) 2. Reduce scope of work required for 2.0 release But those features can be implemented in K2 (actually, the first one is pure backend feature and does not relate to K2 release)
a
But is the backend tied to the target? Wouldn't make it more sense to optimize it somewhere between frontend and backend?
d
My comment was mostly about the second issue As for the first I can tell that most likely jvm team has more important tasks
a
So there is no issues per se with it, but just different priorities?
d
Maybe there are, I don't know (I'm not from JVM team)
a
My point being, that this is an optimization (first one) between frontend and backend as there could be plugins trying to do other voodoo before sending to backend, and before the backend, as it works with all backends not only JVM. Additionally, there should be a difference between
==
and `is`: while == checks for equality where
is
could check inheritance as well (
B is A
<- B is a sub class of A)
As the check could be made before sending to either of the backends, it could be optimized. That's why I asked specifically for frontend
d
Frontend does not perform any optimizations at all
a
It is possible that I misunderstood what "backend" means, as I think this means taking an IR and compiling to JVM bytecode
d
Backend is the combination of IR lowerings and platform codegen
a
So it can be target agnostic?
why did you mention the JVM team then?
d
Because other backend teams are busy even more
a
How many are there to be so out of time?
d
It's not about number of people but about number of tasks
a
https://youtrack.jetbrains.com/agiles/153-1251/current the tasks on the left, right? How many people are in the kotlin team actually, are there numbers somewhere?
d
This board is quite outdated, more recent version is on website In each small team we have 5-12 people
And the board more or less correctly represents all developer teams
a
so there is like 50 in total
d
Actually more than 100
*counting QA, supporters and other non-devs
a
and developers?
d
~70, never counted the exact number
a
o.o
well... then I either wait the release of K2, or a new PC. My current one starts to smoke when compiling kotlin for Js
d
Sorry to hear that
a
The number 50 I took from https://github.com/JetBrains/kotlin/graphs/contributors?from=2021-12-17&amp;to=2023-04-18&amp;type=c as it gives a more or less amount of ppl working actively on the project as developers
(No need to be sorry, it is expected for such a large language, it's not like LLVM would be any faster. 16GB and an Ryzen 5 2400G (4 cores) are not the best specs to compile languages, I didn't thought about lang dev when buying it back then.) But back to topic: I talked about the 2 issues (in OP) to some ppl. They mentioned that
as
could cause problems, as it is aware of inheritance. Do you see some problems in that?
d
Yeah, it's representative but not fully correct Members of Kotlin IDE team mostly contribute to intellij repository Some of devs work hard but rare commit
They mentioned that as could cause problems, as it is aware of inheritance. Do you see some problems in that?
Easily:
Copy code
interface Base
class Derived : Base

inline fun <reified T> get(key: String): T? =
    map[key]?.let {
        when (T::class) {
            Base::class -> it as T
            else -> throw IllegalArgumentException("Not implemented for the given type.")
        }
    }

fun test() {
    val x = get<Derived>("")
}
a
this is not
is
but an equality, so
==
oh,
it as T
, but this is a cast to something else
d
T::class
will be inlined to
Derived::class
, so actually this whole function would be incorrect for this case
a
it is incorrect by the fact that the cast is in itself false
d
Indeed
a
Copy code
private inline fun <reified T> readBuf(
        buf: ByteBuffer,
        addr: UInt,
        range: MemoryRange,
    ): T {
        val offset = range.makeOffset(addr)

        return when (T::class) {
            UInt::class -> buf.getUInt(offset) as T
            UShort::class -> buf.getUShort(offset) as T
            UByte::class -> buf.uget(offset) as T

            else -> throw AssertionError()
        }
    }
the idea came to be from this code
as unsigned types are not kotlin native (they should be tho), this would cause boxing with
as
, but take a look at the utility. Tbf, this is a workaround of not having compile time traits in Kotlin so a when must be used
d
It's worth to add this example to original ticket
a
Note: This snippet was not put in the project at the end, as... boxing is quite a dumb idea when trying to write a JIT for a an PlayStation 1 Emulator ( https://github.com/vbe0201/jiffy , I'm not the author of this project, I helped him with Kotlin as he was new to Kotlin (coming from C++ and Rust side))
Tbf, this is a workaround of not having compile time traits in Kotlin so a when must be used
So we missed Rust traits (and C++ templates) quite a lot, unsigned where not great (boxing and
as
being a reference cast thing)
Additional Problem, which has been pointed out, was for the fact that rewriting that
T
is an expression so you don't need
::class
anymore, would need a rewrite of the system. Is this right?
d
Sorry, could you elaborate the question?
a
When a reified generic
T
is used as an expression you get an error as this isn't one. You need to specify
::class
so get the class itself, not a "Type" in the sense of compile time construct. So to enable
T
to be used as an expression, the type system and expressions must be adjusted to allow using Types as expressions.
d
Yes, exactly At this point compiler can not treat type as expression in any context (except the
object
access, but it's a completely different story)
a
So this isn't possible and won't be even after the rewrite?
d
It won't work just out of box But it's possible to implement this feature
And the fact that something is possible does not imply that it definitely will be implemented
a
Especially for things like const expressions it would be good to have access to Types
Why cannot Types be treated as expressions? What are the restrictions and problems?
d
The thing that there were no research of this feature So we don't really now which usecases it will cover and which problems it may bring to the language
a
Hmmm, ok. I'm on Rust's Community Discord which has a lang-dev channel with people loving type systems, I will gather more information on this aspect and how this can be implemented. One additional idea I had, was to think about compile time interfaces (basically traits)... I will try to put it in a markdown document and propose. Do you know anything which could be any of help? Like similar ideas?