https://kotlinlang.org logo
Title
h

Hullaballoonatic

04/10/2019, 6:02 PM
yes, it is, but it removes an unnecessary character, no?
m

Mike

04/10/2019, 6:18 PM
0..2 is unambiguous and doesn’t require extra thought, Concision is not a good goal unless it aids readability. The [2..] variation, though… isn’t that
drop(2)
? Actually, would it be
drop(3)
? Another reason to avoid it. Is it 0-based? Is it inclusive or exclusive?
drop(n)
is again unambiguous. Again, more typing, but it’s already there, and doesn’t require parsing. Same reason I’m opposed to introducing the ternary operator rather than just using
if/else
on one line. If you come from Java/Groovy, you have learned the ternary. If you didn’t, think back to the first time you saw it, and had to have it explained to you. And at least in Java,
?
and
:
don’t have any other meaning, whereas in Kotlin, they have other meanings depending on how they appear.
1
h

Hullaballoonatic

04/10/2019, 6:23 PM
I wouldn't want the ternary operator in kotlin since
if/else
is already inline And as I alluded to, yes,
foo[2..]
is the same as
foo.drop(3)
but
foo[..3]
is
foo.take(4)
, but I imagine them being the same function, as opposed to two different functions. Does that make sense?
g

ghedeon

04/10/2019, 6:41 PM
meh.. @Mike it's more like an attempt to reason the current situation, than a real argument. Never
drop
or
take
or whatever workaround name will be cleaner than
[..k]
or
[k..]
. Same reason why
arrayOf()
will be always a sad bump in kotlin.
g

gildor

04/10/2019, 11:41 PM
So array should have own special syntax to be "cleaner", but nothing for lists, right? But In our project we have probably 50 cases for lists per 1 array. Also what about type of this array, should [1,2,3] be IntArray or Array<Int>? If we add also collections to this proposal we getting KEEP-113 with a ton of problems
drop and take not just "workarounds" it's quite common list operators across many languages, especially functional ones So range vs operator it's more about case (sometimes you think in indexes, than range looks better, sometimes in list count) and habits (if you come from python or Swift it may be more common to use range)
h

Hullaballoonatic

04/10/2019, 11:47 PM
I have a hard time understanding the purpose of the existence of both
IntArray
and
Array<Int>
g

gildor

04/10/2019, 11:48 PM
One version is generic and Int will be boxed, another is primitive
h

Hullaballoonatic

04/10/2019, 11:48 PM
Doesn't
List<Int>
already cover the former properties?
g

gildor

04/10/2019, 11:50 PM
But List is not the same as array, array is also JVM type, it cannot be extended, allocated sequentially in memory
Array is much more low level and most of lists are written using arrays (excluding linked ones)
h

Hullaballoonatic

04/10/2019, 11:51 PM
Yeah, that's why I figure
Array<T>
only exists because of its existence in the jvm. We could easily get by with only
List<Int>
and
IntArray
, I believe.
g

gildor

04/10/2019, 11:52 PM
Of course it all about JVM and because of way how generics are implemeted
h

Hullaballoonatic

04/10/2019, 11:53 PM
Either way, for a language that prides itself in being readable and dispelling cryptic nomenclature and syntax, the existence of
IntArray
and
Array<Int>
is certainly a poignant sour spot.
Maybe in 10 years Kotlin Native will phase out KotlinJVM and KotlinJS
g

gildor

04/10/2019, 11:54 PM
This language also prides I terop with existing platforms, and this interop one of main reasons why it is so popular
1
h

Hullaballoonatic

04/10/2019, 11:54 PM
and Kotlin can finally slough off the baggage of the jvm
g

gildor

04/10/2019, 11:54 PM
It will be really sad moment, because it will happen only if JVM will die, or K/N will be impossible to use for MPP
h

Hullaballoonatic

04/10/2019, 11:55 PM
Yeah, I fully understand that this language's top priority is interop
g

gildor

04/10/2019, 11:55 PM
JVM is not the baggage, this is one of main forces of Kotlin
h

Hullaballoonatic

04/10/2019, 11:55 PM
jvm comes with baggage, rather
it isn't wholly baggage by any means
g

gildor

04/10/2019, 11:55 PM
Everything come with baggage
For example this solution about array literal
h

Hullaballoonatic

04/10/2019, 11:56 PM
the existence of baggage everywhere is not a reason to dismiss it.
g

gildor

04/10/2019, 11:56 PM
So, returning to my question after we drop Array<Int> val a = [1,2,3]
h

Hullaballoonatic

04/10/2019, 11:57 PM
is that an
IntArray
or a
List<Int>
, yeah?
g

gildor

04/10/2019, 11:57 PM
So a is IntArray, List<Int> or maybe MuyableList<Int>?
Solution: let's add new syntax for list literals, like {1,2,3}
h

Hullaballoonatic

04/10/2019, 11:58 PM
<1, 2, 3>
eh
g

gildor

04/10/2019, 11:58 PM
And now we have another can of worms: what about compatibility with existing code and will compiler can easily parse it
h

Hullaballoonatic

04/10/2019, 11:59 PM
yeah, there's always the concern of existing code
mutability of lists is an enormous can of worms all on its own
I think
List<Int>
,
MutableList<Int>
, and
ImmutableList<Int>
could cover all the bases, meaning both
Array<Int>
and
IntArray
could kick the bucket
But I don't know every use case
🤷 1
g

gildor

04/11/2019, 12:16 AM
I want to be clear, I'm actually pro-collections literals in general, I just don't see for now good proposal and solution for known problems It's just really hard to do and I wouldn't like to make language more complicated, because we didn't talk also about maps
h

Hullaballoonatic

04/11/2019, 12:17 AM
yeah, and i wanna be clear that I'm very sympathetic toward all your arguments and appreciate your views. i don't wanna seem combative.
g

gildor

04/11/2019, 12:22 AM
No-no, it's fine 👍 just tried to show that everything is not so easy
But I also think that for some cases we could have literals, for example for
in
operator Like:
if (x in [2,5,7])
And also unroll it on compile time
h

Hullaballoonatic

04/11/2019, 12:24 AM
that could also just be set notation:
x in {2,5,7}
g

gildor

04/11/2019, 12:25 AM
Yes, but good thing about [] is that we already have array literal for annotations
h

Hullaballoonatic

04/11/2019, 12:25 AM
righto
couldn't
[]
be used for list literals and
{}
used for collection or set literals? Since we don't have object literals.
i guess the standard is to use them for map literals, but maps are pretty clearly described in kotlin with the
to
infix
g

gildor

04/11/2019, 12:27 AM
In theory set is more correct in terms of semantics, but on compile time, if you want to replace it with intrinsic) there is no much difference
There is also proposal for
to
literal
h

Hullaballoonatic

04/11/2019, 12:27 AM
to do what?
g

gildor

04/11/2019, 12:28 AM
See KEEP-113
To do mapOf(1: a, 2: b) instead of mapOf(1 to a, 2 to b)
h

Hullaballoonatic

04/11/2019, 12:29 AM
ah, yeah
to
isn't any clearer than
:
g

gildor

04/11/2019, 12:30 AM
Correct, but
to
is not even part of the language or syntax, so it much more simple
h

Hullaballoonatic

04/11/2019, 12:30 AM
yeah it's just an infix for a
Pair.invoke()
g

gildor

04/11/2019, 12:31 AM
There are also ideas about constructor literals, to omit class name if type of object is inferred
h

Hullaballoonatic

04/11/2019, 12:31 AM
one of the other tops of my wish list, semi-related, is overloadable
as
operator, but iirc that's a feature in a few languages and can make code vague in reading
g

gildor

04/11/2019, 12:32 AM
To override cast?
h

Hullaballoonatic

04/11/2019, 12:32 AM
yeah
you can do something similar atm with contracts, i believe
would also be nice to have javascript's ability to pass named functions to parameters of lambda type, e.g.
fun bar(baz: (Int) -> Any) {
   // stuff
}
fun foo(foz: Int): Any {
  // stuff
}

val bafo = bar(foo)
as opposed to the current
val bafo = bar({foo(it)})
but javascript treats functions as objects or something, so that's how it easily gets away with it
g

gildor

04/11/2019, 12:39 AM
Isn't it what you can do with function reference?
bar(::foo)
Functions in Kotlin are also objects, you just need reference syntax to get access to object
h

Hullaballoonatic

04/11/2019, 3:51 AM
hmmm, i haven't used the
::
syntax for a couple years. forgot it existed. still don't know what it does
g

ghedeon

04/11/2019, 5:21 AM
Literals are not easy... personally, I doubt it will be ever implemented but so far I like this Clojure adoption the most: https://github.com/Kotlin/KEEP/pull/112#issuecomment-419740049. Stuff like
Array<Int>
and
IntArray
is important but in perspective, Declarative is superior to Imperative. We need to offload accidental complexity that was introduced over the years.
WHAT
is superior to
HOW
. Foreach is better than for loop, because you don't see how it's implemented. That's why
listOf
tells you nothing about its implementation (HOW), because, frankly, nobody cares. In ideal world we don't want to care about
IntArray
as well. One day.... 😏
g

gildor

04/11/2019, 5:35 AM
I agree with you in general like concept. just a lot of nuances that you cannot ignore when you have to implement it to a language with millions lines of code and used in thousands of projects and also remember about future evolution of the language, because small today may cause huge problems tomorrow
In ideal world
There is no ideal world, and Kotlin is not about ideal, it’s to be practical and pragmatic
g

ghedeon

04/11/2019, 6:20 AM
Knowing the stars to shoot for helps to progress in less ideal world. Kotlin could have been just a better java but it already has some distinct functional foundation that might look questionable at the moment because it's not as efficient with the current collections as you'd do it imperatively. But step by step we'll have semantic collections, true immutability, typeclasses and maybe one day we'll ditch the object identity imposed by JVM to make all these things efficient... Boi, do I sound like a Rich Hickey now.. 🙈
g

gildor

04/11/2019, 6:33 AM
not as efficient with the current collections as you’d do it imperatively
What do you mean?
g

ghedeon

04/11/2019, 7:50 AM
There is this beatiful idea in FP that you can express your code as a composition of multiple functions avoiding state and mutability completely, right? The thing is that this theory goes hand in hand with smart collections, advanced VMs and compilers that know how to do lazy/deferred evaluations, reuse objects (hard on JVM because of object identity), etc. The reality is that if you start blindly using all these sweet
partition, window, plus, zip, etc
in kotlin you'll get a significant hit on performance. So, it's kind of there, begging to be used, then you check the implementation, see a lot of copying and most probably end up implement it in old imperative way, with mutable state. Idk, as an exercise, functional Pascal Triangle in kotlin https://pl.kotl.in/HkTog_ht4. That's a lot of allocations there 😒imple_smile: . Supposedly, an advanced low level toolchain will be able to optimize it in a way, that you don't have to be concerned of your operator implementation and just write the code that is as close to formal specification as possible.
g

gildor

04/11/2019, 8:53 AM
Kotlin is not pure functional language and not optimized for this use case obviously (it doesn’t have proper GC, type strcture etc)
And also FP is not about speed, in many cases for real-life performance optimizations or just for some use cases for functional language you need “ugly” imperative hacks
m

Mike

04/11/2019, 10:36 AM
A lot of talk since I was last here. For array literals, kotlin 1.3 introduced then for annotations and intellij now recommends then. IIRC, the intent is to introduce array literal to the whole language but as per comments above, requires a bit more work under the covers, so will be a bit longer. intArray exists for efficiency (as mentioned) but there's no way (unless the compiler had an explicit check) to stop Array<Int>. It's valid code as one is typing the list. Agree it can be confusing. I do believe compiler will always infer IntArray so the only time you'd see Array<Int> would be someone manually applying it.
For FP and concerns of performance because of all the collection creation, consider using asStream. For small lists, it generally doesn't matter, but if it does, asStream can often help. There are initiatives started to have immutable lists that support FP list processing better, but keeping interop obviously makes that much harder.
But I think we all agree jetbrains is doing a great job with Kotlin. Java's not terrible, and it's slowly improving, but anytime I have to write Java, it feels like death by a thousand cuts. No major pain or damage, just little things that keep adding up. I joke that kotlin is Java 30 but right now... Jdk11 added val. Jdk12 switch is finally an expression and can use blocks for cases similar to when and others. So it's coming...
h

Hullaballoonatic

04/11/2019, 7:36 PM
referring to the KEEP post @ghedeon, I think I would prefer
[1,2,3]
for lists. Arrays to be removed from Kotlin.
[1 to 1, 2 to 1]
or
[1:1, 2:1]
for maps and
{1,2,3}
for sets/collections.
@Mike
kotlin 1.3 introduced then for annotations and intellij now recommends then.
is
then
something added in 1.3? I'm confused. Not seeing it in google searches Also, I agree that java is getting a lot nicer to use, but it still lacks any feature that Kotlin doesn't already have (except.... array literals). So maybe it'll get there, but it seems like such a long way off.
m

Mike

04/11/2019, 8:30 PM
Sorry, them. Meaning for array properties, one can use ["value1","value2"] in annotation values rather than arrayOf. Intent is to add this to general array construction AFAIK.
g

gildor

04/11/2019, 11:04 PM
Arrays will never be removed from Kotlin, because it will not be Kotlin anymore, so doesn't make sense to discuss such proposal