[HN Gopher] Java 20 / JDK 20: General Availability
___________________________________________________________________
Java 20 / JDK 20: General Availability
Author : mfiguiere
Score : 208 points
Date : 2023-03-21 14:30 UTC (8 hours ago)
(HTM) web link (mail.openjdk.org)
(TXT) w3m dump (mail.openjdk.org)
| mfiguiere wrote:
| A good coverage of all the JEPs included in JDK 20:
| https://foojay.io/today/its-java-20-release-day-heres-whats-...
| Traubenfuchs wrote:
| I still don't understand what's the correct way to replace thread
| locals holding initialization heavy & non thread-safe instances
| besides using a pool which produces a lot of overhead when using
| loom/virtual threads. In the past, with ThreadLocal, you'd have
| one instance per thread, making sure that those instances could
| only be used once and would only be instantiated for all threads
| of your (acceptor) thread pool
|
| Does anyone know the solution?
| FalconSensei wrote:
| And here I am still on Java 8 :/
| rafaelturk wrote:
| Impressive how many companies are stuck on quite old java
| versions. We are a core API for payments services, and we need
| to force our customers to upgrade to newer Java versions as
| most of them don't support newer encriptyion protocols
| oaiey wrote:
| Thank You for your service.
| TheRealPomax wrote:
| Perfectly fine for already written codebases or codebases that
| need to target hardware that's stuck in the past?
|
| Just don't use it for new projects on modern hardware. Be on at
| least the current LTS version for that and enjoy a much more
| expressive language on a much better JVM.
| taftster wrote:
| I mean, that's OK though. Not sure why this is considered such
| a bad thing. You're missing out on some new language features,
| sure, but Java 8 is still reliable and rock solid. There's lots
| of companies that have hesitation or even inability to upgrade,
| hopefully there's at least some initiative and/or direction to
| do so.
|
| A company that is head-in-sand deliberately not upgrading from
| Java 8 is one thing. A company that is just being conservative
| and intentional about the upgrade path, that's another entirely
| different thing.
|
| I don't mind a company that has been using Java so much that
| it's just a slow process for them to get on the next thing. Old
| libraries that need to be recompiled for Java modules, etc.
| Hopefully it happens for you soon.
| logistark wrote:
| I think that the main problem upgrading beyond Java 8 is Java
| 9 and module system and a lot of javax package classes that
| were removed. It will be very helpful a tool that can detect
| what modules or classes that are being used by your codebase
| and add them as maven or gradle dependencies and add them to
| the classpath.
| rerdavies wrote:
| The main problem with upgrading beyond Java 8 is that it's
| Android! And we all know how THAT went.
| FalconSensei wrote:
| > I mean, that's OK though. Not sure why this is considered
| such a bad thing
|
| For existing software, sure. But the problem I guess is when
| there are a lot of newer projects starting and everyone is
| stuck on the older version
| taftster wrote:
| Totally fair. I guess I would hope in that case that the
| new effort would target a modern Java release, preferably
| Java 17 or greater. If a company is sticking with Java 8
| for new initiatives, yeah, they probably have a culture
| problem and are not going to be happy with that decision.
| [deleted]
| paulmd wrote:
| There's very little reason not to upgrade from Java 8 at this
| point. Everything should be a drop-in replacement and there
| are significant performance benefits (garbage collection is
| leagues better) to doing so.
|
| The bigger problem is that a lot of places are stuck on
| _Oracle JDK_ - 8u252 is the last free version so a lot of
| places just decided they 'd never upgrade, nor do they want
| to look at whether Temurin or Coretto would work for them
| (the answer is usually yes).
| 66fm472tjy7 wrote:
| > Everything should be a drop-in replacement
|
| This is not true for many applications. Due to the removal
| of many APIs from the JDK with Java 9, I needed the
| following dependency artifactIds to be able to move a JEE
| application with SOAP web services to Java 11: jaxb-api,
| jaxb-core, jaxb-runtime, istack-commons-runtime, jboss-
| jaxws-api_2.2_spec, glassfish-corba-omgapi, jboss-
| annotations-api_1.2_spec, activation, jboss-saaj-
| api_1.3_spec, saaj-impl, stax-ex, jsr181-api, txw2.
|
| Many of these spec API/implementations are provided by
| different artifacts that are incompatible with each other.
| Some I only discovered when something failed at runtime as
| they perform implementation lookups and you don't get
| compile errors.
|
| Additionally, many of the Maven plugins we used no longer
| worked and our application server failed to start.
| TacoSteemers wrote:
| > Everything should be a drop-in replacement
|
| It isn't at all, in my opinion. Consider the introduction
| of the module system, for example.
|
| Some libraries moved out of the core language.
| agilob wrote:
| Except 9, 11, 14 and 16 where breaking backwards
| incompatible changes were introduced? And then the talk of
| changes in libraries, remapping imports from JEE to
| Jakarta... that's a long, long way in Java.
| taftster wrote:
| Almost. The Java module system (introduced in Java 9 and
| enforced in Java 11) still plagues companies and/or slow-
| to-update libraries. Particularly companies that have
| written a lot of their own in-house libraries and such.
|
| Custom libraries have, unfortunately over the years, picked
| up the bad habits (by forking/following public libraries)
| relying on reflection and packages that shouldn't be
| directly used (sun.* packages, etc.). So companies are
| wedged in because they made the poor decision to rely on
| private packages. And now, Java 11+ enforces this by
| default.
|
| There are open source Java libraries today that don't run
| unless you "add-exports" to basically everything. google-
| java-format comes to mind, because it's using an internal
| java code parser from the JDK, for example.
| dtech wrote:
| In the latest LTS those all can still be enabled, so
| while it is a serious problem when they are finally
| removed, for now it's not really a good reason to block
| an upgrade.
| taftster wrote:
| I think that's fair. Yes, there is an escape hatch
| currently available. But what is hard is _knowing_ if
| your application is relying on any internal /private
| behavior that it shouldn't. Since the dependency
| hierarchy of most Java projects is very deep, it's hard
| to know if any dependencies of A -> B -> C -> D are going
| to call into restricted areas. You might not even know
| you have a problem until runtime, because you've --add-
| exports everything and now you have a stacktrace to try
| and deal with in production.
|
| But yes, maybe not a good reason to completely block an
| upgrade. It's just postponing the pain, though.
| awelxtr wrote:
| Isn't 202 the last version?
| SPBS wrote:
| My codebase at work is written in Java 8, I honestly don't see
| what other benefits upgrading the language would bring. There's
| already so much business code written in the old Java 8 style
| (which works), don't go trying to change how the code is
| written now. To me Java 8 is simple and boring like Go, with
| some imperfections like the lack of a native map data type.
|
| I'd still upgrade for the new VM's better performance/security
| patches or whatever, but I don't need any language changes.
| riku_iki wrote:
| We migrated our codebase because multi line string literals
| somewhere in jdk14 made writing large SQL queries in java
| code so much easier.
| dtech wrote:
| I unfortunately encounter this mindset so much in Java
| programmers, and the similar "we don't need no feature X"
| even if the feature has proven themselves for a long time in
| a large amount of languages. I'm hesitant to bring it up, but
| I see a lot of Blub Paradox [1] among Java programmers. Heck,
| a lot of places disallow `var`, while over here in Kotlin-
| Python-Rust-C#-Typescript-Go-etc-land that's been the default
| since forever.
|
| Taking this comment in good faith, the following language
| features from 9+ are incredibly useful for everyday
| programmers, you should give them a serious try before
| dismissing them:
|
| - `var` local type inference
|
| - record classes
|
| - text blocks
|
| - switch expressions
|
| - sealed classes and interfaces
|
| [1] http://paulgraham.com/avg.html
| awelxtr wrote:
| My main dependency only supports jdk 8 soooo...
| bcrosby95 wrote:
| Var is nice. But I generally prefer to not require people
| to jump out of the current code to figure out the type of a
| variable. And yeah, I've worked in those other languages,
| and navigating unfamiliar code with var everywhere can be
| confusing, so I try to avoid that kinda thing.
|
| Records are nearly useless to me. Immutability is great,
| but I need a way to derive new sets of information based
| upon an set of information. And the only way to do that is
| bug prone.
|
| Text blocks are nice for writing SQL queries and other
| multi-line things. But I'm not sure how often I actually
| use it.
|
| Switch expressions are nice because it gets me compile time
| checking for things I would previously use a runtime check
| for. Other than that, as they _currently_ exist, they 're
| meh.
|
| Sealed classes are something I've not had a use for. Maybe
| libraries will eventually make good use of them.
|
| So I would say there's _some_ nice QOL things in here. But
| I think "incredibly useful" is overselling it.
|
| The thing is, lots of these things are built to support a
| longer term roadmap towards better support for data
| oriented programming. I think that is a worthwhile goal to
| drive for - and the sum of the parts (many of which are
| still in preview) will be less than the whole together -
| but we don't have the whole, yet. That, to me, would pass
| the "incredibly useful" bar.
| joaonmatos wrote:
| `var` in Java is local for a reason. In most contexts I
| can think of the variable either was created above or was
| passed in as a parameter/object field. Unless you set it
| from a weirdly named creation pattern/function.
|
| Regarding records, you never had someone update a POJO,
| add a field, and forget to update equals and hashCode?
|
| Sealed classes are great for everything
| parsing/validation, in data modelling. They're not a
| solution for behavior polimorphism, but I don't think
| they were supposed to.
| [deleted]
| therealdrag0 wrote:
| People think boring is good but it's not. Simplicity is good.
| Boring is just what you're familiar with.
|
| New features done right improve simplicity by abstracting
| away complexity or need to reinvent the wheel. For example Go
| devs having wrote their own list .map() functions is absurd.
| spacephysics wrote:
| Big reason is security patches. But if the services are
| running in a VPN and don't interact with outside world, it's
| fine
| keester wrote:
| My understanding is that jdk8 has support from Oracle until
| 2030.
| kaba0 wrote:
| _paid_ support. I'm not convinced that most of those
| companies that use older versions even know where their
| JDK comes from.
| 0xDEF wrote:
| It's interesting how the introduction of "modules" has forced
| so many to stick with C++17 and Java 8.
| Longhanks wrote:
| C++ has barely any feature complete compiler implementations
| and build systems aren't ready for all of its additions,
| either (CMake and modules in particular). libstdc++ and
| libc++, gcc and clang are all not ready for production use or
| rather untested and/or buggy.
|
| Unless you're targeting MSBuild Visual Studio Solutions and
| Windows only, C++17 is currently the most up to date, stable,
| and battle-proven version.
| ghostwriter wrote:
| > gcc and clang are all not ready for production use or
| rather untested and/or buggy.
|
| Which items from this table are lying about GCC v11 support
| of C++20? [1] Which of the features are buggy in GCC
| v11-12?
|
| [1]
| https://en.cppreference.com/w/cpp/compiler_support#cpp20
| acuozzo wrote:
| It's a shame "C with classes", as C++ originally was,
| didn't stick around for parallel development.
|
| I work with C daily and I'm well aware of its many
| shortcomings (e.g. its huge list of undefined behavior and
| its PDP11-centric view of modern architectures), but with
| some effort I believe it could function as a semi-portable
| second-level intermediate representation. Nim uses it as
| such, IIRC.
|
| Compiling to C first would introduce some of its own
| issues, for sure, but I imagine doing so would alleviate
| the pressure the C++ standards committee puts on compiler
| vendors each time they expand the size of the kitchen sink.
| soulbadguy wrote:
| Rust ?
| acuozzo wrote:
| Rust compiles to C and then passes that C to a C compiler
| to generate machine code?
| morph123 wrote:
| This feels a bit like discussing the new fancy garden hoe as a
| farm hand as they are making the tractor.
| unixhero wrote:
| Are these hoes somehow related to lemon stealing hoes?
| pron wrote:
| except no one's making the tractor
| mrkeen wrote:
| Java is a conservative language, which means that it waits and
| sees which features work well for the tractor, and then
| retrofits them to the hoe.
| timcavel wrote:
| [dead]
| philipwhiuk wrote:
| Only if you build your tractors out of garden hoes ;)
| nsm wrote:
| What are some good primers to understand the prominent new Java
| features? Not just in 20, but since, say, 8. Asking as someone
| who would like to be cursorily familiar with Java, but does not
| use it day to day. I'm very familiar with things like auto type
| inference, pattern matching, multi-line strings and structured
| concurrency from other languages, so I'm not looking for an
| introduction to Java. I'm looking for something like "Modern Java
| for the experienced Rust/Python/C++ programmer". Thanks!
| VagueMag wrote:
| I've been trying to get caught up while job searching after
| being laid off, and have found YouTube to be a pretty good
| source, the Java language advocates are all very keen to show
| off all the shiny new stuff. Also definitely recommend the JEPs
| as one of the other sibling comments did. All of the "Data
| Oriented Programming in Java" stuff is I think especially
| relevant, Brian Goetz had a good article on InfoQ about it.
| emdashcomma wrote:
| Here are some resources I've found helpful and have read or are
| on my backlog to catch up with these developments:
|
| - https://github.com/wesleyegberto/java-new-features (terse,
| includes links to JEPs, good jumping off point)
|
| - https://github.com/winterbe/java8-tutorial (quick tour
| through features of Java 8)
|
| - https://winterbe.com/posts/2018/09/24/java-11-tutorial/ (same
| for Java 11)
|
| Books:
|
| - Java 8 in Action / Modern Java in Action (Raoul-Gabriel Urma,
| Alan Mycroft, Mario Fusco; 2014 and 2018 respectively)
|
| - The Well-Grounded Java Developer (Martijn Verburg, Benjamin
| Evans, Jason Clark; 2022) - not specifically focused on new
| features but does cover them in the context of going deeper
| into Java and the JVM.
| mongol wrote:
| Boring answer... but Chat GPT? I asked it what was new in Java
| 8 and it enumerated a number of features. I could proceed to
| ask it about more details for each, and then continue Java
| version by version and I think it would be quite exhaustive.
|
| The other day I did something similar for cell biology. As a
| layman I wanted to learn more about DNA, mRNA, tRNA,
| translation, transcription, mitosis, miosis, etc. I think I
| learned it much better by querying Chat GPT than say reading
| Wikipedia. Something about the interaction, to ask for more
| details on what was not clear that helped me understand it.
| illiarian wrote:
| > Boring answer... but Chat GPT?
|
| Trained on data up to September 2021.
| dragonwriter wrote:
| > Trained on data up to September 2021.
|
| Wrap the ChatGPT API in a ReAct pattern implementation
| where one of its available actions is a search against the
| Java 20 docs?
|
| Probably better for reference than tutorial, though.
| anotherevan wrote:
| RP @johl@mastodon.xyz: I wish more people understood that "I
| want the computer to generate a natural language text that
| sounds like a plausible answer to a question about x" and "I
| want the computer to answer a question about x" are two very
| different problems.
|
| https://aus.social/@johl@mastodon.xyz/110050185180546324
| nsm wrote:
| Thanks! I keep forgetting to reach for this.
| copperx wrote:
| I've avoided that because of the tedium of having to fact
| check everything.
| Legion wrote:
| The problem with ChatGPT is that, when it should say "I don't
| know", it will instead confidently spew plausible sounding
| garbage.
| aardvark179 wrote:
| You might find just browsing the JEPs will get you a long way.
| https://openjdk.org/jeps/0
| cbm-vic-20 wrote:
| Java Almanac can show the API differences between versions of
| Java.
|
| https://javaalmanac.io/
| 62951413 wrote:
| https://reflectoring.io/java-release-notes/
| https://advancedweb.hu/new-language-features-since-java-8-to...
| furtiman wrote:
| Coming from the telegram bot of hacker news, where this post has
| a lot of downvotes (21 down to 6 up, which is quite a lot for how
| many reactions usually are there), could someone (perhaps even
| from people who downvoted) explain why this news is met with such
| negativity?
|
| I kind of assume it's due to the cliche Java-oriented hatred, but
| curious to hear opinions...
| znpy wrote:
| Does anybody know if there are significant improvement fir java
| on arm in this release?
| exabrial wrote:
| Java on my ARM MBP is _very_ fast, by a large margin; faster
| than my x86 cloud servers by 1.5x-2.5x
| tw1984 wrote:
| [flagged]
| krzyk wrote:
| What is the "cool" language nowadays?
| substation13 wrote:
| OCaml is having a bit of a moment
| throwaway742 wrote:
| HolyC
| helf wrote:
| [dead]
| WesSouza wrote:
| Rust or Zig
| pansinghkoder wrote:
| You are right; lets start a linux kernel in rust. Send me a PR
| for that bootloader.
| philipwhiuk wrote:
| There are bits of the Linux Kernel in Rust.
| pansinghkoder wrote:
| Like I have tic-tac in my car but its not driving the
| engine.
| anaganisk wrote:
| Bits =/= let's dump C
| karmicthreat wrote:
| Because they are very popular languages with a large experience
| base?
| voidfunc wrote:
| That people still write this kind of drivel and actually
| believe it on this site is frustrating.
|
| Every tool has a purpose and Java is a fantastic tool for a lot
| of use-cases.
| jwr wrote:
| That, and there are other languages (like Clojure) that are
| implemented on the JVM. I don't write any Java, but Clojure
| running on the JVM pays my bills.
| somethingAlex wrote:
| C++ for when you need to be very close to the metal.
|
| Java (and C#) are still legitimate options for server side code
| when you want speed and type safety but managed memory.
| oaiey wrote:
| Not only legitimate. Also better for many scenarios. Not only
| when you consider your existing workforce but also hire new
| people. It is so much easier if you onboard someone into
| something which is procedural at its heart and everyone can
| translate their core C/C++/JS/PHP/Python/Perl/... procedural
| programming into Java and C#. The reason async/await is so
| accepted there is because of exactly that.
|
| Try throwing someone into a Go project with a C background.
| Until they learn the way of concurrency there, a lot of time
| is gone. Or even go one step further and throw a generic
| procedural coder into something like F# or Haskell. Or take
| the example of reactive UIs: It took the industry a decade to
| move from MVP based UI frameworks to reactive based UI
| platforms and we are far from being done with that move.
| Angular literal reactive-under-the-hood existence is due to
| that fact that people love to work with their traditional
| ways and are more productive in them.
| pshirshov wrote:
| Why "bad enough"? Java is getting better and the language
| feature set isn't really that big, I would rather call it
| austere. The language slowly adopts Scala features but still
| lags significantly behind it.
| yibg wrote:
| Which new hot language of the day are you chasing this week?
| anaganisk wrote:
| How is time relevant for languages? Unless everyone has stopped
| speaking/using it, it's relevant and is never old and only is
| improved to add new grammar. Applies to both spoken and
| programming languages.
| rjzzleep wrote:
| Here's me wondering how many more years will pass before the
| Wayland support is going GA.
| erik_seaberg wrote:
| If applets and web start are dead, and Wayland doesn't render
| remotely, how would this work? Would a Java app server have to
| ask the user to run something on the desktop?
| carimura wrote:
| More info on 20:
|
| Announcement: https://inside.java/2023/03/21/the-arrival-of-
| java-20/
|
| VM improvements:
| https://tschatzl.github.io/2023/03/14/jdk20-g1-parallel-gc-c...
|
| Non-JEP Improvements: https://nipafx.dev/java-20-guide/
| hn_throwaway_99 wrote:
| Really excited to see how virtual threads are taken up by
| developers, and if they affect the larger programming language
| community. They just really seem like "the best of both worlds"
| to me: the high scalability/low resource usage of async/await,
| with the ease-of-use experience of threads (e.g. not having to
| worry about "function coloring").
| cesarb wrote:
| I'm personally not so sure. We already had something like that
| before (M:N threads), and the world moved away from it, towards
| letting the kernel manage everything (1:1 threads). So I'd
| expect instead that operating system kernels gain whatever
| features are missing for scaling to a higher number of threads,
| and everything once again goes back to each programming
| language thread corresponding to one kernel thread.
| mike_hearn wrote:
| The problem of scaling threads up further is fundamental and
| not really solvable by more kernel features. JVM virtual
| threads can be efficient because the runtime has complete
| knowledge of the executing code and stack layouts, how the
| heap is laid out, how the GC works and it can control how
| code is compiled. The kernel can't do any of these things -
| it has to assume a process is a black box that could do
| anything with its stacks, could be compiled by anything and
| so on.
|
| Note that this advantage obviously goes away the moment you
| call into native code. Then the JVM is in the same position
| as the kernel. It doesn't control the compiler or the stack
| any more, and so that's why a virtual thread becomes "pinned"
| at that point and you lose the efficiency (the JVM needs to
| acquire more kernel threads). Fortunately though the JVM
| ecosystem doesn't rely on native code all that much, so it
| should be rare in practice.
|
| This advantage can be brought to other non-Java languages too
| via Truffle. Truffle languages are reimplemented on top of
| Java and when programs call into native code they have the
| option of calling into JIT compiled LLVM bitcode instead of
| real native code (or indeed any JVM bytecode library). In
| that situation the JVM remains in control and so things
| should in theory still be Loom-able. Not sure if that's
| currently true in practice, but it could be.
| kaba0 wrote:
| M:N is not the interesting aspect of virtual threads at all,
| automagically turning blocking operations into non-blocking
| is - which has not really been tried before (with erlang and
| go being the first).
| ghostwriter wrote:
| > automagically turning blocking operations into non-
| blocking is - which has not really been tried before (with
| erlang and go being the first).
|
| sorry, but Haskell has had it way before Go, with proper
| STM too. Neither Erlang nor Go are offering the same level
| of ergonomics for compile-time checked M:N threading.
| cryptonector wrote:
| GNU Pth had "automagically turning blocking operations into
| non-blocking" ages ago, and it wasn't the first.
|
| I think what you probably had in mind is that C libraries
| of the 90s that did M:N threading didn't turn blocking
| operations into non-blocking?
|
| Using blocking operations to switch contexts is really
| nothing new. Heck, the cooperative multi-tasking systems of
| the 80s (Mac, Amiga) all essentially did that for processes
| (not threads), and so did Unix in the 70s.
| kaba0 wrote:
| > I think what you probably had in mind is that C
| libraries of the 90s that did M:N threading didn't turn
| blocking operations into non-blocking
|
| Yes, mostly, though my history knowledge is definitely
| lacking so do correct me if I'm wrong.
|
| But you are right, there was nothing fundamentally
| missing, probably just no good OS support for non-
| blocking IO calls in the early days? Though probably the
| IO-CPU ratio was also different, so the benefits were not
| as big?
| pkolaczk wrote:
| > low resource usage of async/await
|
| Will calling a coroutine do zero heap allocations like async in
| Rust?
|
| > with the ease-of-use experience of threads
|
| That's highly subjective. Threads usually require locking which
| is often hard to get performant and correct at the same time.
| Async/await allows to write concurrent code with no
| synchronization.
| matsemann wrote:
| > _Async /await allows to write concurrent code with no
| synchronization._
|
| Hmm,I don't see how async/awaits makes a difference. Care to
| explain?
|
| Like, if you have multiple sources that can add or read from
| a queue, unless there is a single thread running all your
| async loops (ala python), you still need some
| synchronization. At least that's my experience using
| coroutines heavily in kotlin.
| mike_hearn wrote:
| _> Async /await allows to write concurrent code with no
| synchronization_
|
| Well you still need some sort of synchronization, because an
| "await" allows arbitrary other actions to occur. If an await
| is introduced in code you transitively call then you might
| find that some invariant you were expecting to hold has now
| changed across a call when it previously didn't.
| Fundamentally, locks are about making invariants atomic and
| that's independent of exactly how code is scheduled and when.
| barkingcat wrote:
| Minor typo in the linked site:
|
| "JDK 20 reached General Availability on 21 March 2022"
|
| Should be 21 March _2023_
|
| Not sure who can edit that page but putting here.
| barkingcat wrote:
| This was fixed by Mark Reinhold
| spicybright wrote:
| Just adding too, I think some of the switch statement example
| code is wrong: Object obj = 123L;
| String formatted = switch (obj) { case Integer i ->
| String.format("int %d", i); case Long l ->
| String.format("long %d", l); case Double d ->
| String.format("double %f", d); case String s ->
| String.format("String %s", s); default ->
| o.toString(); };
|
| Unless I'm not understanding something, the default statement
| should be `obj.toString()` as `o` isn't defined.
| mdaniel wrote:
| JFC, I was going to say they should have used
| `String.valueOf(obj)` since I _expected_ `Object obj = null;
| switch (obj) { default - >` to do something sane but no, the
| stupid PoS NPEs because `switch` itself evidently calls
| `Objects.requireNonNull`
|
| The Billion Dollar Mistake meets the Power of Compounding
| Interest to produce an inflation adjusted number that just
| _keeps on giving_
| _old_dude_ wrote:
| You can add a 'case null' explicitly and merge it with
| default using 'case null, default -> ...'.
|
| See [1] for more.
|
| [1] https://openjdk.org/jeps/433
| pshirshov wrote:
| > structured concurrency
|
| That's another huge effort which delivered us an imperfect
| abstraction.
|
| I would prefer to have HKTs and typeclasses, so I may implement
| my own IO monad.
| quectophoton wrote:
| > I would prefer to have HKTs and typeclasses, so I may
| implement my own IO monad.
|
| I'm not a Java developer, and I haven't even read about higher
| kinded types or typeclasses (the theory side of programming is
| my weakness); but you picked my curiosity with this.
|
| Can you elaborate how concurrency done this way would look in
| Java?
| pshirshov wrote:
| Ideally like this: https://zio.dev/reference/#concurrency
|
| Or this: https://hoogle.haskell.org/?hoogle=fork
| bluetech wrote:
| Some discussion on zio in loom-dev mailing list recently:
| https://mail.openjdk.org/pipermail/loom-
| dev/2023-March/00535...
| pshirshov wrote:
| Loom is useful as an underlying mechanism for an IO
| monad. What I mean is that Java as language still lacks
| important features so they have to deliver half-baked
| things like that "structured concurrency". From my point
| of view these new abstractions are evil - the better ones
| were out there for a while.
| ackfoobar wrote:
| Other than STM, what is special? Almost everything there
| has an equivalent in traditional imperative programming.
| pshirshov wrote:
| More contracts enforced by the typer.
|
| > Almost everything there
|
| Everything. But the mere presence of "equivalents"
| doesn't make pure functional programming less valuable.
| ackfoobar wrote:
| I have used cats-effect but not ZIO.
|
| My view has been that reinventing imperative programming
| (IO monad) on math (pure FP) on imperative programming
| (the machine) brings me no benefit.
|
| What does a coarse-grained effect type get you? The hard
| part of concurrent programming is concurrency, rather
| than knowing what code is effectful.
| digitalsanctum wrote:
| As an engineer that last used Java when it was Java 11, I cringe
| at the thought of diving back in. A trade-off of increased
| release velocity for any language I suppose.
| twblalock wrote:
| You don't need to learn or use any of the new features. Most
| devs seem to still pretend they are writing for Java 8 anyway.
| kaba0 wrote:
| Why? Only the encapsulation difference was a slightly bigger
| breaking change since 8, after you are done with that it really
| is smooth sailing.
|
| Or if you mean addition of new features, then Java is very
| conservative on that front and it is still a very small
| language compared to most other mainstream ones.
| nprateem wrote:
| It's really not as bad as it used to be. I recently picked it
| up again after playing with Spring boot. I got to say Spring
| boot seems awesome, and java as a whole it much more ergonomic.
| Worth another look.
| jayd16 wrote:
| Structured concurrency looks a lot like C#'s Task library without
| the async/await sugar but with the exact same footguns.
|
| Joining into a synchronous function is an anti-pattern in C#
| because you consume threads. This seems to be the same, except
| with the assumption that virtual threads are fine.... But that's
| not an assumption that can be made by the method writer, right?
| carimura wrote:
| More details on 20:
|
| Announcement: https://inside.java/2023/03/21/the-arrival-of-
| java-20/
|
| VM improvements:
| https://tschatzl.github.io/2023/03/14/jdk20-g1-parallel-gc-c...
|
| Non-JEP Improvements: https://nipafx.dev/java-20-guide/
| philonoist wrote:
| Could the pundits of HN please compare this release with Kotlin?
| jillesvangurp wrote:
| Picking the release notes apart:
|
| - ScopedValue (Incubator). Seems like a replacement for
| ThreadLocal that is intended to be a bit less dangerous (it is
| notorious for leaking memory and file handles). The Kotlin
| equivalent would be CoroutineScope. I'd say the latter is the
| cleaner solution. And probably ScopedValues came into existence
| for the same reason (co-routines & structured concurrency kind
| of breaking ThreadLocal a bit).
|
| - Record Patterns (Second Preview). This looks a bit like
| Kotlin's smart casts. Useful. I think the Kotlin implementation
| with contracts is a bit more powerful and broadly applicable in
| more use cases. But nice of course.
|
| - Pattern Matching for switch (Fourth Preview). That looks to
| me like an attempt to beef up the Java switch, which is a
| welcome change. The Kotlin equivalent would be when. Not a
| whole lot of difference at first glance. But combined with
| smart casts, Kotlin is quite nice already IMHO. Scala
| developers might disagree about a thing or two here..
|
| - Foreign Function & Memory API (Second Preview). Looks like a
| nice JVM level feature for integrating native code that is
| potentially also of use to the Kotlin language developers.
|
| - Virtual Threads (Second Preview). The second iteration of
| Loom. The JVM level implementation for this is going to make
| Kotlin's co-routines potentially even nicer. I don't think it
| should be that disruptive for Kotlin developers already using
| co-routines but performance increases are nice.
|
| - Structured Concurrency. Also Loom related. From what I've
| seen of Loom so far, it should just work with your existing
| code without too much changes. And co-routines are definitely a
| nice API to do structured concurrency so not particularly
| relevant for Kotlin users. But it's going to be a big enabler
| for Java developers that have lacked this.
|
| - Vector API (Fifth Incubator). Another JVM level optimization
| that the Kotlin developers should be able to make use of. I
| imagine projects like the kotlindl framework (a deep learning
| framework) can make use of this. A bit niche but nice if you
| use things like that.
|
| So, nice incremental change and a few nice things that Kotlin
| will benefit from probably. Whether you use Java or Kotlin,
| it's going to be nicer for everyone once this ships in an LTS
| jdk.
| jwr wrote:
| As a Clojure programmer, I don't care about any of the Java
| language features or improvements, but I'm super happy that I'm
| getting a state of the art JVM that is continuously developed,
| maintained, extended and optimized, over a time scale of decades.
|
| This is incredibly useful: having a good VM to run your code in,
| with good modern garbage collectors, is not an obvious thing (as
| many other languages have learned).
|
| This is not the LTS release, so I won't be switching to it, but
| I'm looking forward to the next LTS.
| Alifatisk wrote:
| I second this, using jRuby
| zerr wrote:
| The same applies to Clojure CLR, right?
| herculity275 wrote:
| I haven't looked into CLR in a long time, but it feels like
| it has a fraction of JVM's adoption and community size.
| Microsoft also seems to be prioritizing Typescript and Node
| internally with its recent moves.
| soulbadguy wrote:
| At the risk of starting a flame war, the CLI and the
| coreCLR are fare superior VM and platform from a technical
| stand point. A lot of the features schedule for jave 21 /
| project Valhalla are just basically catching up to modern
| VM design. Of course there is more to the choice of a
| platform than just the technical differences.
| grumpyprole wrote:
| The Java JVM was originally designed with a very dynamic
| language in mind, e.g. Java's support for dynamic
| loading, dynamic binding, reflection etc. The influences
| at the time were Smalltalk and ObjectiveC. As Java has
| evolved to be a much more statically typed language
| (especially Java 5), the JVM has somewhat struggled to
| exploit this while maintaining backwards compatibility.
| It's nowhere near as bad as the Python situation though.
| I believe the CLR was built with things like parametric
| specialisation in mind from the beginning.
| kaba0 wrote:
| Im what aspect is the VM "far superior"? Where are CLR's
| state-of-the-art GC or low-level GC? Or does it have
| observability tools like JFR?
| DarkNova6 wrote:
| There would be a world for this argument if the CLR had
| anything even remotely resembeling hotspot runtime
| optimization.
|
| What you describe is the result of different
| philosophies/priorities. CLR focuses on static compile-
| time optimization, while the JVM is a highly dynamic
| construct with unmatched runtime analysis. In the 90s,
| there was a hope that with sufficient escape analysis,
| the need for user-defined primitives would vanish, which
| is why value types have not been done prior.
|
| By themselves, accessing values via stack and not by
| reference is technically trivial. The problem lies in
| backporting that kind of stuff.
| useerup wrote:
| > Microsoft also seems to be prioritizing Typescript and
| Node internally with its recent moves.
|
| You may want to look at Blazor Webassembly
| (https://dotnet.microsoft.com/en-us/apps/aspnet/web-
| apps/blaz...) and Blazor United
| (https://devblogs.microsoft.com/dotnet/asp-net-core-
| updates-i...)
|
| They scrapped the old CLR and started over with a new "CLR
| Core".
|
| Then they ported the new CLR Core along with the framework
| BCL to webassembly and has the CLR running in the browser,
| upon which they built Blazor Webassembly.
|
| So you can now target the CLR and have your code run in the
| browser.
|
| And now they are making progress on Blazor Unified where
| components can start of as server-side rendered exclusively
| and transparently and automatically move to webassembly
| rendering within the same application or page. It really is
| crazy stuff.
|
| Typescript is not the only thing going on in MS
| Engineering.
| logistark wrote:
| As Clojure programmer, i tell you that you should, because any
| moment Java introduce new features libraries will start using
| and most Clojure libraries are Java libraries wrappers.
|
| In addition if you want to use these new Java libraries in case
| and Clojure does not catch up with new Java features the
| ergonomics of using Java libraries with clojure decrease.
|
| And still they are trying to figure out how Ifn Clojure
| interface with Java functional interfaces.
|
| Also when Project Loom lands on JVM it will benefit Clojure
| too, allowing to remove code for instance of Clojure futures.
|
| If Clojure catch up with Value classes can increase performance
| of Clojure too.
|
| But this disregard of Java features or improvements is the kind
| of Clojure developer so content of what he have that forgots
| that can get better things.
| DonHopkins wrote:
| Why not just use C# instead? It was purposefully designed to
| address and correct the many mistakes of Java, and much more
| importantly, it's not owned by Oracle.
| Alifatisk wrote:
| Isn't openjdk disconnected from Oracle?
| kaba0 wrote:
| Disconnected? No. Oracle pays for 95+% of all OpenJDK
| commits. Their OracleJDK is pretty much just an OpenJDK with
| a few logos added -- they have over time made every
| proprietary feature open-source and available in OpenJDK.
|
| But as I expanded a bit more here
| (https://news.ycombinator.com/item?id=35249701 ), Java is
| probably the safest bet from a code longevity perspective.
| znpy wrote:
| Not only that, oracle's jdk is actually a distribution of
| openjdk.
| vips7L wrote:
| Oracle is the main contributor in both lines of code and
| financial backing to OpenJdk.
| twobitshifter wrote:
| C#, owned by the most ethical company in software.
|
| Java is very different and much improved from when c# branched
| off, but many people haven't been following along and still
| think it's the same as in 2002.
| palata wrote:
| Or Kotlin? Or Scala?
| oaiey wrote:
| With all my love for .NET, why not continue Java with its new
| features when it fits to your developer base, existing products
| etc.
|
| Give it one or two more years and Java is where C# is ... also
| aesthetically. As did JavaScript.
| EVa5I7bHFq9mnYK wrote:
| The feature that everyone is excited above - switch statement
| with pattern matching - has been available in C# for 6 years
| now.
| kasperni wrote:
| The feature everyone is excited about is Virtual Threads.
| Something where .NET is still playing catch-up
| https://twitter.com/davidfowl/status/1532880744732758018.
| DonHopkins wrote:
| Why not just use C# instead? It was purposefully designed to
| address and correct the many mistakes of Java, and much more
| importantly, it's not owned by Oracle.
| taftster wrote:
| All the while, adding its own mistakes to the pile.
|
| As an example, idiomatic Java style is moving away from
| getters/setters and instead favors builders and immutable
| types. That whole inheritance vs. composition concept is
| changing the way Java is being used.
|
| Meanwhile, C# has baked getters/setters so deep into their
| language (as properties) that there's just no moving off of
| them. Have you tried making a Builder in C# - ugh. Much harder
| than it should be.
|
| C# took the best of Java and ran deep into a cave with it.
| Meanwhile, Joshua Bloch's Effective Java has completely changed
| the way that "good" Java should be written and likely helped
| kickstart the whole revolution that is modern Java.
|
| I agree with your sentiment in general. C# / CLR are truly
| remarkable engineering feats. But Java is starting to break
| away from its old molds and is seemingly adding agility as it
| goes.
|
| As far as ownership. Java is not owned by Oracle any more than
| C# is not owned by Microsoft. They are both open languages with
| a majority backing supporter that yes, has a lot of influence
| over the languages. I'd argue Microsoft has more influence over
| C# / CLR than Oracle does on Java / JVM (but that's too close
| to call and probably too opinionated to suggest).
| gcl09 wrote:
| Aren't records and init only setters in C# also a way to
| favor immutable types and fix setters in properties? (Not
| trying to criticize, I really want to know).
| taftster wrote:
| Kind of. It gets you close.
|
| With the Builder pattern, you can easily define complex
| relationships for your class inner state. Like maybe if A &
| B are specified, then C shouldn't be specified. But if C is
| specified, then D should have a default value. Etc.
|
| These types of initialization requirements are not easily
| duplicated with C# init-only construction. Instead, in C#
| you have to rely on the callers to _know_ exactly how to
| correctly instantiate your class, including all the complex
| logic like in the example above.
|
| So yes, C# init-only setters are kind of the best option
| you have. You _can_ still create a C# FooBuilder for a Foo
| class. But generally C# programmers want to go out of their
| way to directly instantiate a Foo, and the number of bugs
| you get from this is crazy. It 's a culture thing,
| honestly, not as much a language problem.
|
| My two cents.
| koyote wrote:
| Do you have an example of how builders work in Java?
| desertlounger wrote:
| Yes. And with "records" (record classes, something with the
| characteristics of a tuple or struct) you can get further
| away from getter/setter boilerplate code.
| taftster wrote:
| I just wish records had an easy way to facilitate and/or
| associate a builder with them. Wishful thinking, out of
| scope for what they are. And of course, it's not hard to
| write a FooBuilder that's defined to help construct a Foo
| record.
|
| If Java records could be told to have a private
| constructor, I'd be completely satisfied with them. I just
| don't like the ability for callers to be able to directly
| instantiate a record without having gone through my builder
| to do so. I want to completely enforce that my record is
| instantiated with all its invariants dealt with properly. A
| builder is a very nice way of doing that.
| jgon wrote:
| I wanted to experiment with creating a "Rust-like" option
| and result type for Java and so figured that I would need
| records and pattern matching for this and I ran into
| exactly what you are talking about here with records and
| public constructors.
|
| My solution was to create a sealed interface that
| permitted the None and Some records as the only classes
| to implement it. Those records are not available outside
| the package, while the interface is exposed. Using
| default methods in the interface I could expose a state
| "create()" method which would then instantiate the
| appropriate None or Some record. In this way you control
| the exposure of the construction of the specific record
| implementations of your interface.
|
| You can then either interact with the option through the
| methods on the interface, .isOk(), .unwrap(), etc, etc,
| or with the upgraded pattern matching in switches with
| this release you could have something like
| switch(option) { case option when option.isNone()
| -> blah case option when option.isSome() -> foo
|
| }
|
| Its not as please as Rust matching directly on Some and
| None, but it gets you pretty close.
| kaba0 wrote:
| Designing something with an intent is very different than
| succeeding in it.
|
| Also, absolutely objectively Microsoft has orders of magnitude
| more control over C# than Oracle has over Java. Both Java, the
| language and the JVM has a specification, implemented
| completely independently by several companies, and the
| reference implementation is used as a business critical
| infrastructure of almost all Fortune 500 companies, many of
| which could single handedly continue to support and develop the
| platform. Meanwhile C# doesn't have an open-source debugger..
| desertlounger wrote:
| AFAIK Java was GPL'd by Sun (before the Oracle purchase). This
| resulted in the OpenJDK, which is the basis for all
| distributions of Java. Oracle is a big contributor to the
| development, but so are many others. You can get a pure OpenJDK
| or any of a number of branded JDKs like those from Eclipse,
| BellSoft, etc. You can get non-free distributions with support
| too. A sticking point for a number of years was the TCK
| (Technology Compatability Kit) used to validate Java, but that
| too was GPL'd. Java has evolved quite a bit since being open
| sourced. IMHO C# has some great features, but Java is great for
| certain things. For instance, making native apps for Mac, Win,
| and Linux based on modular libraries from the JDK is now fairly
| easy (and with a modern UI using the OpenJFX framework).
| beezle wrote:
| Asking honest question here - did Oracle change the terms
| back so that one can now develop and distribute applications
| using their JDK without fees so long as one does not also re-
| distribute/bundle their jdk with your application(s)? I just
| read something along those lines having thought that one
| couldn't use their JDK for anything without fee anymore.
|
| If so, is there a reason to go with OpenJDK over Oracle other
| than GPL purity?
|
| Again, legit question, no axes to grind.
| mbfg wrote:
| I'm curious what is meant by a "preview feature, or second
| preview feature, or..." in a released product?? I don't suppose
| they are going to remove it later. So in what way is it a
| preview? Are they signalling that it might have breaking changes
| in the future?
| simonkagedal wrote:
| Yes, they reserve the possibilty to completely redo or even
| remove these preview features. They are not enabled by default,
| you have to opt in with a compiler flag.
| mbfg wrote:
| ok, that makes some sense.
| carimura wrote:
| You can read all about it here: https://openjdk.org/jeps/12
|
| with a slight addendum here: https://openjdk.org/jeps/8300604
|
| and podcast that discusses both:
| https://inside.java/2023/03/21/podcast-030/
| somenameforme wrote:
| "A preview feature is a new feature whose design,
| specification, and implementation are complete, but which is
| not permanent, which means that the feature may exist in a
| different form or not at all in future JDK releases."
|
| https://docs.oracle.com/en/java/javase/19/language/preview-l...
| [deleted]
| marsven_422 wrote:
| [dead]
| PaulHoule wrote:
| Note all the new cool stuff is incubator and preview status and
| I'm a little worried that this will still be the case for the JDK
| 21 stable release.
| zjaffee wrote:
| I really hope to see the SIMD vector related improvements come
| through, I know there are some independent JDK code bases that
| have more evolved SIMD support, but for a lot of big data
| processing tools, switching away from jdk based languages
| appears to be the way SIMD related performance improvements
| have been realized because of this missing crucial feature set.
| JDK 11 was when this stuff was first in development, and it's
| truthfully insane that it hasn't fully been released yet.
| kaba0 wrote:
| Most of these low-level APIs simply just wait for value types
| - they don't want to hardcode something into the language,
| that might not be a perfect fit for those. Which makes sense,
| frankly.
| mike_hearn wrote:
| Within limits. Valhalla seems to be still far from
| launching, and allowing features to back up behind it might
| just recreate the situation Java has previously found
| itself in during the 7/8 era where slippage in massive
| projects caused everything else to slip too. The new
| release cycle was meant to fix that, but if half the new
| stuff ends up waiting for value types then the problem has
| just reappeared in a new form.
|
| The odd thing is that part of Valhalla is about how to
| migrate existing types to being value types, and they
| already have code that can simulate the same restrictions.
| So it's not really clear why these features have to wait.
| Migration is a part of the Valhalla plan anyway.
| grishka wrote:
| IIRC they are going to release pattern matching for switch and
| record deconstruction as stable in JDK 21.
| rfrec0n wrote:
| I think this is supposed to be the last preview version of FFI
| and the other JEPs from Project Panama, so hopefully we will
| have them at least but I definitely share a bit of that
| concern.
| carimura wrote:
| Probably not this go-around: https://openjdk.org/jeps/442
|
| Better to be right then rushed though.
| ludovicianul wrote:
| I have hopes to see Virtual Threads in Java 21, also being the
| next LTS.
| roschdal wrote:
| Java 8 is the best Java.
| pmontra wrote:
| Maybe that's why the two Java based products used by a customer
| of mine both have been using Java 8 since forever. One
| eventually switched to Java 11 last year.
|
| Or licensing, or having to rewrite too much of those apps for
| no perceived value. Who knows.
| vips7L wrote:
| Java 8 is an antiquated runtime. You're doing a disservice to
| your customers and developers by continuing to use it.
| deely3 wrote:
| Java 8 is working runtime. Whats wrong in using runtime that
| works?
| oweiler wrote:
| Why? Java 11 is already leaps and bounds better than Java 8.
| cesarb wrote:
| Not the parent poster, but I can see why: IMHO, the best new
| feature for Java was try-with-resources (Java 7), and the
| second best new feature was all the functional stuff in Java
| 8. On the other hand, Java 9 started the introduction of
| several breaking changes (it took years before I stopped
| seeing updates to Java libraries to fix their compatibility
| with Java 9 and Java 11), so it can be seen why someone would
| think of Java 8 as the highest point of that language.
|
| (For Java 9/10/11 in particular, there are several small
| enhancements, but nothing as earth-shaking as the changes we
| got with Java 7/8.)
| vips7L wrote:
| IMO you're neglecting the thousands of improvements in the
| HotSpot runtime.
| zjaffee wrote:
| This is by far the biggest improvement to java in the
| last few years and plays a big role as to why a lot of
| different types of backend tools still are written in JVM
| based languages rather than switching it up. This said,
| hotspot still has some issues with taking full control of
| SIMD optimizations.
| cesarb wrote:
| You can't use any of these thousands of improvements if
| your software is broken because it depended on something
| which was removed, or changed in incompatible ways. It
| can take a lot of work and time until it all works fine,
| even more when the breakage happened deep within a third-
| party library, and as far as I could see, there was a lot
| of these breakages early on the Java 9/10/11 cycle. IMO,
| it's worth it to make your software compatible with the
| latest Java LTS release, but I can understand why some
| people see it as too much work for too little gain.
| adra wrote:
| There were some subtractions for a bunch of stuff that
| wasn't getting much love to begin with. They removed
| their JS interpreter which was based on rhino which
| continued being a side library the entire time that java
| added it to the Java runtime. The only personal break
| that had no remediation was a minor helper class in JMX
| that affected me. Pretty much anything that was removed
| has some library addition that can add back what was cut.
| Basically Java 6-8 added a bunch of library support
| things that were probably better maintained as a third
| party library to begin with. The module system usually
| means adding some security policy exclusions for popular
| libraries, but in general I get a very well performing
| JVM that feels like it optimizes the code significantly
| better than in previous generations.
| layer8 wrote:
| They aren't critical to most applications, and are
| invisible to most developers.
| hocuspocus wrote:
| As a Java developer you should really set up at least
| some basic monitoring and perform load testing from time
| to time.
|
| And even in the unlikely event you don't see any
| improvement with recent versions of the runtime,
| something like Spring Boot 3 requiring Java 17+ isn't
| exactly "invisible" in the Java world.
| jabroni_salad wrote:
| I'm in Security and 8 generates a lot of revenue for me :)
|
| I'm not sure that it's inherently insecure, there is just a
| ton of old stuff in the ecosystem still chugging away.
| roschdal wrote:
| Java 8 was before Oracle started with evil licensing terms
| and crazy language changes which allowed all kinds of
| alternative syntaxes.
| 62951413 wrote:
| In locations which JDK Release Notes reach in eight light-
| years.
| akavi wrote:
| Now even Java has pattern matching, what's Javascript's excuse?
|
| Literally the only feature preventing Typescript from being my
| perfect language.
| BiteCode_dev wrote:
| Given the terrible result we came up with in the Python
| community, I understand the JS wants to take their time. It's a
| great feature, but it's hard to get right, especially on an
| existing language.
|
| Not to mention JS is not typed, but pattern matching that can't
| match typescript types would be terrible.
| sgt wrote:
| What's wrong with match? I've used it quite a bit and it is
| quite powerful.
| BiteCode_dev wrote:
| The syntax is reusing regular python syntax with completely
| different effects, so you have to learn 2 syntaxes.
|
| Trying to do simple things like matching the content of a
| variable will fail if you forget you have to use a dotted
| path if you want to avoid binding.
|
| Trying to do advanced things such as "match a dict with
| variable key names and values, but you wish to enforce the
| number and the types and unpack them in variables" is
| ridiculously twisted to do, when it's even possible.
|
| I use match/case, but it like the early years of type hints
| or asyncio: terrible ergonomics, and we know there is a
| ceiling to how much it can improve.
| vexna wrote:
| Its incredibly powerful! One downside is variables captured
| in the match are lifted to the function level. The lack of
| block level scoping in the match statement leads to a lot
| of people shooting themselves in the foot by overwriting a
| variable that they didn't intend to. On a personal note, I
| find the 2 levels of indentation to reach the case body to
| be too much as well... but that's just a personal
| preference.
| dgb23 wrote:
| I don't see a huge benefit for pattern matching in JS outside
| of it being expression based rather than statement based.
|
| Either way, the benefit has to be enormous. It's a feature that
| can easily break existing code.
| baq wrote:
| In a world where upgrading node versions without language
| changes breaks existing code I wouldn't be too worried.
| int_19h wrote:
| How would it break existing code?
| dgb23 wrote:
| Because it is an expression that introduces a new keyword.
|
| You could say "return match..."
|
| It's not easy to introduce without breakage. Not saying it
| cannot be done.
|
| But PHP didn't manage to for example. It also isn't real
| pattern matching but that's a different issue.
| int_19h wrote:
| Oh, so you were referring to the specific syntax in the
| current proposal, rather than pattern matching in
| general?
|
| Java and C# show how the syntax can be done in a fully
| backwards-compatible manner. It looks like it's just not
| the JS way by choice - apparently every new keyword that
| was added since ES5 is an actual keyword reserved in all
| contexts, not context-dependent?
| dgb23 wrote:
| That's good to hear!
| Waterluvian wrote:
| https://github.com/tc39/proposal-pattern-matching
|
| I'm not sure if it's stalled or not. But it's being discussed.
| jackworks wrote:
| We're still developing this proposal. be patient LOL
| akavi wrote:
| Sorry, that was rude of me. I know it's a ton of work, and
| am _endlessly_ appreciative of the work you (I assume?) and
| others have been doing to push this forward.
| javajosh wrote:
| Wow that's a proposal! I really like the idea of pattern
| matching, and I'm glad you're steering clear of modifying
| switch, but I find the sketches in the proposal pretty hard
| to read, especially with the combinator examples. I hope
| you guys take your time and stay more proud of what you
| leave out than what you put in.
| TheRealPomax wrote:
| This is something that far too few folks put in their
| progress/change logs.
|
| "We _didn 't_ do ..." is so incredibly important.
| hn_throwaway_99 wrote:
| The combinator example is the JS equivalent of what was
| discussed in another comment on this article,
| https://news.ycombinator.com/item?id=35247615. I like
| having the clarity of using different "and" and "or"
| keywords instead of overloading && and ||.
|
| But I definitely agree with the sentiment - every new
| feature is another thing that a developer needs to learn
| if they encounter that code. There should be a large
| "barrier to entry" for new features.
| Waterluvian wrote:
| I've got infinite patience for the brave souls who propose
| and implement TC-39 specs. =)
| Yahivin wrote:
| Check out Civet https://civet.dev/#pattern-matching
| Alifatisk wrote:
| What' the hype with pattern matching? What does it solve?
| [deleted]
| dcminter wrote:
| It's _really nice_ syntactic sugar. Complicated conditional
| logic cluttered with redundant types turns into a series of
| simple patterns. "Just" makes it easier to not make stupid
| bugs (I'm all for it).
| therealdrag0 wrote:
| Agreed. Example from Scala // Given an
| Option val maybeThing: Option[String] = getThing()
| // Classic if (maybeThing.isDefined) {
| useThing(maybeThing.get) } else {
| NotFoundResponseEtc() } // Pattern
| matching (not too IDE auto generated exhaustive match
| cases!) maybeThing match { case Some(thing)
| => useThing(thing) case None =>
| NotFoundResponseEtc() }
|
| This scales well when matching a higher cardinality of
| things like a variety of Exceptions or enums or other tuple
| responses like Either etc.
| brabel wrote:
| Hype with pattern matching? That sounds quite funny to me
| considering certain languages (Haskell, Erlang, OCaml...)
| have had that for decades.
|
| What convinced me of the power of pattern matching was seeing
| a red-black binary tree being implemented effortlessly in
| Ocaml (I think), while in C++ and Java it was a really
| difficult algorithm to implement.
|
| When you have provably exhaustive pattern matching (i.e. the
| compiler forces you to handle every possible case), certain
| things that are very difficult to write otherwise become very
| easy.
| munificent wrote:
| If you've ever done any assembly programming or worked with
| other old or low level languages, you may have encountered an
| environment where you can write simple operator expressions,
| but you can't compose them. So this is OK:
| a = b + c d = e - f g = a * d
|
| But the compiler doesn't allow: g = (b + c)
| * (e - f)
|
| You have expressions that produce, but they don't compose.
| You can't produce a value from a more complex, nested
| expression. We, rightly, no longer use languages like that.
|
| Pattern matching parallels that, except for assignment and
| decomposing values. Many languages today let you write:
| topLeft = rect.topLeft.x; left = topLeft.x;
| top = topLeft.y; bottomRight = rect.bottomRight;
| right = bottomRight.x; bottom = bottomRight.y;
|
| Or even: left = rect.topLeft.x; top
| = rect.topLeft.y; right = rect.bottomRight.x;
| bottom = rect.bottomRight.y;
|
| (Because at least you can compose expressions on the RHS.)
| But they don't let you write: (topLeft,
| bottomRight) = rect; (left, top) = topLeft;
| (right, bottom) = bottomRight;
|
| Or even: ((left, top), (right, bottom)) =
| rect;
|
| Pattern matching gives you that. It is freely composable
| destructuring.
|
| Also, the "matching" part means that in many languages you
| can also ask questions about values as you destructure them,
| which enables a particularly nice style of programming.
| hn_throwaway_99 wrote:
| All of your examples basically map to Javascript
| destructuring, which is already fully supported. Comment
| you are replying to is asking about pattern matching for
| flow control or conditional assignment, which JS doesn't
| currently support.
| satvikpendem wrote:
| Is Dart's pattern matching influencing the JS proposal as
| well? Or are both sort of separate without much influence
| from either side?
| munificent wrote:
| I have read the JS proposal many times, so it's an
| influence on Dart. I suspect Dart hasn't had much
| influence on JS because our proposal is newer.
| vips7L wrote:
| > the "matching" part means that in many languages you can
| also ask questions about values as you destructure them,
|
| I started implementing Lox with Java's sealed classes +
| pattern matching on switch. The exhaustiveness has been
| really nice to ensure I cover each new token/expression as
| I add them.
| nvarsj wrote:
| It makes it very easy to deal with nested data structures.
| Imagine creating a nested map/struct literal, and then
| extract the values out using a very similar syntax on a
| single line.
|
| It's one of those things that when you get used to, you
| wonder why other languages don't implement it.
| Alifatisk wrote:
| I think this answers the question very well, thank you. I
| found this [1] documentation from Ruby explain what it
| solves pretty good aswell.
|
| [1] https://docs.ruby-
| lang.org/en/3.0/syntax/pattern_matching_rd...
| foolfoolz wrote:
| its amazing how much the world hasn't been able to keep up with
| java. github PRs still have no syntax highlighting support for
| record and var
| jayd16 wrote:
| Why do you think that is? I thought things like the language
| server protocol made this a self service kind of problem. Who
| needs to be catching up?
| oaiey wrote:
| Because syntax highlighting in JavaScript is (presumingly)
| not covered by LSP but by a generic syntax parser. And these
| updates take endless through the supply chain pipeline.
|
| And as a side note: LSPs are not exactly free these days
| anymore. Java is not considering it core project (I guess
| outsourced to RedHat and Eclipse) and Microsoft has a very
| erratic behavior towards what is in and out the LSP or DAP.
| TheAceOfHearts wrote:
| Github uses Linguist for syntax highlighting and has a section
| in their CONTRIBUTING document for fixing bad syntax
| highlighting [0].
|
| Admittedly I couldn't figure out exactly what repo is being
| used for Java's syntax highlighting since vendor/README.md says
| Java is using tree-sitter/tree-sitter-java and grammar.js in
| that repo appeears to already include references to record.
|
| languages.yml [1] shows ace_mode java, and ace editor's
| java_highlight_rules.js doesn't mention record anywhere. I'm
| not clear if github is using ace editor or code mirror, since
| both are mentioned there.
|
| Hopefully this helps get started on improving the poor syntax
| highlighting experience.
|
| [0]
| https://github.com/github/linguist/blob/master/CONTRIBUTING....
|
| [1]
| https://github.com/github/linguist/blob/c34f887f48d81e2ed42b...
|
| [2]
| https://github.com/ajaxorg/ace/blob/a2e89b94b4dcdff28bf3c8f4...
| mrkeen wrote:
| With Java it's always win/win. If external software works with
| it, "Java has great tooling", if it doesn't, the rest of the
| world is slow.
| WesSouza wrote:
| lol
| timcavel wrote:
| [dead]
| ar9av wrote:
| Gist: ``` JDK 20 introduces six features: - Scoped values for
| safe sharing of data across threads - Record patterns for
| declarative data navigation and processing - Foreign function and
| memory API for interoperation with code and data outside the Java
| runtime - Virtual threads for lightweight concurrent programming
| - Structured concurrency for simplified multithreaded programming
| - Pattern matching for switch statements and expressions for
| concise and safe complex data-oriented queries ```
| carimura wrote:
| ...but also thousands of other stability, performance, and
| security updates.
| ActorNightly wrote:
| Don't worry, someone will still manage put in a bug that
| results in a zero day in the next 2 years.
| papercrane wrote:
| While the Java community has had some high profile
| vulnerabilities, I can't recall a major one that was
| actually tied to the JVM itself since dropped applets.
| Instead it's usually a popular library or framework.
| cesarb wrote:
| > I can't recall a major one that was actually tied to
| the JVM itself since dropped applets.
|
| Not exactly tied to the JVM, but IIRC one of the
| prerequisites for the Spring4Shell vulnerability was the
| existence of a new method added by Java 9. If you were
| still on Java 8, you were not affected.
| kaba0 wrote:
| As opposed to what, powering off your servers so they can
| never get vulnerable?
| tiffanyh wrote:
| What's the relationship between the Java releases and GraalVM
| releases?
| mike_hearn wrote:
| They're being synchronized at the moment.
| leros wrote:
| This seems like an appropriate place to post the official Java
| rap: https://youtu.be/b-Cr0EWwaTk
| BenoitP wrote:
| I prefer this one: Java Forever And Ever Movie (Java vs Windows
| .Net)
|
| https://www.youtube.com/watch?v=RnqAXuLZlaE
| elygre wrote:
| All the JavaZone videos are amazing. Like this one:
| https://www.youtube.com/watch?v=1JZnj4eNHXE
| oaiey wrote:
| Awesome but today this would be a different story line ...
| maybe: two old conservatives (Java and C#) re-inventing
| themselves to fight against the hipsters (Go, Swift, JS, ...)
| ;)
| orthoxerox wrote:
| JS is older than C#.
| Idiot_in_Vain wrote:
| Damn, time flies.
|
| I remember the excitement from the different alpha/beta versions
| that were coming out in 1994/1995.
| jvolkman wrote:
| Time only started flying with the release of Java 9. Prior to
| that versions stuck around for years.
| jwr wrote:
| I still remember the Java launch party that was done by Sun
| Microsystems (regional office).
| garblegarble wrote:
| This is exciting, can't wait for the LTS release next year...
| that said, I don't much care for the "case SomeType t when ..."
| pattern matching syntax, I don't see the benefit of introducing a
| new keyword over using "if"... or even just "&&". To pinch the
| example used in[1]: case Tuner t &&
| guitar.isInTune() -> ...;
|
| and case Tuner t if guitar.isInTune() -> ...;
|
| both seem as clear as case Tuner t when
| guitar.isInTune() -> ...;
|
| ...am I misunderstanding the reasoning here? Is it being
| introduced to keep the grammar definition simpler?
|
| 1: https://foojay.io/today/its-java-20-release-day-heres-
| whats-...
| pron wrote:
| This year. Six months from today.
| shagie wrote:
| (just on the following up on this)
|
| https://en.wikipedia.org/wiki/Java_version_history
|
| The non-LTS releases are every 6 months and have support for
| one year.
|
| LTS releases are every 4th release which falls on odd
| numbered years in September.
| lifewallet_dev wrote:
| I think the only reason is that they're very different, if you
| define them: type when expression -> block
| if expression -> block
|
| For parsing works better, for programmers is better since they
| don't confuse both concepts, and in general pattern matching
| isn't the same as a if condition or a switch.
|
| https://stackoverflow.com/questions/199918/explaining-patter...
|
| I think the difference is when you start pattern matching on
| tuples and other types that you cannot do a simple `if
| ident.isinstanceof(type) ->`.
|
| For example in Elixir you can do: def
| ident(param = {:key => true}):
|
| This will only match when the param type is not only `map`, but
| also contains a key named `:key` and its value is `true`.
|
| In the end though, it's syntax sugar (but everything is if you
| put it that way classes are syntax sugar).
| mason55 wrote:
| In the case of &&, the left hand side of the expression (Tuner
| t) isn't a boolean expression.
|
| In the case of "if", you're right, the grammar doesn't work,
| both because the syntax of Java already says that the if
| condition must be enclosed in parentheses and also because an
| if block is a statement and you need an expression here.
|
| To make either of those work, you'd have to make the rest of
| the pattern matching syntax much worse.
| anyfoo wrote:
| The "&&" one is super confusing indeed, but the "if" one is
| just a question of style. It would be possible to reuse the
| "if" keyword for different grammar. python does it for its
| trinary operator, where there is an expression instead of a
| statement after "then" (e.g. "foo = if bar then 1 else 2"),
| but if Java does not have the same habit of reusing keywords
| already (not sure), it might not want to start now for
| consistency.
| papruapap wrote:
| they want it to be as ugly as cpp
| dang wrote:
| Maybe so, but please don't post unsubstantive and/or
| flamebait comments to Hacker News. We're trying for something
| different here:
| https://news.ycombinator.com/newsguidelines.html.
| bcrosby95 wrote:
| In 2nd preview, they used &&: https://openjdk.org/jeps/420
|
| At 3rd preview, they switched to when:
| https://openjdk.org/jeps/427
|
| In that JEP they state:
|
| > Based upon experience and feedback we propose instead to
| allow when clauses in switch blocks to specify guards to
| pattern labels
|
| So I assume people thought && was confusing.
| [deleted]
| anyfoo wrote:
| The "&&" one is bizarre, it makes it look like the whole thing
| is a Boolean expression, which it absolutely is not. That gets
| even weirder because the part right of it actually is a Boolean
| expression, so on top of very confusing reading you now make it
| look like there are strange interactions with operator
| precedence. Using && is one of the worst choices.
|
| The "if" one does not suffer from any such problem and reads
| okay to me. I guess one argument against it could be that since
| the whole thing is a distinct grammatical construct, why not
| just introduce a distinct keyword instead of making an existing
| keyword depending on context? That's mostly a question of style
| though (e.g. I don't know right now if Java already has an
| habit of reusing keywords like that).
| garblegarble wrote:
| The "&&" approach is how you express that same logic in an if
| statement in Java today.
|
| Given this pattern matching syntax change, you'd write:
| switch(obj) { case Tuner t when guitar.isInTune()
| -> ...; ... }
|
| For a switch, but for an if statement it's written as:
| if (obj instanceof Tuner t && guitar.isInTune()) {
| ... }
|
| Edit: I do wonder, actually, if avoiding "&&" is to allow the
| "when" case execution to be reordered (e.g. to allow JIT to
| extract common "when" conditions prior to the switch
| expression), which would be wrong to do given the short-
| circuiting rule implications of "&&"
| hn_throwaway_99 wrote:
| As another comment mention, they _did_ use && in the 2nd
| preview, but then switched it, so you're right, it must have
| been confusing.
|
| FWIW, though, I don't find it "bizarre". While it's not a
| boolean expression per Java, at least in my mind it serves
| the same purpose: "in the case that thing x is of type
| SomeType _and_ ...some other thing about ((SomeType)x) is
| true... ".
|
| I think it's a tough choice, I'm sure they were probably not
| wanting to add a new keyword, but at the end of the day
| "when" is so familiar to anyone who's ever written SQL (which
| I'm guessing is most Java devs) so seems like a good choice.
| anyfoo wrote:
| > While it's not a boolean expression per Java, at least in
| my mind it serves the same purpose
|
| But if some construct looks the same, but is not the same,
| and worse, only "somewhat" the same, you get confusing
| behavior. At least for newcomers, or even just software
| engineers who just don't care about language grammar that
| deeply (which I imagine are not only a lot, but also a lot
| of the Java target audience specifically).
|
| Case in point, the author I was replying to wondered in a
| followup whether && would/should still act like a shortcut-
| and operator would, or not.
|
| There is definitely some subjectivity to it, but personally
| I much prefer if different constructs look clearly
| different. Any ambiguity is squashed immediately, and in
| the case of "when" it's still fully clear how it works. I'm
| also okay with the "if" variant, because while it reuses a
| keyword, it's clearly a different "if".
| pkulak wrote:
| I think Rust uses "if" for its match guards too and I don't
| recall it upsetting anyone. I'm all for keeping things
| consistent between languages if only to prevent too much bike
| shedding.
| mikepurvis wrote:
| I'm not a Java user, but I really don't love the overloading
| of `if` in Python (statement, ternary, comprehensions), so
| introducing a new keyword here seems pretty reasonable to me.
|
| And don't even get me started on `static` in C++.
| pajko wrote:
| OK, no static then, but what about if constexpr (...) ? :D
| rerdavies wrote:
| And then there's "static constexpr" (which is only used
| in places where non-static constexprs are illegal). An
| overloaded keyword that's become so overloaded, it's even
| used in places where it's completely unnecessary! :-P
| planede wrote:
| Also `if consteval {...}` in C++23. But really "if" still
| semantically means the same thing in all of these. Unlike
| "static", which is all over the place.
| munificent wrote:
| I work on Dart which is also adding pattern matching [1]. When
| we designed the syntax for guards, we also considered exactly
| these three choices before ultimately landing on "when" too.
|
| Our main reasoning was:
|
| "&&" is intuitive but it means that you can have a pattern that
| is immediately followed by an infix operator. That can be
| problematic if you ever want to make "&&" a valid _pattern_
| infix operator. And, in our case, we ended up doing exactly
| that, so "&&" would have been ambiguous. If you were to write:
| case foo && true:
|
| Then it could be parsed as either a pattern that matches when
| the value is equal to the constant "foo" and is equal to the
| constant "true". Or it could be parsed as a pattern that
| matches when the value is equal to the constant "foo" followed
| by a pointless guard that always succeeds.
|
| "if" is nice because it's already a reserved word and the
| semantics are pretty obvious. But in Dart, an if statement
| always has the condition in parentheses. Those are pointless in
| a pattern since we already have another explicit delimiter
| separating the guard from the case body: case
| foo if (condition): // ^
|
| We could say that the if condition in a guard doesn't need
| parentheses but if conditions elsewhere do. But that's likely
| just an annoying footgun where users will write them
| unnecessarily (but harmelessly at least) in guards and forget
| them in if statements and get compile errors.
|
| If Dart didn't require parentheses around if conditions, we
| probably would have used "if" for guard clauses to (like Scala
| and Rust do).
|
| So we tried "when" and most users and team members seem to like
| it. Syntax design is a human-centered process so often the
| right answer is just what feels right to the most people.
|
| [1]: https://github.com/dart-
| lang/language/blob/master/accepted/f...
| garblegarble wrote:
| Thank you, that's excellent insight into the thought process
| for the same feature at about the same time.
|
| You mention about the human-centred nature of syntax
| design... do you have any instinct for why one route vs
| another felt right to users? Do you feel like you've
| developed a better instinct for this over time, or is it
| still hard to predict what will feel natural to users?
| munificent wrote:
| _> do you have any instinct for why one route vs another
| felt right to users?_
|
| That's a good question. It is something I spend a lot of
| time thinking about when I see how users react to a design.
| In this case, I don't think I have a good answer as to why
| "when" seemed to go down easier than "if".
|
| _> Do you feel like you 've developed a better instinct
| for this over time, or is it still hard to predict what
| will feel natural to users? _
|
| I'd like to believe so, but "if" was my first pick, so I
| guess not. :)
|
| I think what our team does have now that really helps is
| better processes to evaluate a design, talk about it, get
| feedback from users, and incorporate that feedback into the
| design. It's all pretty informal, but I think we're
| iteratively able to get designs users seem to like.
|
| But it's always really hard. There are so many trade-offs
| and users have different preferences and expectations, so
| finding the right balance is always difficult. I think
| that's why it's so endlessly fascinating to me: you can
| never fully "solve" syntax design.
| evntdrvn wrote:
| C# ended up with `when` for guards as well, a couple
| years ago :)
| Pet_Ant wrote:
| Gotta say I'd've taken the if with parentheses myself. Feels
| like it's reusing something familiar even if they are
| extraneous at times.
| munificent wrote:
| That was my initial pitch too. But after months, almost no
| one seemed to have warmed up to it. When we changed it to
| "when", just about everyone seemed to like it better.
|
| Syntax design is weird. Sometimes the only way to tell if I
| did it right is when no one says anything. People
| complained when I used "if". No one did after I switched it
| to "when". <shrug>
___________________________________________________________________
(page generated 2023-03-21 23:00 UTC)