@Roman, my Person and your Person will not compose...
# language-proposals
o
@Roman, my Person and your Person will not compose, even if both have the same exact name and date params as their constructor params
e
I’m sure if we are both working on the same code in the same project we can figure out how to make sure we have a common concept of Person.
o
Yes, but if you have written extremely nice library, which can do everything with Person which has name and date, then it won't be reusable for me, coz my program uses such Person which also have age in it's constructor... Of course keywords by themselves doe snot solve it. It's jsut mapOf(key/value) is not the same as class
but if you would write functions which use maps with keys, then by only using the same keys, I can use my maps... and you don't care that I pass you map with 20 other keys, whicih you don't care... but can't do with classes. Classes in this case enforces extrem tight coupling... but this is offtopic of my KEEP. My KEEP is more about keywords as they are in LISP and Clojure... if you don't see it as good fit, no problem... Kotlin awesome as it is without keywords
e
If I were to write such a library with a goal to make the Person it works with extensible, then I would have defined an
interface Person
with the corresponding properties and defined my opertions on it.
2
You don’t have to explain to me the benefits of Clojure approach. I’m just telling that if you work on application that benefit from such an approach, then you should be programming it in Clojure, not in Kotlin.
a
Closure is dynamically typed, how would you do keywords in kotlin where everything is statically typed? Is everything a
Map
that you pass around?
o
well under the hood you could map/compile any :keyword to string "_some_very_secret_prefix_keyword" and be done with it... and :keywrod(datastruct) would map actually to datastruct[:keyword] syntactic sugar
a
How could i tell the caller of my function that the map he is passing must have a
firstName
,
lastName
and
age
?
o
You don't. It's not problem of Compiler, that the big thing. You as function expect map with firstName, lastName, and age... if the data is there, you do, if the data is not there you react accordingly, as you program. The big benefit, is that... when you have such function, I can pass you map containing also eyeColor, birthDate and referenceId, and your function will work perfectly... Now you have created truly reusable function.
But if you enforce your view of data on the whole world, then whole world either will ignore you, or write their own function, or will be force to write additional function whcih does mapping between worlds view of person, and your view of person
now you have 2 functions, and one of them is just because, you can't take birthDate even when you don't need it 🙂 It's like you don't accept Amazon package if it ships with the truck containing other packages ,not related to you 🙂
and Kotlin actually has this accidentaly - delegates
If you would take map, and deleaget your properties to that map, you will be happy even if I send you map whcih has extras... and by your own delegated property definition you will enforce the contract, but your enforcement will be more or less correct, not restricting me... and I can reuse the Map down the stream
a
For what it's worth, I prefer to use classes and composition as it keeps code and debugging simple. At least right now any benefit I see for 'clojure' seems to be for performance or less verbose extension. 2 biggest drawbacks imo are increased learning curve, and loss of static type check. With named parameters, nullable types, and default arguments, and syntax for creating a class in kotlin, they're very cheap to use in terms of boilerplate. If it's about using delegate by open class, I would be for it.
Even then usually delegate by interface is enough
d
I don't see the benefit of map over composition either