Here are three reasons why this proposal makes me uneasy. (None is decisive, but for me they all add up.)
Length
listOf()
→ emptyList()
is a 37½% increase in length.
But ""
→ String.empty
is a 600% increase!
Conciseness isn’t the most important factor in any language, of course; but it’s one of the major factors in making Kotlin such a pleasure to read and write, and a named constant reduces that.
Familiarity
""
is used in just about every programming language that has strings. String.empty
is not; in fact, I don’t think I know any that do.
And that unfamiliarity leads to confusion. Most JVM developers will know that string constants get inlined. But most won’t know how any String.empty
is implemented. It is opaque. Does it return the same constant each time? (If so, what’s the point of it?) Or can it create new ones in some or all cases (e.g. a thread-local instance)? Does it do any processing? (After all, being Kotlin, it could call an arbitrarily-complex getter method.)
Consistency
The more alternatives there are, the more likely it is that the code I write will be different from the code you write. That makes it (very slightly) harder for us to read each other’s code; and to teach the language because there are more alternatives to cover; and to recognise similarities in different-looking code; and generally to share and maintain code.
As a counter-example, Perl has a deliberate policy of providing multiple approaches; in fact, its motto is ‘There’s More Than One Way To Do It!’. That arguably led to everyone writing in their own personal dialect, giving it a reputation as an impenetrable Write-Only Language and maybe even contributing to its waning popularity as compared with e.g. Python. I don’t want to see Kotlin taking even tiny steps down that road.
One of the arguments for a named constant is that hard-coded literals are bad. And in general, they are (or at least, are a code smell). But for me, the empty string is a special case; it’s so ubiquitous, so widely used and understood, and so obvious, that its intent is perfectly clear, and the risk of confusion or typos negligible. And due to string constant inlining, it has no performance issues; nor does it need localising or translating or white-labelling.
Of course, this is a very small proposed change, and not worth getting heated up over. (Maybe that’s why we’re bike-shedding here!) But I think it illustrates the need for a Minus 100 Points approach to language design. Kotlin’s designers haven’t been afraid to add major features where their benefits outweigh the added complexity. But they’ve also shown taste in knowing what to leave out, so that the language’s ‘complexity budget’ is well-spent. And for me, the benefits of this particular proposal seem nebulous and far from outweighing the points above.