https://kotlinlang.org logo
Title
h

Hullaballoonatic

01/18/2019, 9:40 PM
is there a way to accomplish this without finding some class from which both inherit?
s

Shawn

01/18/2019, 9:43 PM
overloading and delegation to a private method that holds common logic is probably the general solution
h

Hullaballoonatic

01/18/2019, 9:44 PM
could you perhaps give me an example? delegation is something i'm not super comfortable with, and i'm not sure what we'd be overloading here
a specific example of what i'd like to accomplish:
class SynchedPairs<K, V> {
    val a = ArrayList<Pair<K, V>>()
    val b = ArrayList<Pair<V, K>>()

    operator fun get(key: K): V = a[key]
    operator fun get(key: V): K = b[key]
}
but that doesn't work, because they share signatures
so i tried doing it inline with reified types, but that means the return type will be Any?, meaning it would require explicit typing when you call the function, eliminating much of the convenience i want to create here.
make sense?
s

Shawn

01/18/2019, 9:53 PM
Well, my recommendation would work with concrete types, generics make things a bit more complex
h

Hullaballoonatic

01/18/2019, 9:54 PM
yeah, it's just I like using generics as much as possible because it's good refactoring practice and I think it makes things more readable
s

Shawn

01/18/2019, 9:54 PM
in your case I don’t really know what you’d really be able to do aside from define non-operator functions like
getK
and
getV
h

Hullaballoonatic

01/18/2019, 9:55 PM
yeah and that's really unfortunate
s

Shawn

01/18/2019, 9:55 PM
maybe
@JvmName
would help here, but that’s maybe a bit of a stretch
h

Hullaballoonatic

01/18/2019, 9:55 PM
shame kotlin doesn't smartcast the output of inline functions
to the precise type that the function returns in this case
...or...does it?
s

Shawn

01/18/2019, 9:58 PM
I don’t think inlining should change the behavior of smartcasting
h

Hullaballoonatic

01/18/2019, 9:58 PM
yeah, i get you, but do you agree it would be nice to accomplish what i'm trying to?
s

Shawn

01/18/2019, 9:58 PM
buuuut I just tried out the
@JvmName
solution and it doesn’t give me compile errors
class Test<K, V> {
  val a = mutableMapOf<K, V>()
  val b = mutableMapOf<V, K>()

  @JvmName("getK")
  operator fun get(key: K): V? = a[key]

  @JvmName("getV")
  operator fun get(key: V): K? = b[key]
}
h

Hullaballoonatic

01/18/2019, 9:59 PM
how does this help me?
or rather
s

Shawn

01/18/2019, 9:59 PM
From Kotlin you’ll be able to define your operator `get`s and use them without having to call specific methods
h

Hullaballoonatic

01/18/2019, 9:59 PM
would i still call it as a standard get operator?
s

Shawn

01/18/2019, 10:00 PM
yep
you’d just need to use those
getX
methods from Java
h

Hullaballoonatic

01/18/2019, 10:00 PM
I'm kind of baffled the solution was... like this
ah, i get it
s

Shawn

01/18/2019, 10:01 PM
The problem with even inlined methods is that the method still needs to be generated and named at compile time before it gets inlined into a method body
so those methods still need to be distinct to the JVM
h

Hullaballoonatic

01/18/2019, 10:04 PM
I feel like i'll be using this annotation... quite a bit...
i really should probably use more of them, but i don't fully understand what they are. i think from context they are directions to the compiler.
the only other one i've used in kotlin was
@JvmStatic
because...well, obviously
s

Shawn

01/18/2019, 10:05 PM
Some annotations are, other annotations are directives or metadata for other frameworks like Guice which handles dependency injection
h

Hullaballoonatic

01/18/2019, 10:05 PM
yeah, in angular they are like constructor arguments
s

Shawn

01/18/2019, 10:06 PM
the
@Jvm*
ones are provided by the language to ease JVM interop problems
for your particular case, I feel like you’re more just brushing up against the limits of the Kotlin type system and generics on the JVM
h

Hullaballoonatic

01/18/2019, 10:07 PM
Is JB trying to bake it into the kotlin compiler to deprecate those annotations?
s

Shawn

01/18/2019, 10:07 PM
I mean, the annotations are supposed to be used judiciously, to ease the occasional conflict
afaik JB probably isn’t planning on prioritizing more of the math-ey type system features
h

Hullaballoonatic

01/18/2019, 10:08 PM
hmm
s

Shawn

01/18/2019, 10:09 PM
TypeScript and Elm and F# are all tackling that kind of thing, and it likely just appeals to their userbases more than Kotlin’s
h

Hullaballoonatic

01/18/2019, 10:13 PM
TypeScript is the only other language that really competes as my favorite to write in. There are times, however, i really just wish I had pointers, and pass by value / reference
i wish i liked writing in cpp more
s

Shawn

01/18/2019, 10:15 PM
Personally speaking I’m pretty glad I don’t have to manage things like pointers and move/copy semantics
h

Hullaballoonatic

01/18/2019, 10:30 PM
i prefer that i don't have also; just like with garbage collection, but it would be nice to have the option somehow
p

Pavlo Liapota

01/18/2019, 10:33 PM
Interesting which method will be called in example with
@JvmName
if
K
and
V
will be the same type 🙂
h

Hullaballoonatic

01/18/2019, 10:33 PM
hmmm, that's a good point
s

Shawn

01/18/2019, 10:34 PM
Pretty sure the class will just be unusable at that point
h

Hullaballoonatic

01/18/2019, 10:34 PM
i could certainly make it unusable
s

Shawn

01/18/2019, 10:34 PM
you’ll just get an overload resolution ambiguity error at compile time
h

Hullaballoonatic

01/18/2019, 10:57 PM
class BidirectionalMap<K, V> {
    val a = mutableMapOf<K, V>()
    val b = mutableMapOf<V, K>()

    operator fun get(key: K): V? = a[key]

    @JvmName("getB")
    operator fun get(key: V): K? = b[key]

    operator fun set(key: K, value: V) {
        a[key] = value
        b[value] = key
    }

    @JvmName("setB")
    operator fun set(key: V, value: K) {
        b[key] = value
        a[value] = key
    }

    operator fun contains(key: K): Boolean = a.containsKey(key)

    @JvmName("containsB")
    operator fun contains(key: V): Boolean = b.containsKey(key)
}
we'll see how this works
if it does, i can expand it to have sort and other shit