And the newbie asks, "Why `const val` instead of just `const`?"


#1

Sorry if it’s been asked before, but this is the first (admittedly nit-picky) “Huh?” question that jumped out at me as I’ve been perusing the Kotlin reference. It seems to me that the val keyword in the const val declaration is completely superfluous, since a compile-time constant is by definition just that much more immutable.

Can someone clarify the rationale behind this salty bit of syntax? Thanks.


#2

In const val, const is a soft keyword, meaning that it has special meaning only in that context, and can be used as an identifier in other contexts. If we supported const without val, we’d need to recognize const as a regular keyword. In general, we want to avoid adding unnecessary keywords to the language, and in this case we considered const val to be a good compromise.


#3

I thought at first the same, "Why not just const"… And then after a while it came to me , why not just lateinit, or for functions why not just tailrec and so on. It just makes more sense writing val after const.


#4

What would be the drawback to add “const” to the list of keywords? Using it as “soft” won’t provide much benefits (nobody would use it elsewhere anyways). I propose to just use const rather than const val to reduce boilerplate even further.


#5

At this point it would be a breaking change for not so big impact.


#6

it could be optional. So that you can still use const val (not to break backwards compatibility) but const alone as well.


#7

In order to make const alone possible, it would need to be treated as a keyword by the Kotlin compiler. Keywords cannot be used as identifiers. Currently const can be used as an identifier (variable names etc) .

The change that you want breaks existing code. It is not compatible.


#8

Well, being able to use const as an identifier is quite useless. Please tell me who would do that.

I see the point regarding backwards compatibility anyways, although that’d be mostly a formal thing.


#9

It’s about precedent, not this specific issue. Please tell me who would use lateinit as an identifier, or public, or whatever. The key is maintaining separation between a context-specific modifier and a keyword. By adhering to the practice of reducing keywords, you save yourself from future changes too when you want to add a new modifier. If they had thought “make it a keyword because who would do that” then they wouldn’t have been able to add the actual/expect modifiers to the language easily.

As for “who would do that”, I do, in code generators. I only escape where I have to so I keep a running list of keywords in my code generator (as does kotlinpoet and others).