[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)