[HN Gopher] A categorized list of all Java and JVM features sinc...
___________________________________________________________________
A categorized list of all Java and JVM features since JDK 8 to 16
Author : pjmlp
Score : 255 points
Date : 2021-04-01 16:04 UTC (6 hours ago)
(HTM) web link (advancedweb.hu)
(TXT) w3m dump (advancedweb.hu)
| zodiakzz wrote:
| Is it in the realm of possibilities that Java will someday have
| runtime generics support (instead of type erasure)? It's the most
| frustrating aspect of the language because you can't use basic
| Java features like method overloading with them. Also, I don't
| understand how people use the `Optional <ErasedType>`..? Is there
| a way to use method overloading with it? `ErasedType` could be
| _anything_ at runtime, doesn't sound fun. Besides all references
| types are already nullable/(optional)... so what's the point?
| laurent92 wrote:
| I wish we just had non-nullable types...
| kaba0 wrote:
| With checker framework, you can basically have it (and much
| much more, I believe no other language comes close to that
| level of static analysis). It is annotation-based and not a
| fancy keyword, but it is there.
| nesarkvechnep wrote:
| Haskell, OCaml?
| kaba0 wrote:
| Higher kinded types do make some features obsolete, but
| checker has MapKey checker, Lock and Index checker, and
| while locks may not be needed that often with everything
| is immutable by default mode, concurrency is hard and
| that alone is not always enough. While index errors are
| not as frequent in Haskell, due to (Head:Tail), but if
| you do use Array, you can't express indexing safely
| without dependent types.
|
| I'm not saying that it is better in every aspect than
| haskell (not too familiar with ocaml), but java is an
| easy and extremely popular language. And thus it has
| really really great tooling, and with annotations it is
| really extensible.
|
| And if static analysis is not enough, there is also JML.
|
| Also, checker taps more into intersection types, which is
| not really expressible in Haskell, but I'm yet again not
| knowledgeable enough on this latter, correct me if I'm
| wrong.
| mc13 wrote:
| I believe refied generics are being worked as part of project
| Valhalla. Here's a related JEP which I could find.
|
| http://openjdk.java.net/jeps/218
| gizmo385 wrote:
| From that JEP: "It is not a goal of this effort to produce
| fully reified generics."
| mopierotti wrote:
| > Also, I don't understand how people use the `Optional
| <ErasedType>`..?
|
| I may be misunderstanding your question, but in general you
| wouldn't be doing anything type-specific with an Optional's
| value unless you were in a part of your code that knows the
| type at compile time. For example, a data structure might
| return an Optional<T> from a get() method, but all it's doing
| is returning the T or an empty.
|
| > Besides all references types are already
| nullable/(optional)... so what's the point?
|
| 1. It's nice to explicitly say if a value might not exist than
| to be unsure if a null object is meaningful.
|
| 2. It can force consumers of an Optional to deal with the empty
| case (versus forgetting to null check)
|
| 3. Null might mean something like "this value was accidentally
| never initialized" versus "I am explicitly indicating an empty
| value"
|
| 4. It can give better developer ergonomics with convenience
| methods or monadic style (such as with Scala's Option type,
| where you could .map() on an Option, or merge multiple Options
| together)
| The_rationalist wrote:
| Kotlin supports reified generics (through extension methods)
|
| Java is getting reified generics and more importantly generic
| specialization which is critical for performance
| https://www.reddit.com/r/java/comments/m2dfb5/parametric_jvm...
| pcl wrote:
| Kotlin's reified generics are pretty limited -- they only
| work in inlinable situations, as there is no JVM support.
|
| I assume that Kotlin will quickly add proper reified generics
| support as soon as the JVM allows.
|
| (Your link above is about reified generics in the JVM, not
| just the Java language. Which is great news.)
| kaba0 wrote:
| When exactly would you benefit from overloading based on a
| generic type? How come it is never brought up with Haskell for
| example, or the other majority of languages that employ type
| erasure?
| eweise wrote:
| Haskell has higher kinded types.
| suyash wrote:
| nice to see everything in one place with short example code.
| Specially helpful for those still using Java 8 and looking to
| upgrade, Java 17 will be a LTS so that will be a good opportunity
| to upgrade.
| bluejekyll wrote:
| One of the primary features I'm holding out hope for eventually
| making it into the language is ValueTypes:
| http://cr.openjdk.java.net/~jrose/values/values-0.html and the
| current Valhalla Project:
| https://wiki.openjdk.java.net/display/valhalla/Main
|
| The simplest example of why this would be valuable (edit: this
| was not an intentional pun), the Optional type could become stack
| based, such that you could ensure that the variable referring to
| the Optional type is never null. This would help reduce a common
| class of bugs in Java code stemming from NPE's.
| nlitened wrote:
| I am not sure I understand, why would you want Optional type to
| never be null? Isn't it being null sometimes -- the whole
| point?
| chrisseaton wrote:
| > Isn't it being null sometimes -- the whole point?
|
| No you have it backwards - the whole point is that Optional
| is _never_ null. You use empty instead.
| wffurr wrote:
| There's a big difference between the Optional _containing_
| null (useful) and the Optional itself _being_ null (but why).
| wtetzner wrote:
| Say you have: public void
| doSomething(Optional<String> foo) { ... }
|
| You want `foo` to be `Optional.empty()` or `Optional.of("some
| string")`. The way things currently work, `foo` could _also_
| be `null`.
| nitrogen wrote:
| Kotlin's approach of making null act kind of like Optional
| is pretty nice, but I wish there was a strict option for
| interacting with Java types -- by default, all Java-native
| types (type names ending with _!_ ) can be null and are not
| null checked at compile time.
| savanu wrote:
| How does making Optionals allocated on the stack (value
| types) prevent this?
|
| Or rather why do you need value types to accomplish this?
| bluejekyll wrote:
| Perhaps this example will make it more obvious:
| boolean truthy = false; truthy = null; //
| compilation failure, type mismatch
|
| vs. the Boolean type Boolean truthy =
| new Boolean(false); truthy = null; // compiles
| just fine
|
| The reason Boolean (and other boxed primitive types)
| exist is because it is an Object (a reference type) and
| that allows them to be used in things like collections
| that expect Objects and not primitive types.
|
| Looking at https://openjdk.java.net/jeps/401 it's not
| totally clear to me at the moment how you can use
| ValueTypes (primitive keyword) in Collections. Might be
| that you'll need to take a reference to them with
| Type.ref (but I need to read 401 in more detail to
| understand that).
|
| Hope that helps.
| pgwhalen wrote:
| > Looking at https://openjdk.java.net/jeps/401 it's not
| totally clear to me at the moment how you can use
| ValueTypes (primitive keyword) in Collections.
|
| JEP 401 won't cover it quite yet, note this from the "Non
| Goals" section:
|
| > An important followup effort, not covered by these
| JEPs, will enhance the JVM to specialize generic classes
| and bytecode for different primitive value type layouts.
|
| It wasn't until recently that I understood for myself
| just how large the surface area of the "value types"
| problem is - it will be delivered incrementally. JEP 401
| and 402 are the first steps (if I were to guess they will
| show up as previews soon? maybe JDK 17 or 18?), but there
| is more to come.
| savanu wrote:
| So you are really looking for compiler checks for null?
| Kind of like kotlin?
|
| var truthy = null; // Compile fails
|
| var nullable? = null; // Compile passes
|
| You don't need value types for this?
| bluejekyll wrote:
| That's not exactly the same thing... It can also (again I
| don't know if this is part of the jep or not) be used to
| perform stack based destructors (finalize) and then Java
| could implement RAII. Reading the jep it discusses
| perhaps rejecting finalize as function on primitive
| objects, so this might not be in scope.
|
| Additionally, the type is also lighter weight than an
| Object and should be stack allocated, so there are memory
| advantages to not having to use boxed types as well.
| meddlepal wrote:
| You don't really need to hold out hope for this... it is coming
| and soon. It's been in active progress for years now (its a
| huge undertaking).
| bluejekyll wrote:
| Is there an update somewhere that I've missed? I keep looking
| for updates and haven't seen them.
|
| (And yes, I know it's a huge effort, I was definitely not
| trying to say that it should be an easy change to get into
| the language)
| craigacp wrote:
| There are JEPs out for parts of it now - Primitive Objects
| (which is the new name for value types)
| https://openjdk.java.net/jeps/401 and Unify the basic
| primitives with objects https://openjdk.java.net/jeps/402
| Yeroc wrote:
| I haven't read up on the details of these but this is a
| huge step in the right direction if pulled off properly.
| The dichotomy between primitive and non-primitive types
| in Java is a real rough spot. I'd have to see how they
| deal with null values though because the introduction of
| auto-boxing certainly introduced a new area for
| NullPointerExceptions to catch the unwary off-guard.
| craigacp wrote:
| There is extensive discussion of that topic in the
| valhalla-dev and valhalla-spec-experts mailing lists, but
| I think the details are still being worked out.
| halfmatthalfcat wrote:
| Or use Scala :)
| chrisseaton wrote:
| Does Scala have value types?
| halfmatthalfcat wrote:
| https://docs.scala-lang.org/sips/value-classes.html
| chrisseaton wrote:
| Ah right - that's not really what we're talking about
| here, even though they have the same name.
| halfmatthalfcat wrote:
| "Codes like a class, works like an int!" - Taken from the
| top of the page.
|
| This is exactly what Value Classes are in Scala. You
| supply an underlying value which is then interpreted as
| the value itself, not a reference.
| bcrosby95 wrote:
| > must have exactly one parameter,
|
| Huge limitation. Not anywhere near the same thing.
| chrisseaton wrote:
| What you're talking about is just wrapping a single
| value. It's a type-system thing.
|
| What we're talking about are wrapping compound values.
| It's a VM implementation thing.
|
| They're not really comparable.
| kaba0 wrote:
| Which doesn't have value types because it should be
| implemented in the JVM?
| halfmatthalfcat wrote:
| It has Value Classes which are essentially the same thing.
| They transpile down into the value itself but wrap the
| value in extra functionality if you so choose.
| kaba0 wrote:
| They can only wrap a single primitive type - it's a nice
| feature but nothing extraordinary. When Java implements
| primitive types, Scala will probably use this same
| construct. But the change have to come from the runtime
| level.
| layer8 wrote:
| Even more useful will be a Mandatory<T> type. Maybe with "T!"
| and implicit conversion to T as syntactic sugar.
|
| Edit: Unfortunately it would have the drawback of
| nonoverloadability due to type erasure.
| ballmerspeak wrote:
| As someone who began programming in undergrad, Java was the
| university's language of choice for the "introduction to
| programming" course. My first internship was in Java SE 6 and
| part of the big debate for that summer was when to move to 7.
|
| I haven't used it since but I'm glad to see it's gotten the more
| modern language features that make writing and reading code much
| easier. Without this list, I probably would never have learned
| this so thanks
| foolinaround wrote:
| very beautifully put together.
|
| In fact, they should start with Java 5!
|
| Even in 2021, I see code bases (and devs) who dont know/use
| generics!
| icedchai wrote:
| You'd think they'd get tired of all those casts everywhere.
| jerven wrote:
| Well that is why they write GO right ;)
| dehrmann wrote:
| I'm torn over this because a lot of the features are quality of
| life improvements, but is it too fast?
| jmartrican wrote:
| Not fast enough
| jacques_chester wrote:
| > _but is it too fast?_
|
| It is not.
| tasogare wrote:
| A lot of things are coming straight from C#, so it's battle-
| tested there before inclusion I guess.
| cbm-vic-20 wrote:
| I read an article that said that this is intentional- they
| wait until other languages shake out features, and take it
| slow so they get it right.
| perrylaj wrote:
| As someone unfamiliar with C# but interested in how languages
| impact each-other, could you provide some examples? I know C#
| was heavily inspired (perhaps not a strong enough word) by
| Java, but not as familiar with the opposite.
|
| Java does seem to absorb from tried and tested ideas. There
| are a few major features I can think of that have largely
| come from or been inspired by popular and mature 3rd party
| libraries (time, reactive streams and various collection apis
| come to mind).
| jerven wrote:
| C# and Java are kind of in the same space, they tend to
| pick up the same kind of features. But not always in the
| same way e.g. Records are different between the two
| languages. As is the path to Async.
|
| Java benefits from more experimentation in the JVM and
| bigger variety in implementers.
|
| I need to find the funny slide deck by Brian Goetz (java
| language architect at Oracle) where in slide one (what
| industry thinks he does) he shows his job is to copy from
| C# and in slide two he shows what academia thinks he does,
| copy from scala ;)
|
| It is not this presentation,
| https://www.infoq.com/presentations/java-futures-2019/ but
| it is close in content.
| tasogare wrote:
| In the list provided in the article: record syntax, switch
| expressions and var.
|
| And by the way for the downvoters: there wasn't any snark,
| C# itself being at first a copy-pasta from Java, and now
| taking heavy inspiration from F#. That kind of features
| transfer in-between languages is a good thing.
| kaba0 wrote:
| Java employs the "last mover advantage" strategy. They wait
| a bit for other mainstream-ish languages to be a testbed
| for a new feature, and if it proves worthwhile, they try to
| incorporate it into the language. But a new feature is a
| huge responsibility, since it will have to be maintained
| "forever".
|
| C# on the other hand is quite brave and quick to implement
| everything under the Sun, sort of similarly to c++ - which
| sooner or later will create a really bloated language (imo,
| both are already quite complicated). And in backward
| compatibility, Java definitely wins the cake.
| rakoo wrote:
| Java 8 was in 2014. Go was barely 2 years old. Many of the
| features presented here were considered common in other
| languages at the time, so if anything Java is late to the
| party.
| offbynull wrote:
| They broke backwards compatibility when they moved from 8 to 9.
| If this is all we got out of it after all this time, IMO it
| wasn't worth the change.
| Pet_Ant wrote:
| What backward compatibility did they break except for internal
| com.sun packages that weren't part of the JDK to begin with but
| only Sun's implementation?
| kaba0 wrote:
| They broke some dependencies that depended on JVM internals,
| that was never promised to not change (how could they implement
| anything otherwise?). They implemented a strong encapsulation
| by default so that in the future, such a step won't be
| necessary ever.
| crudbug wrote:
| Waiting for project loom [1]
|
| [1] https://openjdk.java.net/projects/loom/
| cpleppert wrote:
| Worth keeping in mind that the implementation they have chosen
| of stack copying from the heap has a larger performance
| overhead than something like Go which was designed around green
| threads/fibers/virtual threads/ etc. from the start.
|
| If you can keep your stack size very low in each task then this
| probably won't be noticeable if you are doing lots of IO which
| can trigger wakeups. More of a replacement for an async/await
| state machine for handling a request than something like a
| goroutine you could use for everything.
|
| I have a feeling lots of existing Java libraries and frameworks
| won't work well with it. Will be interesting to see how it
| plays out.
| kaba0 wrote:
| The technical details are way out of my league, but I
| remember reading that stack copying can be made really cheap
| somehow? Perhaps due to the JVM having more abstraction below
| a virtual thread than Go?
| aardvark179 wrote:
| Many virtual threads won't have large stacks, and many
| others will not substantially grow or shrink their stacks
| between yields. You only need to copy stack frames from the
| heap as they are needed (so as the stack unwinds) and you
| only need to copy new stack frames to the heap when a
| thread yields. With a few other clever tricks this can
| really reduce the data that has to be copied.
|
| We can do these tricks because we know lots of properties
| of the Java stack, and they give a different set of trade
| offs to Go's approach.
| iso1631 wrote:
| To me, Loom will always be the latest masterpiece of fantasy
| storytelling from Lucasfilm's(tm) Brian Moriarty(tm)
| jacques_chester wrote:
| I am unreasonably excited by Loom, for two reasons:
|
| 1. I cannot wrap my head around library-based reactive systems.
| I have tried and tried and continue to try. But they're like
| some of the original Go4 design patterns: they exist to solve
| the _language_ , not the _problem_. Loom 's promise to make
| steam-powered linear code behave _mostly_ like a fully-dressed
| reactive library system is extremely welcome.
|
| 2. Structured concurrency. Among the entries on the thick
| tablet of hatreds of Golang that I carry upon my heart, mystery
| action at a distance due to go(to) routines appears
| infrequently but painfully. Like so many Go features they
| conspire against composability and testability. Structured
| concurrency looks like an escape from the madness. Please let
| it be true.
| gher-shyu3i wrote:
| What do you mean by structured concurrency? Do you mean
| hierarchy management?
| The_rationalist wrote:
| What you're waiting for is already available with Kotlin
| coroutines (which has a very clean API btw) And no reactive
| streams still are useful for processing collection streams
| asynchronously and here again kotlin solve it all
| https://kotlinlang.org/docs/flow.html
| jacques_chester wrote:
| I like Kotlin coroutines and I've used them, but they (this
| argument is controversial) have a function colouring
| problem. As the JVM adds virtual threads I expect that a
| rebasing of Kotlin's coroutines will remove that objection.
|
| Plus, sometimes, I want to use Java.
| ta988 wrote:
| Also debugging with them can be quite painful. It is
| getting better, but I still pull my hair frequently.
| KptMarchewa wrote:
| What's the difference in programming model (not
| implementation) between Loom and goroutines?
| jacques_chester wrote:
| Briefly, that a thread cannot escape a scope. All threads
| must be joined before leaving the scope.
|
| Some resources:
|
| https://wiki.openjdk.java.net/display/loom/Structured+Concu
| r...
|
| https://cr.openjdk.java.net/~rpressler/loom/loom/sol1_part2
| ....
|
| https://vorpus.org/blog/notes-on-structured-concurrency-
| or-g...
| crudbug wrote:
| Agreed !
|
| Current reactive code is littered with async/await for every
| IO function, which feels like they are trying to bolt
| reactive behavior. Library-based threading model provide the
| sync thinking with optimized async compute model.
| seniorsassycat wrote:
| What is the point of String's transform?
| wiradikusuma wrote:
| After a long stint with Scala, I recently came back to Java
| because I'm setting up a team for a greenfield project. Java has
| a good balance for ease of use, type safety, massive+mature
| ecosystem, and talent pool.
|
| The new language features (post v5) and framework maturity help
| reduce the "bloated" feeling that made me switch to Scala. Still
| not happy with the semicolon.
| pcl wrote:
| You might consider Kotlin then. It's more JVM-aligned than
| Scala, but waaaay terser than Java (as yet -- the Java team is
| making great strides).
| halfmatthalfcat wrote:
| What do you mean by "JVM-aligned" and how is Kotlin more JVM-
| aligned than Scala? Speaking as someone who uses Scala on a
| daily basis and never touched Kotlin.
| dbsmith83 wrote:
| Kotlin types and Java types are much more compatible than
| Scala types. No need to use converters. Also, Scala leans
| very FP, while Kotlin and Java don't, so they are also more
| similar in that regard, though I don't know if that's what
| "JVM-aligned" means here. Overall, Kotlin and Java just
| have better interoperability than Scala and Java
| pcl wrote:
| Yeah, that's exactly what I meant.
|
| The JVM is designed to execute the constructs of the Java
| language. Scala compiles to JVM bytecodes, but it does a
| lot of (very cool!) things that are not natively
| supported by the JVM, and thus tend to be pretty
| expensive. Scala's pattern matching, for example, goes
| beyond what can be efficiently expressed in the JVM.
|
| As a rule, Kotlin does not take this approach. Instead,
| almost all the constructs in Kotlin can be cleanly
| expressed in JVM bytecodes.
|
| Reified generics is a good example. Kotlin only allows
| them when a function can be inlined, since in those
| situations, you don't actually _need_ generic arguments,
| since the code in the inlinable function can be dropped
| in place. This allows for the convenience of reified
| generics -- but only if you 're willing to live within
| the limitations of the inline restriction. (And it's also
| elegant, since it'll be easy to relax the constraint once
| the JVM adds the needed support.)
|
| I've run across one or two things in Kotlin that _don 't_
| translate to JVM bytecode elegantly, although I'm
| struggling to find a good example off the cuff. They're
| definitely the exception, though, whereas the Scala team
| took a more radical approach.
| The_rationalist wrote:
| It's not clear that bytecode changes are needed for
| efficient pattern matching support. Java is getting
| pattern matching support. The related JEPs mention that:
| The implementation will likely make use of dynamic
| constants https://openjdk.java.net/jeps/309 I strongly
| suspect that Scala could be more efficient if it used it
| too. However I have no idea if this could improve compile
| time. (kotlin has until now procrastinated implementing
| pattern matching support because they say it increase
| compile time, but maybe that doesn't hold with constant
| dynamics)
| pimlottc wrote:
| I've always admired Java for managing to slowly but surely move
| the language forward while maintaining backwards compatibility
| and keeping the community together. When you look at how many
| other languages have faltered and lost momentum due to transition
| issues (Perl 6, Python 2/3), it really shows have difficult of a
| task it is.
|
| Progress can seem glacially slow at times - it's always
| disappointing to see your favorite upcoming feature get pushed to
| a later release - but the current language is undeniably light
| years better than what we started with.
|
| Respect.
| harshalizee wrote:
| I would add C# to the list of languages with good backward
| compatibility and progression with every new version. Very
| similar to Java, and has a lot more feature set with somewhat
| decent documentation.
| Yhippa wrote:
| One thing I've always admired about C# is that it's an ISO
| standard. Which I'm not sure if that really means much these
| days in terms of computer programming languages. It seems
| like it would be an amazing hedge against a private
| organization co-opting it in the future.
| int_19h wrote:
| The catch is that C# standardization lags behind language
| evolution. At the moment, the most recent edition is
| ECMA-334:2017 aka ISO/IEC 23270:2018. It corresponds to C#
| version 5.0, originally released back in 2012 - it was the
| one that introduced async/await, and it's still missing
| stuff like null chaining.
|
| (for the curious, here's the complete list of C# language
| versions: https://docs.microsoft.com/en-
| us/dotnet/csharp/whats-new/csh...)
| carimura wrote:
| A big benefit of the 6-month release cadence (since Java 10) is
| that if your favorite feature gets pushed, the next release is
| just around the corner.
| tyingq wrote:
| _" Helpful NullPointerExceptions describing precisely which
| variable was null JDK 15"_
|
| I wonder what number of collective hours would have been saved
| with this one, had it come earlier.
| pvorb wrote:
| Oh yes. Did you ever have a statement where you chain more than
| two method calls and don't know which returns null? I tend to
| split calls like this on separate lines just to be able to tell
| which call returns null from the line number in the stack
| trace. obj.call1().call2().call3();
|
| becomes obj.call1() .call2()
| .call3();
|
| And if I now get an NPE at line three, I know that call2()
| returned null.
| dlbucci wrote:
| All the backend projects I work on were originally written in
| Java. I'll admit that Streams and Lombok make it a somewhat
| pleasant experience to work with, at least compared to when I
| used it in college (I think Java 8 was newest?).
|
| But that said, I once tried writing a new feature in Kotlin, and
| now all our code is Kotlin. I don't really see how Java can
| compete with the non-nullable types, data classes, and type-
| inferencing Kotlin gives you, with easy interoperability, to
| boot! (Although you might start regretting your use of Lombok at
| that point...)
| still_grokking wrote:
| Same goes for Scala, where those Kotlin features come form
| originally.
| pron wrote:
| Those features (except for nullability types) predate Java,
| let alone Scala and Kotlin, by a couple of decades. Those
| three -- like all programming languages -- get inspiration
| from similar sources. Java is just the most conservative of
| the three with regards to language features.
| ragnese wrote:
| I think it's disingenuous to deflect by saying that Scala
| didn't invent those concepts.
|
| I think it's pretty clearly significant that Scala and
| Kotlin are JVM languages, specifically.
|
| If we just said "Well, StandardML had XYZ feature 30 years
| ago," you could reasonably wonder whether implementing
| those features on the JVM was a legitimate hurdle to not
| including them.
|
| But the fact that the guy who wrote generics for Java then
| went and created Scala with these features is telling.
|
| I also don't think that "Java is conservative" is the
| correct description of what's going on here. Look at the OP
| (I know you're a Java guy, so I don't mean that literally)-
| Java used to get maybe one language change for each major
| version until 16 where it got a bunch.
|
| Why? I don't know. But I think it's totally fair to observe
| two correlations in recent history:
|
| 1. Oracle obtained control of Java
|
| 2. Many other, very good, programming languages have been
| coming on the scene: Swift, Go, Rust, Kotlin, TypeScript,
| C#, F#. Even older programming languages have seen major
| advances in the last 5-10 years: C++ and PHP among them. I
| think it's pretty clear that Java just didn't feel the
| pressure to make itself better until recently.
| pron wrote:
| You're right about your main points: for some years
| before Sun's demise Java was neglected and lacked
| resources, and Oracle has gradually but significantly
| increased its investment in the platform. It is also true
| that the abnormality of ~2000-2005, when there were few
| popular languages, has ended. But the following two facts
| are also true: Scala didn't invent those features, and
| neither Kotlin nor Scala are big enough to be serious
| competitors for Java. So Java might be feeling the heat
| of competition, but not from those two, and, like all
| other languages, it looks around and borrows features,
| but not from those two more than others.
|
| It is possible that Java platform languages might
| indicate the palatability of certain features to Java
| programmers more than non-Java platform languages, and
| the Java language designers do have a closer relationship
| with the designers of other Java platform languages. But
| overall, these effects are not particularly big. Knowing
| the current designers of the language, I can say with
| certainty that Haskell has served as a bigger inspiration
| than either Kotlin or Scala on recent features and their
| design ( _inspiration_ , not direct source).
| brabel wrote:
| I write a lot of Kotlin code but still tend to use Java a lot.
| All of the features you mention are not really an advantage for
| Kotlin anymore.
|
| Java has had tools to deal with nulls for a long time, we tend
| to assume everything is non-null unless annotated with
| `@Nullable` and let tools check correct usage at compile
| time... data classes are very similar to Java 16's records.
| Type-inference since Java introduced `var` is pretty much on-
| par with Kotlin.
|
| Some people have already started talking seriously about Kotlin
| now just adding friction, as you need to keep updating its
| version and the Gradle plugin (which is not compatible with
| some versions of Gradle if you're stuck with some old Gradle
| plugins). Java 17 should probably stabilize sealed classes,
| which is one of the biggest advantages of Kotlin at the
| moment... to be honest, even though I've always been a
| proponent of Kotlin, I am not nearly as enthusiastic now as I
| used to be about it.
| ragnese wrote:
| If I remember correctly, it's fairly easy to use @Nullable
| and still end up with nulls there, even without an IDE
| warning. I'll have to double check to see if I can still
| reproduce that.
|
| But, to be fair, it's actually fairly easy to break Kotlin's
| null safety, too: https://blog.haroldadmin.com/circular-refs-
| kotlin/
|
| But I basically agree with what you've said. Kotlin is
| certainly still a much more ergonomic language, but Java
| caught up fast recently.
|
| Kotlin 1.5 will be really cool, though, with the new value
| classes and the mutable methods feature (stolen from Swift).
| BoyRobot777 wrote:
| Value classes cannot provide the performance/memory
| flatness that Valhalla will bring though. So I'm not really
| sure what benefit does "values classes" bring. Just to make
| sure, you are talking about the inline class which is just
| a wrapper around single property? inline
| class Password(val value: String)
| ragnese wrote:
| Yes and no:
| https://github.com/Kotlin/KEEP/blob/master/notes/value-
| class...
|
| "value class" is the next step for inline classes. They
| are going to behave very much like Swift's struct and its
| "mutating methods". And they are going to be "Valhalla
| ready" so we'll get the performance improvements
| automatically when it lands.
|
| In a sense, they are an upgraded data class with a much
| more precise and controlled form of mutation. Rather than
| a `var` field meaning the object will mutate in-place, it
| will basically automatically call a kind of (implicit)
| "copy()" method. Further, you may _only_ mutate these
| `var` fields inside of class methods that are marked with
| a new keyword: `mutating`.
|
| Read through the KEEP. It's pretty interesting stuff. At
| first it kind of rubbed me the wrong way, but the more I
| thought about it, the more excited I got about it-
| especially after thinking about how Swift does it and it
| works well there.
| aphexairlines wrote:
| You can only assume non-null for your own code though. The
| java ecosystem of 3rd-party libraries will give you nulls,
| and most of the time won't include nullability annotations.
|
| var is a nice step, but encourages mutability since it's not
| final by default.
| EvilEy3 wrote:
| > Java has had tools to deal with nulls for a long time, we
| tend to assume everything is non-null unless annotated with
| `@Nullable` and let tools check correct usage at compile
| time...
|
| Oh yeah, nothing like creating Frankenstein's monster instead
| of using a tool that was designed for the purpose. And no,
| it's not the same. You'll never beat Kotlin compiler , no
| matter how many annotation you use - you will always miss
| something.
|
| > data classes are very similar to Java 16's records.
|
| You mean Java 16's records are similar to data classes, since
| those were first.
|
| > Type-inference since Java introduced `var` is pretty much
| on-par with Kotlin.
|
| Not even close. Can't use it outside of functions, clunky
| final var instead of val.
|
| > Some people have already started talking seriously about
| Kotlin now just adding friction, as you need to keep updating
| its version and the Gradle plugin (which is not compatible
| with some versions of Gradle if you're stuck with some old
| Gradle plugins).
|
| My favorite kind of people. 'Some'.
|
| > Java 17 should probably stabilize sealed classes, which is
| one of the biggest advantages of Kotlin at the moment...
|
| Nice!
|
| Let's wait until you'll upgrade to Java 17 while Kotlin has
| everything already and much more with compilation to JS and
| native in the future.
| meddlepal wrote:
| Java gets a bad rap from people that used it late 90's through
| early 2000's and got burned out by XML and design pattern heavy
| frameworks but its a lovely language that with a little
| discipline can be used to create very lean looking code.
|
| Go is one of the HN darling languages and I work in Go everyday
| for work (and generally like it), but I really wish I could reach
| for Java most days.
| laurent92 wrote:
| "Java is a big DSL to transform XML into stacktraces" -- so was
| the joke at the time when domain-specific languages were the
| hype.
|
| This, and the FizzBuzz, Enterprise Edition:
| https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
|
| More seriously, what are you missing in Go that is well-done in
| Java? I assume verbosity of the code is still the defining
| characteristic of Java?
| pgwhalen wrote:
| Not OP, but...
|
| > More seriously, what are you missing in Go that is well-
| done in Java?
|
| As cliche as it is to say, Go missing generics (for the time
| being) does hold it back in many ways relative to Java. I
| like and use both languages regularly, and as I thought about
| my answer to this question I realized that essentially all of
| my complaints stem from the lack of generics - things like
| streams, a rich collection framework, and non-channel
| concurrency features (java.util.concurrent among them) don't
| exist in go because you can build them as generically as
| needed for them to be useful.
|
| You might have said "well-done" as a way of excluding
| generics in Java since many people like to suggest they're
| not well done; of course most developers would like more, but
| they already enable an enormous amount of stuff not possible
| in Go.
| srparish wrote:
| Verbosity of code is more of a go thing these days:
| hasThing := false for _, v := range stuff { if
| checkForThing(v) { hasThing = true break
| } } if !hasThing { return false }
|
| Java: if !stuff.stream().anyMatch(v ->
| checkForThing(v)) { return false; }
|
| In the 2020s, loops are the new "goto", too much boiler-plate
| and ways to subtly be incorrect, much safer to use higher-
| level collection methods.
| matsemann wrote:
| The java ecosystem is very nice. Not necessarily the language
| itself, but everything else. The jvm, the tools, the
| libraries are all very mature and good.
|
| Skipping java and instead using Kotlin allows one to reuse
| all that knowledge in a great language as well.
| bcrosby95 wrote:
| I guess it depends upon what you mean by ecosystem.
|
| Java the language is ok. The culture (which is part of the
| ecosystem) and how you're pushed to write code is the
| biggest problem with Java. The wide array of tooling,
| frameworks, and libraries within the ecosystem is nice.
|
| But the way you have to use them tends to be shit due to
| the culture surrounding the language. At least it seems to
| be shifting to something more sane.
| avmich wrote:
| Good language ought to discourage (enough) the bad
| practices. Culture forms slowly, and it's Java fault that
| the culture managed to produce such excessities as
| proverbial FactoryFactoryFactory.
|
| Edit: I still think Java is a good language, especially
| later versions, and both original goals and recent
| advances are quite noble.
| meddlepal wrote:
| I somewhat agree, but Java grew up in a different era
| when communication about these things wasn't as easy.
| It's hard to change the direction of something as large
| and widely deployed as Java. It's happening but it will
| take time and its always going to dealing with its legacy
| as there just so much of it out there.
| geodel wrote:
| Huh, one needs to see first party Java libraries from
| earlier times. It is pretty clear engineers at Sun also
| believed that AbstractFactoryFactory everything will be
| the way world need to be rebuilt.
|
| Of course one can show empathy and understand
| justifications for things they like and simply laugh out
| "LOL Go No Generics' when they don't.
| tonyarkles wrote:
| Now we've got Spring, which in my, admittedly limited,
| experience does a great job of transforming what could have
| been compile-time errors into run-time errors.
| The_rationalist wrote:
| Just use micronaut if compile time errors is what you want.
| It can even validate generated queries.
| jacques_chester wrote:
| The wheel of karma is ever-turning, though [0],[1].
|
| Disclosure: I work for VMware, which sponsors Spring
| development.
|
| [0] https://spring.io/blog/2021/03/11/announcing-spring-
| native-b...
|
| [1] https://github.com/spring-projects-experimental/spring-
| fu
| The_rationalist wrote:
| Those are nice advances but I hope that spring will one
| day support compile time validation of generated queries
| and of beans like Micronaut do.
| jacques_chester wrote:
| I'm confident it'll reach that point.
| noisem4ker wrote:
| ...and probably well before Micronaut gets rid of its
| bugs, comes close to feature parity and generally matures
| as a framework.
| victor106 wrote:
| Spring native is a game changer for so many organizations
| using containers for startup times. There are other
| spring related issues you still have to deal with
| avmich wrote:
| Well said :) . Spring looks so much as to show how useful
| ideas can be misapplied with catastrophic results. For
| example, liberate encouraging of dependency injections
| leads to multitude of interfaces which are only ever
| implemented once by a production code class, and maybe one
| more time by a test class, even though Java has all methods
| virtual and testing could be done without requiring the
| interface.
| mamon wrote:
| >> Java has all methods virtual and testing could be done
| without requiring the interface.
|
| Not sure what you mean by that. I thought that
| interface/implementation divide is the way to implement
| virtual calls. Unless you want testing frameworks to do
| bytecode instrumentation.
| nitrogen wrote:
| Modern testing frameworks can indeed mock concrete
| classes, which beats the bytecode generation that Spring
| would be doing anyway.
| avmich wrote:
| If your interface is going to be implemented by just one
| class, I'd offer to skip interface - it reduces amount of
| code. If you still need to pass, as a parameter, a class
| A in order to test a class B, you can instead pass class
| C inherited from A, with all necessary methods
| overloaded.
|
| If you just create a class A in java, no interfaces
| involved, class A will have its methods virtual. I'm not
| sure what do you mean by interface/implementation divide.
| oftenwrong wrote:
| It's reasonable to provide a single implementation of an
| interface, if the goal is to facilitate dependency
| injection for that component. The problem I find with
| Spring is that it is designed for dependency injection at
| all levels of its architecture, leading it to be one of
| the ultimate examples of Ravioli Code.
|
| https://wiki.c2.com/?RavioliCode
|
| DI is a powerful concept, but Spring projects rely on DI
| in such a generic way that it often doesn't even make
| sense for your application. You have to gain intimate
| knowledge of the abstractions, and inject a bunch of code
| in a bunch of places just to make it do the very-
| straightforward thing you were trying to do.
| blntechie wrote:
| Running 'mvn install' on even a simple Spring project with
| default dependencies is scary to watch on the console. So
| many things happen and it's not even the verbose mode.
|
| Running 'dotnet build' is much more saner and one can
| reasonably understand what happens.
| frant-hartm wrote:
| Try `npm install` then..
| geodel wrote:
| Yep. Give it a one line error description and it turn into
| stack trace longer than "War and Peace".
| meddlepal wrote:
| > More seriously, what are you missing in Go that is well-
| done in Java?
|
| 1. Generics. And yea, I know Go is getting generics "Real
| Soon Now" (tm), but it is incredibly annoying to write the
| same collection code over and over and there's some third-
| party libs that would really benefit from generics (looking
| at you Azure Go SDK).
|
| 2. Error handling... with the big caveat that I actually like
| Go's error handling mechanism at small scale but wish there
| was a good way to chain several operations together and
| return an error to the top if any failed... I find myself
| writing a lot of `err != nil` checks in sequence and I've
| found baking my own abstractions around this to be leaky or
| difficult to grow as the program requirements change.
|
| 3. Diverse collections API.
|
| 4. Iterators.
|
| 5. Not Java-the-language but the JVM has amazing monitoring
| tools.
|
| > I assume verbosity of the code is still the defining
| characteristic of Java?
|
| Pound for pound... I think Go and Java have about the same
| verbosity. I'm honestly never quite sure what people mean by
| "verbosity" in Java. Generally I interpret this as
| "frameworks" but I predicated my OP on the idea that legacy
| framework bloat is where most of people's frustration with
| Java lies... not the language itself.
| ragnese wrote:
| I agree with your points here, but just want to add that,
| while Java's generics are better than the non-existent
| generics in Go, I still find Java's type system to be
| really subpar for today's era.
|
| The type system is not strong or expressive enough to do
| full type erasure, but then we're stuck with type-erased
| generics, so it's just incredibly frustrating.
| avmich wrote:
| > I'm honestly never quite sure what people mean by
| "verbosity" in Java.
|
| Java improved with "var" keyword (use with caution!) and
| introduction of records. These are not the only code-
| shortening features (there are e.g. interface methods,
| diamond operator, lambdas, convenience "of(...)" methods,
| even "fluid style"), but they, used well, can really reduce
| verbosity.
| Scarbutt wrote:
| I'm surprised you didn't mention the Streams API.
| bobthepanda wrote:
| Also, a lot of verbosity in Java came from people going
| off the rails with design patterns to hide crap multiple
| levels deep in a file with 5+ words in the class name.
|
| If you have a hammer everything's a nail.
| nitrogen wrote:
| Frameworks like Spring/Spring Boot kind of force that as
| well with their runtime creation of proxy classes.
| twh270 wrote:
| Much of the verbosity came from the false presumption that
| every field in every class needs a public getter and
| setter. (I cannot express in words how terrible this is.)
| Some can come from the framework, mostly poorly-designed
| ones.
|
| I think Java 11 and higher are reasonably terse/expressive
| without being overly dense.
| DaiPlusPlus wrote:
| Remind me, _why_ doesn't Java have object-properties yet?
|
| So far the only reason I've concluded is Java's language
| designers' egos were so damaged by C#, Swift, Kotlin,
| TypeScript, etc that after dogmatically denying the
| developer-productivity benefits of properties for the
| past 20 years that to concede now would mark the end of
| Java as a language entirely.
|
| ...I kid, but seriously I haven't heard any compelling
| argument from the Java camp yet for refusing to add this
| feature. Object-properties are easily the lowest-hanging-
| fruit with the biggest productivity-gains.
|
| Heck, even some of the most popular C++ compilers support
| object-properties as proprietary extensions.
| zmmmmm wrote:
| It's so crazy - with all the huge and radical features
| they've added this would surely have been so simple by
| comparison and yet added more value than about 80% of the
| things they've done. It's about half the reason I still
| use Groovy now since Java has solved most of the rest
| over time. But I just cannot go back to writing getters
| and setters!
| doctor_eval wrote:
| Couldn't agree more, the madness of idiomatically adding
| setters and getters to every field was something I ended
| up putting an end to in my last gig, and my life improved
| immeasurably as a result.
| The_rationalist wrote:
| Kotlin property access solves this. You access to the
| property but behind the hood it will call the
| getter/setter if it exists.
| kerblang wrote:
| Sorry that I find it necessary for yet _another_ answer to
| your verbosity question, but: The real verbosity is in the
| standard libraries. What would be a one-liner in any other
| language is usually at least 2, often 3, and sometimes
| enough that you end up writing your own wrapper function or
| library. Especially noticeable is the agony of Lists &
| Maps, which are first-class citizens in most languages
| (classic job interview question: what is the difference
| between ArrayList and LinkedList? Real answer: Nobody
| actually uses LinkedList).
|
| The stdlib often seems to be written by people who had no
| intention of using it. I guess maybe this applies to C++ as
| well, so for some folks it seems normal.
| hibbelig wrote:
| About verbosity: you needed to define classes for so many
| things. Eg you want others to hook into processing in
| certain places. So you create a listener interface with
| some methods. And the provider needed to work with those,
| and the consumer also needs to work with them.
|
| In modern Java maybe you can make do with functional
| interfaces and lambda, but it doesn't always work I think.
|
| And in emacs: the provider does run-hooks, and the consumer
| defines a function and says add-hook. Done. Very little
| ceremony.
| pron wrote:
| I'd say the defining characteristic of Java is an
| unparalleled combination of performance, observability, and
| maintainability.
| Thaxll wrote:
| "Go is one of the HN darling languages"
|
| It's def not the case, I spend too much time here and on Reddit
| and people are always complaining about Go ( generics, errors,
| type system etc ... ), if you want the godly language it would
| be Rust, anything about Rust will be upvoted.
|
| As for Java, it's a good language / runtime that is overly
| complicated behind layers of abstraction. Take Spring for
| examnple, magic everywhere, add an anotation there and it does
| x.y.z, you can't see it in the code but it does something.
| geodel wrote:
| > if you want the godly language it would be Rust, anything
| about Rust will be upvoted.
|
| That is just better half part, sad part is anything negative
| about Rust will be heavily downvoted. Most of the time I
| disagree with Java/Go in their thread it would be just fine
| but not with Rust.
| The_rationalist wrote:
| The same can be said about pro chromium or contra mozilla
| comments, it's a kind of cargo cultism/echo chamber
| kaba0 wrote:
| Java itself is most definitely not overly complicated. Many
| frameworks, and created programs are due to enterpriseTM
| software development, but it's orthogonal. And spring is a
| really feature-packed framework which has a solution for
| almost every business problem that one can face. Of course it
| comes with a great deal of complexity, but it is a tradeoff.
| I rather tinker with how to use a given feature than
| implement it myself, often in an inferior way.
| ragnese wrote:
| The hype around Rust is largely justified. There. I said it.
|
| Rust is nowhere near perfect. It's also supposed to be a
| systems language- it was probably not originally intended to
| replace languages like Java for general "app" development.
|
| But it's so much better of a language than most of the higher
| level languages you see in popular use: Java, PHP,
| JavaScript, Python, etc, that people are actually willing to
| deal with the lack of garbage collection just to get to use
| its excellent type system and well-designed standard library
| API. I think that says a lot about Rust _and_ the programming
| language environment today.
| DaiPlusPlus wrote:
| It surprises me that we don't yet have an applications
| language with an ultra-modern type-system. It's so strange
| that the current leaders are a scripting-transpiler
| (TypeScript) and a systems language (Rust) - but not an
| apps language in-between.
|
| ...then again it's understandable when you see how the
| traditional apps languages (C#, Java, etc) are severely
| hobbled by their VM/runtime, because that's usually the
| source of constraints on their type-system. Kotlin and F#
| do some neat tricks to work-around the limitations they
| inherited from the JVM and the .NET CLR respectively, but I
| think we've reached the limits of what platforms originally
| designed ~25 years ago can reach. I just don't see the JVM
| nor the CLR getting anything like first-class support for
| higher-kinded types or true algebraic types: there's too
| much pressure from establishment banks and insurance
| companies not to break their decades-old codebases
| maintained by outsourcing companies. Languages like Swift
| and Go are free to break their own molds because they're
| happy not leaving a legacy, but what will that mean for
| Rust? Systems code is the last place you need major
| breaking changes, but I don't see Rust's progress slowing
| down the way ISO C++ languished for almost 20 years. Hmmm.
| int_19h wrote:
| The situation is changing in the CLR land, now that they
| can just say that legacy codebases can stay on .NET 4.x,
| and .NET Core is where all the fancy development is
| happening. There are already some C# language features
| that are Core-only because they require the corresponding
| runtime changes.
|
| The other thing is - people always forget that, unlike
| JVM, CLR has more than just the object layer. By design,
| it has enough low-level constructs to compile a language
| like C++, complete with multiple inheritance, unions,
| varargs etc. Obviously, you can do pretty much anything
| on top of that - the only problem is that you won't be
| able to interop with other .NET code, except through
| C-style FFI. But, hypothetically, it would be possible to
| establish a higher-level ABI without baking it into the
| VM as an object model, thus allowing a reboot without
| throwing everything away.
| ragnese wrote:
| It surprises me as well. And to belabor my own point some
| more: there's a reason the #1 question about Rust from
| newbies seems to be "Is there a language like Rust, but
| with a garbage collector?" - sometimes reworded as "Is
| there a way to turn off the borrow checker?"
|
| To be fair, I think that a decent amount is possible on
| JVM and CLR. Scala, for as much hate as it gets, has a
| much stronger type system than Kotlin/Java.
|
| And Swift has its own backwards baggage! It has to work
| with Objective-C. There's actually a few weird things in
| Swift that I've bumped into that I'm _pretty_ sure are
| only there because of Objective-C.
|
| The Rust devs certainly take backwards compatibility very
| seriously and they guarantee backwards compatibility
| forever. There will be no breaking changes in Rust except
| in extreme cases of finding unsoundness or whatever.
|
| There are currently ZERO good high level app-building
| languages, IMO.
|
| Rust isn't it because of the lack of garbage collection
| (which is not a point against Rust- just for the "domain"
| of optimizing for user-space app development).
|
| Swift would probably be it, but it's pretty much Apple-
| only and I don't expect that to change.
|
| TypeScript is close, but it's held back by needing to
| work with JavaScript and the JavaScript standard library
| and ecosystem suck. It also can't do threads.
|
| Kotlin/Java are decent, but not good at concurrency, and
| having things like different sized integer types is
| really silly for a high-level language where everything
| goes on the heap anyway...
|
| Python is slow and can't do threads.
|
| Some languages like Lisps and MLs might be good for
| building apps if they just had the ecosystem around it.
| Haskell would be a giant pain the ass because real apps
| are full of "IO".
|
| So, yeah. It's kind of a miracle that we can get anything
| done. I guess that's why we get paid so well...
| The_rationalist wrote:
| Kotlin is the application language you're looking for
| (and Scala 3 to a lesser extent). Contrary to what you
| say it is the best language I've ever used for
| concurrency. It has it all, structured concurrency,
| cancelation, Flow, transparency (no await), etc.
| Regarding your second point the JVM is increasingly using
| the stack and with the soon complete generics you'll be
| able to avoid the boxed versions of the primitive types
| (though they remain useful when you want identity)
| kukx wrote:
| It also gets a bad rep because of Oracle.
| superyesh wrote:
| >got burned out by XML and design pattern heavy frameworks
|
| Most succinct summary I have heard lately :) I think a good
| bunch of blame is also on the developers who blindly adhere to
| said patterns. https://www.quora.com/What-are-the-most-
| ridiculous-Java-clas... to rest the case.
| ragnese wrote:
| I disagree that it's a lovely language. I think, as developers,
| we very quickly develop Stockholm syndrome. Once you "learn" a
| language, it's really easy to churn out code and apply idioms
| without even realizing that you're constantly writing
| workarounds and kludges for your language's deficiencies.
|
| As a polyglot dev, the following are my gripes with Java:
|
| * null - we all know, so I'm not going to bother expanding
| except to say that @NotNull is NOT a solution and it doesn't
| guarantee shit.
|
| * interfaces are extremely lacking compared to type classes and
| lead to verbose and cumbersome patterns such as "Adapter".
|
| * Type-erased generics. Why shouldn't I be able to implement a
| generic interface for multiple types? E.g., class MyNumber
| implements Comparable<Integer>, Comparable<Short>,
| Comparable<Long> {}
|
| * It only just got Records and sealed interfaces, so thank
| goodness for that. But prior versions of Java are extremely
| lacking in expressiveness without these.
|
| * I don't hate checked exceptions as a concept, but the fact
| that you can't be "generic" over the exceptions in a function
| signature is frustrating. This is why everyone says they're
| "incompatible" with Java's closure APIs.
|
| * No unsigned ints.
|
| * Silent integer overflow/wrap-around. It's not C- did it
| _really_ have to copy this insanity?
|
| * Dates and timezones are still insane, even in Java 8+.
|
| * The fact that arrays got type variance wrong.
|
| * JDBC sucks. JPA also kind of sucks.
|
| * No concept of `const` or immutability.
|
| I'm not saying that Java is the worst language in the world or
| anything, but it's far from great, IMO. Most programming
| languages are pretty awful, IMO.
| MaxBarraclough wrote:
| > No unsigned ints.
|
| I think that's a mixed blessing. I believe Java did this
| deliberately to avoid the trouble that C and C++ have with
| signed and unsigned integer types having to coexist.
| Personally I've never been inconvenienced by Java's lack of
| unsigned integer types, but I'm sure it can be annoying in
| some situations.
|
| I'm quite fond of Ada's approach to integer types, but I
| suspect I'm in a minority.
|
| > Silent integer overflow/wrap-around. It's not C- did it
| really have to copy this insanity?
|
| Curiously this cropped up 10 days ago. [0] You're not alone.
| The great John Regehr put it thus: [1]
|
| > _Java-style wrapping integers should never be the default,
| this is arguably even worse than C and C++'s UB-on-overflow
| which at least permits an implementation to trap._
|
| > The fact that arrays got type variance wrong.
|
| At least Java has the defence that they didn't know how it
| would pan out. C# has no such excuse in copying Java.
|
| > No concept of `const` or immutability.
|
| I recall a Java wizard commenting that although a const
| system is the sort of feature that aligns with Java's
| philosophy, it's just too difficult to retrofit it.
|
| [0] https://news.ycombinator.com/item?id=26538842
|
| [1] https://blog.regehr.org/archives/1401
| int_19h wrote:
| > I believe Java did this deliberately to avoid the trouble
| that C and C++ have with signed and unsigned integer types
| having to coexist.
|
| The problems really only come from mixing those types, and
| the simple solution is to disallow such mixing without
| explicit casts in cases where the result type is not wide
| enough to represent all possible values - this is exactly
| what C# does.
|
| I think Java designers just assumed that high-level code
| doesn't need those, and low-level code can use wrappers
| that work on signed types as if they were unsigned (esp.
| since with wraparound, many common operations are the
| same).
|
| > Java-style wrapping integers should never be the default
|
| The ironic thing about this one is that C# introduced
| "checked" and "unchecked" specifically to control this...
| and then defaulted to "unchecked", so most C# code out
| there assumes the same. Opportunity lost.
|
| While we're on the subject of numeric types - the other
| mistake, IMO, is pushing binary floating point numbers as
| the default representation for reals. It makes sense perf-
| wise, sure - but humans think in decimal, and it makes for
| a very big difference with floats, that sometimes
| translates to very expensive bugs. At the very least, a
| modern high-level language should offer decimal floating-
| point types that are _at least_ as easy to use as binary
| floating-point (e.g. first-class literals, overloaded
| operators etc).
|
| C# almost got it right with "decimal"... except that
| fractional literals still default to "double", so you need
| to slap the "M" suffix everywhere. It really ought to be
| the other way around - slower but safer choice by default,
| and opt into fast binary floating-point where you actually
| need perf.
|
| > At least Java has the defence that they didn't know how
| it would pan out. C# has no such excuse in copying Java.
|
| I think both Java and C# did it as an attempt to offer some
| generic data structure that could cover as many use cases
| as possible, since neither had user-defined generic types.
| In retrospect, it was an error - but before true generics
| became a thing, it was also a godsend in some cases.
| The_rationalist wrote:
| Your analysis is interesting and far from exhaustive, It
| would be nice to have a collaborative feature matrix for
| languages, on github.
|
| Kotlin solve the following points:
|
| _null - we all know, so I 'm not going to bother expanding
| except to say that @NotNull is NOT a solution and it doesn't
| guarantee shit.
|
| I don't hate checked exceptions as a concept, but the fact
| that you can't be "generic" over the exceptions in a function
| signature is frustrating. This is why everyone says they're
| "incompatible" with Java's closure APIs.
|
| No unsigned ints.
|
| No concept of `const` or immutability._
|
| Kotlin allow to specify either variance or contravariance so
| I guess it fixe this point too? * The fact that arrays got
| type variance wrong*
|
| * interfaces are extremely lacking compared to type classes
| and lead to verbose and cumbersome patterns such as
| "Adapter".* Interesting, can you link to an example? Kotlin
| has first class support for delegation as an alternative.
|
| * Type-erased generics. Why shouldn't I be able to implement
| a generic interface for multiple types? E.g., class MyNumber
| implements Comparable<Integer>, Comparable<Short>,
| Comparable<Long> {}* Kotlin has support for reified generics
| to some extent. The JVM is currently getting state of the art
| support for it too and for specialization.
|
| * Dates and timezones are still insane, even in Java 8+.* I
| always hear that Java has got the best Time library, what is
| the complaint about?
|
| * JDBC sucks. JPA also kind of sucks.* Do yourself a favor
| and use the JDBI or so many other sexy alternatives.
|
| Of all your points the only unaddressed are: * interfaces are
| extremely lacking compared to type classes and lead to
| verbose and cumbersome patterns such as "Adapter".
|
| And Silent integer overflow/wrap-around*
|
| Strong agree about stockolmization and cargo cultism of
| language constructs.
|
| _Most programming languages are pretty awful_ Correct, hence
| why Kotlin stands out.
| happyweasel wrote:
| Java isn't the worst C++ program I know.
| ericbarrett wrote:
| I got burned out by endless JVM preening and devs configuring
| their runtime options to use 128MB in a 2GB container, or
| capitalizing their -Xm option wrong, or what have you. So now
| with cloud computing you have the JVM in a container on a
| virtual host, all of which have their own constraints to set--
| matryoshka dolls all the way down.
|
| Like, people always say, "Well that just means they didn't know
| what they were doing with the JVM"--yes, and it's been a
| problem for two decades and is about as likely to go away as
| buffer overflows in C.
|
| Honestly the thing I like about Go, Rust, C++ the most is the
| resultant binary just runs in userspace, and you can set the
| constraints there. Even Python scripts don't have to muck with
| the JVM.
|
| FactoryFactoryFactoryFactory code is the least of Java's
| issues.
| edp wrote:
| Starting with OpenJDK 11 (and I think available in OpenJDK8
| with an optional flag), the JVM will use the memory
| constraints of the container, so no more -Xmx flags and so on
| if you are running the JVM in a container environment.
| oftenwrong wrote:
| No flag necessary for latest versions of OpenJDK 8, either.
| forty wrote:
| What's the best way to run java apps in a container nowadays?
|
| The official openjdk images are based on "oracle Linux" and that
| doesn't sound right :) is there good small and well supported
| java image based on a popular distribution?
| germanier wrote:
| Isn't Oracle Linux basically rebranded RHEL?
| inyorgroove wrote:
| If that is a problem for you there is AdoptOpenJDK:
| https://hub.docker.com/_/adoptopenjdk
|
| EDIT: Also openjdk has buster based images:
| https://hub.docker.com/layers/openjdk/library/openjdk/jdk-bu...
| aphexairlines wrote:
| Use jib (java image builder) with maven or gradle and it will
| build an image with distroless-java plus your app:
|
| https://github.com/GoogleContainerTools/jib
| https://github.com/GoogleContainerTools/distroless/blob/mast...
| jillesvangurp wrote:
| I've been using Java and the JVM since about 1995 when Sun
| released the early betas (pre 1.0). It's more or less a
| convenience marriage. Right place and right time I guess. I
| happened to specialize in it for a while. A long story short: I
| pivoted to Kotlin a while ago and stopped caring about what
| Oracle is doing to keep up. Too little, too late; and it seems to
| perpetually not matter at all unless you are still doing Java,
| which I'm not.
|
| Kotlin works great on the JVM and about the same across Jdk 8-16
| (probably from v6 even). A lot of stuff happened in between but
| the Kotlin compiler and library ecosystem seems to cover up and
| smooth out the differences. Most of the Java compiler or standard
| library changes stopped mattering to me. There's not a single
| thing from v15 to v16 that I can name that matters to me, at all.
| All my code works fine with v11 (the first and only post v8 LTS
| release) and the delta with getting it to work with v8 is
| trivial. There's just nothing since about 2014 that actually
| matters to me. Not even a little bit. All of my Kotlin code bases
| trivially work with any release since then.
|
| I use Spring and Spring Boot in their latest versions and there's
| no question about Kotlin being the preferred language for that at
| this point. You get basically everything they did to make it work
| with Java 8 plus everything that Kotlin adds on top, which is a
| lot. Some of that even works with recent Java versions.
|
| At this point that includes stuff like co-routines and Flows that
| makes the whole abomination that is Spring Flux usable (as
| opposed to a minefield of complexity you have to deal with via
| 2014 era Java), data classes instead of last century style Java
| Beans (just, no!), etc. Java 9 and on-wards is kind of half
| getting there with things like Loom and records landing only very
| recently and not havig had any impace yet whatsoever. You want
| something modern, fresh, and nice with Spring that is not
| experimental and well supported: Kotlin is it. Everything else is
| stuck at being experimental until way after Oracle labels latest
| & greatest Java version as LTS, which might happen in the next
| two years or so. Java 11 technically happened but never really
| registered in the same way that Java 8 did. For a lot of
| conservative places, 8 was the last stable release. That was in
| 2014! Everything after that is optional, nice to have, and yet to
| impact major frameworks. Except of course if you use Kotlin,
| which fast forwards you about seven years plus whatever Java has
| left to catch up.
|
| There really is no functional difference between JDKs other than
| slight changes in Java APIs you probably should not be using with
| Kotlin anyway. All the important stuff is tested with and works
| fine with v8. I'm talking libraries, tools, and frameworks. Most
| of my code works exactly the same with Java 8 as it does with
| Java 16. I get very little value out of using something more
| recent than jdk 8. But I still upgrade. Kotlin uses some of that
| transparently but mostly it does not matter, at all.
|
| We are basically talking purely non functional things that are
| mostly about things like performance being slightly better, new
| garbage collectors, or the whole modules thing that is largely
| irrelevant to any kind of server side usage having happened or
| not. I've never been on project where that actually mattered even
| the slightest. Complete waste of time that pre-dates the
| acquisition by Oracle even. But nice that they cleared some
| technical debt there and got rid of some circular dependencies in
| a standard library that I largely don't depend on with Kotlin.
|
| Which is a different way of saying that I get very little out of
| Java updates in the last seven years. My mode is mostly that,
| well if you are going to pick a JVM, you might as well pick a
| recent one because it probably has a few fixes that may or may
| not matter to you. But it's going to work fine either way.
|
| The next big thing with Kotlin is multi-platform and cutting
| loose from Oracle. I'm already utilizing kotlin-js for some front
| end stuff and am keeping an eye on their WASM efforts and native
| stuff as well. A lot of what I care about already works fine
| across all of those.
| The_rationalist wrote:
| The JVM will be getting state of the art, fine grained generics
| specialization, riefied generics and even Constant generics (you
| know that big feature that make a lot of noise in the Rust world)
| https://www.reddit.com/r/java/comments/m2dfb5/parametric_jvm...
|
| (note that Kotlin already has riefied generics to some extent and
| that Scala support explicit Specialization (and Kt too through
| overloading))
| the_only_law wrote:
| Thank god someone did this?
|
| Not sure what it was about those versions particularly, but I
| kinda lost track of the language and runtime after Java 8 and
| I've spoken to a lot of other people who did as well.
|
| Admittedly it's around the time I stopped working in Java a lot,
| but I guess a lot of others did as well?
___________________________________________________________________
(page generated 2021-04-01 23:02 UTC)