I have seen a lot of comments mentioning Swift, and most of them are ill-informed or outright wrong. So I’d like to offer my perspective as a primarily Swift developer looking at this feature for Scala.
TL;DR; I don’t think collection literals are right for today’s Scala but I also don’t think they are as catastrophic for the language as some people have suggested.
Collection literals work really, really well in Swift. In fact, the support for literals in general (e.g., including numbers) is one of the things Swift really nailed down compared to e.g. C++, Rust, and yes to some extent Scala.
You can look at the following for an example. Regardless of how it will make you feel, my point is that no experienced Swift developer would find surprising, confusing, or hard to read.
Some standard-looking Swift code
/// Returns a table mapping each element in `xs` to its number of occurrences.
func histogram<C: Collection>(_ xs: C) -> [C.Element: Int] {
var result: [C.Element: Int] = [:]
for x in xs { result[x, default: 0] += 1 }
return result
}
let h0: [Int8: Int] = histogram([1, 2, 1, 1, 2])
.merging([3: 10, 4: 2]) { (lhs, _) in lhs }
print(h0) // Prints [3: 10, 4: 2, 1: 3, 2: 2]
Note the “literal syntax” in several places:
[1, 2, 1, 1, 2]
is an array literal
[3: 10, 4: 2]
is a map literal
[:]
is an empty map literal
Also note that the type of the array in the call to histogram
has been inferred from context (to Array<Int8>
), driving the inference of the number literals in the sequence 1, 2, 1, 1, 2
, which otherwise would have defaulted to Int
.
Swift defaults [x, y]
to Array<T>
, which is like a mutable ArrayBuffer
and it defaults [a: x, b: y]
to Dictionary<T, U>
, which is like a mutable HashMap
. If you’re alarmed by the mention of “mutable”, keep in mind that Swift has a very different approach to mutation that does not come with the usual foot guns.
Swift has an empty map literal that is distinct from an empty array literal (i.e., [:]
vs []
). In the presence of an expected type, Swift will look for an instance of the corresponding ExpressibleByXXXLiteral
type class and so one can customize this system as will. Swift does not infer the type of an empty collection literal. But the language has a very different relationship to generics and erasure so this design choice makes a lot of sense there.
Now, perhaps surprisingly, as a Swift developer who loves collection literals in Swift, I don’t think they are a good fit for Scala. At least, I think they can no longer be retrofit in the language without causing harm.
My two main arguments are:
- In a language with pervasive use of variadic arguments (which confuses no experienced Scala developers regardless of how they make me feel),
Array(1, 2, 3)
does not read worse than [1, 2, 3]
.
- Looking at this thread and the one before, I bet that collection literals will be seen as a needless addition by at least a good third of Scala’s community and that will create different schools of style.
I’ll also add that I don’t find the use cases presented so far to be particularly compelling. Note that Swift will struggle to infer the type of @odersky’s example without annotations, despite its strong support for collection literals. That is because typing JSON requires a schema, not a single concise annotation on a val
.
Also, JSON is not code and the product of a world where everything is dynamically typed. I do not believe it is a good benchmark for evaluating statically typed language. In fact, I am convinced my life would be easier if JSON had type annotations so that I would not spend precious hours guessing the format of my CI’s configuration files. Commenting on one of the proposal’s feature, I actively dislike that val x = []
can type check.
More generally, I think that the importance of writing embedded DSLs is often overblown. An embedded DSL must embed in its host language, otherwise it’s just a DSL (which is fine!) If one must support syntax that is too alien for the host, then one should write a compiler. It’s not that hard … 
One interesting argument was the lowering of Scala’s “differentness” for folks coming from Python, JavaScript, etc. but:
- I think no one is surprised that there’s a cost to moving from one language to the next, which includes learning new syntax.
- I doubt that people coming from Python to Scala will leave because they must write
List(1, 2, 3)
. The language has one zillion other reasons to stay (or leave) if that’s the background that you have.
- As many have pointed out and @sjrd has eloquently summarized, adding choice to the language can sometimes make it harder to pick, not simpler.
That being said I do not think the feature will be nearly as disruptive as braceless syntax because, in general, it only concerns tiny spots in the code. I personally don’t write that many collection literals in standard code so I can easily believe that the feature will be most often used for quick scripts and configuration files, which I guess are the relevant use cases driving the proposal. So at the end of the day, if you don’t like it, you can simply ignore it.
Finally, unlike other syntax changes/addition, this one is very easy to recognize/transform. So I bet tooling can adapt very quickly. I have no doubt that corporate code has countless tool-enforced guidelines that can effectively ban collection literals from a codebase.