Nino
04/18/2023, 8:42 PMdata class Latitude(val value: Double)
fun doStuffWithLatitude(latitude: Latitude): Double = latitude.value + 1.0
I checked typealiases which are rather useless for type protection. For inline / value classes, I see no difference with my basic idea of a data class wrapping only one primitive. But value classes seem rather useless as a whole if you can't do something like :
@JvmInline
value class Latitude(private val d: Double)
fun doStuffWithLatitude(latitude: Latitude): Double = latitude + 1.0 // <-- Doesn't compile, wtf ?!
Particularily, I'm quite lost when the documentation mentions
Inline class instances can be represented at runtime either as wrappers or as the underlying type... but it's not possible, as seen with example ☝️ I guess I'm missing something with inline / value classes that may help me. Or maybe there's another way to prevent mismatching 2 primitives of the same type ?
Chris Lee
04/18/2023, 8:45 PM@JvmInline
public value class Latitude(public val value : Double)
…allows Kotlin to have the type knowledge/safety, and inline this to the extent possible.Nino
04/18/2023, 8:47 PMBenoît Liessens
04/18/2023, 8:47 PMChris Lee
04/18/2023, 8:47 PMChris Lee
04/18/2023, 8:48 PM@JvmInline
public value class Latitude(public val value : Double)
public operator fun Latitude.unaryMinus(): Latitude = Latitude(-value)
Nino
04/18/2023, 8:50 PMChris Lee
04/18/2023, 8:51 PMChris Lee
04/18/2023, 8:51 PMChris Lee
04/18/2023, 8:52 PMNino
04/18/2023, 8:53 PM@JvmInline
value class Latitude(val value: Double)
fun doStuffWithLatitude(latitude: Latitude): Double = latitude.value + 1.0
Chris Lee
04/18/2023, 8:53 PMNino
04/18/2023, 8:54 PMChris Lee
04/18/2023, 8:55 PMpublic operator fun Latitude.plus(b : Double): Latitude = Latitude(value + b)
Chris Lee
04/18/2023, 8:55 PMsomeCall(lat.value)
Nino
04/18/2023, 8:56 PM.value
lolNino
04/18/2023, 8:56 PMNino
04/18/2023, 8:56 PMsomeCall(lat)
, I have no ideaChris Lee
04/18/2023, 8:57 PMJasonB
04/18/2023, 8:57 PMChris Lee
04/18/2023, 8:58 PMNino
04/18/2023, 8:58 PMInline class instances can be represented at runtime either as wrappers or as the underlying type
Nino
04/18/2023, 8:58 PMChris Lee
04/18/2023, 8:59 PMNino
04/18/2023, 9:07 PMval latitudeValue: Double = latitude
, but when code is compiled, it's basically a double so performance is preserved...
fun main() {
val latitude = Latitude(Random.nextDouble(90.0))
doStuff(latitude)
}
private fun doStuff(latitude: Latitude) {
println(latitude.value)
}
@JvmInline
value class Latitude(val value: Double)
becomes
public final class MainKt {
public static final void main() {
double latitude = Latitude.constructor-impl(Random.Default.nextDouble(90.0));
doStuff-yvxom7k(latitude);
}
private static final void doStuff_yvxom7k/* $FF was: doStuff-yvxom7k*/(double latitude) {
System.out.println(latitude);
}
}
Chris Lee
04/18/2023, 9:09 PMNino
04/18/2023, 9:10 PMval myInt: Int = f.i
in this part (this is quite literraly the only "final usage" of value classes anyway), so I expected it to be impossible, even more so when the first example declares a private property like value class Password(private val s: String)
Chris Lee
04/18/2023, 9:11 PMChris Lee
04/18/2023, 9:11 PMpublic val _foo_ : Double = Latitude(0.5).value
Nino
04/18/2023, 9:11 PMChris Lee
04/18/2023, 9:12 PMNino
04/18/2023, 9:12 PMNino
04/18/2023, 9:12 PMChris Lee
04/18/2023, 9:12 PMtoExternalRepresentation()
as a level of indirection.Nino
04/18/2023, 9:13 PMNino
04/18/2023, 9:14 PM.value
on my value classes 😄Youssef Shoaib [MOD]
04/19/2023, 8:14 AMNino
04/19/2023, 8:20 AMtypealias
thrown there as they don't provide any compilation type safety ATM, but would if the design makes it... Or am I missing something ?Youssef Shoaib [MOD]
04/19/2023, 8:28 AMsatisfies
operator is the key feature here, not the typealias
part, but it's probably just more convenient to restrict satisfies
to only appear in typealias declarations from a language design POV