4 ms·
To me, most of the JVM languages have 2 similar problems with the "defaults": references are optional, rather than mandatory; objects are mutable, rather than
by Roboprog 10y ago
To me, most of the JVM languages have 2 similar problems with the "defaults": references are optional, rather than mandatory; objects are mutable, rather than immutable.
It's past time for a language that makes it's references mandatory unless you explicitly indicate "optional" / "maybe" or whatever. Slapping "Optional<...>" on stuff when "mandatory" isn't enforced seems to just make things worse.
Similarly, classes/objects, methods, modules, packages should be side-effect free, unless there is a flag for mutation or other side effects.
We don't need Java 1.9, we need 2.0, with "breaking" (fixing) changes :-)
Scala shows some good ideas, but it doesn't go far enough. That, and I kind of liked Groovy, too, as I would like to be able to turn on and off strong/static type checking. (default on, but if you ask nicely...)
- nradov 10y agoYou can enforce most of those rules through static analysis and annotations. Of course it won't be as solid as having it in the core language specification but you can achieve most of the same benefits.
- Roboprog 10y agoOh, I know. @Nullable, @NonNull (@Pure/@Function - something like that ???), etc. I'd like to see a bit less clutter in Java, though. I mean, thanks for mentioning it, but Java 1.x has really gotten out of hand in terms of unreadable logorrhea filling the screen for trivial things.
- overgard 10y agoAs much as I think immutable-by-default is a good idea for code correctness, it does have a really big performance penalty since it means a LOT of GC pressure (since you have to make a lot of allocations). Side effect free is great, but, at the moment anyway you can't really do it in real time systems where a GC pause is a huge problem
- tormeh 10y agoA lot of those deallocations should be easy to figure out by a compiler, though. Maybe the JVM can accommodate a delete instruction? If I say list(1,2,3).par.map(x=>x*x) there's a couple of intermediate objects that can immediately be deallocated. The GC shouldn't be bothered with cases that are so obvious.
- Roboprog 10y agoBeside generational GC, I also forgot to mention escape analysis, which sounds like what you are leading up to.
- Roboprog 10y agoAs always, there's a spectrum of problems that require increasingly lower level grunt work to be fast "enough" (or rather, "performant", as The Management likes to say these days) However, to me at least, it makes sense to start at the top and work your way down when bottlenecks arise (systems level software aside): Configuration -> DSL -> scripting -> "FP on VM" -> "(mutable) OOP on VM" -> "traditional 3GL (with bounds checking)" -> C -> assembler -> hardware. Generational GC should take most of the pain out of immutable temp value churn. You can also use libraries and frameworks that "ask nicely" to mutate things, such as behind-the-scenes internal accumulators for filter/map/reduce type operations.