I am new to Kotlin, been at it for the past week and was reading about the val/var qualifiers. I have found that val and final (from Java) are functionally equivalent and var would be a variable without having any qualifier in Java.
Isn’t the Java’s final system less verbose, as in, not required for normal variables(resulting in less code)? Couldn’t Kotlin carry forward the same convention? What is the real advantage here?
I’m not sure how you concluded that Java is less verbose. Most of the fields declared in Kotlin code will have implicit types, so they should be on par with modern java code.
The difference between var and val is not about functionality, but about design. There are some additional optimizations for read-only variables in JVM, but in general, it is not about that.
In kotlin “normal” property is val. Highlighting the fact that one should prefer an immutable/read-only state over a mutable. It is a subtle difference, but it greatly affects the design.
Verbosity. I don’t know where did you get an idea that final var is less verbose than val. For me it’s the opposite. I think you would need to elaborate on this.
What @darksnake said. final feels like an additional flag or constraint for the variable. Final variable feels like a special case of a “normal” variable. On the other hand, val and var are on the same level, they are “siblings”. In Java I rarely used final, even if I always designed my code to use immutable variables. This is due to final’s verbosity and because I always felt like I need to have a good reason to mark a variable as final. In Kotlin I code “val-first” and as a result 80-90% of my variables are val.
My opinion is that val and var are actually a little different things, conceptually. Remember that when used on interface/class, val really means: “there is a getter” and var means: “there is a getter and setter”. If we would use final then it would mean something like: “there is no setter” or “remove the setter” - it sounds a little odd to me.
Ahh, I think I understand your point about verbosity - you compare String foo and var foo: String.
Firstly, it seems you think mutable variables are somehow “default” or more common, so you focus on this case. This is exactly what I meant saying that Java gives you a feeling that mutable variables are “normal” ones. As a matter of fact, it is always better to prefer immutable variables - for performance and code readability.
Secondly, I think you mistook what is the real cause of this additional verbosity. This is not really val vs final. In Kotlin we are just more explicit about all kinds of definitions. In Java we need to use special keywords to define a class, enum, etc., but we don’t use any keywords for defining fields and methods - definition is implicit from the syntax. In Kotlin all definitions are explicit, so we always have to use val, var or fun. I guess this is to increase code readability (but yes, this is more verbose).
final is more verbose than val, and there are implications for that. A language that has more verbose version of immutable variables, tend to favor mutability against immutability, ie. Java. A language that has less verbose version of immutable variables, tend to favor immutability against mutability, ie. Rust. A language like Kotlin though, makes equal emphasis on immutability and mutability.
Having a keyword in front of a field is the better choice. In C it didn’t matter, so they started with a type, but as soon as there is type inference, you need some kind of keyword, even in Java.
Having this keyword there by default gives you a more consistent look:
// Java
String foo;
var bar = "xyz";
// Kotlin
var foo: String
var bar = "xyz"
I find the Kotlin way much easier to read.
In almost all cases the name of the variable and whether it is immutable is more important than the actual type, and that’s what you always see first in Kotlin.