Var and val in Java?
blog.joda.org
blog.joda.org
Just do what C# did. Then rinse lather and repeat for Generics, Async/Await, Auto-Properties, and Extension methods. And all the features I don't know about in C# 6 because I've been stuck in the dreary land of Java since before that came out.
It is something that C# does have. It just doesn't allow immutable variables to be implicitly typed, i.e. you can't write something like "const var x = 0;" This lack of let or val in C# is a reminder that "var" was introduced in the language not just to reduce visual clutter, but to support anonymous types, which were in turn introduced to greatly enhance LINQ experience allowing for such nifty feature as "let" clauses in query expressions...
Any of the potential keywords `let`, `val`, `var` could potentially conflict with auto generated code. This would be a breaking change with those generators.
Instead of mixing "you can't override this in a subclass" and "you can't reassign this value" as Java did with final, it clearly separates these concerns:
class Foo {
var qux = 1.23
val bar = 42
final var fiz = "fiz"
final val wow = "wow"
}
(new Foo).qux = 2.34 // valid
(new Foo).bar = 23 // invalid
(new Foo).fiz = "fuz" // valid
(new Foo).wow = "wew" // invalid
class SubFoo extends Foo {
override var qux = 2.34 // valid
override val bar = 23 // valid
override var fiz = "fuz" // invalid
override val wow = "wew" // invalid
}That is NOT at all clear for me. Why is: (new Foo).fiz = "fuz" // valid?
fiz is Final! Why would you be allowed to re-assign a final variable on an instance??
> SecurityPositionCalculationFunction function = new SecurityPositionCalculationFunction();
is exactly why Java needs var/val/whatever decide already (PICK ONE! DON'T RUIN THIS JAVA!).
So I'm not sure why he would pick some piece of code that violates the simple rules the C# team suggests and then burn that strawman with a flash of gasoline.
That said, I'm grateful for joda, and Stephen has written a hell of a lot of (good) java...
I'm therefore slightly in favour of the val/var option over "final var" as the former might encourage the immutable by default approach since it requires less typing. I would guess the view would split pretty much exactly like that between those who do and don't currently use final locals by default. Rich bike-shedding lies ahead :)
Does this make him the best Java coder in the world? No, of course not. But it does make me more inclined to listen when he has opinions on what makes good Java.
Do give him some credit as a good Java developer, is my point.
In this particular case, I actually disagree with him about var/val- I think they're a great step forward. But that said, I value his differing opinion on the matter, and try hard to really see his point as to why he disagrees. Perhaps in time I'll realize he was right, or perhaps in time he'll realize he was wrong. Or maybe it will be like putting final on every variable declaration- my teammate and I will never see eye to eye on it (so much extra noise for so little gain, imho).
There's obviously plenty of boilerplate in Java that can be rather painful to deal with at times but again I don't mind it when declaring variables.
It would also harm the professional users, lowering their productivity as measured in keystrokes/day.
That’s just an attack that doesn’t really contribute.
Java’s concept is more about backwards compatibility, and compatibility with generated code.
Which, btw, is why a lot of the tasks that should commonly be done by a compiler can be done by a compiler in the Java world as well.
Look at what JavaPoet and Lombok can be used for.
The problem with "code generation", especially IDE-based, is when the programmer still has to worry about the resulting complexity. Reading code is harder than writing it, because understanding is what takes the mental work. So a language should seek to preserve intent and human-meaningful structure as its primary goal.
I mean, take this idea of a "pattern" that is manually macro^Wexpanded - In the best case, a later developer reads many lines and immediately recognizes the single concept. But likely they recognize the general pattern and miss a slight difference, because the human brain works by glossing over details.
Scala cut through much of the bullshit, and Clojure is a beautiful piece of work. But the primitive concepts of the underlying platform still remain as a crooked foundation. They seem fine when you're just reacting to them, as all programming requires accepting some layer of abstraction. But eventually you realize you're committed a long series of seemingly reasonable compromises (dependency on the massively complex JVM, community libraries that embrace unnecessary complexity, poor startup time, reliance on a single vendor, and the aforementioned "half-way" abstractions that represent neither your machine nor a simple high level model) and you snap, seeking out better abstractions that can be both relied upon and transparent when needed.
But hey, just because I've been through this doesn't mean you need to take my comment as sarcastically as I've written it. The same sentiment will undoubtedly be earnestly expressed by actual Java programmers still stuck in that tar pit, talking about explicitness, IDE completion, general uniform verbosity, and simplistic conservatism. And I personally quite like the hope in the analogy to the seasoned master starting an apprentice off with a toothbrush to scrub floors, so that their struggle will encourage them to grow.
In the Java world, we've abandoned IDE autocompletion years ago.
Annotation processors are the magic of the day.
You write an annotation into your class, say @ToString, and a tostring method is generated during build — it never shows in the code.
In the same way you can use annotations to do compile time dependency injection resolution, or to do compile time expansion of ORM bindings.
You write just plain Java, add annotations, and everything else is done by the — expandable — compiler.
In general, none of my objections are insurmountable - any specific issue will have an obvious solution, as one would expect in a Turing-complete language. But this is what makes the tar pit so insidious, as you pay the mental overhead of workarounds every time you need to cross the abstraction barrier.
And I disagree with OP's notion that adding var to Java is at the expense of the reader. There is no expense, var improves code readability dramatically.
These sound like arguments Java devs came up with through cognitive dissonance to hold on to the notion that Java's language features are superior to C#'s, they are not.
Could someone please tell me the following: How do I tell the type of x?
var x = callSomeRandomFunction()
We have to go look in callSomeRandomFunction, don't we? Now how easy will it be to do that if you have 15 variables and calls to different functions?How do you know what types are iterable and what types aren't?
What I love about the way explicit definition works is that you are almost guaranteed that in a function you have the type that you are looking for.
If they kill that, they kill one of the greatest parts of Java: the parts that make it not only easy to write but easy to understand.
Hell, I'd have a hard time debugging new code if I saw var x, y, z;
Var means nothing! It has no implicit meaning. It just means whoever wrote the code was too lazy to write out the type names.
If you agree with that or not, just know that the few seconds it would have taken you to type out a full type name will probably save someone debugging your code in the future hours and make it infinity easier for someone who comes along and needs to start working on your code base.
dynamic, on the other hand....<looks shiftily into C#'s direction>
J/K. I Love dynamics.
Why not?
let (a, b, c);
is perfectly valid Rust, it just declares 3 locals a, b and c. fn main() {
let (a, b, c);
a = true;
b = [1];
c = "foobar";
}
https://play.rust-lang.org/?gist=ebedd0cd5b6707410aff&versio...If "..." ISN'T in your control, then...don't use "var".
If you work with other developers that don't understand the above 2, review their code, influence them, convince them. If you work with so many of such people that you cannot convince them of the value of this, go work somewhere else.
You have lost a huge debugging technique, using your eyes, for your lack of patients for writing a variable type.
Something doesn't just stop being a problem because an IDE helps you avoid it.
The explicit nature of Java is what makes it great. What you type is what happens.
And using var doesn't suddenly make things happen randomly, everything is still perfectly well defined, just less verbose. And it is a feature that 99.9 % of the time does what you want, situations in which you want a different type than the inferred one are rare in practice. Actually the only one that I can remember is initializing a variable with some concrete implementation of an interface and desiring the interface type instead of the concrete type. And this one occurs pretty rarely because I think aiming for single assignment is a good thing.
While typing a variable name explicitly is a feature that 100% of the time does what you want.
HashMap<String, AtomicReference<Foo>> fooMap = new HashMap<String, AtomicReference<Foo>>();
What is the disadvantage of using var? var fooMap = new HashMap<String, AtomicReference<Foo>>();
It's less redundant, easier to read, does not clutter the code and has exactly the same information content. And if you really want the variable to be of type Map<,> nobody stops you.It's been in C# for a few versions, and you do find there are places where it always makes sense to use (foreach loops), and there are places where you want to use some judgement. Of course all variables still have a type, it's just not made explicit in the source code, so you can get your IDE to tell you what it is (e.g. by hovering).
If this is widely adopted, I'd say that there will be a lot of problems that stem from it. That's why I say this shouldn't be a feature.
It is the mixture that is all wrong, and it is that mixture that you do not get in Scala or Kotlin.
Why don't we get that mixture in Scala? final is a valid keyword there, too. scala> final var x = "y"
x: String = y
This works, even when it's not used. This would be just a matter of time in Java when nobody will use the `final var`.Java needs easy syntax for immutable, while having inferred mutable is questionable.