It is also horrifying.
It is also horrifying.
C programmers do that with pre-processor. C++ programmers do that with templates and pre-processor. Java programmers do that with annotations.
I see you as a hero and hope for a 1/1000 of your productivity when I peak.
Glad to see you were a Schemer too.
It is also horrifying.
[1]: Switching to another language on the same platform (JVM/JS) lowers the cost considerably, but it is still high.
Personally, I've been using Java for over a decade, and a few years ago I added Clojure to the mix and expect it to serve me for over a decade, as well. I like them both and believe they both qualify as good picks. I'm also adding Kotlin now, too, mostly because its switching cost and added risk are practically zero.
[1]: for reasons other than targeting a new platform
[1]: http://www.ozy.com/rising-stars/taavi-kotka-is-putting-the-e...
I agree with you about languages and targeting 10+ years with it. Stability is worth more than anything to me, out of the box performance also important (this tend to be great for older languages) not to mention the std library quality. For these reasons Java is an excellent choice.
Clojure came to me as a total surprise, since I haven't studied CS and because I was surrounded with Perl/Java engineers for a long time I haven't heard about Lisp till 2011. It changed my approach to software engineering a lot. It is absolutely eye opening, mind blowing and all that jazz.
But, I'm sure someday we'll all discover your one true God... Err... Programming language, like the lispers and smalltalkers, the rubyists and the haskellers, the C++ fanatics and the C faithful...
None of this has anything to do with objective technical superiority of one solution or another, assuming you could make that case definitively. And if one could make that case, technical superiority is only one input into a much more complicated decision-making process.
Again: there is no one true language. There never was and there never will be. Our entire industry, hell, all industries, operate based on tradeoffs, whether those be business, technical, political, or other. Why would programming language selection be any different?
Don't fall for that trap. What matters is that you build solid software that delivers value.
If you mean immutability, it's doesn't make sense to single out Java, since immutability was not significantly valued by any mainstream language until the 2000s (of course Haskell and various MLs existed before, but I'm talking about popular mindshare).
It was only until concurrency/parallelization/multi-core became more important that immutability-by-default gained much traction.
Nowadays, Java feels like the victim of the OO hype: mutable by default, static methods being the only escape hatch from OO, only predefined value types (yes, I know, Java 9). People always say that Go is like pre-generics Java, but it at least doesn't make two of the aforementioned mistakes.
This only works for invariants that constrain the state of a single object. Realistically, invariants that constrain the state of multiple objects are a necessity, and no amount of in-object validation will help you enforce those.
That Lisp is written for the virtual machine originally written for Java.
It is 2015, please let us stop the FUD at least now :)
PS: I love Java and use it for my day job. Just a few days back I was reading about AutoValue and Immutabiltiy and wishing that Java had more power that would make these hacks unnecessary. I am not saying Lisp is the greatest, but Java definitely feels like assembly when you reach the edges and one has to wait for years to get updates.
I don't like Java. I don't like Java at all. (I prefer Clojure or Scala, depending.) But I recognize why it is where it is, and Paul Graham saying Paul Graham things doesn't really change reality.
This framework just makes it a little bit shorter to type as it automatically generates some boilerplate code.
Of course, you cannot get the same guarantees that e.g. Haskell provides. Moreover, unless you return concrete types, that Map<> being returned by a method could be mutable or immutable (it's your guess ;), or hopefully in the documentation).
(And no, Collections.immutableMap doesn't.)
(And then there are problems with the JVM bytecode as well - do you know you can pass 2 into a function expecting a boolean? And sometimes it'll get treated as true and sometimes as false? The JVM is "wonderful" like that.)
But, from an OOP perspective, modelling state changes is natural and desirable. So mutability seems a sensible default.
It's only the recognition of issues that can arise from state changes that has us wanting to lop off the entire feature. A rather strange and drastic "solution" in my view.
As cognitive resources become the bottleneck, it's sensible to invest in tools that decrease cognitive burden. So we're seeing an upswing in popularity with methods and techniques aimed at limiting the amount of unnecessary, incidental complexity generated. "Easier to use" is nice, but "less complex" is imperative right now.
Immutability is one of those techniques that can be leveraged to limit growth of complexity.
What you're saying is perfectly rational, right down to your emphasis on can. I don't take exception to immutability as one tool. My problem is with the notion that it is the only tool and the corollary that mutability is always wrong.
However, totally unconstrained mutability is definitely a shortcoming. The ability to look at a type signature and be immediately able to tell what might or might not change is a big win for maintainability, especially in big projects.
By the way, constraining mutability doesn't require a purely functional language. The ML family (Standard ML, OCaml) allows all expressions to have arbitrary side effects (when evaluated), but all values other than reference cells are immutable.