[HN Gopher] Java in the Small
       ___________________________________________________________________
        
       Java in the Small
        
       Author : crummy
       Score  : 382 points
       Date   : 2024-12-18 20:42 UTC (2 days ago)
        
 (HTM) web link (horstmann.com)
 (TXT) w3m dump (horstmann.com)
        
       | wing-_-nuts wrote:
       | I remember reading horstmann's books in college and it doesn't
       | surprise me at all that java is the hammer he reaches for given a
       | particular nail.
       | 
       | I have to say I find it an odd choice for small replacements for
       | bash scripts. I think python or golang are probably better
       | choices for that purpose. Java is one of those 'enterprise'
       | backend languages which lend itself to making a _team_ productive
       | over making the individual productive, and I say this as a java
       | / go dev who's most comfortable with java for most backend work.
        
         | ggerules wrote:
         | Dr. Horstmann was my advisor in college, San Jose State.
         | 
         | I just loved his lectures, very dry sense of humor, and
         | extremely funny.
         | 
         | He was just getting started writing books in the early 90s. He
         | has this awesome way of thinking about programming, that I
         | imparted to my own students when it came my turn to teach
         | programming. I wish there some videos of his classes that I
         | could go back to and share with people.
         | 
         | Good website also, https://horstmann.com/
         | 
         | The picture on the website with him in the row boat has a funny
         | story with it. When asked why he is in a row boat, he would
         | reply, "Students are in the row boat with me, learning to
         | program. At some point I push them out of the boat into the eel
         | infested lake. The ones who are clever enough to make it back
         | to the shore will be good programmers." All of this said with a
         | faint hint of a German accent and a sly smile.
         | 
         | If you happen to read this, Dr. Horstman. I made it to shore.
         | Thanks! It has been an awesome journey!
        
           | spike021 wrote:
           | That's an interesting experience. I also had him as a
           | professor a while back and he was awful. He was always
           | looking at his phone or computer especially during project
           | presentations and completely ignoring what anyone said. He
           | also didn't seem to know much course material in general.
           | 
           | What I remember most is his obsession with Emacs.
           | 
           | There was one time that I was grateful though, I had to buy a
           | few of his books and one of them had a defect from the
           | printer, so he helped me get a new copy from the publisher
           | for free.
        
         | anitil wrote:
         | > lend itself to making a team productive over making the
         | individual productive
         | 
         | That's a really insightful way of presenting this. I think if
         | that's how I'd been introduced to Java I might even have
         | tolerated it.
        
       | PaulHoule wrote:
       | I learned to code "single file Java" when I was working through
       | Hacker Rank before they added features to the JDK to make it
       | easier. Certainly if you want to do whiteboard coding sorts of
       | problems it is good to know.
        
       | losvedir wrote:
       | I've been using Java 21 for Advent of Code this year, and I've
       | been surprised at how much less clunky it is than I remember.
       | `var` and `record`'s are especially nice for how I like to code.
       | It's still not perfect, but it's not something that I hate
       | programming in now.
       | 
       | These were some neat tricks. I've been using the `java
       | myfile.java` approach for running the AoC problems. I didn't
       | realize the "implicit class" thing where you could have top level
       | statements and methods, though, with the automatic import of
       | java.base. That's pretty slick for this.
        
         | papercrane wrote:
         | Records being allowed in methods has been great for me when
         | doing things like path finding. Makes it easy to write
         | something like:                   record Node(int cost, int
         | row, int col){}         var pq = new
         | PriorityQueue<Node>(Comparator.comparingInt(Node::cost));
        
           | gf000 wrote:
           | This is actually a natural extension of classes being allowed
           | inside, which is not well-known for some reason. Nonetheless,
           | I also really like this feature with records.
        
             | dehrmann wrote:
             | > which is not well-known for some reason
             | 
             | Really? A whole generation of Java programmers wrong
             | functor classes in-line.
        
               | danhau wrote:
               | Those are anonymous classes, if we're thinking of the
               | same thing. Java also supports named classes bound to a
               | method's scope (local classes).
        
           | roncesvalles wrote:
           | It's allowed because Record automatically implements methods
           | called cost(), row(), and col().
        
         | user_of_the_wek wrote:
         | Just to be clear, the implicit class thing is still a preview
         | feature as of Java 24, which should come out next March. It
         | might be finalized for Java 25, in the coming September. But no
         | guarantees. Until then you'd need to explicitly enable it with
         | a cli parameter.
        
         | ansgri wrote:
         | So it's almost as good as C#? Which would be my favorite
         | language if not for strong ties to MS ecosystem.
        
       | Nijikokun wrote:
       | Java is still great, same for PHP and they have only been getting
       | better.
        
         | lxgr wrote:
         | Great is pretty domain-specific!
         | 
         | Java has been great for larger projects for a while, but I
         | think smaller things like one-off scripts have been firmly out
         | of reach so far.
         | 
         | It's good to see that change, as being able to use it in the
         | small has obvious synergies.
        
           | riku_iki wrote:
           | > but I think smaller things like one-off scripts have been
           | firmly out of reach so far.
           | 
           | why specifically?
        
             | lxgr wrote:
             | The article lists several good reasons:
             | 
             | Having to compile every time (or at least there not being a
             | convenient wrapper that compiles and runs at once), the
             | boilerplate of having to define a class and main method,
             | exception handling, and most of all having to deal with
             | Maven.
        
               | riku_iki wrote:
               | you don't need to deal with Maven if Java standard
               | library(which is huge) is enough for you. Also, not sure
               | why such big resistance against maven.
               | 
               | Other pointers are either opinionated or minor. From
               | another hand, if dev has experience in Java, benefit of
               | not learning some new language/ecosystem is kinda huge.
        
           | never_inline wrote:
           | For CLI scripts, PicoCLI with Graalvm seems to be a good
           | option now.
        
       | HaroldCindy wrote:
       | I wasn't aware that single-file Java without a top-level static
       | class was possible now, that + JBang seems quite useful for small
       | tasks.
       | 
       | One nit:
       | 
       | > Python programmers often use ad-hoc dictionaries (i.e. maps) to
       | aggregate related information. In Java, we have records:
       | 
       | In modern Python it's much more idiomatic to use a
       | `typing.NamedTuple` subclass or `@dataclasses.dataclass` than a
       | dictionary. The Python equivalent of the Java example:
       | @dataclasses.dataclass         class Window:             id: int
       | desktop: int             x: int             y: int
       | width: int             height: int             title: str
       | @property             def xmax(self) -> int: return self.x +
       | self.width                  @property             def ymax(self)
       | -> int: return self.y + self.height                   w =
       | Window(id=1, desktop=1, x=10, y=10, width=100, height=100,
       | title="foo")
        
         | qsort wrote:
         | This is obviously valid, but it's definitely more common in a
         | language like Python to just dump data inside a dict. In a
         | dynamic language it's a far more flexible structure, it's the
         | equivalent of HashMap<? extends CanBeHashed,
         | LiterallyWhatever>, which is obviously a double edged sword
         | when it comes to consuming the API. Luckily more rigid
         | structures are becoming more popular at the API boundary.
        
         | bcoates wrote:
         | That's deranged, just use a namedtuple and some functions. Even
         | decorators for something this simple are a code smell.
         | 
         | What do you do when another module needs ymin, inheritance?
         | 
         | OO is dead, leave it buried umourned.
        
       | lxgr wrote:
       | It's of course always a good idea to read the article before
       | posting, but doubly so here - I was getting ready to yell about
       | all of the annoyances making this infeasible to anyone with a
       | less-than-extreme pain tolerance, but it turns out Java has
       | changed a lot since I last used it around six years ago :)
        
       | Shakahs wrote:
       | After years of Python and TypeScript, I've started using Java as
       | my default for everything. It's just so much more productive. The
       | ancient developer memes that Java is slow and clunky don't apply
       | anymore.
       | 
       | Postgres also had a long-held reputation for being slow and
       | difficult, but it made incremental improvements for decades and
       | now it's the default choice for databases.
       | 
       | I see Java in the exact same position, as the Postgres of
       | languages.
        
         | agumonkey wrote:
         | what parts do you enjoy now ?
         | 
         | I do agree that new ecosystems (js for instance) makes you miss
         | some of the old big languages development feel. less churn
        
         | sdf4j wrote:
         | First time I hear those claims about Postgres. Was that the
         | sentiment 30 years ago?
        
           | dannyobrien wrote:
           | It was definitely initially seen as big and cumbersome
           | compared to MySQL, but sentiment shifted.
        
             | cryptos wrote:
             | MySQL was kind of a fast toy database in the early days,
             | but it was good enough to power simple PHP based websites.
        
           | Tostino wrote:
           | If say it was only about 15 years ago that the Postgres is
           | slow stuff started dying off. Right around 2010.
        
           | bcoates wrote:
           | 14 years or less. Any version of Postgres before 9.0 was a
           | nightmare to administer as a real production transactional
           | dbms, at least the off the shelf version without a whole lot
           | of tweaking without a (then very rare) pg expert.
        
             | fulafel wrote:
             | I don't remember that. But I remember having basic DB
             | features like transactions while MySQL didn't.
        
         | cflewis wrote:
         | The problem with Java since Java 8 has never been Java. It's
         | been about the appalling ecosystem that infected it with
         | reflection frameworks. It was bonkers that "POJO" was ever a
         | thing that had to be defined.
         | 
         | It feels like these frameworks are now just falling away, which
         | is great. I'm not even hearing about Spring anymore, and if
         | there is any reason to not use it, it would be this cringe "how
         | do you do fellow kids?" blurb I just saw on their front page:
         | 
         | > Level up your Java(tm) code
         | 
         | > With Spring Boot in your app, just a few lines of code is all
         | you need to start building services like a boss.
         | 
         | I personally would reach for Go by default, but I have no ill-
         | will to Java.
        
           | MattPalmer1086 wrote:
           | Ahhhhh, yes. Java itself isn't bad and has been getting
           | better. The frameworks made me want to scream.
        
             | arez wrote:
             | which ones specifically? I like Spring Boot tbh
        
               | MattPalmer1086 wrote:
               | Hibernate mostly. Spring too, but it has been a while.
               | Mostly I just find the abstraction isn't worth it .
        
               | Alupis wrote:
               | The way you write this makes be think you rawdog'd
               | Hibernate and Spring Framework. Don't do that... you will
               | hate yourself.
               | 
               | Boot is something entirely different. You write very
               | little code and get a _ton_ done. The trade off is you
               | are firmly now a  "Boot" codebase, but once you learn how
               | Boot works it's not a big deal.
        
               | fiddlerwoaroof wrote:
               | I've had to maintain a couple Spring Boot apps and I
               | absolutely cannot stand them: they pull in a whole pile
               | of random dependencies and do weird things to your build
               | with little explanation. Then, all the functionality
               | involves a ton of classpath scanning and annotation-based
               | DI that makes it hard to figure out how all the things
               | fit together.
        
               | gf000 wrote:
               | I mean, have you learnt the framework before attempting
               | to do that?
               | 
               | Frameworks are frameworks, not libraries. You can't just
               | start writing/understanding them - frameworks are
               | different from libraries precisely because _they_ call
               | your code, not the reverse.
        
               | lproven wrote:
               | That's a great explanation. Thanks for that.
        
               | fiddlerwoaroof wrote:
               | Yes, the problem is exactly that the framework calls your
               | code instead of being called by you code.
        
               | Alupis wrote:
               | That's how _all_ frameworks work though. This is not a
               | criticism of Spring Boot. You are criticizing the use of
               | a framework at all.
               | 
               | Some people hate to write the same basic things over and
               | over. That's where a framework excels. Write only the
               | glue/logic you need to make your app work.
               | 
               | The way you have described your experience with Spring
               | Boot seems to imply you did not take the time to learn it
               | at all, and therefore its' unsurprising to us you had a
               | hard time of it.
        
               | fiddlerwoaroof wrote:
               | Not writing the same thing over and over again is a
               | feature of abstraction. A framework is a user-hostile way
               | to abstract because it makes the source code opaque to
               | developers. There's no reason why a library-based
               | approach has to be more repetitive than frameworks.
        
               | gf000 wrote:
               | CRUD backends have well-understood requirements, in a
               | way, a significant part of the work is done for you. You
               | are there to customize certain parts only.
               | 
               | How else would you architect with this in mind? Given
               | that literally every other framework is quite similar
               | (RoR, PHP's solutions, etc).
               | 
               | There is another niche, the HTTP server libraries, but
               | they are much more low level.
        
               | Alupis wrote:
               | Right, so you cobble together 48 different libraries,
               | wrangle all of their configurations and stitch them all
               | together yourself.
               | 
               | You do this 18 times because you have 18 different apps
               | with similar requirements but deal with different
               | data/endpoints/whatever.
               | 
               | On your 19th app you decide to standardize how you cobble
               | together all of these libraries so that you don't have to
               | start at ground zero every single time.
               | 
               | Now you've invented a framework.
        
               | MattPalmer1086 wrote:
               | I was working with legacy code bases where the original
               | Devs loved frameworks. Massive performance problems and
               | nobody could understand how it all fit together at
               | runtime.
               | 
               | Hibernate eventually got entirely nuked, Spring we
               | couldn't entirely unwind easily; it had caused a whole
               | bunch of crappy architectural issues and was too much
               | effort to rewrite from scratch.
               | 
               | Although the code _looked_ simpler using the frameworks
               | and annotations, it was actually a huge rotten mess that
               | didn 't work well at all, with workarounds for all kinds
               | of weird things in it.
        
               | Terr_ wrote:
               | I find pretty much every ORM in any language is
               | problematic. The best you can hope for is a certain
               | amount of internal design consistency, so that even if
               | you can't do what you want it's at least clear what you
               | are doing.
        
               | cryptos wrote:
               | Since I had the "joy" to use TypeORM (node.js stuff), I
               | really value Hibernate, although there are some little
               | corner cases I'd like to be better. But ORMs solve a
               | really hard problem and I haven't seen anything better
               | than Hibernate so far (and don't come up with JOOQ or
               | MyBatis!).
        
           | qsort wrote:
           | > The problem with Java since Java 8
           | 
           | I agree with the sentiment, but I'd move up to a version with
           | type inference at least. I have nothing against static types
           | and in fact in a vacuum I prefer them, but the particular
           | brand of OO and "weak" generics that Java and C# have feels
           | like filling forms in triplicate. "var" alleviates that
           | significantly.
        
             | neonsunset wrote:
             | Generics in Java and C# are _vastly_ different.
             | 
             | .NET has true generics with full type information and
             | struct type parameter monomorphization which works the same
             | way generics do in Rust.
             | 
             | Edit: C# _does_ have type inference for generics, just not
             | the full HM one. It is also quite more capable for lambdas
             | which is a bit frustrating because it does not resolve
             | nested generics otherwise. I miss it - F# does it the way
             | it always should have been.
             | 
             | There are many other differences small and big that arise
             | from the way Java does generics and the fact that
             | primitives can't participate - you will never see
             | `IntStream` kind of workarounds in C#. Some libraries abuse
             | and misuse generics for no profit (looking at you Azure
             | SDK), but it's not as widespread. Shallow generic types are
             | always inferred from arguments.
        
               | qsort wrote:
               | yes, this is true. I was talking more about the UX of how
               | to use them, which in both cases is quite painful without
               | type inference.
        
               | throwaway03452 wrote:
               | > you will never see `IntStream` kind of workarounds in
               | C#.
               | 
               | You may not see that in Java in the future either. Java
               | will have value objects from the Valhalla project, and
               | part of the plan is to replace Integer with a value
               | object. Then there will be less of a reason to use raw
               | int primitives, because the JVM can treat value objects
               | much more efficiently than normal objects.
        
               | neonsunset wrote:
               | The difference is that C# has been designed with proper
               | generics since version 2 (pushed by F# research group
               | with Don Syme) and is now on version 13. At the same
               | time, structs have been present since version 1.
               | 
               | All APIs and collection types build on this foundation,
               | with standard library leveraging generic monomorhpization
               | for zero-cost abstractions. Code that would have needed
               | C++ implementation in the past is naturally expressed in
               | pure C#. Generics are fully integrated into the type
               | system at IL level, avoiding special-cased types or
               | bespoke compiler handling (besides monomorphization).
               | 
               | This enables numerous zero-cost features: tuples
               | (unnamed/named), structs with controlled mutability and
               | record structs, pattern matching, stack buffers that do
               | not rely on escape analysis, structs with byref pointers
               | for slice types (Span<T> and friends) which a good two
               | thirds of the standard library accepts. Numeric and
               | vector primitives are used in a simple way without setup
               | requirements like Panama Vectors.
               | 
               | While project Valhalla will get Java's foot in the door
               | in some domains, it will remain a less optimal choice
               | than C#, C++, Rust, etc. Java's evolution primarily
               | serves its ecosystem's needs, whereas C# benefits from
               | being a newer language that learned from both Java and
               | C++ and got influenced by F# and other research projects
               | inside MS. This makes C# more idiomatic and terse. The
               | historical drawbacks - platform lock-in, being closed-
               | source, and having _relatively_ weak compiler - have been
               | resolved over the past ~9 years.
        
             | layer8 wrote:
             | Any competent Java IDE automatically generates you a
             | variable declaration from the expression you want to assign
             | to it. It's actually less keystrokes than having to type
             | "var". Unless you only use a simple editor that doesn't
             | perform static analysis, less typing is not a good excuse
             | for using "var".
             | 
             | Conversely, in Java you often use the diamond operator like
             | in:                   List<String> items = new
             | ArrayList<>();
             | 
             | (Half of which, again, is code completion in your IDE.)
             | 
             | That doesn't work with "var". You'd have to write:
             | var items = new ArrayList<String>();
             | 
             | while losing the ability to constrain your variable to a
             | narrower type.
             | 
             | The loss of directly seeing the type information in
             | statements of the form                   var foo = bar(x,
             | y);
             | 
             | should meet a very high bar, IMO.
        
               | bcrosby95 wrote:
               | I've found var preferable when reading code.
               | 
               | I've wrought my hands over this and eventually came to
               | the conclusion that developers in every language that
               | started with local type inference have embraced it. So
               | I've mostly ignored my concerns and gone with "var for
               | everything".
               | 
               | If you have trouble with a type then rename the function
               | or variable (AKA your "foo" and "bar" example. The names
               | are bad, _fix them_. Context matters, _we have none
               | here_. No one has an editor that displays a _single line
               | of code at a time_.). But in general we haven 't had
               | issues on our projects.
               | 
               | Beyond that, my IDE (Intellij) makes it easy to uncover
               | the inferred type if I really need to be 100.00% sure
               | what it is. In general I don't, because in general I
               | don't care, and even before 'var' I was generally
               | ignoring the type anyways.
        
               | gf000 wrote:
               | I think there is a tasteful way to selectively use var
               | where it makes sense.
               | 
               | Even in your example, narrowing the variable doesn't make
               | much sense - you are in a local scope, you control
               | everything. Narrowing is more meaningful in fields, where
               | var won't work by design.
               | 
               | Locally a well-named variable is often significantly more
               | important than some long, somewhat useless type
               | signature, especially when the right hand side makes it
               | clear.
        
           | gf000 wrote:
           | Spring boot is itself also very different than Spring, so
           | depending on what was your last experience with these
           | frameworks, you might be surprised.
           | 
           | Given, they are still quite reflection-heavy and full of
           | POJOs and annotations, it supports compile-time resolution
           | for many things now.
           | 
           | Also, you would be hard-pressed to find a more productive
           | developer than a well-versed Spring boot guru for typical
           | backend jobs. You might dislike the framework, but credit
           | where it's due, it is a workhorse and the amount of time
           | someone makes a POC, you can make it with spring properly, in
           | a way that you can build your prod app on top. Like, it's
           | easily as productive as RoR and similar.
        
             | p2detar wrote:
             | Serious question - what could Spring Boot give me for
             | POC/prototyping that Javalin or Micronaut couldn't? I
             | really struggle to understand why most of Java shops out
             | there have set themselves on the Boot path. Is it
             | technology-based decision or politics?
        
               | Alupis wrote:
               | Boot has an "app" (err, lib) for everything. It's fully
               | featured, and highly opinionated.
               | 
               | Pretty much any modern computing problem you have, Boot
               | has you covered[1].
               | 
               | So while you may not have ever used a Streaming library
               | before, if you know Boot, then the Spring Boot Streaming
               | library will already be familiar.
               | 
               | [1] https://spring.io/projects/spring-boot
        
               | ivan_gammel wrote:
               | It's established patterns. Javelin or Micronaut are
               | probably great, but not a lot of people understands how
               | to build a real project with them. With Spring Boot you
               | don't even think about it.
        
               | le-mark wrote:
               | I'm not familiar with either of those frameworks so can't
               | comment on them specifically, but 10+ years ago not using
               | spring/boot entailed glueing together a lot of disparate
               | libraries to do things spring boot had built in. Spring
               | boot includes pretty much everything. Plus reliability,
               | battle tested, easy to hire people with experience using
               | it.
        
               | gf000 wrote:
               | Spring Data can be ridiculously productive. It _is_
               | definitely in the magic category, but you can just have
               | an interface with methods named in a specific way, and
               | then just call that from a controller class, and you have
               | a REST API that calls into your DB for any of the usual
               | CRUD queries immediately. And it 's not even just a hack
               | that works on the easy case, you can annotate it with
               | complex hand-written SQL (both db-independent, but feel
               | free to use native queries), and easily extend them with
               | real implementations if you need more control.
        
               | throwaway03452 wrote:
               | I choose Spring Boot anytime I have to create a service,
               | just for that reason.
               | 
               | The eco system is a huge force multiplier, and is
               | constantly evolving. Spring Boot simplifies that a lot by
               | simplifying the setup to the point where you often only
               | have to add a single dependency, and everything is
               | configured with default configurations (which you can
               | change if necessary of course)
               | 
               | Just look at all the different projects under the Spring
               | banner: https://spring.io/projects
               | 
               | One example is the new Spring AI, where they have
               | abstracted a lot of functionality and you can change
               | providers (OpenAI, Mistral, AWS, Azure, Google) easily.
        
               | vips7L wrote:
               | The ecosystem factor is real. I was looking at
               | implementing the SCIM protocol [0] in our user management
               | app, and if we were on Spring I could have just added an
               | Apache boot-starter dependency and been done in a few
               | days. However my company uses the Play framework and it's
               | going to take me weeks to implement it by hand.
               | 
               | [0] https://scim.cloud
        
               | throwaway03452 wrote:
               | If I ever found a startup I will mandate that we use
               | Spring Boot (java/kotlin) until we grow big enough to
               | afford the extra overhead with other frameworks. Spring
               | Boot is truly a Get Stuff Done framework
               | 
               | It would be hard to convince some people of this, because
               | "everyone knows Spring is enterprise". Unfortunately many
               | only have experience with legacy companies, bad code or
               | through reading old blog articles, and base their
               | opinions on that.
               | 
               | It's actually something you need to have experienced
               | yourself to recognize the possibilities.
               | 
               | It may sound strange, but I enjoy going through the long
               | list of projects in the Spring web site. I almost always
               | find something cool and is surprised at how much they can
               | simplify complex functionality
               | 
               | The learning threshold is also relatively low, because
               | they tend to use common best practices in the framework.
        
               | vips7L wrote:
               | I've spoken about this before but choosingg Play and not
               | Spring has been my companies biggest mistake. It has lead
               | us down so many half documented custom solutions that
               | would have just worked out of the box if we had chosen
               | the more popular stack.
               | 
               | I like Kotlin, but the lack of checked exceptions really
               | kills it for me. Exception safety is a bigger thing for
               | me than null safety.
        
       | simonw wrote:
       | Wow:                 void main(String[] args) {
       | println("Hello world");       }
       | 
       | I just saved that as "hello.java" and ran it (using OpenJDK
       | Runtime Environment Homebrew (build 23.0.1) which I happened to
       | have on my Mac already) like this:                 java --enable-
       | preview hello.java
       | 
       | This is SO MUCH less crufty than the old "public static void
       | main(String[] args)" thing. I always felt that was a terrible
       | introduction to programming, when Hello World included a whole
       | chunk of boilerplate and a class that didn't need to exist.
        
         | jimbob45 wrote:
         | I disagree. Working through each keyword until you understand
         | the full signature felt great when learning.
         | 
         | It's the Python if __name__ == __main__ trash that was the
         | worst. You'll never understand it and it doesn't fit in the
         | language.
        
           | Comma2976 wrote:
           | In my humble and correct (trumping anyone else's) opinion,
           | they are both garbage.
        
             | Quekid5 wrote:
             | You're not wrong... but for different reasons :)
        
           | exe34 wrote:
           | you don't need it until you get to importing modules.
           | 
           | hello world in python is literally just print("hello world!")
        
             | dvdkon wrote:
             | You don't even need it afterward, unless you want a file to
             | be both an importable module and an executable script.
             | 
             | Arguably you could be a happy Python programmer without
             | this capability.
        
               | jraph wrote:
               | I never understood why people bother with this when
               | writing their python main file, which is never going to
               | be imported because it doesn't make sense in the first
               | place.
        
               | elteto wrote:
               | Because I dislike interspersing executable statements at
               | module level with function definitions. I'd rather have
               | all code live inside functions and have one main entry
               | point for the script. It's just a personal preference,
               | nothing wrong with not doing that though.
        
               | jraph wrote:
               | But you could have a single main() call without the if
               | statement, couldn't you?
        
               | telotortium wrote:
               | REPL-based development. You might be developing a script,
               | but notice a bug. If you import your script as a module,
               | you can run the function you're debugging, figure out
               | what's wrong, edit the file, and then reimport the module
               | (using importlib.reload).
        
               | jraph wrote:
               | Okay, that's quite convincing, thanks!
        
             | usrusr wrote:
             | Isn't that hugely elaborate compared to languages where top
             | level statements are a function, functions return their
             | last statement, and the return value of the entry function
             | is sent to stdout unless invoked in special ways? That
             | print() around the "hello world!" does not appear any less
             | superfluous than all the public static void you can throw
             | at a javac 1.0
        
               | driggs wrote:
               | You mean a language like... Python?                 >>>
               | 'hello world'       'hello world'
        
               | usrusr wrote:
               | Exactly like that (well, almost exactly: if python
               | includes the quotes then it's not really equivalent to
               | print()).
               | 
               | The point was that by including that print(), people
               | already do say yes to including "like you'd do in a real
               | program" ceremony in their supposedly minimal examples.
        
           | dajtxx wrote:
           | Python seems to have started with 'why do those other
           | languages have all this trash' and then spent the time since
           | then learning why and coming up with worse versions.
           | 
           | I use python a lot these days, and like it, but it's pretty
           | funny seeing stuff like the above and type hints.
           | 
           | I hate not knowing what types a function takes and returns.
        
             | nayuki wrote:
             | > Python seems to have started with 'why do those other
             | languages have all this trash' and then spent the time
             | since then learning why and coming up with worse versions.
             | 
             | This seems true to me too. Examples:
             | 
             | * if __name__ == "__main__": main()
             | 
             | * Private members being marked by convention with leading
             | underscore (e.g. def _foo()) instead of being a language
             | feature
             | 
             | * @staticmethod as a decorator instead of being a language
             | feature
             | 
             | * Duck typing vs. abstract base classes
             | 
             | * Static type hints got retrofitted to the language
             | gradually, one feature at a time
             | 
             | * Reference-counted garbage collection seems to be more
             | deterministic than tracing garbage collection and ensures
             | that unreachable resources have their finalizers run as
             | soon as possible... except it's not true
             | 
             | * Having a GIL instead of being truly multi-threaded from
             | day one
             | 
             | * Various OOP concepts that are much better explained in
             | Java than Python: __eq__(), __hash__(), monitor wait() and
             | notify(), object finalizers, thread safety, weak references
             | 
             | * Distinction between str and bytes. This is the biggest
             | change from Python 2 to 3 and caused a lot of
             | incompatibilities. Java separated String and byte[] from
             | the start (though the use of UTF-16 is unfortunate).
        
               | Quekid5 wrote:
               | The whole switch/pattern matching thing is a true
               | abomination borne from: Well, things in statement
               | position can't be expressions (or however Pythonistas
               | might phrase it), so clearly switch/pattern matching
               | _must_ be a statement... It 's such an own goal and
               | undermines the main point of pattern matching.
               | 
               | (I do realize that there was opposition on this, but that
               | the Clearly Wrong side won out is baffling.)
        
               | nayuki wrote:
               | Yeah, it's a shame for Python. I am extremely impressed
               | that Java 14's switch expression (
               | https://openjdk.org/jeps/361 ) is a generalization of the
               | switch statement (since Java 1.0); it's like they took a
               | page from Rust's language design. I have found the switch
               | expression to be quite useful in my work.
        
               | Quekid5 wrote:
               | Probably from ML/Haskell, but yes :)
        
               | cutler wrote:
               | Same principle behind Python's crippled lambdas.
        
               | deaddodo wrote:
               | Your quibbles show either a) a fundamental
               | misunderstanding of Python or b) are just flat out
               | incorrect.
               | 
               | > * * if __name__ == "__main__": main()
               | 
               | So, don't use it. Python is frequently run as a scripting
               | language (something Java is fundamentally bad at) and
               | this stems from that. All it does is box logic off when a
               | file is being run directly vs imported. It's a user
               | convention and not a language one....ignore it if you
               | hate it so.
               | 
               | > * Private members being marked by convention with
               | leading underscore (e.g. def _foo()) instead of being a
               | language feature
               | 
               | This is all very well explained in the PEP. The quick run
               | down, Python doesn't do anything to hide logic from
               | users. Contracts are just conventions and python treats
               | it that way; so the developer can say "you _shouldn 't_
               | use this directly, here's a notation to let you know",
               | but nothing will stop a developer from doing what they
               | want. In Java they'll just write a wrapper class, inherit
               | the base class, and expose that logic. Or worse, fork the
               | library just to edit the class' functionality in some
               | minor way. In Python they'll just call it directly.
               | 
               | > * @staticmethod as a decorator instead of being a
               | language feature
               | 
               | @staticmethod is a built-in, it is a language feature. It
               | just doesn't follow your preferred syntax.
               | 
               | > * Duck typing vs. abstract base classes
               | 
               | You can do both in Python:
               | 
               | https://docs.python.org/3/library/abc.html
               | 
               | The concepts aren't mutually exclusive or even directly
               | related. Java just happens to be bad at one of them, due
               | to it's weirdly non-effective (for a VM'd language, at
               | least) reflection system; so you think it's bad.
               | 
               | > * Static type hints
               | 
               | You're complaining about reflective programming and then
               | complaining about a feature that essentially exists
               | because you can't reflect. It's circular.
               | 
               | > * Reference-counted garbage collection seems to be more
               | deterministic than tracing garbage collection and ensures
               | that unreachable resources have their finalizers run as
               | soon as possible... except it's not true.
               | 
               | GC arguments have run for decades and everyone has their
               | opinions.
               | 
               | > * Having a GIL instead of being truly multi-threaded
               | from day one
               | 
               | Python was created in 1989. Java was created in 1996. Can
               | you guess what major change in computer history was
               | happening around the latter's time?
               | 
               | Everything was GIANT-locked when Python was designed,
               | unless it was specifically intended for SMP mainframes.
               | The entirety of the FreeBSD operating system had a GIANT
               | lock on it at the time, for instance. Linux didn't even
               | exist. Mac OS and Windows both were fundamentally single
               | threaded and cooperatively multitasked. Commercial Unices
               | that supported SMP were only ~4-5 years old and a very
               | small niche.
               | 
               | You might as well be complaining about "why didn't the
               | x86 architecture just have 64-bit capabilities from the
               | outset?"
               | 
               | > * Various OOP concepts that are much better explained
               | in Java than Python: __eq__(), __hash__(), monitor wait()
               | and notify(), object finalizers, thread safety, weak
               | references.
               | 
               | In other words: "it's not Java, so it's bad".
               | 
               | Java is a pure-OO language; Python is a procedural
               | language with OO as an optional feature. To that end, it
               | exposes OO-features in an optional manner versus forcing
               | you to use them against your will.
               | 
               | So if the basis of all your arguments is "OO is better in
               | Java", well the the response is "yeah I'd _hope_ so,
               | since you have no other choice as it 's the _fundamental_
               | paradigm ". Guess what? Haskell is much better at
               | functional programming than Java; that _also_ doesn 't
               | make a valid argument about whether either is good or
               | bad.
               | 
               | > * Distinction between str and bytes. This is the
               | biggest change from Python 2 to 3 and caused a lot of
               | incompatibilities. Java separated String and byte[] from
               | the start (though the use of UTF-16 is unfortunate).
               | 
               | Java was developed 7 years later and during a time that
               | Unicode was becoming the standard over ASCII. Python was
               | designed when everything was still ASCII and Unicode a
               | mere glint to the general computer science realm.
               | 
               | As you pointed out, even Java made a bad decision here
               | due to their premature adoption of the standards (as any
               | modern designed language is quick to point out).
        
               | nayuki wrote:
               | And your reply is half right, half wrong. Let me address
               | the wrong parts.
               | 
               | > Duck typing vs. abstract base classes / You can do both
               | in Python
               | 
               | I'm saying that the original intent of Python was duck
               | typing, but then people realized that abstract base
               | classes play an important role - e.g. isinstance()
               | testing, static type annotations. So they still ended up
               | where Java started.
               | 
               | > Static type hints / I don't even know what that means.
               | 
               | I'm saying that Python was designed with no type
               | annotations on variables (though values did have types),
               | and then they realized that people wanted this feature...
               | and ended up where C/C++/Java/C# have been all along.
               | Python became "enterprisey".
               | 
               | And then, Python implemented type hints rather badly from
               | 3.0 through 3.10 and beyond. It doesn't include types in
               | the official documentation, so now you have to guess what
               | open() returns (it's typing.BinaryIO/typing.TextIO). It
               | doesn't have an official type checker, instead relying on
               | third-party tools like mypy. It moved items between
               | typing and collections.abc. It requires `from future
               | import __annotations__` for non-trivial programs. It
               | changed typing.List to just list in 3.9. It introduced
               | the | (union) operator in 3.10. And a bunch more little
               | things I can't recall; it just had a bad out-of-the-box
               | experience and kept tweaking things over the decade.
               | Documenting generics and especially protocols in Python
               | takes effort.
               | 
               | > Python was created in 1989. Java was created in 1996
               | 
               | Wrong. Java was created in 1991, and the first version
               | released in 1996.
               | https://en.wikipedia.org/wiki/Java_(programming_language)
               | 
               | Python 1 was released in 1994, and 2 in 2000. They had
               | their chance to make breaking changes.
               | https://en.wikipedia.org/wiki/History_of_Python
               | 
               | While you're right that Python predates Java, it's not by
               | as many years as claimed.
               | 
               | > Various OOP concepts that are much better explained in
               | Java than Python
               | 
               | To exemplify, here is how you figure out how to override
               | `==`: https://docs.python.org/3/library/stdtypes.html#com
               | parisons , https://docs.python.org/3/reference/expression
               | s.html#express... . Notably, there is no documentation
               | for object.__eq__().
               | 
               | Here is the Java version: https://docs.oracle.com/en/java
               | /javase/23/docs/api/java.base...
               | 
               | Now for __hash__() / hashCode(), the Java version is
               | clearer: https://docs.python.org/3/reference/datamodel.ht
               | ml#object.__... , https://docs.oracle.com/en/java/javase/
               | 23/docs/api/java.base...
               | 
               | Python __del__ is buried in the "Data model" page: https:
               | //docs.python.org/3/reference/datamodel.html#object.__...
               | . Java's finalize() is easily found on Object: https://do
               | cs.oracle.com/en/java/javase/23/docs/api/java.base... .
               | Furthermore, Joshua Bloch's book "Effective Java" has a
               | chapter titled "Avoid finalizers and cleaners" that
               | explains in detail why finalizers are problematic.
               | 
               | Python explains a lot less about weakref than Java:
               | https://docs.python.org/3/library/weakref.html , https://
               | docs.oracle.com/javase/8/docs/api/java/lang/ref/pack...
               | 
               | > Java is a pure-OO language
               | 
               | Extremely wrong. Java has primitive numeric types, which
               | do not have methods or fields, and undergo painful
               | boxing/unboxing conversions to interoperate with the OO
               | world. Whether the performance benefits are worth it or
               | not is debatable, but what's not debatable is that Java
               | is not pure OOP. Some say that Java is a bad copy of
               | Smalltalk, which I heard is fully object-oriented.
               | 
               | > Python is a procedural language with OO as an optional
               | feature
               | 
               | Wrong. Every Python value is an object that can be
               | inspected (dir(), .__dict__, etc.). And in the CPython
               | API, every Python value is a PyObject*. I have ample
               | grounds to believe that Python is more OO than Java.
        
               | ivan_gammel wrote:
               | >Wrong. Java was created in 1991, and the first version
               | released in 1996.
               | 
               | Gosling and others started working on it in 1991, but
               | does it really matter? First public release is when you
               | can learn about it and borrow ideas. It doesn't make your
               | point less valid, of course - Java made a lot of hype
               | back then.
        
               | deaddodo wrote:
               | > Python 1 was released in 1994, and 2 in 2000. They had
               | their chance to make breaking changes.
               | https://en.wikipedia.org/wiki/History_of_Python
               | 
               | You're purposefully fudging dates to make the argument
               | more favorable to your point. If you want to argue
               | initial source release, then you can maybe make the point
               | for 0.9:
               | 
               | > In February 1991, Van Rossum published the code
               | (labeled version 0.9.0) to alt.sources
               | 
               | And say that Python had it's initial release just
               | slightly before Java had begun design specs. But Python
               | was in use before that and Rossum had developed the
               | initial version well before that (again, 1989):
               | 
               | > The programming language Python was conceived in the
               | late 1980s,[1] and its implementation was started in
               | December 1989[2] by Guido van Rossum
               | 
               | It's ironic that you're trying to make that same argument
               | for Java and dismissing it for Python, when Python was
               | very much in public use pre-1.0 and Java was not (outside
               | of internal teams).
               | 
               | > Wrong. Every Python value is an object that can be
               | inspected (dir(), .__dict__, etc.). And in the CPython
               | API, every Python value is a PyObject*. I have ample
               | grounds to believe that Python is more OO than Java.
               | 
               | I feel like, just based on this point, you've done
               | nothing more than open the CPython source code and
               | searched for "object". This naming was in place well
               | before Python even had any of the OO-functionality that
               | exists today (new-style classes derived from the Object
               | type). If you're going to argue for "old-style" classes
               | being OO in any way but name, you're probably going to
               | fundamentally disagree with any OO fundamentalists, the
               | designers of Python itself, _and_ the Java community
               | /designers. You might as well argue that structs with
               | function pointers in C make it an OO-language, as that's
               | functionally all they are.
               | 
               | PyObject doesn't correlate to a Python class/Object. It's
               | a container data structure to allow for their
               | duck/dynamic typing. Object is a type of PyObject; but it
               | contains an additional layer of functionality to _make_
               | it a Python Object (specifically PyMethodObject and
               | PyTypeObject, and their correlative functionality).
               | Again, to allow for the reflection /introspection and GC
               | that you so bemoan; and due to the lack of C generics at
               | the time (or really, even today). Being able to
               | introspect a type has nothing to do with it's "OO-ness",
               | although it can be very useful in such languages (such as
               | C#).
               | 
               | As to your other point, sure...using "pure" was probably
               | going too far. But by that same argument, even Haskell
               | isn't pure-functional (nor do any really exist) due to
               | it's need to interface with IO. But Java is about 90%
               | there and strives for it. Python most definitely isn't
               | nor does it make any intentions to do so.
               | 
               | Again, fudging the history/facts/topics to try and make
               | your point. It's not worth discussing with someone who so
               | fundamentally converses in bad faith. Especially since
               | I'm making no claims to which is _better_ , just
               | outlining the flaws in your complaints. I really don't
               | care about "better" languages.
        
         | p1necone wrote:
         | Really Java has always been kinda okay - the really horrible
         | part of Java was always the "enterprise OOP" programming
         | patterns that were basically a given in any commercial codebase
         | - little things like pointing out the verbosity of a basic
         | single file project are just shorthand for "look at all this
         | shit people have written".
         | 
         | As the adage goes - Java programmers can write Java in any
         | language.
        
           | Terr_ wrote:
           | ... But if they do make it in Java, at least you have the
           | tools to analyze and refactor it.
        
           | bzzzt wrote:
           | You mean stuff like in the 'Design Patterns' book by the Gang
           | of Four? That was originally written for C++ programmers and
           | predates Java by a few years.
           | 
           | Seems 'Java programmers' were already writing Java before
           | Java's release ;)
        
             | fuzztester wrote:
             | Python programmers be like:                 from __past__
             | import JavaProgrammer             /usr/bin/python: error:
             | line 0: not a chance
        
             | watwut wrote:
             | That is something yet different.
        
           | trallnag wrote:
           | Is the problem design patterns or opaque frameworks that rely
           | on a ton of reflection?
        
             | watwut wrote:
             | Afaik, at the time issue was a lot of programming in xml -
             | where those frameworks are configured in various xmls and
             | hard to understand and maintain. Reflection based
             | frameworks are later development.
        
               | mercutio2 wrote:
               | "In XML" is neither here nor there.
               | 
               | The massive amounts of indirection which the IDE wouldn't
               | help you understand was the difficult thing. What
               | encoding you use for that is pretty irrelevant. JSON
               | would have been worse.
        
         | jjice wrote:
         | Anecdotal, but I had an intro to programming class in high
         | school and the teacher was a wonderful woman, but not a
         | programmer. She didn't know that this was a function
         | declaration or its meaning, so she would just have us repeat
         | out loud "public static void main string box args". I get a
         | laugh whenever I think of that. I hope she's doing well.
        
           | keyle wrote:
           | I had an Excel class 20-25 years ago where a teacher
           | explained click and double click every class, and emphasising
           | "DOUBLE CLICK" out loud every time she did the action...
           | There were a few facepalms.
           | 
           | The next class was assembly programming, where the teacher
           | didn't bother to show for 4 months and then resumed the class
           | as if we "self-taught up until this point". We were utterly
           | lost in that one.
           | 
           | I imagine things have changed greatly today but back then it
           | was a complete roller coaster.
        
             | ElevenLathe wrote:
             | In elementary school we had a "class" with the "computer
             | teacher" once a week. He was just one of the only adults on
             | the school district payroll who knew how to turn on and off
             | an Apple //e. Nice guy (he also volunteered at the same
             | community theatre I did), but "computer class" was just
             | letting us loose with copies of Fraction Munchers and
             | helping us if we jammed the disk drive or whatever.
        
               | nickpeterson wrote:
               | I remember being 10 and going to a computer lab full of
               | power macintoshes and playing sim city 2000, kid pix, and
               | Carmen San Diego. This was in between looking at a cd
               | encyclopedia (encarta?), old computers were awesome ;)
        
             | hobs wrote:
             | Wow, you reminded me of two experiences at once.
             | 
             | I wasn't good at getting educated, but I ended up at a
             | community college to "get my generals" - my first class of
             | the day was computer something or other, and the class was
             | led by a man in extremely thick glasses who said that our
             | general approach in the course was going to be:
             | * perform actions with the computer       * take a
             | screenshot       * paste the screenshot into mspaint
             | * print out the screenshot as proof that we had completed
             | the thing       * put that in a folder       * he would
             | review the folder for completion
             | 
             | (for anyone paying attention, anyone could just print out
             | multiple copies)
             | 
             | While it was a significantly younger and less experienced
             | me who quit this bullshit in an absolute huff, I don't know
             | if I could go through it today.
             | 
             | Fast forward a few years later, and I was training folks on
             | tech support(a random reversal) and I had a lady who should
             | have taken his class... every time I told them to click on
             | something she asked "is that right click or a left click?"
             | and each time I would respond "its a left click unless I
             | tell you otherwise" (she didn't last long.)
        
           | xienze wrote:
           | A lot of Java professors did that in the past, because the
           | "not hello world" parts of "hello world" require a bit more
           | understanding, and in the spirit of getting people started,
           | the idea is to just say "hey memorize this boilerplate stuff,
           | eventually you'll understand what it means."
        
         | riku_iki wrote:
         | > than the old "public static void main(String[] args)" thing
         | 
         | you forgot surrounding class definition.
        
         | geokon wrote:
         | I haven't written Java in a million years.. so I'm trying to
         | understand better.
         | 
         | But what does this code even mean..? Isn't Java's whole
         | simplifying model that everything lives in "Objects"? This
         | seems to break that fundamental paradigm and makes the language
         | more complicated. If you needed something like global functions
         | then in vanilla Java as I remember you'd stick it into static
         | final Objects that acts as a namespace of sorts. So you don't
         | need to worry about functions floating around in a global
         | namespace soup.
         | 
         | If you're gunna just have free floating functions in your
         | file.. then why not just cut to the chase and have a
         | println("Hello world");
         | 
         | floating in your file..? (I mean... you don't have REPL so
         | maybe that wouldn't be too meaningful...)
        
           | int_19h wrote:
           | It's implicitly still a class, you just don't need to write
           | all the scaffolding to indicate that. The functions are still
           | methods of that class etc.
           | 
           | But, yes, with static imports, you can just write "println"
           | like that and have it work.
        
             | almostgotcaught wrote:
             | > It's implicitly still a class, you just don't need to
             | write all the scaffolding to indicate that.
             | 
             | did you know that every function in a python script is
             | actually an attribute of that module (which is basically a
             | class). so my point is: who cares.
        
             | imtringued wrote:
             | geokon's point still stands. This is meaningless syntax
             | sugar that does not change anything fundamental about Java
             | except add one more special rule into the language aka it
             | is one more thing to learn. Rather than being helpful, it
             | just becomes friction when an old developer uses the old
             | method and a new developer uses the new method.
             | 
             | You still need to know what a main class is, so that you
             | can reference it in your build.gradle file.
        
               | losvedir wrote:
               | If you're using a build.gradle file then you probably
               | won't see any benefit to this implicit class, yes.
               | 
               | But it's useful for little one-off scripts, where you
               | just go `$ java foo.java` from the command line.
        
           | semiquaver wrote:
           | > you don't have REPL
           | 
           | (ahem) https://docs.oracle.com/en/java/javase/23/jshell/intro
           | ductio...
        
             | spullara wrote:
             | only since 2017 :) people basically judge java based on
             | what you learn in AP CS which is basically (a dumbed down
             | version of) java 6 (released 2006).
        
               | vips7L wrote:
               | It's honestly the only programming language that will get
               | its 1996 version compared to a new 2025 version of
               | another language. And the only language that will be
               | criticized by someone who last used it in 2006.
        
               | homebrewer wrote:
               | PHP gets the same treatment all the time.
        
               | AmpsterMan wrote:
               | PHP and Laravel are amazing.
        
               | mey wrote:
               | I have been developing Java for a long time and my brain
               | tends to stay stuck in Java 8 mode a lot of the time.
        
               | james_promoted wrote:
               | Definitely not the only language. Other long-lived
               | languages like C++ get this treatment too.
        
               | motorest wrote:
               | > And the only language that will be criticized by
               | someone who last used it in 2006.
               | 
               | You don't sound like you work with Java. I know for a
               | fact that even some FANGs, with their army of software
               | engineers, still use Java8 for most of their Java
               | projects.
        
               | throwaway03452 wrote:
               | Historically an upgrade could cause issues if the code or
               | dependencies used undocumented functionality (like Byte
               | code manipulation) or calls to native code, or the
               | transitions to modules in v9. Upgrades after version 11
               | should be less "risky" and be easier to argue to
               | management.
               | 
               | From what I can tell, there are 4 main reasons why some
               | don't upgrade.
               | 
               | 1. They have legacy software and are afraid of breaking
               | it, sometimes with good reasons.
               | 
               | 2. The devs don't know or care enough about the new
               | versions to bother with it. Noone is promoted because of
               | an upgrade. Work to live, and don't live to work
               | 
               | 3. The ones who don't have buy in from management to
               | spend time fixing something that works
               | 
               | 4. They are using version 11+ that should be much safer
               | to upgrade than earlier versions, but they are still in
               | the mindset of 1 or 2 above
               | 
               | There have been huge improvements not only in the
               | language itself, but also performance and memory use.
               | They could save money if they upgrade, but in some cases
               | this is acceptable because they can make more money by
               | spending time on a new feature, than an upgrade.
               | 
               | In my last 3 workplaces, they usually tried to use the
               | latest LTS versions. But to be honest, some of the
               | services were in maintenance mode and we didn't get
               | enough benefits to upgrade, so we were sometimes falling
               | behind. Today we have a mix of v17 and v21. Anyone can
               | upgrade anytime they want but noone cares about a service
               | that you seldom work with. I feel kind of bad for that,
               | but not enough to bother. I focus mainly on the services
               | that I work with daily, and make sure they are using the
               | latest versions
        
               | motorest wrote:
               | > From what I can tell, there are 4 main reasons why some
               | don't upgrade.
               | 
               | You missed the most obvious reason to not upgrade: there
               | is no good reason to do it.
               | 
               | > There have been huge improvements not only in the
               | language itself, but also performance and memory use.
               | 
               | That's debatable, and even if we blindly assume that then
               | it's debatable whether the upgrade justifies the gains.
               | 
               | More often than not, it doesn't.
        
               | vips7L wrote:
               | > That's debatable, and even if we blindly assume that
               | then it's debatable whether the upgrade justifies the
               | gains
               | 
               | This is not debatable. It's a factual truth. Every single
               | actual performance review concludes that modern Java
               | vastly out performs the decade old Java 8 runtime.
               | 
               | For an example here is a quote from Hazelcast when
               | comparing performance of modern Java on data heavy
               | workloads [0]:
               | 
               | > JDK 8 is an antiquated runtime. The default Parallel
               | collector enters huge Full GC pauses and the G1, although
               | having less frequent Full GCs, is stuck in an old version
               | that uses just one thread to perform it, resulting in
               | even longer pauses. Even on a moderate heap of 12 GB, the
               | pauses were exceeding 20 seconds for Parallel and a full
               | minute for G1. The ConcurrentMarkSweep collector is
               | strictly worse than G1 in all scenarios, and its failure
               | mode are multi-minute Full GC pauses.
               | 
               | This is from 2020 and the gap has only gotten wider.
               | 
               | [0] https://hazelcast.com/blog/performance-of-modern-
               | java-on-dat...
        
               | vips7L wrote:
               | I work in Java every day and have upgraded my entire
               | companies fleet of services to Java 21. FANGs are nothing
               | special. And every actual survey shows that there are as
               | many people on a runtime > 8 as there are people on 8:
               | 
               | https://www.jetbrains.com/lp/devecosystem-2023/java/
        
               | motorest wrote:
               | > And every actual survey shows that there are as many
               | people on a runtime > 8 as there are people on 8:
               | 
               | I don't think you even bothered to read the sources
               | you're quoting, and you're just trying to make baseless
               | assertions.
               | 
               | The very first question on JetBrain's survey is "Which
               | versions of Java do you regularly use?", and 50% answered
               | Java 8 with around 2% mentioning Java 7 and 1% answering
               | Java 6. On top of that, Java11 alone comprised around
               | 38%.
               | 
               | And you're talking about Java21? It doesn't even register
               | in the survey at all.
        
               | vips7L wrote:
               | I'm not talking about Java 21 when referring to that
               | data, I was refuting your baseless claim that I don't
               | work in Java. I don't think you even bothered to actually
               | read or comprehend my comment.
               | 
               | The data there clearly shows that the ecosystem has as
               | many users running a modern version. Which directly
               | counters your assertion that everyone is just running 8.
        
               | motorest wrote:
               | > people basically judge java based on what you learn in
               | AP CS which is basically (a dumbed down version of) java
               | 6 (released 2006).
               | 
               | I don't think people realize Java8 was until very
               | recently the dominant java version in production
               | software, and currently close to 90% of all java projects
               | still run on java11 and earlier.
               | 
               | Edit: after checking New Relic's 2024 report on the java
               | ecosystem, it sounds like java11 and earlier is now at
               | slightly over 60%, with java17 being used in around 35%
               | of the projects.
        
               | spullara wrote:
               | For software written in that era currently under
               | maintenance mode, I don't expect people to upgrade their
               | java language version though upgrading their JVM is a
               | good idea.
        
             | sgt wrote:
             | Try doing a cold load of JShell though. Can easily take 2
             | seconds on a rather fast machine. People will never use it
             | as a quick REPL for that reason.
        
               | vips7L wrote:
               | I use it as a repl all the time. IntelliJ can load your
               | projects classpath into too. It's really awesome.
        
               | sgt wrote:
               | Thanks, I'll give it a shot in IntelliJ.
        
               | vips7L wrote:
               | docs if you're interested:
               | https://www.jetbrains.com/help/idea/jshell-console.html
        
           | Quekid5 wrote:
           | I'm having such a hard time figuring out whether this is
           | satirical.
           | 
           | (My guess: It is.)
        
             | Joker_vD wrote:
             | I know, right?
             | 
             | > So you don't need to worry about functions floating
             | around in a global namespace soup.
             | 
             | Because having _classes_ floating around in a global
             | namespace soup is fundamentally different and should give
             | no worries to anyone. Yet this was argument made in earnest
             | back when arguments about Java 's strengths and weaknesses
             | were much more popular.
        
               | lmz wrote:
               | There's always going to be a namespace soup but at least
               | in Java there's only one kind of thing in the soup.
        
               | Joker_vD wrote:
               | The famous "anemic namespace soup" language design
               | pattern.
        
               | lazide wrote:
               | Hey, it could be Perl!
        
           | gf000 wrote:
           | As others mentioned, there is an implicit class here in play.
           | 
           | Basically, imagine a `class Temporary4738 {` and `}` written
           | above and below the .java file's content, that's roughly how
           | it will behave.
           | 
           | It not having a fixed name is deliberate, so if you decide to
           | build a bigger system you won't use this mechanism in a hard
           | to maintain way, and also it needed a good semantic model for
           | "top-level" variables/fields.
           | 
           | But with this implicit class model, top-level definitions are
           | just fields of the class.
        
             | motorest wrote:
             | > As others mentioned, there is an implicit class here in
             | play.
             | 
             | The same strategy is also followed by C# with their top-
             | level statements. And yes, it's syntactic sugar.
             | 
             | https://learn.microsoft.com/en-
             | us/dotnet/csharp/fundamentals...
        
           | winrid wrote:
           | Because this is the entrypoint? Having code exec out of an
           | explicitly defined entry point that's an entire file sucks.
        
           | dkarl wrote:
           | > This seems to break that fundamental paradigm and makes the
           | language more complicated
           | 
           | Welcome to the last 10+ years of Java. They're trying to play
           | catch-up to other languages that made fundamentally different
           | and better choices, making Java more and more complicated in
           | the process. They are so deeply entrenched in the enterprise
           | back end space that programmers put up with it, nay, even
           | feel grateful for it. People who are stuck using Java for the
           | rest of their careers are happy to see it grow to accommodate
           | 21st century programming techniques, even if it means that it
           | becomes so complicated and crufty that no beginner will touch
           | it ever again.
        
             | x0x0 wrote:
             | In java's defense -- and I share your criticisms -- it
             | offers some very nice things that no other language has.
             | 
             | eg want to run code for 6 months at a go managing hundreds
             | of gigs of data, tens of thousands of threads, at high
             | load, with sustained gigs a second of garbage generation?
             | the jvm will just silently tick away doing just that while
             | being nearly bulletproof. As much as I love ruby and
             | python, you ain't doing that with them.
             | 
             | With hot code loading, introspection, etc. All the stuff
             | that makes developing super-robust long-lived systems way
             | easier.
             | 
             | And the flip side of the clunky language is your code from
             | 20 years ago still works.
        
               | woooooo wrote:
               | Also, conservative feature adoption works in the long
               | term.
               | 
               | Scala mainstreamed a bunch of concepts that java was slow
               | to adopt, but the end result was java only took the good
               | ideas and didn't take the bad ideas.
        
               | dkarl wrote:
               | Fortunately, you don't have to use Java to use the JVM.
               | There's Kotlin, Scala, Clojure, etc., all of which are
               | simpler languages.
        
             | NBJack wrote:
             | It doesn't surprise me; that sounds exactly like how C++
             | has progressed (sans the enterprise beans, hopefully).
             | 
             | 10+ years ago I considered myself proficient at C++. It
             | made sense, I didn't mind the pointers, and while the std
             | library still felt clunky, it was fine. But I tabled these
             | skills, and they indeed rusted a bit, but surely I could
             | bring them out when needed again, right?
             | 
             | Smart pointers with multiple variants, judicious use of
             | macros, rampant use of double colons to ensure proper
             | namespace resolution (which IMHO makes the code an absolute
             | eyesore), to name a few. I won't argue these changes aren't
             | necessary, but it isn't pretty.
        
         | foobarian wrote:
         | Song version: https://www.youtube.com/watch?v=yup8gIXxWDU
        
           | globalnode wrote:
           | what did i just witness....
        
             | klez wrote:
             | One of the best metal band Italy has on offer, that's what
             | you just witnessed.
             | 
             | SEMICOLON!!!
        
           | AiTricky wrote:
           | Thanks for sharing this. I watched it while both enjoying and
           | cringing at it.
        
           | Phelinofist wrote:
           | this is actually fucking amazing :D
        
         | rottc0dd wrote:
         | I agree that can serve as terrible intro to programming. But,
         | often when we have tools either designed for a purpose in mind
         | or a dominant paridigm or reaction to existing set of tooling,
         | this can result in understandable yet extreme abstractions.
         | 
         | Java is designed with OOP in mind and it kind of makes sense to
         | have the user to think in terms of lego blocks of interfaces.
         | Every method or class needs to have clear understanding of its
         | users.
         | 
         | public - software handle is for all users
         | 
         | protected - software handle for current and extending classes
         | 
         | default - software is exposed to current package
         | 
         | private - software is restricted to be used in current class
         | alone and nowhere else
         | 
         | So, the beginning of java programming starts with interface
         | exposed to the user or other programmers. Is it weird and
         | extreme. Yes. At least, it is consistent.
        
         | brokenmachine wrote:
         | >less crufty than the old "public static void main(String[]
         | args)" thing. I always felt that was a terrible introduction to
         | programming
         | 
         | I somewhat agree, but it was kind of exciting to learn what
         | each of those previously meaningless words meant.
         | 
         | Kind of a sneak preview... Tune in for next week when we learn
         | what static means!!
        
         | fulafel wrote:
         | It's a good local improvement, but the other hand that old
         | traditional syntax was a good effective "keep away" sign in
         | Java that saved many CS students from being fed Java as a first
         | language. And it's still a bad first language after this
         | change. I wonder if this small improvement might make things
         | worse in the big picture.
        
           | thayne wrote:
           | And yet it is still the first language taught in many
           | programs.
           | 
           | Although my high school programming class was c++, which is
           | even worse as a first language.
        
           | user_of_the_wek wrote:
           | These features are explicitly to make teaching Java as a
           | first language easier. From https://openjdk.org/jeps/463
           | 
           | Goals:
           | 
           | Offer a smooth on-ramp to Java programming so that
           | instructors can introduce concepts in a gradual manner.
           | 
           | Help students to write basic programs in a concise manner and
           | grow their code gracefully as their skills grow.
           | 
           | Reduce the ceremony of writing simple programs such as
           | scripts and command-line utilities.
           | 
           | Do not introduce a separate beginners' dialect of the Java
           | language.
           | 
           | Do not introduce a separate beginners' toolchain; student
           | programs should be compiled and run with the same tools that
           | compile and run any Java program.
        
             | themaninthedark wrote:
             | I learnt to program using Pascal, then C++ in Highschool.
             | 
             | In collage, CS101 and 102 required me to learn and use
             | JAVA, which I felt was a huge step backwards in usability
             | and a lot of excess typing.
             | 
             | But as I reflect on it now, I think my feeling were because
             | I came from knowing how to do some things and therefore not
             | requiring the framework that JAVA offed to first time
             | programmers.
        
               | fulafel wrote:
               | I think the sins of Java as a first language are twofold:
               | 
               | 1. The obvious excess incidental complexity
               | 
               | 2. and more important, the enterprisey culture that's
               | much less compatible with the intellectual curiosity,
               | looking under the hood, etc attitude that's needed to
               | become a decent programmer.
        
         | BeefWellington wrote:
         | They've also done quite a bit of work to make things such as
         | hosting a web service much much simpler, through the addition
         | of things like SimpleFileServer, as well as some better
         | convenience methods.
         | 
         | It makes it far far closer to the python experience.
        
         | user_of_the_wek wrote:
         | You don't need the args!                 void main() {
         | println("Hello world");       }
         | 
         | should work just as well.
        
         | jillesvangurp wrote:
         | You might also like Kotlin script.                  #!
         | /usr/bin/env kotlin             println("Hello world")
         | 
         | You have to brew install kotlin for this to work of course. But
         | it's a great way for using a lot of Java stuff as well.
         | Kotlin's Java interoperability is excellent if you are using
         | Java from Kotlin.
         | 
         | IMHO Kotlin is underused as an alternative to python currently
         | for data science stuff. It's surprisingly capable out of the
         | box even with just the standard library and there are a lot of
         | nice data science libraries that make it more useful. Not for
         | everyone; but fairly easy to get started with.
         | 
         | Kotlin scripting is unfortunately not necessarily very user
         | friendly (e.g. imports can be a bit tedious and IDE support is
         | a bit meh). But it can be a nice way to embed some kotlin stuff
         | in a script. Generally, Jetbrains could give this topic a lot
         | more love and attention and it wouldn't even take that much to
         | level up the experience.
         | 
         | KTS works in jupyter as well (there is a kotlin engine for
         | that). And that of course is nice if you want to use Java
         | libraries in jupyter. And developing kotlin DSLs for stuff and
         | then using them in a script is kind of a power move.
        
           | a57721 wrote:
           | > Kotlin scripting is unfortunately not necessarily very user
           | friendly (e.g. imports can be a bit tedious and IDE support
           | is a bit meh). But it can be a nice way to embed some kotlin
           | stuff in a script. Generally, Jetbrains could give this topic
           | a lot more love and attention and it wouldn't even take that
           | much to level up the experience.
           | 
           | Kotlin has been pretty bad at scripting and REPL, and
           | unfortunately the team decided to drop both:
           | 
           | https://blog.jetbrains.com/kotlin/2024/11/state-of-kotlin-
           | sc...
        
             | GTP wrote:
             | Based on that page, they're dropping the REPL in favor of
             | notebooks, but their're not dropping scripts. They are
             | dropping some script-related functionality to focus on
             | others.
        
               | jillesvangurp wrote:
               | Also worth noting that notebooks and kts overlap quite a
               | bit. They use the same mechanism for imports and defining
               | remote repositories, for example. A notebook is
               | effectively a kts script. And of course gradle uses kts
               | as well for its Kotlin dialect. These things actually
               | overlap quite a bit.
        
               | a57721 wrote:
               | Yes, they are not dropping scripts completely, at least
               | because of Gradle, but they are removing some parts of
               | scripting support and advise against using Kotlin for
               | scripting. And I would prefer a true command line REPL
               | instead of the notebooks. IIRC they were promising
               | various improvements in both scripting and REPL for
               | several years, and now they just gave up, I guess because
               | of shifting the focus to K2 and KMP. I find this quite
               | disappointing.
        
         | pragma_x wrote:
         | It took almost 30 years to get here. I never thought I'd see
         | the day.
         | 
         | What really threw me for a loop is the article author mentions:
         | "I knew plenty of professors who were bothered by [the public
         | static void main thing]." I could have sworn that OOP die-hards
         | in academia _wanted_ the formal class boilerplate in the
         | original design. Maybe they aged out? Perhaps, times are
         | changing.
        
       | forty wrote:
       | You might also want to look at scala and ammonite [1]
       | 
       | [1] https://ammonite.io/#ScalaScripts
        
         | eweise wrote:
         | exactly my thought. If you think java makes a good scripting
         | language, you will be really happy with scala
        
         | dropofwill wrote:
         | Also scala-cli https://scala-
         | cli.virtuslab.org/docs/getting_started
         | 
         | I still like to use Ammonite as a REPL, but scala-cli has
         | replaced it for me in those cases where i get fed up writing
         | bash.
        
         | vvillena wrote:
         | Scala-cli would be even better. It explicitly supports Java
         | too!
        
       | brundolf wrote:
       | Very cool to see all these quality of life improvements. I
       | haven't kept up with Java for several years. Still, the
       | dependencies thing seems like an issue (as it is in Python)
       | 
       | Deno has been my go-to scripting tool lately. Similar benefits to
       | Java as used by the OP, but it also allows you to import
       | dependencies directly by URL, which means you can have your
       | script self-define dependencies without a separate manifest file
        
         | qsort wrote:
         | Python packaging continues to be a pain, but you can specify
         | dependencies for single-file scripts with inline script
         | metadata, see:
         | https://packaging.python.org/en/latest/specifications/inline...
        
       | nesk_ wrote:
       | Remembers me the "Java for Everything" blog post:
       | https://www.teamten.com/lawrence/writings/java-for-everythin...
       | 
       | Also, thank you for sharing! I do appreciate Java and I'm glad to
       | see it can be used for scripting nowadays.
        
       | neonsunset wrote:
       | Still long way to go before it reaches .NET levels of
       | productivity (especially so if you use F# for scripting, but C#
       | is no slouch either) :P
        
         | pjmlp wrote:
         | Depends on the platform, some don't have any .NET productivity
         | available. :)
        
           | neonsunset wrote:
           | These platforms are not being considered here nor have much
           | relevance anymore. You cannot seriously claim this unless you
           | don't use the tooling side by side at all.
           | 
           | The difference is so stark it's no longer amusing. Performing
           | setup for complex Java projects has me go through similar
           | steps as if they were written in C++. Performing setup for C#
           | projects of comparable complexity usually requires just
           | cloning and hitting 'dotnet run', much like it usually
           | happens with Rust or Go (some may claim I undeservedly bash
           | it but credit is where credit is due).
        
             | pjmlp wrote:
             | Like my phone, or those used by US military?
             | 
             | I love your identity with .NET ecosystem, to the point of
             | nothing else being in the way.
             | 
             | See latest JetBrains Developer Surrey about platforms.
             | 
             | .NET is a great ecosystem, but lets be real where it stands
             | outside Microsoft shops, across everything that has a CPU
             | on them, and the various ecosystem where sadly it doesn't
             | even get a tier 1 support.
             | 
             | Programming languages are tools, a toolbox has space for
             | plenty of them.
        
             | mike_hearn wrote:
             | Are you comparing "complex Java projects" against just
             | ordinary "C# projects"? Because ordinary Java projects will
             | also be "./gradlew run" or the Maven equivalent, that's
             | nothing special.
        
               | neonsunset wrote:
               | And in many other situations "./gradlew run" just doesn't
               | work. Hell, Gradle does not even let you quickly scaffold
               | it without pre-existing knowledge and community advice!
               | (if you want to avoid pitfalls and have the best
               | "streamlined" experience) Something that is not an issue
               | in Rust or Go. Maven is even worse.
               | 
               | Meanwhile I can 'git clone https://github.com/ryujinx-
               | mirror/ryujinx && cd ryujinx/src/Ryujinx && dotnet run -c
               | Release' and it works on the first attempt (though takes
               | a moment to pull nuget packages, it's a big project).
               | 
               | The Java ecosystem has incredible projects from the
               | technical point of view (GC implementations, OpenJDK's
               | JIT compiler), but the tooling and application packaging
               | and distribution seem like the painful parts.
        
               | mike_hearn wrote:
               | It usually works in my experience, since the toolchains
               | feature was added, as that takes the Java version mostly
               | out of the equation.
               | 
               | There is "gradle init" to scaffold a project, or of
               | course IDEs offer a GUI over that.
               | 
               | Additionally, your "dotnet run" does require the dotnet
               | tool to be installed and of the right version. The
               | Gradle/Maven equivalents now no longer do, because they
               | bundle scripts into your repository that will download
               | and run the build tool itself of the right version. They
               | just need some moderately modern Java installed.
               | Everything the project needs including possibly a newer
               | Java will then be downloaded.
               | 
               | I'm not sure what the point of naming individual projects
               | is. I can point at dozens of projects off the top of my
               | head where you can just clone and run them without
               | incident.
               | 
               | There _are_ painful parts of both Gradle and Maven.
               | Absolutely. They are very far from perfect build systems.
               | But this is partly because they do a lot more than tools
               | like cargo does.
        
               | neonsunset wrote:
               | > "dotnet run" does require the dotnet tool to be
               | installed and of the right version
               | 
               | It only needs an SDK installed on the system. If you have
               | the necessary framework dependency, it will just work. If
               | it's missing - the command output will specify this,
               | which is solved by doing `sudo apt install dotnet-
               | sdk-{version}` or just `dotnet-runtime-{version}`
               | (because newer SDKs can build most older targets). You
               | can also usually roll-forward the applications without
               | retargeting them or installing older runtime (which is
               | trivial still). It's a reliable and streamlined process.
               | 
               | Probably one of the best approaches to managing the SDK
               | and framework dependencies that does not rely on any form
               | of help from external tooling or IDEs.
               | 
               | Gradle and Maven need JDK installed in either case. I had
               | Gradle that shipped with the code crash on me because it
               | was sufficiently old to have issues on newer OpenJDK
               | versions. Solved it by installing properly, but you can
               | see how it can be an error-prone process.
               | 
               | ------------------------------------
               | 
               | Ultimately, if you're an expert and it's a long-term
               | project - none of this matters, solving odd breaks and
               | tooling issues is part of the job. It's nice when things
               | work, it's not unexpected when they don't. Some languages
               | have more of this and some less, but at the end of the
               | day due to business constraints and company environment
               | none of this is a showstopper per se - you just deal with
               | it.
               | 
               | Do I think the CLI tooling, dependency management,
               | packaging and distribution is painful in Java or Kotlin?
               | Yes, it's what also precludes either from being
               | productive scripting languages unless you have nailed the
               | setup that works around all of these. Does it matter for
               | writing complex applications? Not really, project and
               | environment setup for such is mostly one-time thing. It's
               | coincidentally where Java ecosystem shows its strength.
               | My rant here is posted because I believe we can discuss
               | pros and cons without stating that specific issues don't
               | exist when they do or vice versa.
               | 
               | Among everything I tried Cargo, .NET CLI and Go had the
               | smoothest experience of things mostly working and when
               | they weren't - not requiring to dig through heaps of
               | documentation, possibly dumped into a language model to
               | catch the exact specific piece that would help to solve
               | the puzzle. I heard good things about Python's uv. If
               | actively maintained, Node.js projects also work reliably,
               | not so much when they aren't though. Some C++ projects
               | are kind enough to offer build scripting that works out
               | of box on Unix systems - props to the maintainers, which
               | is also the case with Java projects. But whenever either
               | of the last two didn't work, it often took me the most
               | effort and swearing to get either working, unlike other
               | languages.
        
               | throwaway03452 wrote:
               | I don't share your experience. I have no problems
               | importing a Maven project                  git clone
               | https://github.com/...        cd somedir        mvn
               | spring-boot:run
        
         | gibspaulding wrote:
         | I'd be curious to hear more about how you're using F#? I've
         | previously used Python for scripting, but just started
         | developing for a company pretty deeply entrenched in .NET.
         | Currently they're migrating a lot from VB to C#, but I've
         | missed having a handy scripting language like Python for small
         | tools or test applications. Do you think F# could fill that
         | roll?
        
           | stackskipton wrote:
           | Powershell is probably best fit for that role. You have to
           | learn a new scripting language but since it runs on .Net you
           | can actually bring in .Net Classes if you need a little more
           | power.
           | 
           | https://learn.microsoft.com/en-
           | us/powershell/module/microsof...
        
           | neonsunset wrote:
           | It should be able to! F# has "gradual typing" and full type
           | inference which means you often do not need to specify the
           | types at all, and it also happens to be whitespace-sensitive
           | language much like Python is. Both of these aspects should
           | make it feel quite familiar while also giving you full
           | advantages of static typing.
           | 
           | One thing to note is I find `dotnet fsi {some script
           | name}.fsx` taking more time to start than ideal - up to 800ms
           | is just too much, normal .NET applications usually start in a
           | fraction of this.
           | 
           | I recently posted a submission here for "FSharpPacker"
           | written by my friend that lets you compile F# _scripts_ to
           | standalone applications (either runtime-dependent, self-
           | contained or fully native binaries, much like Go), it also
           | has some comments on getting the best mileage out of it:
           | https://news.ycombinator.com/item?id=42304835
           | 
           | Probably the best feature that also comes with scripting
           | (both C# and F#) is "inline" nuget references e.g. #r "nuget:
           | FSharp.Control.TaskSeq" which will automatically pull the
           | dependency from nuget without ever dealing with manually
           | installing it or tinkering with build system in any other
           | way.
           | 
           | Some additional links:
           | 
           | https://learn.microsoft.com/en-
           | us/dotnet/fsharp/tools/fsharp...
           | 
           | https://github.com/dotnet-script/dotnet-script (C# is _also_
           | a quite productive language for scripting and small programs
           | because of top-level statements, record types, pattern
           | matching and many other functional features though perhaps
           | not as strongly represented as in F#, it 's just very
           | unfortunately abused in enterprise world, with teams often
           | going out of their way to make the code far more bloated than
           | necessary, against the language design intentions)
           | 
           | https://github.com/waf/CSharpRepl
        
           | taberiand wrote:
           | F# is a leap if it's your first functional / ML style
           | language (but worthwhile). Modern C# is good for small tools
           | and scripting, there is the dotnet-script tool for running
           | single .csx files
        
       | singpolyma3 wrote:
       | > Java has many features that make it well suited for large,
       | long-lasting projects
       | 
       | Already disagree, haha
        
         | whtsthmttrmn wrote:
         | I'll bite. Explain, please.
        
         | KyleBerezin wrote:
         | There are reasons to not like Java, but this isn't one of them.
         | Java is a fantastic language for large long lasting projects. I
         | can't think of a more suited language for large long lasting
         | projects in fact.
        
       | mongol wrote:
       | I don't think Java is fit for "the small". And there is nothing
       | wrong with that. My go-to language for "the small" is Go. Java is
       | good for enterprise heavy-lifting, not for quick and nimble
       | tools.
        
         | Pet_Ant wrote:
         | For the small I like Groovy. Especially as Grapes is like Maven
         | but in annotations that you include in the script file. Being
         | Java-based means that if it goes from "in the small" into
         | something larger you are already on a stable foundation.
        
         | jknoepfler wrote:
         | and you get a nice little portable binary that doesn't force
         | someone to install a compatible version of an
         | interpreter/virtual machine to run.
        
           | mongol wrote:
           | Exactly
        
           | vips7L wrote:
           | That's if they're on the same architecture and operating
           | system as you. Half the people I know are on mac, half of
           | them are on arm. The other half are on windows and x86.
        
             | Terr_ wrote:
             | Now I'm having flashbacks to porting a whole stack of
             | applications from x86 to a customized Linux distribution
             | running on a big-endian PC platform. A mishmash of C/C++,
             | Java, Node-JS, Python...
             | 
             | It was really dumb, but that's what the client needed. So
             | much cross compiling.
        
             | evantbyrne wrote:
             | Go has cross compilation.
        
             | hiAndrewQuinn wrote:
             | Actually, you can specify to build portable binaries for
             | all 3 of these platforms. You can even make them totally
             | static, so that deployment is as easy as "copy the
             | executable file with windows/Linux/Mac/etc in the name and
             | run it".
             | 
             | This is part of my standard Go build.sh script. You just
             | never know who might want to run a given thing where.
        
             | jknoepfler wrote:
             | Who the heck is on ARM (outside data centers)? But yeah,
             | with golang that's just:
             | 
             | GOOS=linux GOARCH=amd64 go build
             | 
             | GOOS=linux GOARCH=arm64 go build
             | 
             | GOOS=darwin GOARCH=amd64 go build
             | 
             | Which again, let's me distribute a binary to my end user as
             | a single file, without directing them to install java or
             | python3 or whatever.
             | 
             | (The ARM question is kinda immaterial, but I'm curious)
        
               | mrkeen wrote:
               | Who the heck is on ARM (outside data centers)?
               | 
               | Mac people, for a few years now.
        
         | tmiku wrote:
         | Can you tell us about how you use Go in the small? I like Go,
         | but it doesn't strike me as particularly nimble for scripty use
         | cases like this - error handling is part of it, but I know
         | that's fixable with the Must() pattern.
        
           | mongol wrote:
           | I just write a small Go program. I agree that error handling
           | is a weak point, but the tooling is well integrated. The
           | article mentions that Java does not know about Maven. The go
           | tool is much more versatile in that sense.
           | 
           | Also, go run is almost like running a script.
        
           | ricardobeat wrote:
           | You can quickly whip up a single-file go program anywhere,
           | without any boilerplate or setup:                   package
           | main              import "fmt"              func main () {
           | fmt.Println("hi")         }              // go run file.go
           | 
           | You can write this in any text editor, but using one with LSP
           | support means that `import` statement is added automatically,
           | and with CoPilot or another assistant, the `main` function
           | writes itself as well as any `if err ...` statements. Go is
           | extremely well suited to code generation due to how
           | predictable it is.
           | 
           | Adding dependencies with `go mod` is uneventful.
           | 
           | It will never be as 'scripty' as JS or Ruby, but the
           | readability, safety and performance are totally worth it.
        
             | Capricorn2481 wrote:
             | I don't really see how this is different from `dotnet run`,
             | `python main.py`, or `lua main.lua`. Like the commenter, I
             | don't find Go very nimble.
             | 
             | Is limited features (Go) gonna be better for AI generation
             | then breadth of examples? (C#). I'm not sure.
        
             | yxhuvud wrote:
             | I see 3 or four lines of boilerplate in your example,
             | depending on if the closing brace is counted or not.
             | Compare with the following equivalent program in ruby or
             | crystal (it is valid in both):                   puts "hi"
             | 
             | And the crystal version is just as typesafe and performant
             | as the go version. I also find it more readable, but that
             | is a very individual metric.
        
               | mongol wrote:
               | I don't think minimal examples are so useful. I reach for
               | Go when bash is insufficient. That means there is a
               | minimal starting size that is large enough that package
               | and imports boilerplate are insignificant, all things
               | considered
        
               | ricardobeat wrote:
               | I love Crystal and have been a sponsor for a long time,
               | but it's not comparable yet. Compiling is much slower,
               | you have to manually add dependencies to shards.yml,
               | cross-compilation is not as simple. And when it comes to
               | scripts and tools, popularity / stability is a main
               | concern.
        
             | gf000 wrote:
             | This is literally longer than the java version mentioned in
             | the article, and that can be started just as simply with a
             | single command.
        
             | ricardobeat wrote:
             | The question I responded to was 'how you use Go in the
             | small', not a comparison to the post.
             | 
             | As I mentioned, yes, it's verbose, but simple and worth the
             | effort and _peace of mind_. My primary language is JS, I
             | 've written a fair share of shell and Ruby but would still
             | choose go a lot of the time, just because it doesn't pull
             | in any extra complexity.
        
         | booleandilemma wrote:
         | Go refuses to compile if you have an unused variable and that
         | is the opposite of quick and nimble.
        
         | gf000 wrote:
         | Go is severely less expressive than Java, so.. disagree. You
         | will end up with longer files with more boilerplate for
         | questionable benefits.
         | 
         | Also, in many areas Java's standard library is more expansive.
        
         | lenkite wrote:
         | Every function call is 4 lines in Go. No basic error
         | propagation support means Go code bloats up very fast in line
         | count.                 result, err := callFoo()       if err !=
         | nil {           return nil, err       }
         | 
         | No collection streams means LOTS of mind-numbing/eye-glazing
         | for loops. Things have improved _slightly_ with the slices and
         | maps package but these are just hacks. Maybe with the new
         | iterator support, Go will slowly and steadily get a bit more
         | expressive.
         | 
         | Go is good for middleware coding thanks to Go-routines and and
         | excellent networking support in the standard library but is
         | cumbersome slow and inexpressive for scripts.
         | 
         | Also go.mod does NOT separate dev/test/prod dependencies -
         | unlike Java Maven or Rust Cargo. You don't want your script
         | dependencies coming into production code.
        
       | dajtxx wrote:
       | I started with Java 1.0 and thought it was great. I still do,
       | although I haven't used it since 2020.
       | 
       | The only thing I don't like is how there is no built-in JSON
       | package which seems like a necessity these days.
       | 
       | Removing the public static void main(String[] args) business
       | seems like pandering to a non-existent audience, or at least a
       | miniscule and insignificant one. Anyone who is going to use Java
       | for a real project is not going to be worried about that, and
       | anyone who thinks that's too difficult to deal with is never
       | going to be a good programmer anyway.
        
         | Zu_ wrote:
         | The last part seems like a very 'gate keepy' point of view.
         | 
         | If you want to introduce someone to programming, you probably
         | don't want them to worry about what all those 'magic words' do.
         | 
         | At least for their first steps, they won't need to know what a
         | class is or what `public` and `static` mean.
        
           | znpy wrote:
           | > If you want to introduce someone to programming, you
           | probably don't want them to worry about what all those 'magic
           | words' do.
           | 
           | I learned Java when i was 15 or 16, reading some random book
           | first and then I stole 35 euros from my mother's purse and
           | bought a copy of "Java how to program" by deitel and
           | deitel[1]. The recommended version at the time was Java 5,
           | and the SJCP certification was still issued by Sun
           | Microsystems.
           | 
           | I can tell you, "public static void main" is not going to be
           | the problem.
           | 
           | [1]: looking back (i'm in my 30ies now) sometimes I wonder if
           | i would have been better off buying weed or alcohol (or both)
        
             | acbart wrote:
             | So you believe that your experience is a universal one for
             | all learners? Cognitive load is a real consideration in
             | teaching, and having to ignore and filter text is
             | challenging for some folks.
        
               | twic wrote:
               | The boilerplate around a main function is 10 units of
               | load. Everything else you have to know to write a simple
               | program is 500-600 units of load. The boilerplate is a
               | rounding error, and just does not matter.
        
               | dgfitz wrote:
               | Yes, all people are different, and some are smarter than
               | others. Education funding won't change that.
               | 
               | Way to disparage a random person on the internet.
        
               | znpy wrote:
               | Mostly yes. Given how much there is to learn, public
               | static void main is not going to be "the problem".
        
           | jknoepfler wrote:
           | Yeah, you want to start with basic imperative programming
           | with as little cargo-cult nonsense in the way as possible.
           | 
           | Your csci 101 kids will not benefit from unpacking what it
           | means to compile an object-oriented language down to bytecode
           | to run on a virtual machine. It's not that it's not valuable
           | knowledge, they just won't have the context to make
           | meaningful heads or tails of it.
           | 
           | related: I still puke a little remembering the requirement
           | that students work on assignments in emacs on terminal
           | machines rather than their text processor of choice(which was
           | fine for me, but why on god's green earth would you put
           | usability warcrimes like 'hjkl' in the way of someone just
           | starting to learn? No wonder nobody in the early naughts
           | wanted to learn to program...).
        
             | dustyventure wrote:
             | A lot of people learn to program from declarative languages
             | like spread sheets. We should all be happy we have access
             | to defective versions of assembly at too high a level but
             | be angry that we had to use too low level an editor?
        
             | anthk wrote:
             | Emacs doesn't use 'hjkl'. I think you weren't there in the
             | 90's...
        
               | cutler wrote:
               | Evil mode ;-)
        
             | fijiaarone wrote:
             | You shouldn't try any modern programming language until
             | you've mastered GOTO and GOSUB and know why lines are
             | numbered in multiples of 10.
        
               | lproven wrote:
               | I think this is a really important point, even though I
               | suspect you're joking.
               | 
               | Along with all the BS boilerplate text this specific post
               | talks about eliminating, which is great, we simply forget
               | how much legacy tech BS we just assume.
               | 
               | Beginner programmers should not have to know what a
               | "file" is, or what an "editor" is, or that they need an
               | "editor" to "edit" a "file". This is technical debt:
               | these are implementation details which should be
               | invisible.
               | 
               | This goes double for "compilers" versus "interpreters"
               | and "source code" versus "binary code". FFS the noun
               | _code_ means _a system for rendered text unreadable_.
               | 
               | You have a computer. You are talking to it in words,
               | words which resemble English because that is one of the
               | simplest world languages when you think about scripts --
               | writing systems -- as well as sounds. Hangeul is easier
               | but only works for Korean which is harder than English.
               | Grammatically Chinese is simpler, but spoken Chinese has
               | tones which are very hard, and written Chinese is insane.
               | Typed Cyrillic is no harder but handwritten gets weird
               | and complicated and Russian is much harder than English.
               | And so on.
               | 
               | English wins and so we talk to computers mostly in
               | English.
               | 
               | So, you have a computer, and you type on it in English.
               | That is all you should need to know: how to enter text,
               | how to correct it when you get it wrong, and that is it.
               | 
               | BASIC has a great virtue which all the Unix and even the
               | Lisp fans forget:
               | 
               | It's designed to work at a command prompt. Type a
               | command, the computer does it. Give it a number, it
               | remembers it for later.
               | 
               | This is a _profound and important_ metaphor. It
               | eliminates all the 1960s /1970s legacy BS about "files"
               | and "folders" and "editors" and "compilers". Beginners
               | don't need that. Let them learn that later if they prove
               | to have real aptitude and want to pursue this.
               | 
               | Type a bare expression, the computer does it. Number it,
               | the computer remembers it for later. _That is all you
               | need to get writing software_.
               | 
               | And just like Python sorted out the problem of spoiled
               | whiny little baby C programmers whinging about their
               | pathetic obsessions with indentation patterns by _making
               | indentation semantic_ so _everyone has to comply_ , line
               | numbers in BASIC are a vital simplifying unifying
               | mechanism, so lean on them: for beginners, make line
               | numbers syntactic.
               | 
               | Don't force kids to learn pro tools like nomenclature and
               | hierarchies. Give them a toy that they can get started
               | with.
               | 
               | At first, they can structure their programs with line
               | numbers, and they learn about leaving space, about
               | RENUMBER commands, about LIST x TO y ranges, and stuff
               | like that, because we are not using a bloody Commodore 64
               | any more.
               | 
               | But give them IF...THEN...ELSE and WHILE...WEND and
               | REPEAT...UNTIL and named procedures so they can learn
               | structure and not GOTO.
               | 
               | All the rest is baggage and should be deferred as late as
               | reasonably possible.
        
           | smaudet wrote:
           | Agreed.
           | 
           | I still feel like the author is missing the forest for the
           | trees. Bash is not great to write e.g. a red black tree in or
           | do complex image processing, but you don't have to maintain a
           | Java install, download libraries, or setup an editor with an
           | LSP (and really, calling java script.java 10 asdf? Why do I
           | need to invoke Java at all? At that point, I'm probably going
           | to wrap it in a script anyways...)
           | 
           | Python has its own issues but it's a small, embedded install
           | that you don't have to accept 5 different licenses for and
           | worry about it being able to get the same version...
           | 
           | And bash? That's what pacman -S jq is for - anything I can't
           | easily do in bash or batch I just offload to a small utility
           | written in python or rust.
           | 
           | Java is, at it's core, just too heavy, IMO.
        
             | fijiaarone wrote:
             | Some people write programs that do more than simple scripts
        
             | gf000 wrote:
             | pacman -S jdk-openjdk, this is the reference java
             | implementation and it has the exact same license as the
             | Linux kernel. And java has never done such a breaking
             | change as python did.
             | 
             | There is also jre-openjdk-headless, for 140 MB. How is that
             | any different than Python?
             | 
             | This "java too heavy" is like 30 years out of date, if it
             | has ever been true.
        
               | smaudet wrote:
               | Quick check via msys2:
               | 
               | "error: target not found: jdk-openjdk"
               | 
               | > And java has never done such a breaking change as
               | python did.
               | 
               | I'm not really sure that's true? Java 8 to afterwards,
               | there are breaking changes that mean a lot of old
               | enterprise stuff can't easily move forward, or worse,
               | bytecode incompatibilities mean source-code-less stuff
               | can't be used anymore...
               | 
               | The whole thing about Graal is mentioned almost as an
               | afterthought, my point is that the language etc. is so
               | poorly designed as to be prohibitive to interface with
               | unless...well you're on Java. Yes there are bridges etc,
               | but a _big_ point of the shell, bash, etc. is _easy_
               | interoperability between many programs, etc.
               | 
               | Java is still today stuck in a mentality of "it doesn't
               | exist if its not in Java", which is why yes, 30 years
               | later, it is still "too heavy". Assuming you are the
               | effective Operating System is an extremely heavy
               | assumption.
        
               | smaudet wrote:
               | > and it has the exact same license as the Linux kernel
               | 
               | Also, I neglected to touch on this point more, perhaps
               | license is not the right word, as much as distribution -
               | I don't know if you have ever tried building the JDK (not
               | simple), or worked with the official JDK vs the open one
               | (not the same functionality), or tried to access old
               | versions of the SDK on the official websites, or had to
               | deal with their installers, etc.
               | 
               | Giant headache and all around.
               | 
               | Not to mention, even if your pacman command works, this
               | is still simply not comparable, the example I used was
               | for installing a jq binary because JRE simply doesn't
               | include this functionality by default...
               | 
               | And now you need the overweight pom/gradle mess to
               | interface with the Java libraries because <insert
               | technical debt reasons here>
        
               | gf000 wrote:
               | The official JDK is the OpenJDK for several years.
               | 
               | Under Sun there were differences, but Oracle open-sourced
               | every last difference and now there is only some Oracle
               | branding logo as the only difference (and maybe some tiny
               | proprietary codec, but your code _will_ run on both the
               | same way).
        
           | jraph wrote:
           | I think gp is right, and I don't think it's gatekeeping. I
           | thought this about Java, it was easy to criticize its
           | verbosity, but I realized how insignificant this is when
           | actually practicing it. There's probably way more interesting
           | and deeper criticism to make about Java.
           | 
           | About the first steps of a newcomer, there's always going to
           | be some level of "don't worry about this now, we'll see what
           | this means later" for any language. I remember this to be the
           | case for every tutorial I read to learn a language. And it's
           | fine, as long as you can try stuff and it doesn't get in the
           | way.
           | 
           | I'd say it's more important for a language and its vocabulary
           | to be well structured and well documented for a newcomer and
           | Java does quite good on this front.
        
           | AnimalMuppet wrote:
           | As mongol said in a top-level comment, Java isn't a great
           | language for programming "in the small". It's not a great
           | language for a casual user - or rather, there are languages
           | that are significantly better. If you want to introduce
           | someone to programming in a semester course, "public static
           | void main" isn't going to be a significant hurdle. If you
           | want to introduce someone to programming as a 14-year-old,
           | maybe don't start with Java.
        
             | gf000 wrote:
             | Why? Java is a small language with not many concepts, that
             | is typed so many of your first attempts will be caught with
             | helpful messages at compile time, and it fails safely at
             | runtime with error messages pointing to an exact line
             | number. Besides, it is a language that is actually used in
             | the industry and has one of the biggest ecosystems. It's
             | also plenty performant, can be low-level enough for
             | learning about all kinds of data structures/algorithms,
             | including concurrent ones and has probably the best tooling
             | (IDE, debugger, etc)
             | 
             | What other language would you start with?
             | 
             | And isn't it easier to introduce concepts one at a time?
             | For that reason implicit classes makes sense, and also for
             | the occasional scripting, as in doing something one-off,
             | but it is not as trivial that I can do it with piping 3
             | commands together.
        
               | AnimalMuppet wrote:
               | > Java is a small language with not many concepts
               | 
               | True. But you need to know too many of them to get
               | anything to run.
               | 
               | > that is typed so many of your first attempts will be
               | caught with helpful messages at compile time
               | 
               | But it doesn't feel that way. It doesn't feel "helpful",
               | it feels nitpicky. It feels like I have to get everything
               | exactly right before _anything_ will run. For a raw
               | beginner, that 's very frustrating. It is (emotionally)
               | better to have something run as far as it can run, and
               | then crash. (I agree that exceptions pointing to the line
               | number are very nice.)
               | 
               | Again, for a semester class, the startup overhead for
               | learning Java is too small to worry about - it's maybe a
               | day or two. But for someone on their own, not in a class,
               | a day or two is a _huge_ investment to put in before they
               | can get something running!
               | 
               | What would I start with? Something with a REPL. (It could
               | be a language that is normally compiled, but there needs
               | to be a REPL. Raw beginners need to be able to get
               | something, _anything_ , to work as quickly as possible.)
        
           | unclad5968 wrote:
           | GP is right. If the words public static keep you from
           | learning how to program you were never going to learn anyway.
           | If I introduce someone to soccer and they quit because they
           | couldn't figure out how to put their shoes on, chances are
           | they werent going to learn how to play no matter what.
        
             | norir wrote:
             | Did you know that the first thing John Wooden did with
             | incoming freshman collegiate basketball players at the most
             | prestigious program in the country was teach them how to
             | properly put on their socks?
        
             | smaudet wrote:
             | I think the converse(?) to this though is that the words
             | public static are inconsequential.
             | 
             | Sure, if you are incapable of learning what a couple
             | adjectives mean you won't go far, but that holds for much
             | more than software.
             | 
             | Rather it's not important that the ball is big and blue so
             | much as that you can kick it across the field - learning
             | what the ball means can come later, but it's just
             | unimportant noise (to start).
             | 
             | Java is pretty bad at this, though, insisting on specifying
             | unimportant details up front rather than allowing for
             | qualification. This is OK for a large monolithic
             | application with complex requirements and a litany of edge
             | cases, but inappropriate for many smaller use cases.
        
         | cbsmith wrote:
         | javax.json has been around since Java 7.
        
           | theandrewbailey wrote:
           | It's part of Java/Jakarta EE.
           | 
           | https://jakarta.ee/specifications/platform/10/apidocs/jakart.
           | ..
        
             | cesarb wrote:
             | > It's part of Java/Jakarta EE.
             | 
             | If it's part of J2EE, it's in practice "part of Java" since
             | the JDK comes with the J2EE packages built-in...
             | 
             | That is, it came with the J2EE packages built-in, until
             | Java 11 decided to break everything, and force people to
             | get each piece of J2EE from a separate upstream project,
             | with AFAIK no "all of J2EE" uber-jar you could simply copy
             | into your project to restore the status quo. It's no wonder
             | so many projects are to this day stuck on Java 8.
        
               | klez wrote:
               | > since the JDK comes with the J2EE packages built-in...
               | 
               | Are you sure about that? I just downloaded the Java 8
               | JDK, and javax.json is not there. And the documentation
               | doesn't mention it either. What am I missing?
        
               | cbsmith wrote:
               | The JDK doesn't include all the J2EE goodness:
               | https://docs.oracle.com/javaee/7/api/javax/json/package-
               | summ...
        
         | II2II wrote:
         | > Removing the public static void main(String[] args) business
         | seems like pandering to a non-existent audience, or at least a
         | miniscule and insignificant one.
         | 
         | Perhaps the audience doesn't exist because of that business.
         | There are many times when I would have used Java over Python to
         | write simple programs for no other reason than having the
         | ability to create a GUI without resorting to third-party
         | libraries. Yeah, Python has tk but it has never clicked with me
         | in the sense that Swing does. Unfortunately, cramming every
         | last thing into an OOP model means that simplicity is rapidly
         | lost. (The same can be said of Python, except Python has not
         | forced it. Java, historically did.)
        
         | msgilligan wrote:
         | I agree that for experienced programmers working on large
         | projects a little bit of verbosity around `main` is
         | insignificant. But first impressions matter, especially when
         | there is pervasive word of mouth about "verbosity".
         | 
         | Pretend you are a college student and you are taking your first
         | programming class (e.g. CS 1) and your friends have told you
         | that Java is "verbose". You start with "hello world" and you
         | have to type `public static void` etc. One of your friends
         | shows you the same code as a Python 1-liner.
         | 
         | Or similarly you're a beginning programmer in the workforce and
         | your employer asks you to solve a problem using Java. You've
         | heard Java is verbose and when you start with "hello world" you
         | find that what you heard was true.
         | 
         | This is not a non-existent/minuscule audience. They should have
         | fixed this decades ago. Better late than never.
         | 
         | I've been impressed with the modernization of Java over the
         | last 10+ years. Simplifying "hello world" is a minor change
         | relative to the others, but still an important one.
        
           | dgfitz wrote:
           | > But first impressions matter, especially when there is
           | pervasive word of mouth about "verbosity"
           | 
           | I watched most of my comp sci 101/102/201 classmates fail out
           | because they didn't want to understand how things worked,
           | they just wanted to make a lot of money.
           | 
           | Edit: hn even helped me prove the point:
           | https://news.ycombinator.com/item?id=42457515
           | 
           | Teach that to a 10 year old, where their primary keyboard
           | experience is a phone.
           | 
           | More than that, if rust is the future, which I have seen
           | espoused before, picking on the Java keywords and syntax is
           | highly amusing.
        
           | bigstrat2003 wrote:
           | I _did_ cut my teeth on Java back in middle school-ish. It
           | never bothered me at all, I was too busy having fun learning
           | to program. I agree with GP, the mandatory class is a
           | completely overblown complaint about Java.
        
           | fijiaarone wrote:
           | If you think Java boilerplate is bad, wait until you have to
           | learn about ELF file formats in order to execute almost
           | everything else.
        
         | voidhorse wrote:
         | I'm of two minds about it. On the one hand, the verbosity is
         | arguably noise if you are first learning to program, or just
         | want to write something quick, so I can see why people dislike
         | it.
         | 
         | On the other hand, viability, classes, and "staticness" are all
         | fundamental structural concepts in Java. Hiding them for a
         | special case is sort of like lying, and, in the long term, I
         | can actually see this special case causing more confusion for
         | new learners. It's sometimes better to be upfront and
         | transparent and force your users to work with the paradigm and
         | semantics they chose to adopt, rather than pretend it doesn't
         | exist. If Java had been designed to allow for top-level
         | functions from the start, it'd be a different story. I think
         | special casing is a generally bad way to evolve a programming
         | language.
        
           | gf000 wrote:
           | But there is absolutely no hiding, the design is very smart!
           | 
           | You simply get an unnamed implicit class like `class Tmp367
           | {` written at the top, and the _runtime loader_ has been
           | modified to be more accepting of main methods. There was
           | basically a tiny language change, and no bytecode change,
           | java semantics are just like they always were.
           | 
           | The Main loader just simply will accept an instance method
           | named 'main' for a class with an empty constructor with no
           | args, instead of psvm.
        
             | klez wrote:
             | It's hidden from the newbie who never used java before,
             | that's what we're talking about. As you said, all that
             | stuff is done implicitly. The user never sees any of that
             | unless they go digging.
        
         | norir wrote:
         | The problem is when java is used as a first language, this is
         | needless complexity that gets in the way of the actual
         | fundamentals of programming. Access privileges are irrelevant
         | for a beginner who is hopefully not writing libraries that will
         | be consumed by anyone. The distinction between an instance and
         | static method is also confusing and irrelevant. It's just
         | pointless ritual for the student.
         | 
         | Now, if one is learning java as a second language, that's a
         | different story.
        
       | scotty79 wrote:
       | For error handling they could add error propagation operator `?`
       | from Rust. In Java it could propagate "throws" from the
       | expression it's applied to the signature of a method that
       | contains it. In Rust it's a bit awkward becuse you need to adjust
       | return type. Since Java tracks exceptions separately it would be
       | completely unobtrusive and ultraconvenient.
        
       | deergomoo wrote:
       | It's not a popular choice for it, but PHP is also fantastic for
       | the sort of things described in this article. A relatively recent
       | version is pre-installed on many *nixes, it has a decent enough
       | (and gradual) type system, and standard library absolutely chock
       | full of functionality (albeit very self-inconsistent in naming
       | and structure) for dealing with files, JSON, making network
       | requests, etc.
       | 
       | And because it's not compiled, you can just whack a hashbang at
       | the top of the file and chmod it to be executable.
        
         | Terr_ wrote:
         | I agree it'll work, but from a broader ecosystem perspective it
         | feels like a mismatch, given PHP's historic focus on webstack
         | stuff, and the projected likelihood that someone maintaining
         | the system will know PHP versus Python etc.
         | 
         | But perhaps we can both agree that it shouldn't be in JS/Node.
         | :p
        
         | macspoofing wrote:
         | That's true for every other mainstream interpreted language. Is
         | PHP better than Ruby or Python for those use-cases?
        
       | AtlasBarfed wrote:
       | Groovy is still far far far better at cli scripting in javaland.
       | 
       | You don't even need main methods and class wrappers, can import
       | libraries with annotations with Grape, etc.
       | 
       | The real failing of cli and scripting in jaba and groovy is
       | running cli commands with access to stdin stdout stderr streams.
       | I have figured out the dark art for groovy but it takes quite a
       | few stack overflows to get there.
        
         | socksy wrote:
         | Maybe it's sort of not the same because it's compiled with
         | graalvm and so not trivial to add any arbitrary Java
         | dependency, but the tech that scratches that itch for me is
         | babashka -- a proper REPL, because it's a lisp, sensible
         | Clojure syntax, and easy IO. And all the core Java libraries,
         | available in a much snappier form than Clojure or other
         | compiled languages
        
           | brabel wrote:
           | The Groovy shell can be really fast if you use GroovyServ:
           | https://kobo.github.io/groovyserv/quickstart.html
           | 
           | It feels instant, no need for GraalVM.
        
       | e12e wrote:
       | Interesting. Anyone have an opinion on how this compares to using
       | Kotlin for similar tasks?
        
         | mdaniel wrote:
         | Seems very similar https://kotlinlang.org/docs/kotlin-tour-
         | hello-world.html although I haven't ever used Kotlin like a
         | "script replacement" (e.g. https://kotlinlang.org/docs/run-
         | code-snippets.html#command-l... ) to compare and contrast
         | 
         | Overall, I think Kotlin is a vastly superior language to Java
         | and spanks Scala in discoverability and legibility _(less
         | magick moar bettar, IMHO)_
        
           | norir wrote:
           | I've abandoned the jvm, but I found Scala much better
           | designed than Kotlin. Things in Kotlin felt consistently ad
           | hoc and I would frequently run into weird special casing
           | whereas Scala actually had general principles that could be
           | applied to more use cases.
           | 
           | Kotlin on the other hand had better IDE support in intellij
           | for obvious reasons. That was not nearly compelling enough
           | for me.
        
             | therealdrag0 wrote:
             | What'd you switch to from JVM?
        
         | occz wrote:
         | I'd consider it equal or better in all regards.
         | 
         | - Top-level functions/main is supported - data classes are
         | approximately as good as records - A scripting mode comes built
         | in, and can use annotations to import and use dependencies
         | within the same file - There's a repl - The keyword 'var'
         | exists, and the keyword 'val' is more ergonomic than 'final
         | var'
         | 
         | The only thing I remember missing from the article is the
         | implicit imports which I don't remember Kotlin having.
         | Regardless, I'd reach for Kotlin every time. I think funnily
         | enough Java never fully clicked for me until I started using
         | Kotlin, which in many ways is "Java, except many best practices
         | are on by default".
        
         | jillesvangurp wrote:
         | Also, see my comment about kotlin scripting (kts) elsewhere in
         | this thread.
         | 
         | But, in short, you can write kts shell scripts; import any
         | library you want, use anything in the JVM or the Kotlin or Java
         | library ecosystem that you need, etc.
         | 
         | Works on the command line (you need a jvm and kotlin installed
         | from your favorite package manager). The Kotlin Jupyter kernel
         | also uses kts and this is a nice way to use Java stuff in
         | jupyter.
        
       | anthk wrote:
       | On Java, a lot of 1.2/1.3 era games are half-broken and threads
       | fail a lot with interpreter from Java 2SE (>1.6/OpenJDK 6) and
       | beyond.
        
       | msgilligan wrote:
       | For those interested in the rationale for the simplified main
       | methods (and the rationale for _not_ simplifying further), the
       | relevant JEP is a good read.
       | 
       | JEP 495: Simple Source Files and Instance Main Methods (Fourth
       | Preview) https://openjdk.org/jeps/495
       | 
       | The parent article mentions and links JEP 477 -- the 3rd preview
       | of the same feature-set. JEP 495 is the 4th preview and is
       | included in JDK 24 which is in "stabilization" mode for release
       | in March 2025.
        
       | aardvark179 wrote:
       | I regularly end up using Jshell when I'm analysing things like
       | profiling data. Partly because I have access to libraries that
       | parse those formats, but also because typing and autocomplete
       | make it really effective for this sort of interactive thing.
        
       | driggs wrote:
       | Lightweight Java has always been a thing for those who appreciate
       | Java-the-language but despise Java-the-ecosystem.
       | 
       | You don't need to fool with Gradle or Maven or Ant if you'd like
       | to incorporate third-party or your own custom dependencies in
       | single-file "Java scripts".
       | 
       | Just copy some .jar files into ~/lib, and in your `.bashrc`:
       | export CLASSPATH=~/lib;$CLASSPATH
        
         | miuramxciii wrote:
         | Ah.. the old days of java programming - set up your CLASSPATH
         | and done.. Nowadays; however, most libraries have tons on other
         | dependencies and doing this manually is tedious and a pain in
         | the neck - download the wrong version of the dependency, and
         | you are in for a rabbit-hole trying to figure out the
         | compilation errors. Do not get me wrong, Maven is ugly and
         | disgusting(so are the other dependency managers for java), but
         | gone are the days of CLASSPATH.. unless you avoid using
         | libraries bloated 3rd part libraries at any cost.
        
           | rmgk wrote:
           | If you like to have most of the simplicity of just setting
           | classpath, but still have convenient dependency resolution, I
           | highly recommend checkig out coursier: https://get-
           | coursier.io/
           | 
           | Its a cli based artifact fetching tool for the JVM ecosystem,
           | and you can have it just make up classpath strings for you,
           | i.e., to use some Apache dependencies with the single file
           | simplified java running you could just:
           | 
           | java --enable-preview --class-path (cs fetch --classpath
           | org.apache.commons:commons-collections4:4.4) program.java
           | 
           | Also, maybe do have a look at scala-cli: https://scala-
           | cli.virtuslab.org/ It does work just fine with Java files,
           | and allows you to write single-file programs that include
           | dependencies as special comments. The tool has some
           | idiosyncrasies (like a background compiler server), but
           | overall works extremely well if you need some of the power of
           | a build tool, but without having a complex project structure.
        
             | oftenwrong wrote:
             | Also, see this project that is in a similar space as
             | Coursier:
             | 
             | https://github.com/bowbahdoe/jresolve-cli
             | 
             | https://github.com/bowbahdoe/jresolve
        
         | palmfacehn wrote:
         | java -cp .:* OneOffTestCase.class
        
         | d_burfoot wrote:
         | I use Java extensively for my personal work and never use
         | Gradle/Maven/Ant. I run Python scripts that marshal javac and
         | java calls, it works great. I do cute tab completion tricks
         | that examine the class layout and extend based on what it
         | finds. I even have a "SmartCompJava" script that finds .java
         | files that have newer modtimes than their corresponding .class
         | files and just compiles them - a bit dangerous if you're not
         | careful, but it's super-fast!
        
         | oftenwrong wrote:
         | >Lightweight Java has always been a thing for those who
         | appreciate Java-the-language but despise Java-the-ecosystem.
         | 
         | I always disliked Java until I was converted by some developers
         | of that group in a past job. I suppose it is fair to judge a
         | language by the overall flavour of its ecosystem, but it is a
         | bit disappointing. I wish more people could see how simple and
         | _good_ it can be when you use the JDK itself, and not go
         | through other overcomplicated systems to use it. For example,
         | Spring Boot is basically a massive pile of hacks (regardless of
         | whether you consider it good or bad), and Java only really
         | serves as an underlying support technology for it.
        
       | w10-1 wrote:
       | Launching without compiling, a main interface... a Mark Reinhold
       | story
       | 
       | During jdk 1.1 development, there was obviously no consensus on
       | test suites (i.e., JUnit), and the JavaSoft JCK tests required a
       | ridiculous amount of html documentation for tracing to specs.
       | Mark Reinhold, the jdk tech lead, refused to have his team write
       | tests in JCK form, so instead he wrote a small harness with a
       | compiling class loader: point the harness at a directory tree of
       | .java files, and it would run them all, compiling as needed. The
       | test interface was just a main function, and if it threw an
       | exception, it failed. Pure and simple.
       | 
       | But probably the best magic trick for Java programmers is
       | debugger hot reload. You write some empty methods, start the
       | debugger, and then code iteratively, reloading as needed. (Set up
       | the data and interfaces right, and change method bodies as you
       | wish.) It's so much easier than recompile-println when you're
       | just getting started, and after you've grown up and out, it's
       | easier than rebuild/redeploy when you're working on a big system.
        
         | jaccarmac wrote:
         | > debugger hot reload
         | 
         | Hey, that's (close to) the traditional Smalltalk introduction-
         | trick! And this has been available since 1.1? How does one
         | concretely do that in Java and why is it not widely known?
        
           | gf000 wrote:
           | Well, it doesn't sit that well with mutable global/local
           | state. There is a saying that hot reloading works better if
           | you can replace at a smaller, atomic granularity. In the JVM,
           | this kind of reload is at the method granularity, which may
           | or may not be ideal.
           | 
           | But the JVM still has a few tricks up its sleeve, e.g. the
           | class loader can dynamically re-load a newly compiled version
           | of a class at runtime - jrebel is a proprietary extension
           | that uses both tricks, but this latter can also be used by
           | spring for hot swapping many parts of a running system.
           | 
           | Basically, in the JVM a class is unique within the class
           | loader, so with a new class loader you can load as many class
           | instances of the same, or slightly different class as you
           | wish.
        
           | mike_hearn wrote:
           | 1. There's no way to react to hot reload in the normal Java
           | API, so you can't easily clear state.
           | 
           | 2. The JDWP protocol lets debuggers redefine nearly anything,
           | but HotSpot doesn't implement the full protocol. In practice
           | many kinds of reload don't work.
           | 
           | 3. To fix those issues app frameworks went with classloaders
           | for partial app reloads instead, or reimplemented hotswap
           | logic themselves (see JRebel).
           | 
           | There's no fundamental reason these can't be fixed, and in
           | fact the Espresso JVM fixes both 1 and 2:
           | 
           | https://www.graalvm.org/latest/reference-
           | manual/espresso/hot...
           | 
           | You can write JVM plugins that are invoked after redefinition
           | occurs, allowing you (really your app framework) to do
           | something sensible like partially reload state. And it
           | implements the full protocol, so many more kinds of
           | redefinition work.
           | 
           | Using it is easy. Just install Espresso as your JDK, point
           | your build system at it, then debug your app. Recompiling
           | what attached will cause hot reload.
        
             | JavierFlores09 wrote:
             | Interesting, I've never heard of Espresso, I've always just
             | used Jetbrains Runtime[1] instead which is the successor of
             | DCEVM[2] in a way. As for plugins I used HotswapAgent[3] at
             | times however I found it to be rather clunky, does Espresso
             | improve on this aspect?
             | 
             | 1: https://github.com/JetBrains/JetBrainsRuntime
             | 
             | 2: https://dcevm.github.io/
             | 
             | 3: https://hotswapagent.org/
        
         | rramadass wrote:
         | > But probably the best magic trick for Java programmers is
         | debugger hot reload. You write some empty methods, start the
         | debugger, and then code iteratively, reloading as needed. (Set
         | up the data and interfaces right, and change method bodies as
         | you wish.)
         | 
         | Do you have any example you can point to for this ?
        
       | easylion wrote:
       | I totally agree. I use java for every possible coding script or
       | task. I have been using it in my company for last 5+ years and
       | have understood the language too well to be able to switch to
       | something else and learn its caveats. In my comfort zone with
       | java and I love that its being actively developed and improved
       | every day.
        
         | trallnag wrote:
         | Are you in the comfort zone with Spring as well?
        
           | throwaway03452 wrote:
           | I can only speak for myself, but I was lucky to be exposed to
           | Spring Boot back in the v1.5 days after spending a few years
           | creating Java programs without any framework. No XML at all,
           | configuration by code, and opinionated default configuration
           | that covers most use cases.
           | 
           | The learning curve was not that hard, and I got comfortable
           | with it.
           | 
           | In contrast, I find React, Next.js and other frameworks more
           | complex, and it takes a lot longer to be comfortable
        
       | joeevans1000 wrote:
       | Take a look at Clojure and also Clojure Babashka.
        
         | lebski88 wrote:
         | Babashka is truly wonderful and has taken over almost all my
         | scripting projects. But the author started by saying they
         | didn't want to use a language without types so Clojure is
         | probably out!
        
       | Kwpolska wrote:
       | > I am pretty sure [working around checked exceptions] will never
       | be a part of the JDK, because it is arguably bad for large and
       | serious programs.
       | 
       | And yet so many programming languages, including JVM languages
       | like Scala or Kotlin, just don't do checked exceptions, and the
       | world hasn't caught fire yet (and in fact, I can't think of
       | another mainstream language that does have them). Java could just
       | drop them altogether and everyone (except maybe the most devout
       | Java fans) would be happier.
       | 
       | > The file gets compiled on the fly, every time that I run the
       | script. And that's just the way I want it during development or
       | later tinkering. And I don't care during regular use because it's
       | not that slow. The Python crowd never loses sleep over that, so
       | why should I?
       | 
       | Java takes significantly longer to compile than Python does. My
       | Python takes ~40 ms at first startup of a hello world script, ~20
       | in later attempts. `java hello.java` is in the 360-390 ms range.
        
         | klez wrote:
         | > `java hello.java` is in the 360-390 ms range.
         | 
         | That's still pretty negligible. I don't think he's making a
         | strict comparison, just saying that in both cases it's barely
         | noticeable.
        
         | vips7L wrote:
         | Checked errors are not unique to Java. Rust, HNs darling baby,
         | is praised on this forum every day for checked errors. Swift,
         | F# and countless other languages have checked errors.
         | 
         | There is nothing wrong with checked exceptions and there is
         | really no difference between a Result and a function with a
         | checked exception.                   fn a() -> Result<String,
         | SomeError>         String a() throws SomeException
         | 
         | The issue is not with checked exceptions but with Java's
         | syntax. They have not given programmers the language syntax to
         | easily deal with checked exceptions. You cannot easily escape
         | them without boilerplate and they don't work correctly across
         | lambdas. This is why Rust ships with ?; Swift has shipped with
         | try!, try?; and Scala ships with try as an expression and is
         | experimenting with checked exceptions that work across high
         | order functions [0].
         | 
         | Programmers across every language ecosystem are moving towards
         | checked errors and away from unchecked runtime crashes. Even
         | Kotlin, a language that shipped with unchecked errors, is
         | planning on adding a form of checked error handling [1].
         | 
         | [0] https://docs.scala-
         | lang.org/scala3/reference/experimental/ca... [1]
         | https://youtrack.jetbrains.com/issue/KT-68296
        
       | exabrial wrote:
       | > JTaccuino
       | 
       | Shame the link is broken, looked fascinating!
        
       | d_burfoot wrote:
       | It's worth observing that languages significantly over time,
       | usually for the better. I remember writing Java when it was slow
       | and had no generics. Now it's one of the fastest languages, and
       | has not just generics but also (simple) type inference, which
       | cuts down significantly on boilerplate. The point is: if you have
       | a foggy memory from ten years ago of hating some language, many
       | of the problems may have now been fixed.
        
         | mattgreenrocks wrote:
         | It's hard to fault Java at this point: arguably the best
         | runtime of them all from a perf perspective, great tooling from
         | JetBrains, large, high-quality ecosystem whose quality far
         | exceeds npm on average, and sealed classes as an acceptable sum
         | type. My only remaining issue is how prevalent nulls are, but
         | there's some work in progress on improving that. Until then,
         | I'll prefer Kotlin slightly.
         | 
         | Definitely one of those things where the comment section is
         | only good at spouting ancient memes with little regard to the
         | truth of them.
        
           | Xeoncross wrote:
           | > It's hard to fault Java at this point: arguably the best
           | runtime of them all from a perf perspective
           | 
           | The JVM is a massive memory sink compared to the tiny
           | (actual) runtime in Go or the total absence of a VM or
           | runtime in Rust or Zig. I allocate at least 5x more memory
           | for Java tasks, but sometimes its more.
           | 
           | Java is great compared to scripting languages or writing raw
           | C, but not compared to modern compiled languages from a
           | syntax (null, thrown exceptions, inheritance, etc..), library
           | selection, CVE/security, memory usage or raw computer power
           | perspective.
        
             | pron wrote:
             | Many times the "massive" memory sink is because people give
             | the VM more memory than it actually needs (or they use the
             | default, which is to take up to 25% of RAM whether or not
             | it's really needed for the required performance). I.e.
             | people will say a process "takes" 1gb, when the same
             | program could run just as well if they tell it to use, say,
             | 300mb. The more memory, the faster it could run. The GCs
             | offered by the JVM are more advanced than Go's by a couple
             | of tech generations (the Go-like GC was removed from the
             | JVM when it was superseded by two generations of newer
             | GCs), and memory consumption is already going down with
             | compact object headers [1] and will go down even further
             | with Valhalla.
             | 
             | All in all, Go may take up _a little_ less memory for
             | similar performance, but the JVM is more flexible (and more
             | observable), offering you better performance if you need
             | it. And the footprint will continue dropping, as it has
             | done for years [2].
             | 
             | C++, Zig, or Rust are not really an apples-to-apples
             | comparison. Sure, they take up significantly less RAM, but
             | their performance is more expensive per unit of effort, and
             | it's not a one-time cost, either. It's a permanent tax on
             | maintenance, not to mention Java's superb observability.
             | 
             | Don't get me wrong -- I'm a fan of Zig, and C++ is the
             | language I still program in most, but you can't really
             | compare them to Java. Java makes you pay for certain things
             | -- especially in RAM -- but you do get your memory's worth
             | in exchange, and in a way that translates to pretty
             | significant time and money. If you can't spare the memory
             | as you're running in a constrained environment that's one
             | thing, but if you can, it's all a matter of what you want
             | to use it for: do you want to use it all just on data, or
             | do you want to spare some to reduce maintenance
             | costs/increase development speed and improve performance?
             | 
             | BTW, I'm not sure what is actually meant by a "lack of
             | runtime" for C++/Rust/Zig. They all have standard
             | libraries, just like Java. Rust even has a (crude) GC in
             | its runtime that most Rust programs use (and, like Java, it
             | compiles down to a VM). I think what people mean is that
             | compilation to native is typically AOT rather than JIT, but
             | that has both pros and cons.
             | 
             | [1]: https://openjdk.org/jeps/450
             | 
             | [2]: E.g. https://openjdk.org/jeps/254
        
               | needlesslygrim wrote:
               | I'm interested by your characterisation of Rust. I assume
               | 'crude GC' is a reference to Rc/Arc, but I would be
               | interested to see some statistics for the claim most
               | programs written in Rust use them extensively. Also,
               | Rc/Arc arent a part of any Rust 'runtime', but rather the
               | standard library, and are not available when they eould
               | not be suitable for the target, e.g. UEFI. Moreover,
               | rustc compiles to LLVM IR, but LLVM is not a JVM/CLR VM,
               | and rustc is not the only Rust compiler (though the
               | others are admittedly not production-ready yet).
        
               | pron wrote:
               | > I assume 'crude GC' is a reference to Rc/Arc, but I
               | would be interested to see some statistics for the claim
               | most programs written in Rust use them extensively.
               | 
               | Yes, Rust's GC is used through Rc/Arc, and I never said
               | it is used _extensively_ by most programs, only that most
               | programs do use it. It is _because_ it is not used
               | extensively that it can be crude and designed to minimise
               | footprint rather than offer good performance.
               | 
               | > Also, Rc/Arc arent a part of any Rust 'runtime', but
               | rather the standard library
               | 
               | What's the difference between a standard library and a
               | runtime? In the three decades I've been programming,
               | they've been used interchangeably. A language runtime
               | means some precompiled-code that programs use but is not
               | compiled directly from the program.
               | 
               | > rustc compiles to LLVM IR, but LLVM is not a JVM/CLR VM
               | 
               | I never said that LLVM was a JVM -- these virtual
               | machines have very different instruction sets -- but like
               | a JVM, LLVM is a VM, i.e. an instruction set for an
               | abstract machine.
               | 
               | Now, it is true that Rust is typically (though not
               | always) compiled to native code AOT while Java code is
               | typically (though not always) compiled to native code
               | JIT, but I don't understand why that difference is stated
               | in terms of having a runtime. One could have an AOT-
               | compiled JVM (and, indeed, that exists) as well as a JIT-
               | compiled LLVM (and that exists, too).
               | 
               | It is also true that Rust programs can be compiled
               | without a runtime (or a very minimal one) while Java
               | programs can choose to have more or less in their
               | runtime, but even the most minimal runtime is larger than
               | the most minimal Rust runtime.
        
               | whytevuhuni wrote:
               | > What's the difference between a standard library and a
               | runtime? In the three decades I've been programming,
               | they've been used interchangeably.
               | 
               | First of all, you're right. But despite its definition I
               | think people tend to look at it differently.
               | 
               | A runtime is generally thought of as a platform on top of
               | which your code runs on; it needs to start first, and it
               | manages your code. Or perhaps it runs in a side thread.
               | 
               | A language that has a runtime is hard to embed into
               | something via just the C ABI, because a function call
               | wouldn't use just the standard platform calling
               | convention; it would have to start that runtime, perhaps
               | marshal the parameters into something supported by that
               | runtime, and then finally the runtime runs your
               | function's code.
               | 
               | Take for example cgo, for which you'd need to start the
               | garbage collector first (among other things), hence why
               | the cgo FFI is expensive. Take as another example an
               | async Rust function, which would require e.g. a Tokio
               | runtime to be started first. Another example is Java, for
               | which you'd have to start the whole JVM first.
               | 
               | A language that has no runtime, or a minimal runtime, can
               | be called via the C ABI directly. All the function needs
               | is to follow the calling convention, and then its code
               | starts running immediately.
               | 
               | This is just my opinion of other people's opinions, I may
               | be wrong.
        
               | pron wrote:
               | > A runtime is generally thought of as a platform on top
               | of which your code runs on
               | 
               | That's not a well-defined thing.
               | 
               | > A language that has a runtime is hard to embed into
               | something via just the C ABI, because a function call
               | wouldn't use just the standard platform calling
               | convention
               | 
               | But Java can be embedded in native code or embed native
               | code. It has a specified FFI in both directions.
               | 
               | > Take for example cgo, for which you'd need to start the
               | garbage collector first (among other things), hence why
               | the cgo FFI is expensive.
               | 
               | Well, Java doesn't quite work like that, and its (new)
               | FFI is free in most important cases (i.e. same as a non-
               | inlined C-to-C call). Also, "starting the garbage
               | collector" is not well-defined. What "starts" Rust's
               | garbage collector?
               | 
               | I understand what you're trying to get at, but things
               | aren't so simple. There are, indeed, differences
               | especially around JIT vs AOT, but it's not as simple as
               | saying "having a runtime" or not, nor is everything
               | similar in all languages (Rust and C don't work the same
               | vis-a-vis the C ABI, and Java, C#, and Go interop with
               | native code are all quite different from each other).
               | 
               | > A language that has no runtime, or a minimal runtime,
               | can be called via the C ABI directly.
               | 
               | A Java program can easily expose any method via the C ABI
               | to be called directly if the process has been started
               | from Java -- i.e. it's easy for Java code to give native
               | code a function pointer to Java code. Going the other
               | way, i.e. embedding Java in a C program, is somewhat more
               | involved, but even C++'s interop with C, not to mention
               | Rust or Zig, is not always straightforward. Like in Java,
               | certain functions need to be marked as "C-interopable".
        
               | whytevuhuni wrote:
               | > But Java can be embedded in native code or embed native
               | code. It has a specified FFI in both directions.
               | 
               | Most languages have an FFI, but I am talking specifically
               | about the C ABI and the platform calling convention; or
               | more specifically, about starting from scratch, and what
               | is necessary to do from there until your code can finally
               | run.
               | 
               | Anything more complex than the C ABI is what makes people
               | say there is a runtime. It's some layer between your code
               | and the other language's code, inserted there by your
               | language. There's usually no way to remove it, and if
               | there is, it severely limits the language features you
               | can use.
               | 
               | > What "starts" Rust's garbage collector?
               | 
               | Nothing; it doesn't start unless the function itself
               | wants to start one, and the function can choose which one
               | to start, through your code (rather than what the
               | language's required runtime provides).
               | 
               | > A Java program can easily expose any method via the C
               | ABI to be called directly if the process has been started
               | from Java
               | 
               | In that case, the runtime has already been started, and
               | is being reused.
               | 
               | > Going the other way, i.e. embedding Java in a C
               | program, is somewhat more involved
               | 
               | That part is the most important part, and is generally
               | why people say Rust has a minimal runtime; it can be
               | embedded with very little setup. The code you write
               | starts executing almost immediately. Java calling C may
               | add a management layer on Java's side, but
               | C/C++/Rust/Zig/etc need very little (hence, minimal
               | runtime).
        
               | pron wrote:
               | > Anything more complex than the C ABI is what makes
               | people say there is a runtime.
               | 
               | But Rust (or Zig, or C++ for that matter) don't use the C
               | ABI, either, except for specifically annotated functions.
               | 
               | > In that case, the runtime has already been started, and
               | is being reused.
               | 
               | True, but I'm trying to say that the notion of "starting"
               | the runtime (or the GC for that matter) is not really
               | well-defined. HotSpot does need to be "started", but,
               | say, Graal Native Image, which is sort of an AOT-
               | compiled, statically linked JVM, isn't really "started".
               | 
               | > Java calling C may add a management layer on Java's
               | side, but C/C++/Rust/Zig/etc need very little (hence,
               | minimal runtime).
               | 
               | In some implementations of Java this may be the case in
               | some situations, yes. I would go further and say that
               | that's the _typical_ case, i.e. if you want to embed the
               | stock HotSpot, you will need to call some initialisation
               | functions.
               | 
               | If that's what's meant by "runtime", then it's mostly
               | correct, but it's more an implementation detail of
               | HotSpot. Even without it there will remain more important
               | differences between C++/Zig/Rust/C and Java, and this
               | matter of "runtime" is not the most interesting aspect.
               | For example, that Java is usually compiled JIT and Rust
               | is usually compiled AOT is a bigger and more interesting
               | difference.
        
               | whytevuhuni wrote:
               | > But Rust (or Zig, or C++ for that matter) don't use the
               | C ABI, either, except for specifically annotated
               | functions.
               | 
               | Not only that, but Rust, C, Zig also require some setup
               | before their `main()` can start as well.
               | 
               | That is why people say they have a "minimal runtime",
               | rather than "no runtime". There is still a bit of setup
               | there, without which the languages cannot function, or
               | can only function in a limited mode.
               | 
               | Otherwise agreed on all your other points.
        
               | neonsunset wrote:
               | FWIW Cgo FFI is expensive not because of GC but because
               | Go uses virtual threads (goroutines) and prioritizes the
               | simplicity of runtime implementation. The lower bound of
               | FFI cost in .NET is roughly equivalent to direct not-
               | inlined calls in C, despite the GC support.
        
             | mavelikara wrote:
             | These other languages do not have the programing
             | affordances of Java (generics, easy memory safety). Tooling
             | is a big factor in favor of Java - IDEs, debuggers,
             | observability etc. Also, the quality and availability of
             | libraries is also a debatable point (although, it depends
             | on the application at hand),
        
               | Xeoncross wrote:
               | I actually disagree with all of these points and I write
               | Java at work.
               | 
               | Memory safety isn't possible in Java (unlike Rust).
               | 
               | Tooling: they all have debuggers and observability
               | tooling (pprof, pprof-rs, etc..). Rust even has zed now.
               | 
               | Libraries: Rust has really high quality packages. On the
               | flip side, Go has almost everything built into the
               | stdlib. Java requires a ton of third party packages of
               | varying quality and guarantees even for basic things like
               | logging or working with JSON. You have to constantly be
               | on the lookout for CVE's.
               | 
               | In fact, 75% of the cloud-native foundations projects are
               | in Go. K8s and docker are Go. Go is much more web-app or
               | microservice focused than Java is actually. Most Java
               | apps are deployed into the cloud using Go.
               | 
               | Meanwhile, Zig makes using the universe of C/C++ code
               | easy.
               | 
               | I highly recommend you try Zig, Rust, or Go out. They
               | weren't created out of ignorance of Java, but because
               | Java and C++ had areas that could be improved.
        
               | pron wrote:
               | Zig or Rust neither attempt to nor have any chance of
               | directly competing with Java or any other high level
               | language, other than on the margins (they have a hard-
               | enough time competing with C++, which is unfortunate,
               | because both are better than C++ -- Rust slightly so and
               | Zig significantly so, IMO). They are for low-level
               | development and target a domain where both the calculus
               | of cost and value is vastly different from the high-level
               | application space.
               | 
               | It is usually just as easy to write a program in a low
               | level language as it is in a high-level one, and this is
               | true not only for Zig and Rust, but also for C++. Even in
               | 1998 it was just as easy to write a program in C++ as it
               | was in Java. But the maintenance later -- when you have a
               | large 10-year-old codebase -- is significantly more
               | costly, and necessarily so. In a low-level language, i.e.
               | one where there's more direct control over memory
               | management, how a subroutine uses memory may affect its
               | callers. Whether the correct use in the caller is
               | enforced by the language, as in Rust, or not always, as
               | in Zig, changes in low-level languages require touching
               | more code than in high-level ones, and can have a bigger
               | impact.
               | 
               | The low-level domain is, and will continue to be,
               | extremely important. But the market share gap between
               | low-level and high-level languages/domains has only grown
               | over the past decades, and there are no signs of the
               | trend reversing.
               | 
               | Now Go is a different beast altogether, and is a high
               | level language. But it has both pros and cons compared to
               | Java. The tools it includes in the SDK are more user-
               | friendly, but they, like the language, are less flexible
               | and more limited than in the Java world. Nevertheless,
               | the out-of-the-box experience is nicer, something we
               | should definitely improve in Java, but you pay for that
               | simplicity later in lost flexibility. Performance also
               | isn't quite as good as Java's, and neither is
               | observability.
        
               | tonyg wrote:
               | > Memory safety isn't possible in Java (unlike Rust).
               | 
               | This is obviously some strange use of the phrase "memory
               | safety" that I wasn't previously aware of.
        
             | switchbak wrote:
             | I agree with you on the memory sink side. For some kinds of
             | applications the combo of startup time and memory
             | consumption make it unsuitable - think of many small
             | services or short-lived functions. Yes, Graal and such are
             | amazing innovations, but they're very incomplete and poorly
             | supported solutions and not something that's a good plan to
             | bank your future on. This has limited our cloud deployment
             | options to a significant degree, and I know I'm not alone.
             | 
             | Being a memory hog was not such a big deal in the pre-cloud
             | era, but we pay real money for that (far too much!) these
             | days, and leaner approaches are worth a lot in real
             | monetary terms.
             | 
             | I wish push back on some of your other points. Java has
             | evolved quite a lot lately, with improved syntax, much
             | improved runtime (Loom!), better GCs, lots of libraries,
             | etc. The community is a bit stale though, and it's viewed
             | as the Oldsmobile of languages. But that old language still
             | has a skip in it's step!
        
             | throwaway03452 wrote:
             | > The JVM is a massive memory sink
             | 
             | Java tends to prefer using available memory, before it has
             | to clean it. This results in memory usage growing more than
             | it actually needs.
             | 
             | Services often run in containers, so this is less than a
             | problem today than it was before, because the allocated
             | memory to the container is fixed anyway. Try configuring
             | the JVM to only use 75% of the container memory. In many
             | cases, it will trigger an early GC and run better with
             | smaller memory instances
             | 
             | There are of course some overhead for objects compared to
             | primitives, but the Valhalla project is working to reduce
             | the difference significantly on many cases.
             | 
             | You can also reduce memory usage and startup time by
             | compiling to a binary image
        
         | mtrovo wrote:
         | Few languages pull off the balancing act Java does, supporting
         | decades of code while rolling out big new features like project
         | Loom in a backward compatible way. Oracle's work really feels
         | like a lesson in how to evolve a language.
        
       | egeozcan wrote:
       | I use Java/JavaScript/TypeScript at work but I do most of my
       | scripting with .NET using LINQPad. Being able to use LINQ makes
       | scripting so much easier.
       | 
       | Python? Huge respect, huge ecosystem, however I don't know if
       | it's just me but I find it mighty hard to read. PHP with the "->"
       | and Python with the space-sensitivity... Not sure why but it's so
       | hard for me to overcome.
        
         | dominicrose wrote:
         | PHP syntax does add to the line widths, so breaking long lines
         | in multiple lines by extracting variables can help with
         | readability. Using return, continue and break early reduces
         | indentation so that helps too, as well as creating smaller
         | functions.
         | 
         | I use Ruby for scripting because it has a big standard library
         | (unlike javascript) and an expressive syntax. The syntax is
         | also very readable and short. It's also easy to install gems
         | globally and use them. Things only need to be imported once.
         | 
         | I wouldn't say these things are qualities for big projects
         | though. I like Typescript for big projects.
        
       | nprateem wrote:
       | They should adopt the tag line for Java: "Not as bad as you
       | remember"
       | 
       | I was also surprised when I looked at it again a year ago.
       | 
       | I would have used it for my latest Web app but django just beat
       | Spring boot.
        
         | riskable wrote:
         | Have a look at any "mature" Java project on Github and you'll
         | quickly come away with the opposite:
         | 
         | "Wow! It's even worse than I remember!"
         | 
         | "Wow! How many files and directories does this project NEED?
         | It's like someone decided that it's easier to manage files than
         | code..."
         | 
         | ...and there's still XML everywhere :(
        
       | brabel wrote:
       | > As of Java 23, three methods are automatically imported from
       | java.io.IO: println, print, readln
       | 
       | I thought they had just hallucinated `java.io.IO`, but apparently
       | it's a new type, available in Java 23 with --enable-preview:
       | https://docs.oracle.com/en/java/javase/23/docs/api/java.base...
        
         | mtrovo wrote:
         | It looks like they took lots of inspiration from Kotlin with
         | these new implicit imports and their structure.
        
           | brabel wrote:
           | Groovy and Scala already did that way before Kotlin.
        
       | roncesvalles wrote:
       | I just had this thought recently.
       | 
       | Java is a fantastic "scripting" language as long as you're fine
       | running it in an IDE. Clean and typed syntax, powerful standard
       | library (especially for data structures), great performance. A
       | better choice in these respects than say Python, Bash, or Go.
       | 
       | I've used it for scrapers, Advent of Code, plain ole data munging
       | and of course programming interviews.
       | 
       | That being said, I would never write a webserver in Java in 2024.
        
       | va1a wrote:
       | > but the Python API isn't all that wonderful, and dynamic typing
       | means that I spend too much time debugging
       | 
       | I don't know, this just seems more like inertia. "I'd rather
       | stick to what I know best than this popular thing." Which is
       | fine, and I'm glad Java has made improvements making it easier to
       | hit the ground running. But blaming the use of Java on the
       | inadequacies of Python? The python API can do just about
       | anything, it has regex toolings, I've never found myself needing
       | anything else. And the typing complaints? Yeah it can be annoying
       | if you're not good at keeping track of your own typing hints, but
       | modern python supports type annotations and linters like mypy[1]
       | catch everything related to that just fine. I've always admired
       | many of Java's features, but let's not act like the reason for
       | using Java for scripting is the pitfalls of Python. It's just
       | because of an underlying preference for Java.
       | 
       | 1. https://mypy-lang.org/
        
         | BeefWellington wrote:
         | > Yeah it can be annoying if you're not good at keeping track
         | of your own typing hints
         | 
         | If you write all the code you deal with, then sure. My
         | experiences on big projects tend to be typing problems
         | introduced by libraries. The kind where documentation and the
         | decorators suggest it'll only ever return some specific value
         | type, but then very occasionally it'll return a tuple of that
         | value type and a message.
        
           | va1a wrote:
           | Fair, but in the context of scripting, which seems to be the
           | focus of this article, how often are you dealing with complex
           | library code? When I write scripts for file manipulation /
           | simple automation, I'm usually not dealing with complex
           | library objects. Plenty of os method calls, plenty of regex
           | matches, but little else in this context. Big projects are
           | another thing entirely. There's a plethora of reasons why you
           | may want to use a different language for a certain project
           | type. But it doesn't seem fair to imply that python is
           | uniquely handicapped (or otherwise inferior to Java) for
           | scripting and simple automation use-cases.
        
       | pliuchkin wrote:
       | As for my experience, nothing beats nodejs for fast scripting.
       | Its literally just `npm install x y z` and then fire it up `$
       | node script.js`. But Im giving Java a chance.
        
       | bArray wrote:
       | Spent a while trying to get (OpenJDK's) JShell to work, it seems
       | like a buggy mess. I would currently not recommend using it for
       | anything serious.
        
       ___________________________________________________________________
       (page generated 2024-12-20 23:02 UTC)