arrayOf unnatural


#1

Hi,

I have been using Kotlin for a while now and really love a lot of aspects coupled with its simplicity that it brings. There also however is one item specifically that feels very out of place for me; and in all honesty; syntactically is worse than Java (and how can that be :slight_smile: )

In concept I have no issue with the arrayOf, primitive array implementation etc - what I do have an issue with is its syntax. It is ESPECIALLY awkward and long winded in attributes - and while everything is condensed in Kotlin, this one expands already crowded areas. I can offer my suggestion but there are so many clever people involved - just know it feels like a pimple on a Ferrari - completely out of place.

One other thing… this is even more of a personal thing, why did you choose fun as the keyword for function definition? I don’t want to start a troll avalanche towards me, but my personal like is with def; and the fun gets everybody I demo to, to make really boring remarks.

Regards,
Gawie


#2

I’m no fan of this either. One thing I do like about it: I don’t need to use any of those alt keys to type arrayOf( on my keyboard.


#3

arrayOf is just a shortcut function. If you don’t like it just use alternative syntax. Create an instance of Array manually. Or write your own shortcut function.


#4

Thats just the thing… I wouldn’t like it to be a function to start off… what is the use of a different function name?

Java: String[] Whatever = {“A”, “B”};
C#: string[] Whatever = {“A”, “B”};
C++: int foo[] = { 10, 20, 30 };

Kotlin: var Whatever = arrayOf(“A”, “B”)

Don’t mind the naming convention - did it to stay consistent.

Java being able to automatically infer that a parameter to an annotation to be an array makes for much more readable code; good example is the cascade parameter in JPA where one in Kotlin has to:
cascade = arrayOf(Cascade.Refresh). This pattern you will find all over the show - Spring, JPA, EJB etc.

Even if Kotlin cannot determine that it is an array - I firmly believe that by writing:

cascade = Cascade.Refresh to be much less intrusive than
cascade = arrayOf(Cascade.Refresh)

I could even agree with

cascade = {Cascade.Refresh}

Like said previously and clearly not understood - is that this (arrayOf) proliferates in code that looks and feel unnatural, all this where the compiler know what is expected… (an array) - and where it doesn’t - how about a symbolic mechanism for delimiting an array.


#5

Hi @Dittert,

I don’t think I follow you? Alt-Keys?

If you are talking about Shift (as in Shift [ to give you { for example) then it is pretty much 6 of one and half a dozen of the other in my honest opinion. On my keyboard pressing
(
and
{
Is same speed. For me { is actually more comfortable - purely subjective I know. My point is simply that there is no clear benefit of ( over { if this is what you were going for.

So why can Kotlin not borrow the same convention. - everything else in Kotlin sees the line width going smaller;
val, var, fun,class, extends (dropped) in favor of a shorter : better default scope (leaving you without), etc etc

All apart from arrayOf()

Gawie


#6

[ == Alt+5
] == Alt+6
{ == Alt+8
} == Alt+9
( == Shift+8
) == Shift+9

German Mac Keyboard; but Windows really isn’t better.

All of them are very inconvenient to type, whereas arrayOf( is a charm.


#7

Please provide a consistent and convenient method to create array, mutable array, list, mutable list and other mutable and immutable containers. But I agree with you that writing arrayOf in annotations is really inconvenient. And AFAIK JetBrains will fix it soon.


#8

Wow @Dittert! Gee wiz - sorry to hear that man. What does the Java and C# and C++ guys do in Germany - live with the pain or do they remap the keyboard?

ON US/UK keyboards it is
Shift [ and Shift ] = { and } … which are quicker than Shift-8/9. I am not too fussed abou the { } as stated previously. There is a nice consistency to it to many other languages though don’t you think?

An array is a very mathematical entity - mathematics is all about symbols - so whatever symbols are chosen is not my quarrel… it is as stated before…

@molchanoviv - Thanks yes. I am not usually too anal retentive but as Kotlin is as new/fresh a language as one can find (and I like it)… I think it is in my best interest to mention the things that urks me soonest. There are a few other things… but I will leave them for another day -


#9

I’m not a java programmer - so my view of Kotlin is as a stand alone language and I find arrayOf very natural, I hope they don’t remove it as hinted above.
If I want to compare Kotlin to another language, the feel to me is like a cross between FSharp (which also uses the fun keyword) and javascript. If it were just another java, I would not be interested.


#10

Who said anything about removing. Kotlin can have 2 or more constructs to get to the same underlying type (heck you can do it now already) - but you cannot implement short and concise symbol based delimiters in your code. Pain in annotations yada yada fish paste.

Here - some more salt in the wounds (shoot me if I got something wrong… I have experience in many of these languages but not all - some were copied):
Visual Basic: Dim chars1 = {"%"c, "&"c, "@"c}
Free Pascal: Points : TPointArray = ((X: 1; Y: 1), (X:1; Y:2), (X:1; Y:1), (X:1; Y:1));
Python: list = [1, 2, 3]
Perl: my @a = (1,2,3);
Ruby: array = [1,2,3]
F#: let array1 = [| 1; 2; 3 |]

Kotlin: array = arrayOf(1,2,3)
or even worse
@RequestMapping(value = “/hello”, method = arrayOf(RequestMethod.GET)) vs
@RequestMapping(value = “/hello”, method = RequestMethod.GET) or
@RequestMapping(value = “/hello”, method = {RequestMethod.GET})

Imagine having an arrayOf within an arrayOf within an arrayOf.

arrayOf(arrayOf(arrayOf( … vs { { {

So no - sorry - I stick to my point and rest my case.

BTW: I have briefly looked at F# way back when. fun in Kotlin and fun in F# are very very different to what I remember. So imho, comparing it seems hardly appropriate. The fun statement is more of a by the way… at this point there is no point in changing it. It is more of a - in retrospect - don’t you think you made a tiny small mistake by choosing it? I feel funny for using it - and had to get used to it. It still doesn’t read well!

fun evictOccupants() -> Is it fun to evict occupants?


#11

For Kotlin { } would be a bad choice since it is used for lambdas. Is the expression { “A” } an array with a single string or is that a lambda returning a string? That could probably be solved with using [ ] instead.

I personally have no trouble with arrayOf myself, but I can tell you as anecdotal evidence on your side that when I did a presentation on Kotlin to my team, they actually did not believe me when I said that was the only way to create arrays and made me switch to the editor to convince them that Kotlin did not support an array literal syntax.


#12

@dalewking

Yes Dale, I am really full of it when it comes to readability and brevity of the code and one of these reasons - as said before why I love Kotlin… everything is abbreviated/defaulted to most regular fit defaults - lines are shrinking horizontally and vertically. Also, as said before, I have no affinity with specific symbols, the JetBrains guys may have a plan of future operators, I merely show the difference in syntax and readability considering good delimiters and a function.

Remember, the arrayOf argument is only half of my issue, the other half is that in many situations Kotlin knows that an array is expected - so who do I need to be explicty - and if you need me to be explicit - please make me quicker at it.

Imagine having to define a long value
val a = longOf(1000)??? Now, as seen above, many may not have an issue with this over
val a = 100L

Me, I would drop Kotlin like a hot potatoe if that was the case. The language is bound by what the JVM can do and its whole intent is to make the environment more developer productive without being slower to interpret/compile than Java. So why make me write sentences to explain myself for the most basic of construct! And Kotlin does that (shorten the code) 99% on most other things… hence again my pimple/ferrari analogy for the arrayOf (I use mapOf less - but let me win this battle first :slight_smile: then we go there)


#13

@Gawie_Kellerman

I personally was very glad when I learned that Kotlin did NOT have any special syntax for arrays and treated them the same as other data structures.

In Kotlin (like in Java) I use a whole bunch of different kinds of lists, sets and maps. Why arrays should be different? ArrayList is used much more often than Array, but you wouldn’t want a special syntax for ArrayList, would you? There is no way they all are provided with their special syntax.

By design arrays should only be used in those rare cases when you need super-performance (tight loop operations or something). That’s why they lack many convenient utility extensions, which makes it impractical to use arrays often.

For almost any task an ArrayList is better than an array (even with boxing). The only inconvenient use case I know is using arrays in annotations (no choice there).

I wanted to express my opinion in order to prove that there is NO unified point of view that array literals are missing in Kotlin. Many celebrate their removal.


#14

@voddan

Voddan…

Why is it that I can derive from ArrayList… but I can not from an Array. It is (in my mind) because array, int, long, etc, are considered “primitive” types with special provisioning from the compiler. So, lets go one step further, if Arrays still are provided for specially and specifically by the compiler; and is final by nature - it means that there are a finite number of compiler specific array types available.
Now can you see how it would be very hard to have special syntax for ArrayList - as there is possibly an infinite number of them; using the the Mutable or Immutable - or neither of the 2 for inheritance! (IN OTHER WORDS: I can create my own hierarchy of list based types from scratch - achieving the same result. I cannot without the help of the compiler do the same for array!)

Array… it is special.

“Primitive” and psuedo primitive types (String, array) have always had a bit of special provisioning… and there still is in most other modern languages and EVEN in Kotlin they still do! Why not for those who want to use it, expand it a little further. Until someday the JVM is rewritten from scratch - my prediction is arrays will stay there until JVM is no more.

Also: You are trying to give opposite opinion to something that you clearly avoid using; and don’t believe in. So if I want to / need to use it, why do you want to penalise me for it - it should be water off a duck’s back for you shouldn’t it?

Last thing… you do know that even though you don’t deal (or want to deal with the “primitive” array)… many of your data structures use it under the covers - for good reason. Drum roll … wait for it… ArrayList is one of them :slight_smile: Can you see how you get the mother in law with the new wife - even though you really don’t like her?

(BTW - saying a data structure is more efficient completely depends on use… I void that conversation at all costs - bring me the proof and the pudding and the sit).


#15

That’s a good explanation on why arrays may be special.

But how often do you use arrays? I mean really instantiate an array with a list of items. Since we are talking from the point of view of usability here (array literals), the question comes to how useful the feature is vs how hard is it to support it.

About my reasons to oppose this feature:

  • Adding new syntax increases the probability of clashing it with some other language feature in the future
  • The feature would add some to the complexity of the parcer, which would result in a slightly less maintainable compiler, which would result in a slowly development of other aspects of Kotlin

#16

If you don’t mind some prefix like A you can get as close as:

fun main(args: Array<String>) {
   val array = A[1,3,5]   
   array.forEach{println(it)}
}

object A {
    operator fun <T> get(vararg ts: T) : Array<out T> = ts 
}

#17

I think this would create a read-only array, wouldn’t it?


#18

yes it would, so there, I fixed it:

object A {
    inline operator fun <reified T> get(vararg ts: T) : Array<T> = arrayOf(*ts) 
}

#19

And this would create two array instances (one for vararg in get() and another for the spread operator) :slight_smile:

But this should work (I didn’t test it):

object A {
    inline operator fun <reified T> get(vararg ts: T) : Array<T> = Array<T>(ts.size) { i -> ts[i] } 
}

#20

There, you fixed it :wink: