listOf, arrayListOf, setOf, etc

I noticed that the functions above, and some others, are included by default in the global scope.

What Scala does is that these types would have to be prefixed explicitly. For example:

val m = Map.empty[String, String]
val s = Set(1, 2, 3, 4)

and so on.

Why didn’t Kotin adapt a similar approach? Something like

val s = Set.of(1, 2, 3)

instead of

val s = setOf(1, 2, 3)

Thanks

It was a design decision that more fits the personality of Kotlin. It is subjective. Kotlin does not use static factories in the stdlib anywhere. and in longer name cases like Delegates.lazy { ... } it looks more silly than just lazy { .. .}

Not sure why matters, Scala is not the role model for Kotlin and there will be different design choices. Which has been a good thing so far.

We have considered such naming style, for example String.build { } vs buildString { }, and found that the former, while it seems more logically “scoped”, is harder to explore via code completion, and the dot in the middle is kinda obstacle in typing process.

So given how frequent these functions are used, we decided to keep them top-level. For less frequent ones, such as Regex.fromLiteral() the “companion-scoped” approach fits ok.

Another consideration is that Java 9 may provide the similar but slightly different functions to instantiate List, Set and Map: those List.of, Set.of and Map.of (JEP 269). This difference in their contract might become very confusing shall we choose the same names.

1 Like

Thanks @ilya.gorbunov, that makes sense.

What is the reason then to make those functions return LinkedHashSet and LinkedHashMap as default instead of HashSet or HashMap, as the former use up more memory? Is there a way to change the default behavior if needed?

Thanks

Long time ago we defaulted all maps and sets to be linked because it was really confusing to loose order in many practical applications.
If you want a hashset for performance/memory reasons you can obtain it with hashSetOf() or toHashSet() functions.
You cannot change the default behavior of setOf in the standard library, but if you really want, you can hide it with your own explicitly imported setOf function (import my.utils.setOf), though I wouldn’t recommend it as a long term solution.