https://kotlinlang.org logo
#announcements
Title
# announcements
m

mikehearn

11/29/2019, 6:39 PM
but I'm not sure what you mean by work as expected here. you want
a == b
to pass when a and b are of different types and may have fields that aren't included in the comparison?
🧵 4
n

Nir

11/29/2019, 6:45 PM
In truth, I never used them polymorphically in python, so I don't know what the result would be
that said, I also have no interest/intention of using them polymorphically
I just want to reuse the fields
Otherwise you have a situation where you are repeating the same things
s

Steve

11/29/2019, 6:45 PM
so?
duplication is cheaper than the wrong abstraction
n

Nir

11/29/2019, 6:46 PM
Right, so I'm asking if Kotlin has the right one
if the answer is "no", then that's an answer, sure. However, having the right abstraction is possible (e.g. like python's dataclass)
s

Steve

11/29/2019, 6:46 PM
I don't think that is the right abstraction
I would say, if they're not related otherwise, then just duplicate
n

Nir

11/29/2019, 6:47 PM
I mean it's clear, it's readable, it does what I need it do, it avoids repetition.
s

Steve

11/29/2019, 6:47 PM
avoiding repetition isn't the highest goal, though.
n

Nir

11/29/2019, 6:47 PM
No, but it is one goal.
s

Steve

11/29/2019, 6:47 PM
not really
n

Nir

11/29/2019, 6:48 PM
Not really interested in debating this point.
b

Burkhard

11/29/2019, 6:48 PM
Maybe inheritance is the wrong tool here. Maybe you should go with composition. If the related fields can be group logically create a data class with them. Both of your classes can than have a property of that type. This fixes your equality and code duplication problem
s

Steve

11/29/2019, 6:48 PM
tying yourself into an inheritance chain that doesn't really fit, and is just there to avoid repetition can be a worse problem than repetition
n

Nir

11/29/2019, 6:48 PM
@Burkhard I agree in principle composition is more correct, the problem is that it nests the data one level further
Sometimes that is the way to go but sometimes you may be constrained already
b

Burkhard

11/29/2019, 6:49 PM
And sometimes it’s best to just have 2 classes with the same fields, if they are not related directly.
n

Nir

11/29/2019, 6:50 PM
@Steve Sure, that is possible, or not possible. So far, having used this approach in python I've never seen any downside in practice.
@Burkhard Sure, maybe that is the best solution, I was just trying to understand if Kotlin offers anything better
s

Steve

11/29/2019, 6:50 PM
if a and b are different types, there is a very good chance that they will want to change independently. locking them into an inheritance chain makes that much more difficult.
so, to answer your question, composition is what Kotlin would offer here
n

Nir

11/29/2019, 6:51 PM
Curious if Go style "embedding" has ever been considered in Kotlin? Basically, we want to reuse data fields at "top level" but don't want inheritance, which is kind of what embedding is (from what little I know of Go)
s

Steve

11/29/2019, 6:51 PM
or, just having the two fields duplicated, as they're not really the same field if those two classes are not semantically the same
n

Nir

11/29/2019, 6:51 PM
@Steve Sure, and if you're free to design how the data you're modelling looks like, composition is good, but in this case I can't nest the data
s

Steve

11/29/2019, 6:52 PM
you can always have accessors
n

Nir

11/29/2019, 6:52 PM
Not sure what that means. They have the same names, the same types, and not it's not a "coincidence", so I would consider them the same fields.
s

Steve

11/29/2019, 6:52 PM
if a and b are not interchangeable, they're not the same fields
n

Nir

11/29/2019, 6:53 PM
Not really sure what you mean by "interchangeable" in this context
s

Steve

11/29/2019, 6:53 PM
Following the Liskov Substitution Principle.
n

Nir

11/29/2019, 6:54 PM
In that case, I'm not sure what A and B are
s

Steve

11/29/2019, 6:54 PM
the two classes that you want to have inherit from a parent to reuse some fields
n

Nir

11/29/2019, 6:54 PM
those two classes don't have a base-derived relationship...
s

Steve

11/29/2019, 6:55 PM
but you're trying to give them one
n

Nir

11/29/2019, 6:56 PM
no... A and B have a common base, they are not the base child, of one another, so LSP does not apply between A and B
@mikehearn I'm not actually sure what the right behavior would be for equality between instances of different types. It could either not compile, or return False, both of those are fine I think.
s

Steve

11/29/2019, 6:58 PM
what about the issue where they're both cast to the parent class?
n

Nir

11/29/2019, 6:58 PM
Equality works as expected, I meant only that the derived types can compare between instances, and it works as you'd expect, i.e. the values of the base fields are included in the comparison
If you explicitly cast both to the parent class, then it should do a normal parent class comparison, i.e. either True or False depending on all parent fields matching.
Seems completely reasonable?
by doing the cast you're explicitly asking only the parent part to be compared?
s

Steve

11/29/2019, 7:01 PM
so two instance that are the same type but normally wouldn't be equal should be equal just by casting them?
n

Nir

11/29/2019, 7:02 PM
At least, that's one reasonable approach. Another approach would be to implement equals such it first checks if the two instances are really the same type, if not return false, if yes, then proceed with comparison (basically typical double-dispatch /visitor)
s

Steve

11/29/2019, 7:02 PM
I think that's more work than just duplicating the fields
😄 1
n

Nir

11/29/2019, 7:02 PM
I mean this isn't any work for the person writing the dataclass...
this would happen automatically of course
the person writing the classes just writes out the 3 dataclasses, and nothing else
At any rate I can see that the answers to these are a bit awkward in a statically typed, single dispatch language. That said, it's still a bit unfortunate. I use this in python quite frequently and it's quite handy. I actually never use the base for anything but reusing the fields in this situation.
s

Steve

11/29/2019, 7:05 PM
especially in statically typed languages, in general, that's considered bad OOP practice
n

Nir

11/29/2019, 7:05 PM
what's bad OOP practice?
s

Steve

11/29/2019, 7:06 PM
inheriting just to reuse fields
or functionality
n

Nir

11/29/2019, 7:07 PM
Sure, the problem is that in most cases using composition is just as simple, so people were blatantly overusing inheritance when they had another language tool in front of them that solved the problem better
The problem is that there are situations where composition doesn't quite work out, or is annoying and full of boilerplate
Inheritance maybe isn't ideal either but it may still be better in composition.
Needing to model data in this case that's repeated but "flat" in different places, composition doesn't work out
hence why I think embedding is a great idea (despite not liking Go much in general)
s

Steve

11/29/2019, 7:09 PM
in that situation, it's usually better just to have each of those classes have their own version of it
but, back to what you want, it doesn't seem like Kotlin offers that
n

Nir

11/29/2019, 7:10 PM
I mean, it is fine to say "that's the best solution in Kotlin, as it stands". Less fine to say "that's the best solution because Kotlin isn't capable of factoring out this duplication".
Yeah, it seems like not. I was hoping maybe kotlin had something fancy akin to macros, but I suppose not
2 Views