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.
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.
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.
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.
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.
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).
Isn’t the question why const val instead of simply val? Why can’t the compiler automatically figure out what a compile time constant is and what isn’t. This would remove const as a keyword completely.
you can change it with each release of the library. Every program using this library would be able to access this version, even if you change out the library jar for a different version.
If you however have a const val the compiler will inline this string if possible, which would lead to a situation where you compile with lets say version “1.0.0” but you later switch to version “1.1.2”. Your program would still think it is using version “1.0.0” since the string is hard coded at compile time.
I’m aware of that use case but in my experience that it’s an exception and not the rule. It’s also something that could easily be solved through a dedicated annotation like many other things (e.g. @NeverInline). This avoids the keyword issue altogether and makes things less verbose in the nominal case.