oh boy, here we go <https://github.com/JetBrains/k...
# language-proposals
k
๐Ÿ˜ 5
๐Ÿ‘ 3
๐ŸŽ‰ 10
a
Are you talking about the inline classes?
k
yes
u
Is this explained somewhere? Googling for "kotlin inline classes" yields no meaningful results.
s
๐Ÿ‘ 3
u
Ah yes, that. Thanks!
p
that's a pretty bizarre feature to me ๐Ÿ˜„
making Kotlin newcomers more and more dependent on knowing the internals of JVM
s
It seems pretty selfcontained to me. What depends on the jvm ?
p
the detail that the inline value class can only have one field..
a
uh, i like it ๐Ÿ˜„ another way to get farther away from stringified programming
r
Phantom type?
p
how does this differ from
typealias PhoneNumber = String
?
r
if function can receive PhoneNumber we also can send a String, but with inline classes this will not be possible
a
@rrader You cannot use Phantom Types with strings directly, you need to create a wrapper class
r
@Andreas Sinz yes, this wrapper class is called Phantom type if it is erased in compile time
a
@rrader to be clear. in the url you posted,
A
is the Phantom Type,
FileHandle
is a wrapper. inline classes make it possible to make existing types more "type-safe" without a wrapper class
r
@Andreas Sinz do you have an example?
a
an example of inline classes?
r
yeap, without wrapper class
r
@poohbar the difference is
typealias
doesn't create new type, so for example you can't properly redefine methods on it. The following code:
Copy code
typealias MyInt = Int
operator fun MyInt.plus(o: Int): MyInt = this - o
yields the following warning:
Extension is shadowed by a member: public final operator fun plus(other: Int): Int
(and of course mentioned operator is used instead of my own function).
p
thanks
a
@rrader
Copy code
inline class UserId(private val id: Int) {
    operator fun equals(other: UserId) = id == other.id
}

val userId = UserId(5) //At runtime its just an Int, but it's different inside the code
userId == UserId(1) //Works
userId == 5 //Does not work, because there is no "operator equals(Int)" defined
b
I'm concerned about Java interop... how does this look externally?
a
@benleggiero IMO It won't be possible to use it from java just like inline functions
b
@Andreas Sinz What happens when a function returns such a class, then?
Copy code
inline class Foo(x: Long)

// later ...

class Bar {
    fun fooBar(): Foo = Foo(7)
}
What does
new Bar().fooBar()
look like in Java?
r
I'll have a wild guess and say it might be
long fooBar()
. At least for me the idea of
inline class
sounds exactly like that. I didn't look through commits though, so I might be entirely wrong.
a
@r4zzz4k @benleggiero thats an interesting thought. If I understand the scarce information about inline classes right, there should be no sign of that class inside the bytecode and it should be
fooBar(): Long
in java
๐Ÿ‘ 1
so the type-safety is gone in java, but functions that expect/return an
inline class
should work from java
b
so
Long
, not
long
in Java?
a
thats a question for the kotlin compiler devs
e
Why
inline class
and not a parallel for
typealias
such as
typedef
, especially if it's restricted to a single field? Then you could introduce syntax for grouping extension properties/functions under a given receiver type instead (which is a feature that's been requested separately in the past).
And if you really want a full-fledged value type with a single field you can already do that with
data class
, no? The optimizations performed by the compiler/runtime should be transparent.
d
No, it can't be done with a
data class
(for the reasons of backward compatibility, at least; no, data classes never were anything like that)
It's rather awkward to do that with
newtype
, because these things are not meant to be in subtyping relation with corresponding single field type.
Inline classes, for example, can implement additional interfaces (not possible with newtype or whatever, you'd need a different class with a different class file). Just as "primitive" types, values of inline classes are "boxed" when required.
So, it's just yet another class with its own members, which is stored as "unboxed" representation when possible.
e
No, it can't be done with a
data class
(for the reasons of backward compatibility, at least; no, data classes never were anything like that)
A JIT or an otherwise optimizing compiler (i.e. LLVM) can't inline the sole value of a data class when possible? If the constraint is the JVM, this should be another
@Jvm*
annotation instead of part of the language, IMO.
g
I think it should be a separate language feature (and it is), because of very specific semantics (single value, unboxed on runtime, not visible from platform side). Probably, some JIT compilers in some particular peace of code can optimize it, but you never can be sure, and there is no way to force it (tell compiler that you want to use it as inline class) and in most cases itโ€™s just impossible
d
JIT can do that depending on a number of factors. Or can not. Same is true about an AOT compiler. Problem with automatic scalarization is that it's not predictable, and sometimes you really need a transparent performance model.
r
@Andreas Sinz
class UserId
isn't it a wrapper class of Int ?
a
@rrader only inside your code, it will be erased during compilation. just like an
inline function
l
I hope enum and sealed classes can be inline in the future, though the latter may be harder to design right