4 ms·
I really like that Kotlin, Groovy and Scala keep advancing the JVM ecosystem. Java in my opinion should evolve by keeping the original approach (a better C++)
by fithisux 4y ago
I really like that Kotlin, Groovy and Scala keep advancing the JVM ecosystem.
Java in my opinion should evolve by keeping the original approach (a better C++) and leave programming language experimentation to the big three.
- qsort 4y agoHonestly IMO Java is in a very good spot right now. Mature technology, maybe a bit "unsexy", but rock-solid and future-proof. There are still pain points, but the language is leaps and bounds better than the Java 1.6 days.
- hurril 4y agoYet, Java-codebases look the same now as they did then. The program structure is still "externalized" to a container because of a lack of abstractions. It's still exactly the same.
- kaba0 4y agoI really don’t get what you mean. Java is not the most expressive language, but it is eons ahead of the expressivity of C or Go and yet I don’t believe it would be fair to claim that those languages also externalize their structure?
- hurril 4y agoWhat I mean is that a Java program is almost always sitting in a Spring container with most important stuff happening as "decorated magic"; this has been the case since even before 1.6. To say that it is somehow better now than it was, is therefore not worth much. Sure, I'm sure you guys'll put a map or a stream in there somewhere but it's ... still the same thing. There's no real evolution at all. The springification is what I mean by it being externalized and you generally don't see that in C, no. The pre-processor might be sort of the same thing but you generally don't bootstrap the entire thing using it.
- kaba0 4y agoWell, Spring is mainly for backend systems that have a very specific functionality that is best handled by a generic solution. In my experience this is in line with how most other web frameworks operate. But this is absolutely domain-specific, Java the language is indifferent to exposing a library that will handle incoming request and dispatch them based on some library logic, or creating a “traditional” program for the litany of other domains where java is used st.
- hurril 4y agoSpring isn't a web framework, it's gaffer tape for a language that just isn't good enough without it; that's why it's [spring] still around and its use is so prevalent. It's not at all mainly for very specific functionality in the sense that your post sort of implies [for web, and databasy things I presume]; in fact: it's just for wiring and for applying/ attaching things to "abstractions". As in: please decorate these sets of things with this behaviour. If you'd chosen languages that permit abstractions in a real and usable sense, then you would not need this. In fact: with _one_ exception, I've never had a container in any Haskell, Scala or F# project ever. Do you think we ever needed one? And this is my point: those other languages have seen _tons_ of development in the "abstraction arena" with (internal) DSL:s and super powerful frameworks for making powerful DSL:s. Java has had none of this because these concerns har all (poorly) handled at the container level. The tacked on "functional stuff" is for sure cool coming from a Java backround, but they're pretty much useless.
- cityofdelusion 4y agoSpot-on analysis. I work on a team (that strongly prefers using Kotlin) in the CI-CD world. Despite web dev only being a minor part of our work, Spring just attaches itself to everything like a disease. I feel like it has gotten to the point where most Java developers that interview know Spring and not Java. Dependencies themselves also become attached to Spring (our example: bringing in Kafka -- super painful without Spring and hardly any examples or docs.) This "containerizing" is very unique to Java -- I've never seen anything like it in the other various languages I've used. I won't even mention the total disaster of JavaEE containers.
- pharmakom 4y agoIt’s still heavily object orientated. My preferred approach to applications these days is immutable core / imperative shell and Java makes that awkward.
- elric 4y agoCan you elaborate on the immutable core/imperative shell paradigm? Or maybe link me to some references? Sounds interesting! Thx :-)
- pharmakom 4y agoThere is a talk by that name that popularised it. https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell https://www.destroyallsoftware.com/screencasts/catalog/funct... Basically you have business domain objects that have value semantics and are immutable. You have functions that manipulate these objects. This makes the business domain unit-testable. Then on the edge of the application you have imperative code that manipulates databases, serves requests, etc. It’s like Haskell but as a design pattern rather than a language. In the JVM world, Scala and Clojure communities are adopting this approach.
- dgb23 4y agoThe sibling comment explains it well on a conceptual basis. I can maybe add a few notes since I'm in the process of gradually moving code to this architecture (for the lack of a better word). It is essentially straight forward to do. You look at a bunch of code in a module and determine which parts do these kinds of things: - data integrity, validation - parsing, transformation between formats - domain logic, decision making - algorithms and data structures This is your functional core. Note it doesn't matter too much if you have local mutations as long as they don't leak out. What you want to achieve is to have an interface where you can ask questions and you get the same answer for a particular question. This is certainly more productive if your language affords you with functional constructs, but its not strictly necessary to get the benefits. You code these parts in a way that they are data in, data out essentially. This leads to super easy and reliable unit/example tests and generative tests. And this part becomes very simple and easy to reason about. Secondly you have the part of your code that actually _does_ stuff, affecting your environment in some way. - basically any kind of I/O - cross cutting concerns between other side effecting modules and services (think DI and such) - error handling, error reporting and logging - caching, throttling, filtering etc. That's your imperative shell (I just call them modules). This part you write in an imperative/procedural style and you call the functional core parts from here, never the other way around. You coordinate effects so to speak. It is clear that you test these with integration tests, where you need to setup specific program state (or use mocks, but I try to avoid that) in order to find different code paths. This is harder to test properly but at the same time you also get to see everything that actually happens in condensed form. The degree to which you extract "pure" logic from your imperative shell is actually quite flexible. You can go as far as defining purely functional FSMs to extract much of the control for example. I think it really depends on code size and complexity as well as performance implications. The cool thing is that you can be quite pragmatic and iterative about it.
- mcv 4y agoI don't know. To me it feels like Java is a bit of a patchwork, with too many features added on top of it that weren't accounted for in the original design of Java. Generics are probably the oldest example, but there are plenty of others.
- fithisux 4y agoI agree. It needs more standardized tooling and libraries. But as a language it does not need anything more right now. Not even pattern matching. But some small touches here and there could be good.
- cies 4y agoGroovy and Scala have nowhere near the potential of Kotlin. I think Kotlin actually has the potential to dethrone Java on the JVM, it is that good. Kotlin is not much different from Java, conceptually. It is basically Java 2.0. Where Goovy does away with compile time typing, and Scala bolts a Haskell onto Java; Kotlin is "just a better Java".
- jillesvangurp 4y agoProbably a good way to characterize Kotlin. Scala has a lot of interesting features but also a lot of complexity. And not all of those features are necessarily very good. Arguably, Kotlin was born out of frustration with that as Jetbrains at the time rejected the notion of using Scala internally and instead started the long process of developing their own language. It was mainly intended to be a better Java but also to avoid some of the complexity of Scala. Groovy's lack of compile time safety is like throwing out the baby with the bathwater. It's just not worth it for me. Kotlin gets you most of the language features but without doing that.
- aurea 4y agoDo you have any good articles on what would make Kotlin better than Scala? I work only in Scala and have never touched Kotlin.
- jillesvangurp 4y agoNot really. I likewise don't use a lot of Scala. Probably better to think in terms of how the languages are different rather than better. Here's a good overview of differences: https://www.baeldung.com/kotlin/kotlin-vs-scala https://www.baeldung.com/kotlin/kotlin-vs-scala
- arunix 4y agoGroovy has an optional compile time checking feature on a per-class basis via an annotation (this has been around for a long time) https://docs.groovy-lang.org/latest/html/api/groovy/transform/CompileStatic.html https://docs.groovy-lang.org/latest/html/api/groovy/transfor... https://livebook.manning.com/book/groovy-in-action-second-edition/chapter-10/ https://livebook.manning.com/book/groovy-in-action-second-ed...
- dunefox 4y agoFlix will blow your mind then: https://flix.dev/ https://flix.dev/
- MrBuddyCasino 4y agoNever heard of Flix, very interesting!
- JohnL4 4y agoThrew me down this rabbit hole: https://en.wikipedia.org/wiki/Datalog https://en.wikipedia.org/wiki/Datalog Looks like Flix is in a galaxy of languages implementing Datalog, a variant of (or somehow related to) Prolog. I guess Flix is Turing-complete while Datalog is not?
- dunefox 4y ago> I guess Flix is Turing-complete while Datalog is not? Flix is a regular programming language, and supports datalog as a DSL basically, supported by the compiler and type system.