[HN Gopher] Don't call it a comeback: Java is still champ
       ___________________________________________________________________
        
       Don't call it a comeback: Java is still champ
        
       Author : smartblondeva
       Score  : 210 points
       Date   : 2022-08-09 15:24 UTC (7 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | bilsbie wrote:
       | I've never once enjoyed writing Java. To me that's worth a lot.
       | 
       | To me it's always felt like some kind of assembly language humans
       | shouldn't deal with directly.
        
       | hackerlight wrote:
       | Java is the perfect choice if you need something that runs really
       | fast but not really really fast. It fills that niche very well.
        
       | Cwizard wrote:
       | I think Java gets a lot of flak because it is so popular within
       | enterprises. And we all know what kind of code gets written in
       | non-IT corporates. Add to that the fact that Java allows you to
       | do a lot means a lot of crazy code was conjured up over the years
       | which then had to be maintained and developed.
       | 
       | If you apply some discipline, I think Java is a great language.
        
       | fareesh wrote:
       | I don't really write in Java these days, but when I did the
       | biggest pain points for me were:
       | 
       | - IDE: IntelliJ and before that, Eclipse, were painfully slow to
       | use. Even now occasionally if I have to launch Android Studio I
       | have to wait for Gradle and various other things. The entire IDE
       | gets sluggish while it's doing indexing and all sorts of
       | weirdness. vim integration was quite poor at the time, I don't
       | know if things have changed since.
       | 
       | - Verbosity: It always feels like I am writing boilerplate and
       | long names. I remember trying to write something with websockets
       | and no matter what library I picked there was a ton of
       | boilerplate to write for just connecting to a socket and sending
       | a message.
       | 
       | If given a choice I'd much rather write in Python, C#, Ruby or
       | even Typescript. The language feels very dated - or perhaps there
       | are newer ways to do things that I'm totally unaware of.
        
         | fenesiistvan wrote:
         | IDE: Borland JBuilder was a king. I am still using it
         | Websockets: you can write your own in around 400 lines of code.
         | I did it. The specification/RFC is really simple. Just a few
         | bits above TCP
        
       | abadger9 wrote:
       | I've used Java my entire career and i'm fortunate for it. I
       | appreciate how readable the code is (unlike my experience with
       | Erlang, Haskell, etc), typically i don't have foundational issues
       | in the web framework (once again had some with Haskell).
       | Everything works, if I need to do low latency, there's great
       | libraries and resources, if i need to build a simple internal
       | tool, it can be done effortlessly.
       | 
       | I think python is the same way, the ecosystem is so rich that you
       | can really do anything you want (until you get into low latency).
        
         | 62951413 wrote:
         | I believe it's unfortunate people judge the JVM ecosystem by
         | Java. Scala and Kotlin are so much more attractive options if
         | you write code for a living. Between this and the devolution
         | from maven to gradle it's not a surprise junior developers are
         | JVM-shy.
         | 
         | I see companies downshifting to unmaintainable toys such as
         | Python even in data engineering circles. It's really odd that
         | mobile developers with Kotlin (and front-end ones with
         | Typescript) are getting ahead of backend ones in adoption of
         | modern languages.
         | 
         | Once Loom and Valhalla get merged to an LTS the remaining
         | vestiges of bad old Java will have been gone. I really hope
         | Graal goes mainstream too. That will hopefully blow out of the
         | water the golangs of the world. But those are platform-level
         | improvements any JVM language will benefit from.
        
         | thrown_22 wrote:
         | >if I need to do low latency
         | 
         | If the JVM is considered low latency I shudder to think what is
         | high latency.
        
           | hackerlight wrote:
           | Java is pretty fast. Second most popular language in HFT. Can
           | get it to a few tens of micros. Not as fast as C++ at sub 5
           | micros. So good enough for many latency sensitive apps.
        
             | bitcharmer wrote:
             | All our market data feed handlers are sub 5 micro in the
             | 99th. All in Java.
        
             | _gabe_ wrote:
             | > Not as fast as C++ at sub 5 micros.
             | 
             | Try sub 5 nanos. I was curious awhile ago at how fast C++
             | hash set lookup was compared to C#, and it consistently
             | performed a lookup at 1 nanosecond. I tested with up to 6GB
             | of data and then stopped because it was taking longer to
             | generate random data then it was to run the benchmark
             | 10,000 times.
             | 
             | C++ benchmarks here[0]. It's a bit more complicated then
             | just a pure lookup since I was pulling some code out of a
             | larger app, but the benchmark is only measuring the lookup
             | speed. I did the C# benchmarks with BenchmarkDotNet or
             | something like that, I can never remember the exact name.
             | 
             | [0]: https://gist.github.com/ambrosiogabe/66a6e2fdc77e6a600
             | e570f4...
        
               | titzer wrote:
               | > and it consistently performed a lookup at 1 nanosecond.
               | 
               | TBH I'm skeptical that you are measuring what you think
               | you are measuring. There are a lot of micro-benchmarking
               | pitfalls, like dead code elimination, loop-invariant code
               | motion, unrolling, and other issues. Unless you actually
               | looked at the machine code coming out of the compiler,
               | you're measuring something you don't understand. E.g. 1
               | nanosecond is roughly 3-6 instructions. That 100% means
               | the hash lookup has been inlined into the benchmarking
               | loop.
               | 
               | Are your hashtables mostly empty? Really small? Lots of
               | easy hits (or easy misses)? Because the slow cases
               | (actually looking up) are going to be hairier and may not
               | be inlined.
               | 
               | Did you benchmark against Java's HashMap? Because it is
               | also very, very, very fast for simple cases.
        
               | _gabe_ wrote:
               | It looks like caching definitely skewed the results a
               | bit. You can take a look at the linked code yourself.
               | Worst case was still only around 80 nanoseconds which is
               | definitely slower, but still orders of magnitude faster
               | than "sub 5 micros".
               | 
               | Don't take my word for it though, you can take a look at
               | the Robin Hood benchmarks[0]. Robin Hood unordered map is
               | a competitive hash map that's performed much better than
               | the STL for me in many cases. They average a 4 nanosecond
               | lookup speed for a hash map with 2000 elements and an
               | integer key.
               | 
               | > Did you benchmark against Java's HashMap?
               | 
               | I benchmarked against C#, which has a runtime that
               | performs similar if not better than the JVM. The C# code
               | was a ~~few microseconds~~ around 130 nanoseconds. Which
               | is still very fast, but up to 100x slower. (And yes, this
               | was _after_ warming up the code. I used benchmark dot
               | net[1] here.). This is a really easy benchmark to set up.
               | If you doubt me you can write a couple of benchmarks in
               | under an hour and compare yourself.
               | 
               | [0]: https://martin.ankerl.com/2019/04/01/hashmap-
               | benchmarks-04-0...
               | 
               | [1]: https://benchmarkdotnet.org/articles/overview.html
        
               | titzer wrote:
               | Did I read that right? The C# version is computing SHA256
               | hashes?
        
               | _gabe_ wrote:
               | That's a link to the benchmark framework that I used. The
               | C# benchmark are in a separate gist that I didn't feel
               | like digging up. This is the C# benchmarks[0]. All the
               | interfaces and indirection is the result of me adapting
               | this from a separate comment. But the benchmark is just
               | testing `HashSet.TryGetValue`.
               | 
               | Edit: I just re-ran the benchmarks because I didn't have
               | the results pasted in the snippet (which I've now done so
               | I don't keep getting this wrong haha). The C# HashSet
               | takes around 130 nanoseconds, not microseconds. So it's
               | not orders of magnitude slower, but it is still more than
               | a 2x slow down and up to a 100x slow down in the case of
               | an integer key.
               | 
               | [0]: https://gist.github.com/ambrosiogabe/ba6bd0fa80588c2
               | fd2ca26d...
        
           | 5e92cb50239222b wrote:
           | Java is heavily used in high-frequency trading. I believe
           | it's the most popular language after C++.
        
             | zinxq wrote:
             | Indeed. Shutoff Garbage collection completely and it can
             | work. (And make sure your Java code creates no garbage -
             | which is a new type of programming in and of itself)
        
               | zinxq wrote:
               | Edit: My bad - unfortunate wording. I didn't mean this as
               | negative at all. It's cool (if niche) ability.
        
               | vips7L wrote:
               | Maybe I'm taking your comment wrong, why is this a bad
               | thing? What other GC'd language just lets you turn it
               | off?
        
               | bee_rider wrote:
               | I don't think their comment is intended to be negative
               | really -- looks more like appreciative of the option,
               | while cognizant of the fact that using it introduces a
               | new challenge.
        
               | bitcharmer wrote:
               | It's not about turning it off. You just don't allocate on
               | the hot path.
        
               | vips7L wrote:
               | Some people choose to do neither!
               | https://medium.com/@jadsarmo/why-we-chose-java-for-our-
               | high-...
        
           | amusedcyclist wrote:
           | Depends on the use case, but if you are working on web
           | servers or other long lived processes the JVM is pretty close
           | to native and can even beat native code thanks to JIT
           | compilation.
        
         | dkarl wrote:
         | Agree with all of that except readability. Java has some
         | language deficiencies (no first-class functions, "streams"
         | missing for almost twenty years and added too late to be done
         | elegantly) and some cultural norms (mutable everything, overuse
         | of inheritance) that make it a chore to read most of the Java
         | code you encounter in the wild, including the source code of
         | the libraries you depend on. Figuring out the behavior of one
         | method routinely means taking a tour through implementation
         | details in three or four superclasses, factories, factory
         | factories, and all the other Java cliches that are legendary
         | but also absolutely real.
         | 
         | You can do better in your own code, but you still have exposure
         | to the code in the library ecosystem.
         | 
         | Worth it, though. It really does seem like there's a Java
         | library for everything.
        
           | gavinray wrote:
           | Modern Java has first-class functions, pattern matching with
           | structural binding, records/pure immutable data classes, the
           | whole 9 yards:                   static void main() {
           | BiFunction<Integer, Integer, Integer> add = (Integer x,
           | Integer y) -> x + y + 5;             Integer result =
           | addTo(10, add);             Integer result2 = addTo(10, (x,
           | y) -> x + y + 5);         }              static Integer
           | addTo(Integer acc, BiFunction<Integer, Integer, Integer>
           | addFn) {             return addFn.apply(acc, 5);         }
           | Integer eval(Expression e) {             return switch (e) {
           | case INT(var value) -> value                 case ADD(var
           | left, var right) -> eval(left) + eval(right)
           | case MULT(var left, var right) -> eval(left) * eval(right)
           | }         }
        
             | mrtranscendence wrote:
             | I haven't programmed in Java since 2005, so forgive me. But
             | isn't a lambda automatically converted to an object of the
             | necessary single-method type? That feels a little magical
             | and suggests that there really isn't such a thing as a
             | genuine first-class function in Java, as there is no way to
             | define a function, and no universal type to assign to such
             | a thing.
        
             | kaba0 wrote:
             | First class functions are as modern as the Iphone 5.
        
               | mrtranscendence wrote:
               | Pedantically, I want to point out that first class
               | functions predate the original iPhone by a large margin
               | ...
        
             | kaashif wrote:
             | > records/pure immutable data classes
             | 
             | Example?
             | 
             | As far as I know, Java has final, which means that
             | particular reference can't be re-assigned, but the object
             | referred to remains mutable. You have to resort to e.g.
             | having separate immutable and mutable interfaces or
             | whatever to restrict a someone from mutating your object.
             | 
             | If you want an immutable data class more than one level
             | deep, I don't know if there's a convenient way to do that
             | like there is with const in C++ (or the default behaviour
             | in Rust).
             | 
             | But I'm not a Java programmer, I haven't really kept up
             | with the language. Happy to be proven wrong.
        
               | gavinray wrote:
               | JDK 17 record classes:                 record User(String
               | name, Integer age, Boolean isActive) {}
               | 
               | https://docs.oracle.com/en/java/javase/18/language/record
               | s.h...
        
             | dunefox wrote:
             | This is destructuring but not pattern matching.
        
               | gavinray wrote:
               | How is this not pattern matching?
               | 
               | In Scala, I would write:                 enum Expr:
               | case INT(value: Int)         case ADD(left: Expr, right:
               | Expr)         case MULT(left, Expr, right: Expr)
               | def eval(e: Expr): Int = e match         case INT(value)
               | => value         case ADD(l, r) => eval(l) + eval(r)
               | case MULT(l, r) => eval(l) + eval(r)
               | 
               | This "match" syntax is the example given in the Scala
               | docs for Pattern Matching:
               | 
               | https://docs.scala-lang.org/tour/pattern-matching.html
               | 
               | The fact that Java happens to use "switch" instead of
               | "match" is one of syntax, not semantics.
               | 
               | JDK 17/18 introduces Sealed Types, which allow you to
               | create ADT's                 sealed interface Expr {
               | record INT(Integer value) implements Expr {}
               | record ADD(Expr l, Expr r) implements Expr {}         //
               | etc       }
               | 
               | When you "switch" over sealed types, the switch
               | expression is exhaustive if all members have branches and
               | requires no default case + is typesound.
        
             | oftenwrong wrote:
             | Unfortunately, records are only guaranteed to be
             | 'shallowly' immutable. It would be great if future Java
             | versions provided a straightforward way to enforce
             | immutability.
        
         | throwawaymaths wrote:
         | This is a matter of preference, I think. As a non-erlang
         | practicioner I find Erlang to be far more readable than Java
         | (which is good, because IMO Erlang authors have a habit of
         | writing spaghetti code that's poorly organized). As a non-
         | practicioner at some point in Java you run into annotations?
         | Pragmas? and you stop being confident that your mental model of
         | the code is correct. When I run into those I throw my hands up
         | and start cursing.
        
       | mdasen wrote:
       | The JVM is pretty great. I could certainly nitpick things, but
       | it's pretty great. Java is pretty decent. However, I would say
       | that Java lost a lot of time and even now there are some decently
       | rough edges.
       | 
       | Java didn't evolve as a language for a while and that left the
       | door open to other languages and other non-JVM ecosystems a lot.
       | As the article notes, Java 8 was a breath of fresh air, but it
       | was minimal in some ways. Lambdas and streams were great
       | additions to the language. However, Java 8 came out in 2014.
       | That's quite late to the game, in my opinion.
       | 
       | C# is probably the closest competing language/ecosystem (albeit
       | constrained to Microsoft for much of its life). In 2007 (7 years
       | earlier) C# 3.0 had lambdas, the `var` keyword, properties,
       | object initializers, the equivalent of streams (and really
       | better), nullable types for value types (like int), etc. In some
       | ways, Java has caught up - and C# lost a lot of time being
       | constrained to the Microsoft ecosystem. However, in other ways it
       | hasn't.
       | 
       |  _I just want a POJO_ : frankly, this has been a problem that
       | Java hasn't solved and it's been well over a decade where
       | everyone has known it's a problem. No, records don't solve it. In
       | Kotlin, I can make a data class and it's easy. In Scala, I think
       | they're case classes. In C# I have properties where I can say:
       | `class Person { string Name { get; set; } }`. I can see that it's
       | just a boring property without having to look at method bodies.
       | If there's something special, that get or set can have a body to
       | do stuff and it becomes really clear that it's something special.
       | Getters and setters are a wonderful way to set traps for others
       | on your team or for yourself a year later because you look at a
       | class with 15 items and it's going to have 90 lines of
       | getters/setters + another 30 lines of an empty line between each
       | method. You look and just decide "yea, I'm sure this doesn't have
       | special behavior" and go about your business just to get bitten
       | later.
       | 
       |  _I want to be able to instantiate data easily_ : With Java, I
       | can do `var person = new Person(); person.setName("Johnny");`,
       | but that becomes pretty tedious and error-prone when
       | instantiating a large object. With records you have a
       | constructor, but then you're dealing with positional arguments
       | and it's hard to understand. When reading the code, you don't
       | necessarily know what each of the inputs means. Maybe your IDE
       | puts the argument names in. When filling it out, I've found IDEs
       | to only be somewhat helpful. With C#, I can do `new Person { }`
       | and then hit the suggestion key combo inside the brackets in my
       | IDE and it'll offer to fill out all the properties so that I get
       | something like:                   new Person {             Name =
       | "",             Age = 0,             Address = ""         }
       | 
       | That means I don't forget about fields (as can happen if you're
       | just doing `person.setX()` all the time). It's easy to see what
       | is what when reading it. I can delete fields I don't want to
       | initialize at the time. Yes, maybe immutable objects are the One
       | True Way, but C# lets me choose (I can label properties with an
       | initializer `init` rather than a setter `set` and then they're
       | immutable).
       | 
       | Kotlin offers stuff like this too because it's really useful
       | toward creating code that's easy to create and maintain. Go also
       | lets you initialize structs in a similar fashion.
       | 
       | Java has come back to us a decade or more late with records.
       | They're not bad, but they're only offering one thing. They don't
       | cover what C#, Kotlin, Go, and other languages have offered for
       | so long.
       | 
       | The annoying thing about Java is that it doesn't feel pragmatic a
       | lot of the time. It feels like the language hates stealing ideas
       | from others. It's Java: people steal ideas from Java, not the
       | other way around. People do crazy things just to get POJOs
       | including Immutables (http://immutables.github.io), AutoValue
       | (https://github.com/google/auto/), Lombok
       | (https://projectlombok.org), Joda Beans
       | (https://www.joda.org/joda-beans/), and maybe more. They generate
       | lots of code at compile time or do funky runtime stuff.
       | 
       | It just feels like Java misses the pragmatic stuff and still
       | kinda doesn't want to handle that. I feel a bit silly harping on
       | things like POJOs and setting data on a new object, but that's a
       | big part of day-to-day stuff and it definitely pushes users away
       | from Java towards languages that seem "better" simply because
       | they don't have Java's oddly strong attachment to not offering
       | simple value objects. Yes, again, records do something - but it
       | feels like Java ignored how people are using Kotlin, Go, C#, and
       | more and didn't go for something that would have been as widely
       | applicable and pragmatic as it could have been.
       | 
       | Java has a lot of great stuff like great GCs (yes), lots of cool
       | research, great performance, and Project Loom is really exciting.
       | I just wish the language would lean a little more practical.
        
         | kaba0 wrote:
         | The situation regarding POJOs are annoying, but I believe Java
         | maintainers are fighting the good fight: introducing them in
         | the language would hardcode this arguably bad pattern
         | indefinitely. One might say that with the amount of code
         | written this way, properties are already here to say, but I
         | personally find Java's stance on feature addition much more
         | sane than C# cool and quick, buy maybe too fast one.
         | 
         | I like to believe that records with the upcoming 'withers' will
         | be an adequate answer (if a bit too late) to this whole
         | question.
        
         | fabian2k wrote:
         | I really like the C# object initializer syntax, and it looks
         | like the next version might get rid of the last problem I had
         | with it. Right now it does not play nice with nullable types,
         | if a property is declared non-nullable you have to use a
         | constructor or some ugly trick to circumvent the warnings. As
         | far as I understand this will be fixed in .NET 7 (not sure if
         | the decision is final, though) and you can get the full benefit
         | of non-nullable types when using object initializer syntax.
         | 
         | In general there has been quite some effort to allow a
         | programming style in C# with less of the ceremony and verbosity
         | that is often associated with C# and Java. And to me this does
         | make working with C# more pleasant.
        
           | diarrhea wrote:
           | If you perhaps happen to know or have a pointer: how would
           | that work in C#? A field not initialised will be null, and if
           | it's non-nullable... what's its value going to be?
        
             | fabian2k wrote:
             | The check would be moved to the object initialization, so
             | the compiler would tell you if you use the flexible object
             | initialization syntax and left some non-nullable properties
             | uninitialized.
        
       | rr808 wrote:
       | I've ditched Spring, am using Vert.x with Java 17, reactive &
       | functional styles, records. Seems like a completely different
       | language.
       | 
       | If only project Loom will get out there so I wont be coding
       | everything like Javascript I'd be happy. :)
        
         | vips7L wrote:
         | I'd rather write Spring than Vertx callback or observable hell.
        
         | sabareesh wrote:
         | Weird Spring is the reason why i am sticking to Java
        
           | treis wrote:
           | I just can't get past annotations as a thing. Seems like a
           | crime against programming to me.
        
             | sabareesh wrote:
             | Well it is just another design pattern, i love annotations
             | but it might be better even without it, Spring boot takes
             | care of most of the things and it only needs very minimal
             | annotation which makes sense.
        
             | kaba0 wrote:
             | I don't know, I think it's closer to some LISP magic macro
             | than Lispers would like to admit. They are extremely
             | powerful, and thus can be responsible for some very ugly
             | code, but when used responsible, they are huge productivity
             | wins.
        
           | commandlinefan wrote:
           | Spring would be my only reason to ditch Java.
        
           | exabrial wrote:
           | Try CDI! much cleaner, faster, and without the Factory
           | Factory Factories.
        
         | jayd16 wrote:
         | Hmm Javascript has async though, no?
        
           | 5e92cb50239222b wrote:
           | That's exactly what was meant. With Loom Java will hopefully
           | not have the same function split as languages like JavaScript
           | (or C# for that matter) where you have to add lots of
           | async/await everywhere; and instead will have something like
           | Go (where everything is async).
           | 
           | https://journal.stuffwithstuff.com/2015/02/01/what-color-
           | is-...
        
             | jayd16 wrote:
             | I guess I was confused because right now you do not code
             | Java like that.
        
             | [deleted]
        
             | vbezhenar wrote:
             | Async stuff in JavaScript light years ahead of Java's
             | Future madness. Loom might help but I'm not optimistic
             | about it. For example Spring already kind of deprecated
             | blocking http web client and new reactive WebClient is
             | terrible. Will they create yet another BlockingWebClient?
             | No they'll ask you to call `block` everywhere and write
             | reactive nonsense filters if you need to enhance it.
             | 
             | Spring is worst thing happened with Java.
        
               | dymk wrote:
               | That may be true, but JavaScript forces you to bisect
               | your libraries (and functions) into Those that Understand
               | Async and Those That Don't [0]. There appears to be no
               | path forward if you want to avoid that.
               | 
               | It's very difficult to write generic, reusable higher-
               | order code that shouldn't care if it's doing a sync or
               | async operation. Java at least is building a foundation
               | in the right direction.
               | 
               | [0] - https://journal.stuffwithstuff.com/2015/02/01/what-
               | color-is-...
        
               | vbezhenar wrote:
               | If you mean that you can't write `map` which would work
               | for sync and async functions with the same code, that's
               | extremely rare problem IMO. If you really need that and
               | don't want to write two versions of code, you can wrap
               | blocking code with promises and use promise API from now
               | on.
        
               | dymk wrote:
               | It's not at all a rare problem if you work in codebases
               | involving async code. Many `Promise` APIs exist solely to
               | work around that wart. Higher-order functions are the
               | bread and butter of JS, and increasingly Java (especially
               | modern Java).
        
               | kaba0 wrote:
               | But async stuff is a must in JS due to it being single-
               | threaded (yeah I do know about webworkers).
               | 
               | Just spawning a thread with a scope which will fork them
               | at the end is just better from every conceivable way.
               | Easier to grasp, easier to maintain, easier to debug -
               | all of which are quite important when concurrency is at
               | the table.
        
               | [deleted]
        
             | pca006132 wrote:
             | I don't understand the part about go, does that mean go
             | doesn't require async but gives you the functionality of
             | async? (I never tried go)
             | 
             | The problem with async is that we can separate when to
             | start a task and when to ask for its result. The compiler
             | can just add await everywhere an async function is called,
             | it is trivial, but you don't get the flexibility of async.
             | If everything is treated as async, you will need to await
             | everything (perhaps some syntactic sugar to allow for
             | immediate await)
        
               | shellac wrote:
               | > If everything is treated as async, you will need to
               | await everything
               | 
               | In go you work rather differently. You let tasks go off
               | and do their thing, and provide a channel to communicate.
               | Pulling a response from the channel is the 'await'. A
               | good part of go's magic is that these tasks - goroutines
               | - don't result in large amount of blocked threads.
               | 
               | Java will soon have the building blocks of something
               | rather similar to goroutines.
        
               | pca006132 wrote:
               | OK I see, but I think these two approaches address
               | different problems? The approach used by go is more
               | powerful than async but also more verbose. The
               | implementation is also different, async can be
               | implemented with a generator but goroutine can't.
        
         | decebalus1 wrote:
         | The time I used vert.x in my day job was by far the best Java
         | experience in my career. Completely different language. And the
         | vert.x maintainers have been all around great wrt to responding
         | to issues and/or accepting contributions. Great framework. It
         | has it's quirks and limitations but overall I absolutely loved
         | working with it.
        
       | johnklos wrote:
       | ...and it's still a security nightmare...
       | 
       | I think some developers took "write once, run anywhere" as a
       | challenge, which is why I still have to keep virtual machines
       | with ancient Java versions around to configure and use certain
       | remote IP-based KVMs, certain IPMI functions, certain older fibre
       | channel switches, certain poorly thought out IP cameras, and so
       | on.
        
         | nix23 wrote:
         | Just wait until GO has so many years on the back, java is not a
         | "security nightmare" developers/businesses with zero
         | responsibility are.
        
         | charcircuit wrote:
         | Java has been very good at backwards compatibility for me
         | except when they removed some unsupported internal classes from
         | the 1.9 JDK, but there existed a workaround for still using it.
         | 
         | I don't worry about security problems in the JDK or major
         | libraries any more than anything else. I'm not sure where your
         | security concerns are coming from.
        
         | vips7L wrote:
         | Why is that Java's fault? Isn't that the fault of the
         | developers of your applications from not upgrading?
        
           | nailer wrote:
           | I might be wrong but I think they stopped working on major
           | new versions for a decade. There seems to be Java 6 or 1.6 or
           | whatever for a really long time. Like Netscape's version 4.
        
             | kaba0 wrote:
             | Who stopped what? Java 19 is the upcoming release.
        
               | nailer wrote:
               | Sun / Oracle stopped releasing new Java versions for a
               | long time.
               | 
               | I'm sure most people on HN are aware there are new
               | versions of Java now.
               | 
               | Edit: 'there seems' in my original comment should be
               | 'there seemed' which may have caused confusion.
        
               | nix23 wrote:
               | Maybe Java 2 SE v1.4.2? It was like the JDK8 from the old
               | days.
        
               | Cwizard wrote:
               | using the parent comments naming scheme it is actually
               | 1.19, I don't know why they stopped developing major
               | releases however.
        
               | TheRealPomax wrote:
               | But that is not the java naming scheme. Java stared using
               | normal major version numbers back in the Java 5 days.
               | They've developed major releases continuously for
               | decades.
        
               | babypuncher wrote:
               | The real nightmare is Java's versioning scheme
        
               | kasperni wrote:
               | The version number increments by 1 every 6 months. What
               | is so nightmarish about that?
        
               | babypuncher wrote:
               | To someone who has not written Java since High School in
               | the '00s, I find the ecosystem a little confusing.
               | 
               | My recent experience was this: I have a Windows box in my
               | basement that hosts a Spigot Minecraft server for some
               | friends and their kids. This box also hosts my UniFi
               | controller software.
               | 
               | The UniFi controller software requires Java 8, which is
               | what Oracle offers for download on their website.
               | 
               | Spigot usually requires the latest version, at the time I
               | ran into this problem it was 17. You have to go out of
               | your way and actually download the whole JDK for any Java
               | version newer than 8.
               | 
               | So I download and install JDK 17, which replaces the JRE
               | 8 I already had running UniFi. Spigot works, and the
               | UniFi controller appears to start up and function.
               | However I quickly notice that the UniFi app is behaving
               | erratically, and after some troubleshooting and googling,
               | I learn that Java 17 is in fact _not_ backwards
               | compatible with Java 8, so both of them need to be
               | installed.
               | 
               | Of course, Java doesn't make installing multiple versions
               | side by side easy. It's doable, but even then they built
               | no mechanism for a jar file to specify which runtime it
               | needs and automatically run with it. So I had to write my
               | own startup scripts for these apps calling the specific
               | runtime they required.
               | 
               | None of this was particularly onerous to figure out and
               | deal with, but your average user is going to get stuck
               | and feel frustrated. And it left a bit of a sour taste in
               | my mouth because .NET has done a pretty good job of
               | avoiding exactly these kinds of problems.
        
               | kaba0 wrote:
               | 1.6 and 1.8 and the like were major releases. While LTS
               | doesn't have a well-defined meaning for OpenJDK, in
               | general 11+6*n are the versions that are considered LTS
               | (due to other vendors providing paid support for those).
               | 
               | Let's not read more into arbitrary version numbers.
        
       | ralmidani wrote:
       | Java was actually not bad for me in class when learning software
       | design and data structures, but soul-crushing to work with in the
       | real world. Mindless, unnecessary use of getters/setters,
       | interfaces, and AbstractFactoryImpls. Hiding almost every piece
       | of functionality behind 10+ layers of indirection. Dependency
       | Injection with Spring. They all make it feel like Java draws
       | folks who actually __enjoy__ writing bloated, over-engineered
       | garbage.
       | 
       | YMMV, of course, and yes, there are modern frameworks other than
       | Spring (Play is supposedly pleasant to work with), but life is
       | too short to try to sort out that mess.
       | 
       | I plan to stick to Elixir as much as I can, for as long as I can.
       | When the language clicked for me, it was the biggest breath of
       | fresh air since I decided to pursue programming as a profession,
       | and even cooler than when I discovered Python/Django.
       | 
       | Edit: obviously, Java is not all bad, and not all (or even most)
       | people who use it fit the description above. But something about
       | the ecosystem seems to draw those types (no pun intended)
       | disproportionately.
        
         | omegalulw wrote:
         | What's your take on Kotlin? Neatly solves a ton of these
         | issues.
        
         | type0 wrote:
         | Java is the perfect example of software "bureaucracy" for the
         | sake of bureaucracy
        
         | i386 wrote:
         | All my new Java projects don't use spring for that very reason.
         | Nothing wrong with the new keyword.
        
           | geodel wrote:
           | Excellent!. Its good to hear about places where Spring
           | nincompoops do not shove their crap framework down everyone's
           | throat.
        
         | tomohawk wrote:
         | Java has reached the status of Cobol - it is immortal because
         | it is everywhere and has been around a long time.
         | 
         | Because of that, there are a lot of Java devs.
         | 
         | Our team works in Go, and so we get a few Java devs in once in
         | a while as new positions open up. The biggest change for them
         | is to get out of archonaut mode and stop overdesigning
         | everything. After going through a 3-6 month cleanse, it's fun
         | to see them complain about the legacy Java stuff and how overly
         | complicated it is and how slow it is to build and test compared
         | to Go.
        
         | pwinnski wrote:
         | I don't think this is an issue with Java, it's an issue with
         | Spring. I'm baffled by the popularity of Spring.
        
           | geodel wrote:
           | But this article specially mentions Spring as some next
           | generation rocket fuel to send Java even higher.
           | 
           | The problem I see is as far Java ecosystem goes Spring is
           | big, respected dev framework to be used liberally anywhere.
           | So if a developer like me call Spring a revolting piece of
           | shit software it is just me asking to become jobless.
        
           | nick__m wrote:
           | Old school xml based Spring is horrible and if that was your
           | only exposure, I understand your aversion.
           | 
           | But spring-boot has an almost zen like quality once you get
           | that it favor convention over configuration. When I was a
           | Java developer, I'd usually use spring-boot with the
           | following dependencies to make the experience better:
           | 
           | - lombok: to generate the boilerplate: constructors, getters,
           | setters, equals, hashcode...
           | 
           | - mybatis-spring-boot-starter: mybatis is a sql resultset
           | mapper, you write the sql and it maps the results. I find
           | that ORM like Hibernate or Eclipselink are a complexity trap:
           | easy things are really easy but hard things are incredibly
           | complicated, mybatis avoid that.
        
             | ralmidani wrote:
             | Sorry, but the popularity of tools which generate
             | boilerplate for you is, in my opinion, one of the biggest
             | indictments of the whole ecosystem.
        
               | ledauphin wrote:
               | agreed. every time I see static code generation I think
               | "this is why people invent and use properly powerful
               | languages".
        
           | snewman wrote:
           | I think it depends a lot on where you work and what sorts of
           | projects you work on. I've been programming professionally in
           | Java for the last 16 years and I have never encountered
           | Spring. Nor do I typically see the stereotypical sort of
           | FactoryFactoryManagerImpl complexity bloat. It is something
           | you need to watch out for and steer clear of, in particular
           | when selecting frameworks / libraries, but you can definitely
           | live in the Java ecosystem without being pulled too far down
           | this road. (The introduction of lambdas helped.)
           | 
           | (Those 16 years are four years at Google, 10 years in a pair
           | of startups, now 1.5 years at a medium-sized acquirer.)
        
           | ralmidani wrote:
           | I've seen similar patterns with tech that's older than Spring
           | (Servlets/JSP). Also, wasn't it EJB that promoted getters and
           | setters everywhere?
        
             | nick__m wrote:
             | JavaBeans in general promoted that convention. I first
             | learned about Beans using Swing (the ui toolkit) since it
             | makes heavy use of them.
        
         | api wrote:
         | The problem with Java is much more with the ecosystem than the
         | language, for all the reasons you describe. Clean,
         | straightforward software can be written in Java but it seldom
         | is.
        
         | butterNaN wrote:
         | I have been learning Elixir for past couple of months. After a
         | _long_ time, I am in love with programming+design again. It has
         | honestly given my brain a much needed refresh.
         | 
         | Of course, it can definitely be attributed, at least partly, to
         | just moving to functional programming.
         | 
         | Every day I look forward to 6'o clock, so I can stop working
         | and continue on my own projects.
        
           | afhammad wrote:
           | You will also find Clojure just as refreshing / enlightening.
           | My company uses Elixir but I've also done a lot of Clojure,
           | give it a shot if you haven't.
        
       | dopamean wrote:
       | I spent almost all of my career writing Ruby before I ended up at
       | a company that required me to write mostly Kotlin (a bit of scala
       | here and there too). After a few years of Kotlin I don't want to
       | use anything else. There's a bit more ceremony to getting things
       | set up but the experience of writing Kotlin with Intellij IDEA
       | has been so wonderful I'm happy to keep doing it.
        
       | e67f70028a46fba wrote:
       | The biggest thing Java is missing is full hot swap. Its been
       | implemented via the dcevm but, inexplicably, has been ignored by
       | both sun and oracle.
       | 
       | This one, existing technology would make Java DX on par with the
       | dynamic languages
        
         | topspin wrote:
         | > The biggest thing Java is missing is full hot swap
         | 
         | The biggest thing missing in Java is an answer for the billion-
         | dollar mistake. Real world Java is plagued by NPEs because a
         | lot of Java is written by low caliber programmers. Java +
         | functional error handling would be a monumental improvement.
        
           | oftenwrong wrote:
           | Java should adopt something like the Checker Framework
           | Nullness Checker in its first-party tooling.
           | 
           | https://github.com/typetools/checker-framework
        
           | bhuber wrote:
           | It doesn't fully solve the problem, but @lombok.NonNull helps
           | a lot. It makes it clear which properties shouldn't be null,
           | and catches NPEs closer to the source. Incidentally, lombok
           | in general does wonders for boilerplate reduction.
           | 
           | https://projectlombok.org/
        
             | topspin wrote:
             | > but @lombok.NonNull helps a lot
             | 
             | Which @NonNull? There's
             | javax.validation.constraints.NotNull,
             | org.springframework.lang.NonNull,
             | org.checkerframework.checker.nullness.qual.NonNull,
             | org.jetbrains.annotations.NotNull,
             | android.support.annotation.NonNull and a bunch of
             | others[1]. The proliferation of Not|NonNull is evidence
             | that I'm right, no matter how hard I get downed on HN.
             | 
             | [1] https://stackoverflow.com/questions/35892063/which-
             | nonnull-j...
        
               | bhuber wrote:
               | I didn't say it wasn't a problem - if I could wave a
               | magic wand and get rid of the concept of null in Java I
               | would. That isn't what we're discussing though - you
               | said, "The biggest thing missing in Java is an answer for
               | the billion-dollar mistake [- NPEs]". I've provided what
               | I consider to be at least a partial answer. If you care
               | about avoiding NPEs in Java, it's a pretty good solution.
               | 
               | Realistically, null is so fundamental to the Java
               | language that removing it would arguably result in a
               | different language entirely. Certainly all existing java
               | codebases would have to be refactored. The same goes for
               | exceptions. That's obviously not an option when one of
               | your primary selling points is backwards compatibility,
               | so I'm not really sure what kind of solution you're
               | looking for here.
               | 
               | The answer to your SO link notwithstanding, I would argue
               | the @lombok.NonNull is at least one of the best options,
               | as it actually generates a null check that is executed at
               | runtime. This makes it more powerful than most of the
               | other solutions.
        
               | topspin wrote:
               | > Realistically, null is so fundamental to the Java
               | language that removing it would...
               | 
               | Again, as jayd16 pointed out a solution has been
               | retrofitted to C#, Java's great nemesis. I don't accept
               | the argument that this is somehow infeasible. Just make
               | null assignments (including potential ones coming from
               | libraries) an error and allow this feature to be scoped
               | to your source files. Eventually the practice becomes
               | ubiquitous. It's been done again and again in many
               | languages and their various 'strict' modes.
               | 
               | The only actual problem here is that Java language
               | developers aren't feeling sufficient pressure to address
               | it. They should, but they're not, and that's sad. That
               | sort of sadness is a common theme with Java.
        
               | kaba0 wrote:
               | While this could be solved by introducing one into the
               | standard lib, it is not that big of a problem in practice
               | as nullability checkers understand all of these
               | annotations.
        
           | bberrry wrote:
           | Kotlin solved that in a good way IMO. That alone makes it
           | worth switching
        
           | jayd16 wrote:
           | You could always try C#. They have a non-null compile mode
           | where variables are non-nullable by default. They did the
           | work to mark up core libraries and also have some pragmatic
           | handling of olde nullable calls in 3rd party libraries.
        
           | commandlinefan wrote:
           | > low caliber programmers
           | 
           | Can't really blame Java for that, though - if everybody
           | standardized on, say, Haskell (or whatever we might agree is
           | the "gold standard" for programming), the low caliber
           | programmers would find a way to do something stupid in it,
           | too. The only way to get around low caliber programmers is to
           | raise the standard, but any suggestion of raising (or even
           | setting) a standard for programming invites accusations of
           | "gatekeeping" (a gate that really, really, really ought to be
           | kept).
        
             | topspin wrote:
             | > Can't really blame Java for that, though
             | 
             | Hmm. Can't I? I know why Sun made Java. They wanted a
             | platform to develop applications that didn't require the
             | skill of a competent C++ programmer. They were targeting
             | lower caliber coders.
             | 
             | I'm a pragmatist; yes, Java programmers would still find
             | escapes, but they'd do it less and so the net number of
             | flaws would be smaller. As jayd16 points out, there is a
             | pragmatic way to deal with this; provide a compiler mode
             | that eliminates null dereferences and rework the standard
             | library to accommodate this. Simple and obvious. Afterwards
             | you can throw the switch on whatever code your facing and
             | you'll know if you're dealing with crap or not.
        
         | lenkite wrote:
         | Enhanced hot swap using GraalVM has mostly caught up with
         | capabilities https://www.graalvm.org/22.1/reference-
         | manual/java-on-truffl...
        
         | [deleted]
        
       | bullen wrote:
       | The only problem Java has is experienced C programmers don't
       | build servers from scratch with it yet.
       | 
       | Once they take that responsibility, the debate will be over
       | because:
       | 
       | "While I'm on the topic of concurrency I should mention my far
       | too brief chat with Doug Lea. He commented that multi-threaded
       | Java these days far outperforms C, due to the memory management
       | and a garbage collector. If I recall correctly he said "only 12
       | times faster than C means you haven't started optimizing"." -
       | Martin Fowler https://martinfowler.com/bliki/OOPSLA2005.html
       | 
       | "Many lock-free structures offer atomic-free read paths, notably
       | concurrent containers in garbage collected languages, such as
       | ConcurrentHashMap in Java. Languages without garbage collection
       | have fewer straightforward options, mostly because safe memory
       | reclamation is a hard problem..." - Travis Downs
       | https://travisdowns.github.io/blog/2020/07/06/concurrency-co...
       | 
       | "Inspired by the apparent success of Java's new memory model,
       | many of the same people set out to define a similar memory model
       | for C++, eventually adopted in C++11." -
       | https://research.swtch.com/plmm
       | 
       | This combined with the fact that Java doesn't crash and you can
       | easily hot-deploy the classloader (maybe 100 lines) means nothing
       | can compete that doesn't copy everything Java does VM + GC (hello
       | C#, please don't downvote).
       | 
       | To use anything else (than JavaSE without heavy deps.) on the
       | server is madness.
        
         | Banana699 wrote:
         | Comparing Java with C is about as strawman-ny as it gets,
         | you're literally picking on one of the oldest and dumbest
         | languages in production usage. "The PDP-7 assembler that thinks
         | itself a programming language", in the hilarious words of one
         | wise guy.
         | 
         | The problem Java experiences (not 'experienced') is that it
         | isn't the 1990s anymore. People aren't easily hyped, not smart
         | people at least. Programming language research, already way
         | ahead of Java in 1995, moved far ahead some more. The internet
         | and open source and free online education and social media
         | means smart language designer(s) can now begin a baby project
         | and put it on github and wait their luck for a corporation or
         | organization that will support it, and they can wait a decade+
         | on hobby mode till the luck comes. Java's competition isn't C,
         | I highly doubt it ever was, it's dozens of far superior
         | programming languages that were born after 1995, and some of
         | those that were born before but weren't very populer because
         | internet and open source barely existed in the 1990s and they
         | weren't made by a corporation.
         | 
         | Even if you keep overfitting the requirements function time and
         | time again to gradually approach java (by adding "vast
         | libraries" and "performance" to it, although neither of those
         | things are specific to Java), you will eventually reach a very
         | narrow niche with Java and Kotlin squarely in the middle, I
         | know which one _I 'm_ going to choose if I'm willing to
         | maintain my sanity and not drown in 'paper-work programming'
         | that is the developing experience with Java. It's as easy as
         | opening a source file in an IDE and naming it with a '.kt'
         | extension rather than '.java', I'm in love with it.
         | 
         | Companies use Java extensively ? So it's a COBOL then: Old,
         | everywhere, infrastructure-critical, but an utter failure as a
         | programming language in every way that is not "runs my old
         | program I'm too afraid to re-write". This is forgivable in the
         | case of COBOL because it's a literal proto-language, one of the
         | earliest of the species. It's not forgivable in the case of a
         | language designed when Smalltalk and ML and Haskell were
         | around.
         | 
         | The history of Java is the story of a corporation stumbling
         | upon the idea of a VM (1960s stuff) and deciding that it's so
         | good that they need something like this under their name right
         | now, and not giving the slightest shit about the design of the
         | language that sits on top of said VM. And they were right, the
         | idea of a VM is really so fucking good that Java's aweful
         | design was tolerated, until somebody relized running on the JVM
         | no more means writing Java than running on x86 means writing
         | x86 assembly, and wrote the first non-Java JVM language. And
         | because VMs are so fucking beautiful, you get all Java code for
         | free.
         | 
         | >doesn't copy everything Java does VM + GC
         | 
         | Come on, write those 2 words on any half-decent academic
         | research repository and you will get hits from the fucking
         | 1960s. Java is younger than Lisp, Smalltalk, Self, Haskell,
         | Python and the same age as Ruby. All of those languages do VMs
         | and GCs. Java's hotspot is taken from Self, that's documented
         | stuff. And "Copying" isn't copying if it's a better
         | implementation of the interface, JSON didn't "copy" XML, they
         | reimplemented its interface better.
        
         | nelsondev wrote:
         | The p50 speed up from delaying memory management comes with a
         | trade off, namely you get Garbage Collection pauses, bad p99,
         | and spend your effort tuning the Garbage Collector instead of
         | your code.
        
           | philipkglass wrote:
           | With Java 17 I found that using ZGC eliminated [1] the GC
           | pauses that yield bad P99 latencies without any additional
           | tuning. However, it has lower throughput than G1GC so your
           | P50 advantages will diminish.
           | 
           | [1] Reduced them to always well below 1 millisecond.
        
             | cogman10 wrote:
             | Which is always the tradeoff with GC. You get to pick
             | latency or throughput and you trade one for the other.
        
               | kaba0 wrote:
               | In my experience, this is not related closely to GC and
               | are apparent in many systems. A great book on
               | optimizations explicitly mentions that "improving one
               | aspect of performance may degrade another".
        
           | plandis wrote:
           | Low pause collectors exist explicitly for this purpose. ZGC
           | and Shenandoah both trade throughput (more concurrent
           | collections) for extremely low pause times:
           | https://malloc.se/blog/zgc-jdk16
        
             | nimrody wrote:
             | Does that mean they also trade _memory_ for low pause
             | times? Because, in our application, the memory required for
             | avoiding significant GC pauses is at least 4x the amount of
             | memory we actually need at any given time.
             | 
             | This can be significant too.
        
               | kaba0 wrote:
               | Have you measured that with ZGC? Because due to using
               | virtual pointers specifically, "third-party" tools may
               | report higher virtual memory usage than what it actually
               | uses.
        
               | vbezhenar wrote:
               | It's all about compromises. Only Rust is uncompromised.
        
           | xxs wrote:
           | > Garbage Collection pauses
           | 
           | True concurrent GC have been available since late 2000s. Azul
           | had a read-barrier GC as well - effectively a pauseless GC
           | (or pauses under 1ms)
        
           | xxpor wrote:
           | An uncommon but not unheard method around that (in services
           | that have diurnal patterns) is to throw memory at it and
           | collect once a day during the down time. You can take the
           | server out of service, restart it, and put it back in
           | service.
        
             | plandis wrote:
             | This is kind of hard to do in practice unless you're really
             | watching where you're allocating memory. It's very easy in
             | Java to end up accidentally throwing a bunch of allocated
             | memory on the heap without realizing it.
             | 
             | Fwiw, the JVM now has a noop garbage collector so this is
             | easy enough to benchmark.
        
               | vbezhenar wrote:
               | Can you provide an examples of accidentally allocating
               | memory? The only example I'm aware of is autoboxing which
               | is huge misfeature IMO.
        
             | ska wrote:
             | I read this was semi-standard memory management in the
             | early lisp machine days, because that gc was so slow.
        
               | bitwize wrote:
               | Early Lisp (even pre-lispm) had no GC at all -- it just
               | allocated until it ran out. Memory reclamation was done
               | by saving the heap to tape and then reading it back --
               | only live objects were saved. So it was kind of GC with
               | extra steps; the first GC algorithms removed the steps.
        
               | User23 wrote:
               | To this day the Common Lisp standard doesn't require GC.
        
           | kaba0 wrote:
           | Does it really? With Java's G1GC the only knob you _may_ end
           | up having to tune is the max target pause time - which pretty
           | much chooses between better p50 and worse p99 va worse p50
           | and better p90 - aka throughput vs latency, that are almost
           | inherently opposite ends of the same spectrum. It is not GC-
           | specific that any improvement will fail to increase one of
           | those.
           | 
           | So the actual tradeoff is more whether you want better
           | throughput or tail-latency. To improve the latter, you have a
           | singular command line option of using ZGC as well.
        
             | hedora wrote:
             | You mean the integer parameter "-XX:MaxGCPauseMillis"? The
             | name says it all. You can do over a dozen sync disk writes
             | in a millisecond these days.
        
               | kaba0 wrote:
               | Have you seen the output of JVM flight recorder or some
               | other tool used to observe memory allocation/reclamation
               | patterns? The JVM is _very_ lazy when it comes to GC -
               | its algorithms are crazy good and can catch up with
               | really high allocation rates as well. So the maximum
               | pause time's unit doesn't really say much, and when it
               | comes to dynamic memory allocation, the JVM is the best
               | choice according to the biggest web services operating on
               | terabyte sized heaps.
        
           | titzer wrote:
           | > tuning the Garbage Collector instead of your code.
           | 
           | This is a feature, not a bug. Which is riskier?
        
             | cogman10 wrote:
             | Now-a-days, if you are tuning your GC you are almost
             | certainly doing the wrong thing.
             | 
             | While the JVM offers a plethora of levers to pull in case
             | you are hyper concerned about different things, the
             | heuristics are VERY good. Mucking with the fine grained
             | details can disable heuristics and ultimately give you
             | worse results than if you just left stuff alone.
             | 
             | The levers to pull are algorithm, max memory, and max pause
             | time. All other levers should be left alone unless you've
             | got GC logs to back up what you think needs changing. (And
             | even then... Do you really?)
             | 
             | Typically, the better route is flight recorder and
             | eliminating wasted allocations.
        
           | mabbo wrote:
           | That sounds a lot like the complaints about Java from a
           | decade ago. Have you used it lately?
           | 
           | Java's GCs are incredible and you have a menu of algorithmic
           | options that let you avoid whatever problem you're worried
           | about.
        
             | jcelerier wrote:
             | > Java's GCs are incredible and you have a menu of
             | algorithmic options
             | 
             | can these options be used in separate parts of a single app
             | ? e.g. the app I'm developing in C++ has parts that do
             | realtime audio, others that do GPU rendering, others that
             | do classic Qt Widgets GUI, others that do offline
             | computations on datasets - and they all have different
             | performance characteristics and need different memory
             | management schemes to get the best out of each, all while
             | being in a single process; there's reference counting,
             | tree-based allocation, pooled, linear, a GC-ish thing which
             | ensure that memory is freed in specific non-realtime
             | threads... Can that be done with Java or is one tied to a
             | single GC implementation for a given execution of a
             | process?
        
               | imtringued wrote:
               | If Java had isolated heaps then C++ would become
               | redundant in every aspect except memory efficiency.
        
               | marwis wrote:
               | What are the advantages of isolates vs running multiple
               | JVM processes other than avoiding slightly higher memory
               | usage and some small context switch overhead on IPC -
               | which should be negligent as presumably communication
               | between isolated components would be coarse grained?
        
             | dboreham wrote:
             | The JVM GC is fundamentally the same as 10 years ago.
        
               | bitcharmer wrote:
               | Saying this just shows you don't know much about modern
               | JVM.
        
               | titzer wrote:
               | Shenandoah did not exist 10 years ago, and G1 was not
               | deployed.
        
               | cogman10 wrote:
               | 10 years ago the algorithms you could pick were serial,
               | parallel, and CMS.
               | 
               | Today we've removed CMS, added G1GC, and added ZGC.
               | 
               | G1GC is similar to the parallel in the way it operates
               | but is divided up enough to control for latency.
               | 
               | ZGC is fundamentally different from the parallel
               | collector or G1GC. Suggesting it is the same is to
               | suggest you know nothing of the changes that have
               | happened.
        
           | kasperni wrote:
           | With modern concurrent GCs such as ZGC [1] this is really not
           | an issue for most people anymore.
           | 
           | [1] https://inside.java/2022/05/30/sip053/#:~:text=ZGC%20was%
           | 20d....
        
         | lliamander wrote:
         | Erlang is not as peformant as Java, but there are plenty of
         | reasons to prefer the former to the latter:
         | 
         | - a much better concurrency model, that gets you parallelism
         | for free just by adding cores
         | 
         | - no global gc pauses, low-latency
         | 
         | - fantastic operational tools (trace debugging, remote shell,
         | etc.)
         | 
         | - Erlang/OTP gives you great middleware out of the box,
         | including including queues, pub-sub, service monitoring,
         | database, etc.
         | 
         | - Honestly just a more expressive core language.
         | 
         | All that said, I don't really have anything against Java. It is
         | a great language for the server, but it is not the only choice.
        
           | haspok wrote:
           | All that said, Erlang is a very sharp knife, built for one
           | specific purpose. This is just not true:
           | 
           | "a much better concurrency model"
           | 
           | If your program is CPU-bound, where real threads are king,
           | then Erlang is a pretty poor solution. Because you cannot
           | have real threads in Erlang, even if you wanted to. Number
           | crunching or string processing are not its forte.
           | 
           | Also, most enterprise software does not really benefit from
           | green threads anyway, because the scale they are running on
           | easily handles blocking JDBC and http request calls. Not all
           | companies are google or want to run a telephone switch that
           | handles >million concurrent calls...
           | 
           | And finally, if you go Erlang, you get actors, whether you
           | like them or not. You cannot have CSPs, for example, which in
           | many ways are superior to actors. You don't get to choose
           | your concurrency model, it is chosen for you. If your use-
           | case suits this model, great. If not... not so much.
        
             | lliamander wrote:
             | There are responses to each of those points, but ultimately
             | you are right that there are tradeoffs. My point was really
             | that Java isn't the _only_ sane server-side language, and
             | that Erlang is an entirely sane option.
             | 
             | The one thing I will say is that, when I say Erlang has a
             | better concurrency model, I mean that it is much easier to
             | write correct concurrent code in Erlang than in Java.
        
           | neeleshs wrote:
           | Biggest benefit with Erlang for me is preemptive scheduling.
           | Has a perf hit, but you don't get brownouts. Java lacks this
           | and this results in hanging threads. A lot monitoring has to
           | be there to detect these conditions . Project loom makes this
           | somewhat better, but at its core, java threads are not
           | preemptible
        
             | imtringued wrote:
             | Java uses regular OS threads that provide preemption by
             | default... Whatever you are talking about has nothing to do
             | with preemption.
        
               | neeleshs wrote:
               | Right. I meant interruption is cooperative.
               | 
               | https://docs.oracle.com/javase/tutorial/essential/concurr
               | enc...
        
           | bullen wrote:
           | No Erlang can't share memory between cores atomically.
           | 
           | Erlang can only scale 1-to-1 things like phone calls.
           | 
           | Java is the ONLY language that scales many-to-many with
           | stable non-blocking IO and concurrent parallelism that shares
           | memory atomically AND doesn't crash.
        
             | TheRealDunkirk wrote:
             | And for the fraction of the software projects out there
             | that that actually need this feature as a hard requirement,
             | I'm sure it's wonderful.
        
               | pdimitar wrote:
               | Yeah, all web apps everywhere are definitely a fraction,
               | I'm sure. :P
               | 
               | Green threads are an amazing fit for web apps. I made a
               | career out of using those for web apps and API apps.
        
               | bullen wrote:
               | Well many-to-many IS the point of the internet.
               | 
               | Think MMO here, which is the "metaverse" thing they keep
               | talking about.
               | 
               | Simulating 3D reality over the network IS the ONLY thing
               | humans can do now that doesn't HAVE to burn all the
               | energy we got left while giving use a tool to experiment
               | without risk.
               | 
               | So I'm building the final 3D action MMO game engine.
        
               | imtringued wrote:
               | Everyone dreams of their own MMO but nobody wants to pay
               | for it except whales.
        
           | bjourne wrote:
           | Imo Erlang's scalability benefits are oversold. Unless you're
           | a national carrier the performance of Java far outweighs
           | Erlang's scalability. Instead, Erlang's undersold killer
           | feature is its robust support for hot code reloading. It
           | enables almost any part of the system to be upgraded without
           | affecting running processes. Other languages and VMs can't do
           | that because they optimize call frames differently and rely
           | on mutable state. It's like building a new road on top of an
           | existing one without impacting traffic. Almost magic and very
           | important for always on services like emergency numbers.
        
             | lliamander wrote:
             | Yep, I would say that it's support for ops in general is
             | it's biggest strength (deploys, monitoring, fault
             | tolerance, etc.)
        
             | kelnos wrote:
             | I feel like Erlang somewhat missed its timing window on
             | this, though. With platforms like AWS, GCP, and Azure, you
             | don't really worry about upgrade downtimes, because you
             | just roll out a new fleet of servers (or new fleet of pods,
             | if you're using something like Kubernetes), and then drain
             | the traffic from and decommission the old fleet.
             | 
             | Certainly there are a lot of companies managing real
             | physical servers, where this is not as feasible, but I
             | think the ease of server provisioning makes hot code
             | reloading just not that important to most engineering
             | teams.
             | 
             | (And personally I'd be wary of using something like that,
             | considering that the rollback path -- in that case that you
             | deploy bad code and need to back it out -- sounds not as
             | robust.)
        
               | lliamander wrote:
               | I work in an AWS/K8s-heavy shop, and it is pretty great,
               | but we have a fairly sizeable engineering team.
               | 
               | Managing K8s microservices is easily an order of
               | magnitude more work than managing them in Erlang as
               | applications.
        
           | exabrial wrote:
           | > no global gc pauses, low-latency
           | 
           | Java also has this for at least a few years now. G1GC and ZGC
           | in JDK17 offer no global stops unless absolutely necessary,
           | and ZGC even has latency targets.
        
             | MaxBarraclough wrote:
             | Also Shenandoah. Those Java garbage-collection folks have
             | been busy recently.
             | 
             | Or is it that people interested in doing ground-breaking
             | garbage collection research tend to target Java?
        
           | the8472 wrote:
           | > - no global gc pauses, low-latency
           | 
           | ZGC has sub-millisecond pauses https://malloc.se/blog/zgc-
           | jdk16 And afaik azul's C4 collector has no global pauses,
           | only per-thread pauses (which are also short)
        
             | pkolaczk wrote:
             | Low pauses, low memory overhead, low CPU overhead. In Java
             | world, pick one. In C/C++/Rust/Zig you can have all three
             | at once.
        
               | krzyk wrote:
               | Add memory safety to the list. And allow to select only
               | 3.
        
               | pkolaczk wrote:
               | But that's not performance category. And, btw, Rust has
               | all 4 of them. If we're talking about safety guarantees
               | then let's add data race freedom to the mix. Or use-
               | after-free protection for non-memory resources. ;)
               | 
               | Java is cool language and has many nice features, but its
               | type system is not its major advantage.
        
         | stiray wrote:
         | https://go.dev
         | 
         | Experienced C developers have switched to it. Actually it gets
         | even better, they are extremely productive in it. Don't trust
         | me, check github.
         | 
         | I wonder why. /s
        
           | BenoitP wrote:
           | With Loom incoming, Go's only unfair advantage (shared with
           | Erlang) may be gone soon. I guess we'll have the answer in a
           | few years.
           | 
           | Will the next WhatsApp be written in Java?
        
             | lliamander wrote:
             | It will take more than green threads to be equivalent to
             | Erlang. Erlang's concurrency model depends upon a
             | completely non-shared memory model, which Java will never
             | have.
             | 
             | Edit: and programming it in Java will always be more
             | laborious than in Erlang. Sure, you could put Erlang on the
             | JVM (as the Loom folks want to do) but then is Java really
             | the winner here, or did Oracle just make an alternative
             | BEAM?
        
               | BenoitP wrote:
               | Surely having a shared memory model increases the design
               | space? Or is this about memory management performance?
               | 
               | A benchmark should settle things in that case. Maybe it
               | will be a draw! Erlang's almost-no-op deallocation vs
               | Java's world-class JIT. Some applications are bound to be
               | better suited to one specific side. I guess we'll see;
               | but it cannot be denied that with Loom Java started to
               | compete on a non-void part of Erlang's land.
        
               | cogman10 wrote:
               | It's certainly a trade off. One thing erlang can do which
               | java cannot is survive one of it's actors OOMEing. That
               | kills the actor and not the VM.
               | 
               | That comes at some extreme costs and implications to what
               | the VM is capable of achieving, but it is something
               | that's pretty impressive.
        
               | lliamander wrote:
               | Absolutely. And I'm not particularly partisan in this: I
               | like Erlang ( the language in general as well as the
               | concurrency model) and if Java moves closer to that then
               | all the better.
        
               | wewtyflakes wrote:
               | While interesting, I'm not sure how that will translate
               | into practice. How easy is it to hire up an organization
               | of Erlang developers, versus, Java developers? I suspect
               | Java's features as compared to Erlang will be good
               | enough, that the specific use-cases enabled by
               | knowledgeable Erlang developers will be non-competitive
               | in the general developer labor market, but I am open to
               | being wrong/educated.
        
             | haspok wrote:
             | Loom does a small fraction of what the Erlang VM is capable
             | of doing.
             | 
             | For one, the Erlang VM has built-in preemptive green thread
             | scheduling, which means it can suspend your green thread at
             | ANY instruction, not just when an IO call is in progress.
             | 
             | Loom is a step in the right direction, but Erlang is in its
             | own universe for what it was designed for.
        
               | throwawaymaths wrote:
               | Erlang still has failure domains as a first class concept
               | which neither go or Java are likely to have ever.
        
               | BenoitP wrote:
               | > which means it can suspend your green thread at ANY
               | instruction
               | 
               | True. Out of curiosity: what's the use case for this?
               | 
               | Surely side-effects-out-of-your-system is enough?
        
               | notamy wrote:
               | > True. Out of curiosity: what's the use case for this?
               | 
               | Scheduling is deterministic, which is a VERY useful
               | property to have. See ex.
               | http://erlang.org/pipermail/erlang-
               | questions/2006-December/0... about changing scheduler
               | determinism.
        
               | marwis wrote:
               | The thread you linked is about the benefits of inducing
               | scheduling non-determinism.
        
               | slekker wrote:
               | Is Loom THAT big of a deal? Can you point me towards some
               | references of why this is the case?
        
               | SureshG wrote:
               | Yes, IMO game changing for java. Read this JEP -
               | https://openjdk.org/jeps/425
               | 
               | Here is a simple echo server running on Virtual thread
               | (using same old blocking APIs, handle 5m persistent
               | connections) - https://github.com/ebarlas/project-
               | loom-c5m/blob/main/src/ma...
        
         | nocman wrote:
         | > To use anything else (than JavaSE without heavy deps.) on the
         | server is madness.
         | 
         | That's a terribly broad generalization. There are multiple
         | other options that are entirely sane.
        
           | DoesntMatter22 wrote:
           | When all you have is a hammer... What a ridiculous take, most
           | server apps don't use Java and they are just fine.
        
             | bullen wrote:
             | This was true until 2017 when I became a C programmer.
             | 
             | They are fine until they need to scale and iterate quickly
             | without downtime.
        
               | DoesntMatter22 wrote:
               | Java apps have plenty of downtime during deploys, that
               | isn't uncommon at all. You have such a naive view of
               | java.
        
           | Scarbutt wrote:
           | What other good dynamic runtimes with widespread use like the
           | JVM exist?
        
             | TrueDuality wrote:
             | Restricting your world view to only programming languages
             | with dynamic runtime environments like the JVM is a major
             | handicap.
        
             | [deleted]
        
             | hedora wrote:
             | Linux, for C/C++/Rust.
             | 
             | It also provides memory safety and multiprocessor support.
        
             | lliamander wrote:
             | BEAM
        
         | sushisource wrote:
         | > This combined with the fact that Java doesn't crash
         | 
         | Huh? Doesn't crash in what way vs. C? I can still deref a null
         | pointer and blow up.
         | 
         | Java's perfectly fine, and I have no idea why you'd write C any
         | more, but if you care about (extreme) performance and not
         | crashing, Rust seems the obvious modern choice here.
        
           | plainnoodles wrote:
           | One of the weird things about Java is that there's a big low-
           | latency/high-performance Java community around that stems
           | from Island (now owned by NASDAQ) using Java as the
           | platform/language for their matching engine. Then, talent
           | flow from that team resulted in lots of proprietary trading
           | shops using Java to low-latency trading/order execution.
        
             | SlipperySlope wrote:
        
           | kaba0 wrote:
           | If you do that in C, your program may run "just fine" on the
           | surface forever, yet it can silently corrupt all of its data.
           | Java _can_ catch NPEs and handle them appropriately (e.g. a
           | web server might just _answer_ server error 500, but it will
           | continue to run with well-defined semantics). I don't think
           | the two is comparable. Even Rust will go off the happy path
           | with a single use of unsafe, and there is no sailing back
           | from there, while a Java program can't crash in a UB-like
           | way.
        
           | vbezhenar wrote:
           | Dereferencing null is undefined behaviour in C. Probably it
           | could be handled with platform-specific code, but handling it
           | correctly not the easiest thing to do. Other than
           | dereferencing null, there're so many ways to accidentally
           | blow up C code and something like reading uninitialised
           | memory is truly undefined behaviour which can't be worked
           | around.
           | 
           | Java does not have undefined behaviour at all. Dereferencing
           | null would throw NPE which is ordinary exception, completely
           | fine to handle or suppress or whatever. There's no concept of
           | uninitialised memory. The only sources of undefined behaviour
           | in Java is calling native code or using unsafe methods which
           | are very rare and usually located in well tested library
           | code.
           | 
           | Even stack overflowing is defined behaviour and you can
           | easily recover from it.
        
             | tomohawk wrote:
             | I've never seen Java code in production handle NPEs, OOMs
             | or other such conditions well.
             | 
             | It's a shame Java does not have value types, which makes
             | nulls a much rarer thing to have to deal with.
        
           | mcculley wrote:
           | I have worked on big projects with up to ~100 developers. On
           | the C projects, someone's null-pointer dereference brings
           | down the whole process. On the Java projects, the event
           | handler or daemon thread has an exception handler at the top
           | that logs the error and keeps executing. This is a huge
           | difference in behavior.
           | 
           | Sometimes, you want to fail fast and be forced to fix that
           | bug. More often, I want to keep doing whatever I can to test
           | and develop the system and find more bugs without restarting
           | the whole thing.
        
             | pkolaczk wrote:
             | You can have a null pointer handler in C as well.
             | 
             | But this is generally not a good idea. I find software that
             | does not crash early and visibly but instead tries
             | continuing despite an obvious bug very brittle and often
             | causing trouble because it can take a long time before
             | operators notice the problem. If you accumulate enough bugs
             | of this type, you get a mess that "kinda works" but is full
             | of surprises.
        
               | mcculley wrote:
               | Yeah, I implemented an "atcrash" handler as a library
               | which I embedded into multiple projects. But it was only
               | so I could walk the stack, dump a stack trace into the
               | terminal, and tell the user, "Please email this to the
               | developer." And then as cleanly as possible shut down the
               | process. In C, as you say, not much else can be safely
               | done.
        
               | pkolaczk wrote:
               | In Java if you encountered a null pointer exception or
               | out of bounds error at the global level, there is also no
               | guarantee you can safely continue, and dumping the stack
               | and terminating is the only sensible option. Sure, the
               | JVM is ok, but your app state might be already corrupt.
        
               | mcculley wrote:
               | This has not been my experience at all.
               | 
               | The JVM is not corrupted by a NPE or out of bounds access
               | unless you are using native code.
               | 
               | For example, I worked on a large X-Windows/Motif
               | application with many developers. If some library
               | dereferences a null pointer, it is game over. Kill the
               | app. In a Java Swing app we built for a similar use case,
               | we just trap the exception in the AWT event dispatcher,
               | log it, and keep going. Yes, sometimes an exception has
               | ruined the global state in some catastrophic way, but
               | this is rare. We can keep running and debugging without
               | restarting the whole app.
               | 
               | Another example is a web app: Any exception that bubbles
               | up to the main request handler loop is likely (in our
               | architecture) to happen before any change is made to the
               | persistent store. Log it and handle another request. This
               | makes debugging a lot easier than restarting the whole
               | app.
        
               | LaGrange wrote:
               | > This has not been my experience at all.
               | 
               | This has been my experience with software written in Java
               | by developers who think it was not their experience.
               | 
               | > In a Java Swing app we built for a similar use case
               | 
               | ...oh no. I actually tend to associate Swing UI with
               | weird, undefined behaviors, and whenever I'd look under
               | the hood, it would nearly _always_ be due to them trying
               | to swallow runtime exceptions. Pure hubris, as far as I'm
               | concerned.
               | 
               | > Another example is a web app: Any exception that
               | bubbles up to the main request handler loop is likely (in
               | our architecture) to happen before any change is made to
               | the persistent store. Log it and handle another request.
               | 
               | Please, please, _PLEASE_ just crash the server. The OS
               | will handle it, it will be OK, and systemd will even do
               | the right thing and give up if your thing crashes
               | _persistently_, including all the fancy stuff like
               | keeping track of how often it crashes.
               | 
               | I've done too much cleaning up after overly-confident
               | superstar architects, your examples just brings painful
               | memories. I beg you stop trying to be clever and just log
               | the error and crash the app.
        
               | pkolaczk wrote:
               | I haven't said that the JVM would be corrupt by NPE. But
               | C program state would also not be, and you could do the
               | same handling as in Java.
               | 
               | But if your code invoked an NPE or bounds check, then it
               | means either the algorithm is incorrect or the data it
               | processes are already corrupt by incorrect processing
               | earlier. Continuing in such situation increases the risk,
               | because you don't have any guarantees which parts of the
               | application state might have been already corrupted by
               | the bug. I've seen many many times an NPE was a result of
               | a shared data corruption caused by a data race. JVM does
               | not guarantee thread state isolation, so one bug can
               | break the state of all threads.
               | 
               | > Log it and handle another request
               | 
               | That gives you only a false sense of safety. A Java app
               | (and any other app) may die for many other reasons you
               | can't handle. You need to be prepared for that anyway if
               | you want a reliable service. But if you are prepared for
               | that, and your server can restart in 0.1 second, you
               | don't win anything by recovering from NPEs.
        
               | kaba0 wrote:
               | Depends whether your "null pointer" is truly zero, or
               | some random value that was not initialized.
        
         | tomohawk wrote:
         | No doubt, Java GC is a feat of engineering. But it has to be to
         | avoid being swamped by the lack of mechanical sympathy between
         | the language and memory management. Pretty much everything you
         | do generates lots of unnecessary litter, which then must be
         | eventually collected.
         | 
         | Except in very narrow circumstances, I've not ever seen Java
         | perform at the level of C or C++, especially when I/O is
         | involved. Java typically needs 2-4x the memory and a lot more
         | cores to do the same job. That's fine if you bought the machine
         | and the machine is big enough, but if you're leasing an EC2,
         | why pay more every hour?
         | 
         | These days, my C, C++, and Java days are behind me. We do
         | mostly Go, and couldn't be happier. The GC and language have
         | really good mechanical sympathy, and the bad memories of tuning
         | Java GC are fading. We pay a small tax in terms of CPU and
         | memory over using C, but not remotely like what we saw with
         | Java. And yes, we built prototypes of critical use cases in C
         | just to see how 'bad' Go would be, and were very pleasantly
         | surprised that Go compared very well indeed.
        
         | a-dub wrote:
         | there have been a handful of infrastructure projects in java:
         | kafka and cassandra come to mind immediately, but there are
         | certainly others.
         | 
         | i think what has always sort of steered me away has been a few
         | things:
         | 
         | 1) i've long been interested in snappy, interactive and
         | realtime local and server things. and the jvm can do this
         | stuff, but usually it's better suited for server side use where
         | it can be warmed up appropriately. this may also just be a
         | personal dogma that i need to get over.
         | 
         | 2) every language and runtime has its quirks where you have to
         | breakdown the illusions of the language itself and understand
         | the internals to get the best performance, but i feel like java
         | is the worst instance of this, where the tricks that people go
         | through in order to control the gc seem excessive.
         | 
         | 3) i like simple and concise programs where i feel like the
         | java ecosystem encourages code sprawl. hello world has so much
         | weird stuff and a serious java project has thousands of small
         | source files where computer aided programming (ie. a proper
         | java ide) is not really optional. i find this not only to be
         | unergonomic, but also challenging for being able to quickly
         | understand what a foreign codebase is doing in a short
         | timeframe. maybe it's different from the perspective of a
         | primary developer on one of these large projects though (and
         | possibly quite pleasant).
         | 
         | 4) for some reason, i've always liked feeling closer to the
         | metal. even scripting languages "feel" closer because of the
         | jvm abstraction. this is probably also a personal dogma.
         | 
         | > He commented that multi-threaded Java these days far
         | outperforms C, due to the memory management and a garbage
         | collector.
         | 
         | people who like java say these sorts of things all the time. i
         | haven't seen a head to head comparison that confirms it though.
         | (although i have not looked). regardless my understanding is
         | that once a jvm is warmed up, it can be quite performant-- and
         | that it has opportunities for live optimization that you don't
         | get in a classic c/c++ runtime.
         | 
         | i don't think c/c++ will be going away as long as operating
         | systems are still written in c. a java operating system
         | seems... strange to me. but that said, i think java has proven
         | itself in terms of high performance application server
         | software.
        
         | pca006132 wrote:
         | But what kind of C program is he comparing against? Single
         | threaded ones? Not heavily optimized ones? Optimized concurrent
         | C programs that use locks rather than lock-free data
         | structures? Or heavily optmized C programs with lock-free data
         | structure? It is unclear to me.
         | 
         | Also, wondering how much of that overhead in the C program is
         | due to malloc (can be overcome by memory arena)
        
         | quadcore wrote:
         | _The only problem Java has is experienced C programmers don 't
         | build servers from scratch with it yet._
         | 
         | Please explain. What kind of crazy jack write servers in C?
         | (Real question, trying to learn here)
        
           | varjag wrote:
           | Servers written in C is the status quo here in real world.
        
           | cozzyd wrote:
           | The developers of apache httpd, nginx, postgresql, redis,
           | among many others?
        
             | xxs wrote:
             | you really dont need redis if you have java. I see zero
             | reasons to offload my datastructures via TCP, instead of
             | have them locally. If need be, replicated them.
        
               | vasilakisfil wrote:
               | Usually you need redis to scale up horizontally, meaning
               | with multiple servers/processes, and still keep
               | consistency in your data. In general redis is a very
               | useful tool that provides various features, even pub sub.
        
         | otabdeveloper4 wrote:
         | I assure you that people writing C++ on the server know how to
         | use lockfree structures and optimized allocators. Using
         | something with a garbage collector when you have access to all
         | that is madness.
        
         | badpun wrote:
         | Java does not (yet) have green threads, which limits the number
         | of connections you can serve per machine. You can go to Scala
         | though (it has them) and still stay on the JVM.
        
         | kentonv wrote:
         | Oh, please.
         | 
         | I once worked on a Java-based server at Google that had to
         | answer requests with millisecond latency. In order to achieve
         | this, the server had to block garbage collection most of the
         | time. Periodically, each instance of the server would ask the
         | load balancers to stop sending requests to it, so that it could
         | then safely run the garbage collector, and then ask for traffic
         | to return.
         | 
         | We likely would not have used Java had we foreseen needing to
         | do this. I believe some time after I left, it was all rewritten
         | in C++.
         | 
         | Sadly the garbage collection debate is full of people who
         | _want_ GC to be the answer to everything, and have chosen their
         | arguments and beliefs through confirmation bias to support
         | their desire. Many of these  "GC is faster!" arguments come
         | from that, but it just ain't true most of the time. Performant
         | GC is incredibly complex and incredibly complex systems tend to
         | fall over if you don't use them in exactly the right way.
         | 
         | Worse, GC is extremely bad at managing resources other than
         | local memory. In complex distributed systems or other software
         | that manages external resources, GC languages tend to be ill-
         | equipped for the job because they lack explicit resource-
         | management tools like RAII. In Java, you sometimes see
         | frameworks where everything has a `dispose()` method and
         | complex systems are built to make sure that `dispose()` method
         | gets called... this is a failure, it should be handled by
         | destructors.
         | 
         | GC is generally nice and convenient for application
         | engineering, but a poor fit for systems engineering. The
         | boundaries between the two are admittedly fuzzy.
        
           | discreteevent wrote:
           | > requests with millisecond latency
           | 
           | You're getting into hard real time territory there. That's a
           | different universe and will require special considerations
           | even in C. I think it's fair enough for people to discuss
           | server performance and assume that the context is our normal
           | programming universe.
        
             | kentonv wrote:
             | Of course! There are plenty of use cases, including server
             | use cases, where Java is a great choice.
             | 
             | But I was reacting to bullen's assertion that "To use
             | anything else on the server is madness.", and to the rather
             | exaggerated performance claims.
        
           | ransom1538 wrote:
           | Google should have picked a real language: php. When script
           | is completed all resources are freed, let the OS figure it
           | out. No manual GC drama.
        
             | MaxBarraclough wrote:
             | That's a strategy called _arena allocation_ or _region-
             | based memory-management_ , and it doesn't have to be tied
             | to the lifetime of a process or interpreter.
             | 
             | There's nothing special about PHP, which if I understand
             | correctly uses reference-counting with conventional garbage
             | collection to handle reference cycles. As I understand it
             | this strategy is non-competitive in all performance
             | metrics, compared against modern garbage collectors.
        
           | luciusdomitius wrote:
           | Speaking of this, have you of LMAX Disruptor[0]? You probably
           | have. And yeah, having fine control over the memory
           | allocation and garbage collection in such a high-level
           | language (multi-platform vm!) is akin to building a ship in a
           | bottle. However, in which stack creating multi-level
           | distributed stock exchange with sub-milisecond response times
           | is easy?
           | 
           | 0. https://lmax-exchange.github.io/disruptor/
        
           | kelnos wrote:
           | > _I once worked on a Java-based server at Google that had to
           | answer requests with millisecond latency._
           | 
           | That's... not really normal, though, and sounds like the
           | exception that proves the rule. For the vast majority of
           | applications, Java will perform better, be easier to develop,
           | and be safer to run, than an equivalent server written in C
           | or C++.
           | 
           | At my previous job we used to run realtime audio through a
           | Java server (RTP streaming). I do remember in the Java 6 days
           | that the GC would need tuning to ensure that GC pauses
           | wouldn't delay audio to the degree that there would be
           | dropouts or perceptual delays. But with Java 8 (and later
           | releases), which came with better GC implementations, those
           | problems just went away. Sure, realtime audio is usually fine
           | with even up to 100ms pauses (or even 200ms, sometimes) -- so
           | this is much more tolerant than your sub-ms example -- but we
           | rarely saw anything even remotely that long with the more
           | modern JVM GC implementations, without really having to tune
           | behavior that much, or at all. Meanwhile, P99 stats for most
           | JVM services were in the low to mid tens of milliseconds, and
           | anything longer was always due to calling out to external
           | services, like relational DBs.
           | 
           | For the rare case like Google's, sure, it's absolutely
           | expected and appropriate to need to use a non-GC'd language
           | instead, at least for some things. For pretty much _anyone_
           | else, the JVM is more than adequate, or can be made adequate
           | with some reasonably simple GC tuning.
           | 
           | > _Many of these "GC is faster!" arguments come from that,
           | but it just ain't true most of the time._
           | 
           | I don't agree. I think it _is_ true most of the time. But I
           | think many people don 't think about what they mean by
           | "faster". Faster as in throughput? Sure, a modern,
           | performance-oriented GC (like the JVM's) can very easily beat
           | manual memory management there. Latency? Well, ok, that can
           | be a bit harder, so you need to evaluate things on a case by
           | case basis, and possibly do some GC tuning to get the
           | latencies you need. But even then, you can usually do just as
           | well (or better) on the latency axis as well. Just not
           | always. But I don't subscribe to the "But sometimes..."
           | school of objections. Yes, sometimes some technologies don't
           | work for certain use cases. That's fine. Choose your
           | technology wisely. But in Java's case, it really is just
           | "sometimes". Not most of the time.
           | 
           | Let me reiterate, though: Google is not the common case! By a
           | long shot! It is an outlier, and it's expected that a company
           | like Google will have to deviate from the mainstream to reach
           | its performance targets sometimes. But also consider that
           | (from what I understand) even Google has a _ton_ of services
           | written in Java, and they... work just fine, no?
           | 
           | > _In complex distributed systems or other software that
           | manages external resources, GC languages tend to be ill-
           | equipped for the job because they lack explicit resource-
           | management tools like RAII._
           | 
           | Eh. I initially thought of this as a problem, but in
           | practice, I've rarely run into an issue with this sort of
           | thing. Maybe it's because there's still vestiges of the C
           | programmer in me that will always think about memory
           | ownership and lifecycle, even when writing in a GC'd
           | language, but I've rarely had my own issues (or seen issues
           | written by others) where someone has forgotten a `.close()`
           | or `.dispose()` on something. The "try with resources" syntax
           | can help here too, even though IMO it can be kinda
           | cumbersome.
           | 
           | And as much as the Java docs tell you to essentially never
           | override `finalize()`, it can be a useful "last ditch" tool
           | to ensure that any "manual dispose" owned references get
           | cleaned up, and you can also add logging there; I'll often do
           | something like "Got to finalize() without disposing of Foo
           | instances: BUG!". I also appreciate when third-party authors
           | who write `dispose()` methods also do this. It's not perfect
           | by any means, but IMO the convenience of relying on garbage
           | collector rather than manual memory management far outweighs
           | this downside.
           | 
           | Lately I've been writing a lot of Rust, and I'm enjoying the
           | sort of "middle ground" approach, where I don't have to think
           | about memory management as much, but don't have to worry
           | about GC performance, either. Certainly Rust doesn't
           | eliminate these concerns; I still need to think about
           | ownership and object lifetimes, but it's never "oh crap, I
           | forgot to free() something and there's a memory leak", or "oh
           | crap, I tried to use something after free()ing it and
           | crashed", it's more like "ugh, rustc doesn't agree with me
           | that this object lives long enough and refuses to compile
           | it". Annoying, but I'd rather find this out at compile-time
           | than runtime.
           | 
           | But then I'll go back to writing Java or Scala after being in
           | a Rust project for a while, and remember how nice it is to
           | just not have to think about these things.
           | 
           | > _...but a poor fit for systems engineering._
           | 
           | Absolutely agreed. But I would not call writing distributed
           | network servers "systems engineering", even though I do agree
           | that the boundary between systems and applications
           | engineering is indeed fuzzy.
        
             | kentonv wrote:
             | > But I would not call writing distributed network servers
             | "systems engineering",
             | 
             | I would agree that a web application server is usually
             | application engineering even if you are running 1000
             | replicas of it. I would not write these in C++. (Well
             | that's a lie, I probably would but I would admit it was a
             | terrible idea.)
             | 
             | On the other hand, the container engine that orchestrates
             | the web app server is systems engineering, as is the
             | database it talks to for storage.
        
           | galdosdi wrote:
           | > I once worked on a Java-based server at Google
           | 
           | This is kind of a fair comment, but kind of not, because Java
           | performance and GC internals have really advanced a lot in
           | the last decade. It would really help if you qualified
           | approximately when this was.
           | 
           | > Sadly the garbage collection debate is full of people who
           | want GC to be the answer to everything
           | 
           | Good point. I think more recently, the Java world is very
           | aware of this. Native and off heap memory has been getting
           | more use in performance sensitive stuff for quite a while.
           | You can totally just (essentially) malloc and free in Java,
           | if you really need to for performance.
           | 
           | That said, if you want to be able to make your code
           | accessible to a wider audience, GC is a must. There are tons
           | of junior and midlevel developers who don't really have
           | experience working with non-GC application code (and in many
           | cases are intimidated by it!), and you will be restricted
           | from hiring any of them if you use a non-GC language.
           | 
           | If that's ok, then that's ok, but with Java you can still do
           | a little off heap stuff in the critical part you need to,
           | encapsulate it behind a safe API, while letting the juniors
           | run amok in the rest of the codebase.
        
             | [deleted]
        
             | kentonv wrote:
             | I agree with all this. Java is a great application
             | programming language.
             | 
             | But bullen was arguing that Java is the best for servers of
             | all types, which is what I object to.
        
           | chopin wrote:
           | Afaik, a malloc is not guaranteed to return fast. With those
           | requirements it's hard even in C.
        
       | oaiey wrote:
       | Funny how the revival of Java is similar to the revival of .NET.
       | After some stale years, both languages refined themselves and are
       | back in the top competition (.NET in the VM space, Java in the
       | language space).
       | 
       | It really shows which languages can re-invent themselves (Java,
       | .NET, PHP, ..) while some fail (Fortran, Basic, Pascal, Perl,
       | ..). Not sure where JS is ;). Python seems to have survived the
       | 2/3 schism by now.
        
         | diarrhea wrote:
         | I guess both JavaScript and Python reinvented themselves
         | through gradual typing. It makes Python quite a different
         | language and JavaScript literally a different language.
         | 
         | My most recent small (1k LoC) Python project is "fully typed"
         | and therefore practically type safe (not strictly speaking
         | though). Lots of the large libraries are typed as well, which
         | is important.
         | 
         | For Python, work around the GIL might be the next evolutionary
         | step, that time in the name of performance.
        
           | oaiey wrote:
           | I agree. It seems like the road for dynamic languages goes
           | through optional typing. And it is logical because their weak
           | spot right now are huge systems.
           | 
           | I have to add that JavaScript would greatly benefit from a
           | solid base class library
        
       | otabdeveloper4 wrote:
       | W-w-wait, I thought all software as unequivocally being written
       | in Rust now?
        
       | jmartrican wrote:
       | I was doing live coding in an interview yesterday and the
       | interviewer said "you have a problem in your code, you put var,
       | and this is Java". I had to explain that the language has
       | modernized quite a bit.
        
       | abledon wrote:
       | For anyone else who can't get the LLCoolJ popup player to work
       | while reading the article:
       | https://www.youtube.com/watch?v=vimZj8HW0Kg
        
       | falcolas wrote:
       | Java's adequate. It's like a Toyota Corolla (insert your boring
       | car of choice here if you don't feel this one works for the
       | analogy). Not the prettiest, not the fastest, not the most
       | efficient. But it gets you from point A to point B with little
       | fuss or muss. I totally get why companies adopt and standardize
       | on it.
       | 
       | Do I use it for personal projects? Nope. Because it's not fun to
       | "drive". For that, I pick the equivalent of a Mazda Miata (insert
       | exciting car of choice), which for me is usually a Lisp.
        
         | hedora wrote:
         | I'm going to go with "Java is like a 2006 Chrysler 300". I'm
         | basing this on this list of the most popular fleet vehicles in
         | the US:
         | 
         | https://www.fuelexpress.net/blog/just-for-fun/4597-2/
         | 
         | The Corolla is known for reliability and fuel economy. It's the
         | car you'd buy for your fleet so you could ignore it, and then
         | you would ignore it, and some day, people would start assuming
         | you are going out of business or something because all your
         | fleet vehicles are from the late 90s.
         | 
         | On the other hand, the 300 claims to be those things, but has
         | terrible fuel economy, and apparently likes to unexpectedly
         | spin out. They claim that new ESP magically fixes the problem,
         | even though they've been claiming such things for years. It's
         | actually supposed to be a luxury car or something, but
         | apparently for some reason it is used as a fleet vehicle, where
         | it is a poor fit.
         | 
         | Also, since it is a Chrysler, I assume it is unreliable. Oh
         | look, I'm right:
         | 
         | https://cars.usnews.com/cars-trucks/chrysler/300/2011/reliab...
         | 
         | (In fairness, the newer ones are supposedly reliable. Sort of
         | like how Java is supposedly pause free now.)
         | 
         | Filling out the rest of the analogy:
         | 
         | fuel economy => Java startup costs, and asymptotic / constant
         | factor slow downs because it doesn't support zero cost
         | abstraction.
         | 
         | spinning out => The GC, of course
         | 
         | magic ESP => The next GC solves the pause / thrashing issues
         | (promised every year since at least 1998)
         | 
         | reliability => Constant API churn, the 8 => 11 => 17 => 20
         | treadmill, and (of course) log4j.
         | 
         | targeting luxury segment => Java targeting toasters, IoT and
         | web browsers back in the 90s, but only being able to run on
         | hilariously overbuilt and power hungry enterprise boxes
         | instead. Also, the classloader's open world assumption.
        
           | Ologn wrote:
           | > targeting luxury segment => Java targeting toasters, IoT
           | and web browsers back in the 90s, but only being able to run
           | on hilariously overbuilt and power hungry enterprise boxes
           | instead. Also, the classloader's open world assumption.
           | 
           | There are over three billion active Android devices in the
           | world, since 2014 they have been running Android Runtime
           | runtime environment, which uses Java (or Kotlin) bytecode.
           | Before 2014 Android used Dalvik, which did the same thing.
           | This is running on some pretty low powered devices.
        
             | hedora wrote:
             | Fair point. I forgot about Android, though it's an (almost)
             | completely different code base.
        
           | kaba0 wrote:
           | I have very vague knowledge of cars, but I know for a fact
           | that your characterization of Java is just bad, no matter how
           | good you car analogy-creation may be.
           | 
           | I won't even correct the others, but how come Java is
           | unreliable? Like, I have a hard time thinking of _anything_
           | in the category of computer programs that would fair better.
        
             | hedora wrote:
             | Have you ever had to maintain an old enterprisey Java
             | thing? It's pure hell.
             | 
             | Basic dependencies (like JUnit) break API compatibility
             | every few years, and then they stop distributing the old
             | version for new JVMs, so you're forced to port your code.
             | The GC falls over in production at the least convenient
             | times. People somehow decide everything should be stringly-
             | typed, and that the best choice between .properties, xml
             | and JSON is "all of the above, and also this in-house DSL".
             | There's this common pattern called "vendoring" where you
             | load multiple incompatible versions of the same library
             | into the same JVM, and exploit loopholes in classloader
             | semantics to prevent it from noticing, and ungracefully
             | exiting (which is what it really, really should do).
             | 
             | There's no way to use language improvements and static
             | analysis to improve program semantics over time (like there
             | is in, say C++) because none of the language level
             | abstractions are sound.
             | 
             | For example, you have a line like "static Foo foo = new
             | Foo()". Guess what? foo can be null sometimes. Here's an
             | unrelated problem: Think you have a function that doesn't
             | throw exceptions? Nope. Some third party garbage can throw
             | errors during normal operation instead. Think that
             | eliminating down casts in your program means it won't throw
             | ClassCastException on unexpected lines? That hasn't been
             | true since generics were invented. Think Optional gets rid
             | of null pointer exceptions? Nope. Instead, it's actually a
             | tri-value null. After all, you can always create null
             | references to an Optional (and, looping back to the
             | beginning of the paragraph, you can't avoid creating null
             | references to Optionals in idiomatic code!)
             | 
             | I could go on for hours.
        
               | kaba0 wrote:
               | > Have you ever had to maintain an old enterprisey thing?
               | It's pure hell.
               | 
               | FTFY. And yes, I have worked on old Java apps, they are
               | not worse than any other app that lived for a similarly
               | long timeframe (and the fact that there seem to be more
               | old monstrosity in Java may just mean that it actually
               | manages to do its work written in java, and not fail in
               | some other language).
               | 
               | Why don't you have a bin repo for old junit versions?
               | Nonetheless, not updating is just technical debt that
               | will have to be paid once either way. Regarding GC, it
               | was never as bad as its name in my opinion, but it
               | improved dramatically in recent years. If it fails it is
               | more than likely a programmer error (which is very easy
               | to debug thanks to the JVM's killer observability).
               | 
               | Regarding XML and .properties, this is related to
               | _enterprisyness_ not java, nor the JVM. These are
               | meaningful abstractions to a degree but are overdone
               | badly more often than not. Vendoring is not really a
               | hack, it is a correct choice from the JVM's PoV (in
               | short, a canonical name and a classloader pair is unique
               | inside the JVM), but it can be abused, and application
               | servers kind of do so indeed.
               | 
               | Wtf, Java has probably the best tools when it comes to
               | static analysis. It actually has a well-defined
               | specification of what has to happen under nigh every
               | circumstance, and Java is huge in academy as well so
               | different kind of analysis is an active research topic,
               | especially that Java is also huge in the industry.
               | 
               | Runtime exceptions are a thing everywhere, I again fail
               | to see how are they relevant here, and Java is completely
               | type safe with generics, your statement regarding that is
               | completely false. If you don't have casts in your
               | program, it can't fail with classcastexception
               | (reflection-hackery aside).
               | 
               | Optionals are a mistake but the only fault lies in those
               | who put a null inside.
        
               | ElectricalUnion wrote:
               | > Optionals are a mistake but the only fault lies in
               | those who put a null inside.
               | 
               | If you, or a third-party exposed a "Optional", then it's
               | the API mistake. You're never supposed to expose an
               | Optional as either input or output; they're clunky
               | implementation details of the Java Maybe monad.
        
               | kasperni wrote:
               | > Optionals are a mistake but the only fault lies in
               | those who put a null inside.
               | 
               | You can't. 'null' represents an empty optional.
        
         | adrian_b wrote:
         | I am not convinced that Java is adequate.
         | 
         | I do not know if the problems are related to the Java language
         | or to the typical Java programmers, but Java is the only
         | programming language where I have seen a strong correlation
         | between the programming language used to implement some
         | application and a low quality of that application.
         | 
         | During decades of experience with various programs, whenever I
         | was surprised that a program seemed to be abnormally slow, or
         | it had an unusually ugly GUI, or it had a GUI that was
         | impossible to customize, e.g. it was impossible to change the
         | default font or the size of the font, or it had various other
         | annoying features seldom encountered in other programs, I
         | discovered that it was written in Java.
         | 
         | Most of these annoying programs where commercial programs, some
         | of them very expensive programs.
         | 
         | The most recent Java problem that I have encountered was last
         | year, when I could not install some expensive program, because
         | the installer crashed immediately.
         | 
         | After some time wasted to discover the reason, the conclusion
         | was that the installer was written in Java and it always
         | crashed immediately on any computer to which a 30-bit monitor
         | was connected.
         | 
         | That program had both Windows and Linux versions, but both
         | crashed in the presence of a 30-bit monitor, so the Java
         | installer was of the kind "write once, crash anywhere".
         | 
         | The workaround was to disable the GUI of the installer and make
         | an installation from the command line.
         | 
         | There are some 15 years since I use only 30-bit monitors, but
         | this was the first time when I have seen such a behavior
         | (probably because I avoid Java programs, due to past
         | experiences). Googling has shown that this was actually a well
         | known bug in Java installers, which had not been solved in a
         | long time.
        
           | valbaca wrote:
           | I'm with you, even as a Java developer I can immediately
           | recognize when something was written in Java: it's ugly and
           | slow. When it crashes, you know they missed a NPE or tried to
           | use multiple threads.
        
             | gorjusborg wrote:
             | > I'm with you, even as a Java developer I can immediately
             | recognize when something was written in Java
             | 
             | Sure, if we are talking about desktop applications and we
             | ignore the exceptions (Intellij / Minecraft).
        
               | 3836293648 wrote:
               | Minecraft's menus absolutely have that hacky terribleness
               | feeling. It's still much better than Minecraft Bedrock
               | (the C++ reimplementation), but it's also noticeably
               | behind everything else
        
           | haspok wrote:
           | Java UI and applets have been abandoned long ago (>10 years).
           | This was partly due to webapps becoming the standard, but
           | also the realization that for desktop apps non-native UIs
           | just suck.
           | 
           | The vast majority of Java (=running on the JVM) software
           | these days is server-side, without any user interface.
        
             | TheRealDunkirk wrote:
             | Precisely, and exactly why the programming world is an
             | absolute, cargo-culting mess of Javascript frameworks and
             | libraries these days. Sure, React is winning the mindshare
             | war now, but it's just the least ugly baby winning the
             | beauty pageant at the county fair.
        
             | adrian_b wrote:
             | You are right that all the Java programs with which I had
             | problems were programs with a Java GUI.
             | 
             | With Java programs without a Java GUI, I never had
             | problems.
        
             | tannhaeuser wrote:
             | What seems to be little known is that Java began life as a
             | language for programming set-top boxes with lots of UI, and
             | continues to be used for Blue-Ray disc menus/apps. Sun and
             | Oracle also invested quite a bit into developing JavaFX as
             | an attempt at "RIAs" running in browsers when it was clear
             | Applets were going nowhere, yet JavaScript wasn't quite as
             | developed as it is today, and Flash wasn't seen as a choice
             | for complex apps.
        
           | bityard wrote:
           | > Java is the only programming language where I have seen a
           | strong correlation between the programming language used to
           | implement some application and a low quality of that
           | application.
           | 
           | Funny, I hear this sentiment more about PHP which deserved
           | its poor reputation in the early days but is actually quite a
           | nice language now and has been for a good long bit.
           | 
           | I think the biggest problem some people have with certain
           | programming languages is that they don't "look" a certain way
           | they prefer (syntax-wise), or don't have enough modern
           | buzzwords associated with them.
        
         | halfmatthalfcat wrote:
         | What does that make Scala? A RAV4?
        
           | speed_spread wrote:
           | Scala is a ring of four Corollas welded by the edges of their
           | rooftops so that rolling over only changes the set of wheels
           | you're using. Also, all wheels are omni directional so you
           | can drive sideways when required.
        
           | gclaramunt wrote:
           | Lexus
        
           | yurodivuie wrote:
           | Still a Corolla, with left-hand drive and manual
           | transmission.
        
           | btmcnellis wrote:
           | A Pontiac Aztek.
        
           | falcolas wrote:
           | I'm going to catch hell for this, I just know it.
           | 
           | A Chrysler PT Cruiser. Odd looking, beloved by its fans, and
           | a reasonably adequate (if quirky) to drive.
        
         | kaba0 wrote:
         | I don't know, probably some truck would be a better analog. It
         | ain't sexy, but it was made to be a blue collar language, and
         | it is the one that ships cargo nigh everywhere.
        
           | mgomez wrote:
           | You're not alone as someone else made a similar observation
           | in a previous thread[1]:
           | 
           | > To me Java is like a garbage truck. You get to work, start
           | it up, do a nearly invisible but absolutely essential duty,
           | then, at the end of the day, you turn it off and go home. No
           | one dreams about garbage trucks or puts one in a car show but
           | they're there and ready to go right back to work when you
           | are.
           | 
           | [1] https://news.ycombinator.com/item?id=26834177
        
           | perardi wrote:
           | To really nitpick the analogy: Java is a Ford Transit cargo
           | van.
           | 
           | It's primarily used by enterprise shops. You'd never brag you
           | about driving a van. It's not fashionable. It's kinda ugly.
           | 
           | But...it gets the job done.
        
             | topaz0 wrote:
             | Speak for yourself. I brag about driving a 2013 transit
             | connect.
        
         | throwawaymaths wrote:
         | Corollas don't come with all sorts of weird (now aging)
         | buzzword-driven preferences like nudging you towards xml,
         | factories, etc.
        
           | falcolas wrote:
           | Personal rant: I've never understood the hate towards XML.
           | It's a practical and flexible markup language that does not
           | depend on whitespace or quoting every bloody thing. Plus,
           | every markup language invented since has had to re-invent XML
           | things that, surprise surprise were actually needed. Paths,
           | schemas, comments, etc.
           | 
           | I get frustrated with JSON because of things I could do in
           | XML that I can't do in JSON without breaking the spec. And
           | that doesn't even cover how annoyingly verbose anything done
           | in JSON is.
           | 
           | Anyways.
        
             | no_wizard wrote:
             | The bottom line, from my experience is this:
             | 
             | XML means you have to think about how you're architect
             | information exchange much more thoughtfully, because XML is
             | much more strict and follows very explicit rules. It also
             | means you have to develop a schema for your interchange.
             | 
             | With JSON, you can, more or less, just serialize as is, not
             | much thought in the world, and it can be understood by the
             | client. You're not obligated by the protocol to do anything
             | about developing a schema or anything of that nature.
             | 
             | Yes, parts of the XML world have now bled over (defined
             | schema and path algorithms being the big ones I think) but
             | they're optional for better or worse.
             | 
             | Everyone takes the path of least resistance when given the
             | opportunity at the end of the day. This is _especially_
             | true of software engineers I 've found.
        
               | gmfawcett wrote:
               | Eh, not really. You have the option of defining schemas,
               | of course, but it's not required.
               | 
               | In practice, I think most of us used XML the same way
               | that people use JSON today: here's some data from my app,
               | figure out how to pull out the bits you need. No high
               | ceremony required.
        
             | cptskippy wrote:
             | Java/.NET have first class support for XML and SOAP, most
             | other languages don't. It's too easy to use XML in those
             | languages. Other languages don't have that tooling or
             | support and it's just a slog.
        
             | acdha wrote:
             | It's very similar to Java: there's a not bad language
             | buried under huge layers of bad practice and design by
             | committee which most people are stuck using, with a side
             | serving of market failure around the developer experience
             | (e.g. Maven, Spring on the Java side, tools being built on
             | the orphaned libxml meaning that you're stuck in the early
             | 2000s level of XPath, etc. in many cases).
             | 
             | XML 1.0 was decent but I soured on most of the "standards"
             | based on it after too many iterations of chasing through a
             | chain of specs pulled in by reference where you had to read
             | a bunch of ponderous W3C documents and non-working examples
             | to learn that the spec authors hadn't correctly modeled the
             | problem, nobody had time to work on any of this, and the
             | only extent implementations either weren't compatible or
             | had a lot of tedious workaround code. Bonus points if they
             | were replacing a legacy format and ended up with a result
             | which still required deep familiarity with the original
             | format but was also much less efficient.
             | 
             | These problems are cultural. JSON certainly isn't immune to
             | this but the Java/XML world has more people who felt the
             | need to LARP as Very Serious Architects designing extremely
             | expensive systems. Things like Atom show grownups can use
             | XML, too, but they're notably the exception.
             | 
             | In Java, the most direct counterparts I see are the places
             | where people felt like they should copy the Sun library
             | developers for code which is far less universally used and
             | took on a huge support cost building abstractions and
             | customization points which were largely unused, often only
             | for security exploits.
        
             | wvenable wrote:
             | In Java-land, XML became a replacement for actual code. And
             | for that, it's kind of terrible.
             | 
             | But programs that store their data as XML rather than some
             | proprietary binary or text format are awesome.
        
               | vips7L wrote:
               | I've never written XML in Java in the past 7 years of
               | being a developer.
        
               | wvenable wrote:
               | It's not the way Java is done now because, as noted, it
               | was awful. Java is almost 30 years old now. Developers
               | who worked in Java 20 years ago had a pretty different
               | experience than it is now.
               | 
               | However, I'm sure a lot of that code still exists.
        
               | Consultant32452 wrote:
               | [Cries in spring config]
        
               | pwinnski wrote:
               | In Spring-land, I think you mean.
               | 
               | I enjoy Java. I do not enjoy Spring.
        
               | brazzy wrote:
               | Using XML became optional in Spring as soon as Java got
               | annotations.
               | 
               | Which was in Java 5.
               | 
               | 18 years ago.
        
               | [deleted]
        
             | tannhaeuser wrote:
             | I think Spring, Maven (and ant before), JSP, and J2EE
             | descriptors gave XML a bad name, as fields of application
             | where a _markup_ language wasn 't adequate. XML was meant
             | as a simplification of SGML to formalize and extend HTML on
             | the web, but was overhyped as serialization format for
             | everything and anything for all the wrong reasons, among
             | them that XML sold well to management.
             | 
             | It can be argued that, despite not a primary use case for
             | markup, XML has found a useful niche in b2b service
             | payloads and government, banking, and health services in
             | particular. The use case for those might have been "web
             | services" in the original sense where simple CSS-like
             | transforms and styles are applied to payloads for display
             | in browsers, but the JSON community hasn't brought forward
             | a serious replacement for XML Schema, so XML payloads
             | kindof keep sticking around in long-term projects.
        
             | dwaite wrote:
             | Formats are designed for a purpose.
             | 
             | XML was built for a very limited set of purposes - to
             | create a common base markup for various document formats.
             | It was almost purpose-built to create something like XHTML
             | - a mixed content system where you can do semantic
             | decoration of textual media content, and extend it with
             | things like SVG and MathML.
             | 
             | The problem is that it was _not_ built as a cross-platform
             | data structure interchange format, but it wound up being
             | used for that way more than its intended purpose. This was
             | partially because of the extensibility story - companies
             | could agree on a common base format, and define their own
             | extensions to add additional data. However this was a pain
             | - the XML tooling was often generic to support both kinds
             | of usage, and the language itself was ambiguous because the
             | expectation that the underlying document being described
             | would have document-specific clarifications on use and
             | tooling.
             | 
             | JSON is an object notation - it is a way to transmit
             | hierarchal data. It has limited extensibility in the sense
             | that you can define rules for data processing, such as
             | 'ignore things you don't understand' or 'name things which
             | are not agreed upon with URI rather than short names'.
             | 
             | Trying to use JSON to represent the content model of HTML
             | will just cause pain, because thats not what it was built
             | for. It isn't even re-inventing things from XML, it is just
             | cramming a square peg in a round hole.
             | 
             | Neither format was built to be a configuration file format
             | for users to hand-edit config. As a result, they suffer
             | limitations in their syntax and features (closing elements
             | in XML, quoted property names and lack of comments in JSON
             | being the most commonly cited). TOML is one popular choice
             | for this sort of use case.
        
             | silvestrov wrote:
             | xml also scales much better with deeply nested documents
             | (such as html documents).
             | 
             | A deeply nested JSON document is difficult to navigate in.
             | Even with prettyprint it is counting indentation to find
             | out what kind of info this level has.
             | 
             | Take the html page for news.ycombinator.com and convert the
             | html document into JSON format. It becomes unreadable.
        
             | winstonewert wrote:
             | > that does not depend on whitespace
             | 
             | This is precisely one of my complaints against XML, it does
             | depend on whitespace. In JSON, I know that any excess
             | formatting whitespace can safely be removed. But excess
             | formatting whitespace is part of the document in XML and I
             | can't know in general whether it can be safely removed or
             | not.
        
             | lliamander wrote:
             | Once upon a time I was deeply in the world of XML Schema,
             | XSLT, and XQuery. It was actually pretty cool.
             | 
             | But using complex, poorly specified, possibly Turing-
             | complete "config" files written in a markup language that
             | isn't the primary language your app is written in is a
             | serious code smell.
             | 
             | It means you would either be better off using an embedded
             | scripting language (like Groovy) or a better core language.
        
             | aeze wrote:
             | You consider JSON to be more verbose than XML? I'm curious
             | to hear why.
        
             | gen220 wrote:
             | I think people dislike XML precisely because it's so
             | flexible and unopinionated. It means that when you're
             | parsing a new XML source, you have to look for data that
             | might be encoded in two or three little niches. God help
             | you if it's encoded in each of them, and if the data
             | therein is contradictory. Basically, it's easy to "hold it
             | wrong" in a way that harms consumers.
        
               | lenkite wrote:
               | A schema can be written in 15-30 mins to make XML as
               | opinionated as you want it to be.
        
               | adgjlsfhk1 wrote:
               | and then you'll read an xml file that doesn't meet your
               | schema and your code will crash
        
               | lenkite wrote:
               | With nice validation errors pointing to line, col where
               | unexpected information was found. I'll definitely take
               | that.
        
               | falcolas wrote:
               | > I think people dislike XML precisely because it's so
               | flexible and unopinionated.
               | 
               | You're probably right.
               | 
               | > Basically, it's easy to "hold it wrong" in a way that
               | harms consumers.
               | 
               | I feel a bit like this could equally apply to things like
               | GraphQL. I spend more time reading the docs on how
               | someone's internal data model is built than I do writing
               | GraphQL queries. And if I get that data model slightly
               | wrong, my query's garbage.
               | 
               | But that's probably a separate, vendor specific
               | (coughnewrelic), rant.
        
               | solarkraft wrote:
               | Over-engineering (relative to the complexity of the task
               | you want to solve).
               | 
               | Enterprise solutions are often so complex and generic
               | that they can theoretically do and interoperate with
               | anything, but are also hard to get started with and use
               | well.
               | 
               | People like to start with simple things and expand from
               | there instead of buying a whole house when they just want
               | a sink (am I using the phrase right?). In my opinion this
               | makes a lot of because it avoids unnecessary complexity
               | and sensitizes people to why some complexity is in fact
               | necessary.
        
               | gen220 wrote:
               | Every "contract" language (e.g. .graphql) I've used so
               | far has it's ups and downs.
               | 
               | One that keeps biting us in GQL, for instance, is that it
               | won't let you define a union type for mutation inputs, so
               | you end up needing N methods like `GetByX(X)`,
               | `GetByY(Y)`, `...` instead of a single `Get(X|Y|...)`.
               | Not to mention support for versioning message types,
               | etc...
               | 
               | FWIW: I think proto3 is probably the best I've used, at
               | length and in production. Granted it has its "warts", but
               | the idioms to circumvent them are fairly well-documented
               | and agreed upon, even if they're a bit "ugly" in the
               | syntactical sense.
               | 
               | FWIW pt 2: Like yourself, I think, I would not consider
               | JSON to be appropriate as a schema-defining "contract"
               | language in 2022, for a company that plans to be around
               | in 5 years. There are too many better options available.
        
               | mind-blight wrote:
               | I think it also got horribly abused by some use cases.
               | People tried to allow programming in it (e.g. if
               | statements and loops) when an actual DSL would have been
               | a better solution.
               | 
               | I know that was my last straw before I started assuming
               | that anything that required XML would be painful to work
               | with. It wasn't an entirely fair assumption, but it was
               | correct often enough that I used it as a helpful
               | heuristic.
        
             | AnimalMuppet wrote:
             | You're comparing XML and JSON, and you're complaining about
             | how verbose _JSON_ is? Um, JSON is, like, _half_ as verbose
             | as XML is.
        
           | jayd16 wrote:
           | You should update your perspective.
        
         | jeroenhd wrote:
         | My problem with Java is that C# exists which does huge portions
         | of the stuff Java excels at just... better.
         | 
         | Before, .NET only ran on Windows which disqualified it from
         | many serious applications server deployments. Today, this is no
         | longer the case for everything but cross platform GUI
         | libraries, and even those are an option if you're okay with not
         | having Linux support.
         | 
         | It's more akin to the old car you had just before you bought
         | your Corolla. It was also pretty decent, but it was starting to
         | have issues.
         | 
         | The JVM ecosystem is quite expansive and it's capable of
         | running many things that would be a pain to develop in house
         | (or pay a third party developer for). However, Java isn't the
         | only popular JVM language anymore and you're no longer forced
         | to use Java to interact with its surrounding ecosystem.
         | 
         | The language and the ecosystem around it aren't going to go
         | away for at least a decade, but I think it'll slowly move the
         | way of COBOL and FORTRAN: perfectly good languages, with
         | perfectly good situations they outperform their competitors in,
         | practically exclusively used for niche use cases and legacy
         | software systems.
        
           | thankful69 wrote:
           | C# is not a better Java by any means, Java has a more diverse
           | and greater ecosystem, you have plenty of choice for tooling,
           | IDEs, libraries, platforms, etc... With C# you are pretty
           | much stuck with Microsoft which everyone knows what that
           | means (.net core runs everywhere, but still attached to msft
           | in many ways), if you are serious about the C# ecosystem, you
           | need to use Windows, C# IDEs outside of visual studio are
           | mediocre at best. If you like running a operating system that
           | doesn't give a f** about your privacy and developing for that
           | platform then sure. There is a reason why C# (even with Msft
           | huge lobbying efforts, not only to the goverments but to dev
           | communities) have been relegated to boring(and sometimes
           | dying) industries which get huge discounts for using Azure.
           | 
           | EDIT: typos
        
             | solarkraft wrote:
             | I agree with most of your points, but also really dislike
             | Visual Studio. Rider has very good compatibility (unless
             | you care about the constant hangs and crashes and buggy,
             | nonsensically laid out eye sore UI and dumb defaults and
             | ...) and VSCode (the one with all the proprietary Microsoft
             | stuff) is quite usable. What kind of blew me away was
             | finding out that they support Jupyter notebooks now.
             | 
             | The Visual Studio team seems to dislike dotnet supporting
             | other platforms, but it's one of the most critical things
             | for its survival. The more the VS team hates it, the more
             | likely it's to be the right choice (probably a good rule of
             | thumb for building IDEs too).
        
             | dijit wrote:
             | Jetbrains rider is not mediocre by any stretch and many C#
             | developers prefer it, even on windows, even though it's
             | paid.
        
           | pron wrote:
           | > but I think it'll slowly move the way of COBOL and FORTRAN
           | 
           | That could be true of any language that's achieved great
           | popularity, but in 2022 Java is the language that dominates
           | server-side development (by plurality, not majority), it is a
           | technological leader in areas of compilation, garbage
           | collection, and low-overhead in-production profiling, no
           | other single language looks posed to seriously challenges
           | Java's dominant position on the server (as PHP seemed for a
           | while), and, at 27, it is more popular than COBOL was in its
           | (rather short) heyday.
           | 
           | But it is true that Java is among a select set of languages
           | (alongside Python, JavaScript, and C) that have managed to
           | achieve a level of success sufficient to become "a COBOL" or
           | "a Fortran" someday.
        
           | bcrosby95 wrote:
           | What stuff does C# objectively do better than Java?
        
             | babypuncher wrote:
             | Benchmarks generally show C# outperforming Java, but not to
             | a degree that most people would worry about. Performance-
             | sensitive applications are still going to go for something
             | native.
             | 
             | One of C#'s biggest assets is Anders Hejlsberg of Turbo
             | Pascal fame. He's been in charge of C# since its inception.
             | He's done a very good job of keeping the language clean and
             | concise, and generally ahead of Java when it comes to
             | adopting features like generics and functional programming.
        
               | runevault wrote:
               | I thought Anders was full time on Typescript these days?
               | Certainly his fingerprints are all over c# from being in
               | charge for a long time though.
        
               | babypuncher wrote:
               | He still acts as the lead architect on C#, in addition to
               | working as the core developer on TypeScript.
        
               | tejinderss wrote:
               | Nope, Mads Torgersen is lead architect on c# nowadays,
               | Anders is 100% on Typescript's typechecker.
        
               | kaba0 wrote:
               | I would put it differently: C# has a higher performance
               | ceiling due to it having access to lower level controls
               | (mostly value types), but for idiomatic code, there
               | really is no such difference (and if there is any, I
               | would say it goes towards Java). Also, for programs
               | having very dynamic allocation patterns, Java's GCs are
               | the state-of-the-art and are basically impossible to
               | beat.
        
               | the_only_law wrote:
               | > Performance-sensitive applications are still going to
               | go for something native.
               | 
               | What's up with Java in HFT stuff then? I've never
               | understood this: from what I understand in order for it
               | to work, you have to intentionally avoid doing many
               | allocations, and that seems like you'll be throwing
               | massive amounts of the ecosystem (Javas biggest strength)
               | away.
        
             | solarkraft wrote:
             | Can't really be objective here. You could also argument
             | this makes it worse, but it gives you to take shortcuts for
             | things Java would make very hard or cumbersome (unsafe
             | code, properties).
        
             | titzer wrote:
             | Generics, LINQ, structs, delegates, to name just four.
        
               | hhjinks wrote:
               | Can you explain _why_ you think C# does those things
               | better than Java? And what they correspond to in Java?
        
           | babypuncher wrote:
           | C# is like Java except your team can churn out new features
           | 30% faster.
           | 
           | At least that is my experience running the only .NET team at
           | a company that primarily runs Java.
        
           | pwinnski wrote:
           | It's hard to see how C# will ever find wide usage outside of
           | the MS ecosystem. It's so intrinsically tried to MS.
        
           | lenkite wrote:
           | > My problem with Java is that C# exists which does huge
           | portions of the stuff Java excels at just... better.
           | 
           | Might want to give some evidence of this. Also, C# has no
           | plans of green threads. It went the async/await way which is
           | a pain.
        
             | akra wrote:
             | I don't feel its the biggest pain to be honest, at least
             | not in the .NET world where the Async API is so persuasive.
             | I don't think the paradigm would suit Java - the API
             | changes to make it ubiquitous would make it take too long
             | to add value. People seem to code with it (the Async
             | workflow) just fine, and it's a decent model to write some
             | async algorithms. For example firing a few in parallel,
             | starting a task but leaving it running and awaiting it
             | later, etc. The advantage for me is that there is some
             | overhead with Async dispatch - the abstraction of
             | coroutines, green threads, etc is cheap but isn't free and
             | maybe seeing where it could prop up isn't always a bad
             | thing. There is value in knowing that an operation could be
             | async, at least in my time programming and it has a cost
             | that you may not want to pay, defer, delegate to someone
             | else, etc especially in hot loops (e.g. IO).
             | 
             | As a single anecdote working in both languages in my
             | current job in a cross platform environment when having to
             | write Java it feels just that bit more painful, and just
             | that bit harder to get the same performance for the class
             | of apps I write. YMMV.
        
         | baldfat wrote:
         | I personally use Racket (Lispish) just because it is so much
         | fun to build whatever I want and customize it. It just feels
         | good to have my small projects just fit me perfectly.
        
         | skybrian wrote:
         | I wouldn't use Java again because I am done dealing with the
         | brokenness of Maven and Gradle. They are the opposite of
         | "little fuss and muss." The Go build tools fit your analogy
         | better.
        
           | SureshG wrote:
           | > The Go build tools fit your analogy better.
           | 
           | Go uses two build tools for any non-trivial projects. One
           | write in go.mod and another in Make :D (see this - https://gi
           | thub.com/kubernetes/kubernetes/tree/master/build/r...)
        
         | NoSorryCannot wrote:
         | Whoever invented the car analogy should pay for what they did.
        
           | [deleted]
        
           | jgust wrote:
           | Bagging on car analogies is like driving a Hellcat, it's not
           | practical.
        
           | [deleted]
        
           | dls2016 wrote:
           | I remember an intermediate OO class in Java 20 years ago...
           | the existence of the El Camino was proof of the terribleness
           | of both multiple inheritance and car analogies.
        
           | mindslight wrote:
           | Indeed. All cars suffer the same speed limits and traffic, so
           | how effective your car is ultimately depends on how you drive
           | within those constraints. The analogy slyly condenses
           | everything down to some car-manufacturer-marketing version of
           | "fun", betraying both spirited drivers and whatever topic it
           | is applied to.
           | 
           | Since we're throwing out analogies, Java-the-language is more
           | like a riding lawnmower. It is capable of getting you to your
           | destination, but will be slow and painful the entire time.
           | There is probably some external constraint that you'll be
           | forced to endure this, like losing your license.
        
             | shagie wrote:
             | This was something / part of the plot of The First $20
             | Million Is Always the Hardest. I recall the main character
             | getting a car (turned out to be rented) that was really
             | fast and taking the team out driving on 101 in rush hour
             | traffic to make this point.
        
           | mgkimsal wrote:
           | I think the car analogy is just extending a base analogy.
           | There could be other siblings. Perhaps AnimalAnalogy could
           | extend BaseAnalogy and we could talk about animals instead?
           | ;)
        
             | enragedcacti wrote:
             | If you think about it, the car analogy really is the
             | Corolla of analogies.
        
           | bil7 wrote:
           | do you have some other anology we should all switch to? maybe
           | a ferrari level analogy that's way better?
        
           | pushingice wrote:
           | The car analogy is the Ford Model T of analogies.
        
           | bee_rider wrote:
           | Car analogies aren't intrinsically bad, they are just the go-
           | to analogy when someone wants to jam an analogy where it
           | isn't needed. Analogies in general should be used sparingly,
           | and only in an explanatory setting. Instead people use them
           | as a rhetorical device in arguments, which usually reduces
           | the argument to arguing about the analogy (and you can
           | usually shuffle around the parts of an analogy to flip the
           | meaning somehow).
           | 
           | Here it is fine I think, the writer of the comment is just
           | explaining their point of view.
        
             | drewcoo wrote:
             | > Car analogies aren't intrinsically bad
             | 
             | What can I say? They get me from claim A to claim B.
             | 
             | So are you saying that analogies should only be used like
             | secondary steering wheels?
        
               | bee_rider wrote:
               | Analogies should only be used like trains: An efficient,
               | well thought out path from point A to B on a vehicle that
               | is piloted by a pro. Car analogies look appealing -- they
               | look more flexible, but this can also lead to people
               | taking overly circuitous routes to get to the point...
               | maybe the driver just doesn't know what they are doing,
               | maybe the road system is poorly optimized because it
               | needs to hit lots of points, or maybe the driver is like
               | a sneaky cab driver that intentionally takes an
               | inefficient path to increase the fare.
               | 
               | The wider availability also leads to a situation where
               | cars are mostly piloted by random people with no
               | particular qualifications other than a basic license.
               | This can result in lots of car crashes. Of course, it is
               | also possible for a train to get derailed, but this is a
               | rare occurrence. On the other hand a derailing can result
               | in more damage... ah... hmm, I forget where I was going
               | with this...
        
               | aeonik wrote:
               | They only get you from claim A to claim B when there is
               | enough traffic to invest in roads and if people follow
               | the rules.
               | 
               | A more versatile set of analogirs are of course ATVs,
               | Aircraft, or even the humble legs.
        
         | drewcoo wrote:
         | > It's like a Toyota Corolla
         | 
         | This is only an invitation to car-shedding!
        
           | falcolas wrote:
           | So it was. So it was indeed.
        
         | valbaca wrote:
         | Hit too close with the analogy:
         | 
         | Been a Java dev for ten years and I drive a Toyota Corolla....
         | 
         | ...but also in my spare time I play around with Clojure and
         | dream of buying a '69 SS Camaro
        
           | nly wrote:
           | Admit it, you never will.
        
             | TheRealDunkirk wrote:
             | Well, maybe, like me, by the time you can afford it, your
             | knees and back don't align with getting in and out of one.
        
           | falcolas wrote:
           | I appear to be you, just with a Subaru BRZ. It's a manual,
           | it's fun as hell.
        
       | therealmarv wrote:
       | I'm extremely happy I have not had to use it beside one liners
       | for the last 12 years of my professional freelancer career. I
       | still remember the times when Java people were laughing at me
       | when I was telling them that I'm mostly a python developer.
        
       | teknopaul wrote:
       | Trouble with java is that it does not scale up or down in terms
       | of ram.
       | 
       | Minimum RAM for a sever doing something normal over tcp is
       | measured in gigabytes.
       | 
       | Big servers > 16gb get difficult to manage at runtime.
       | 
       | You have to scale with more VMs.
       | 
       | You can write useful C servers that are very small, especially if
       | you compile with musl. And run the same code for 1000kcc (not a
       | typo)
       | 
       | When you have big arrays of memory storing everything as
       | Objects/pointers gets messy and inefficient. But any big heap is
       | hard to manage and keep response times consistently low.
       | 
       | My other gripe os that "write once run anyway" is no longer close
       | to true, since Oracle. Mac, Linux x64 and Windows 64 are your
       | only sane options. If you look at the compile targets list for c
       | or rust you can see write once run anywhere working on a lot more
       | cpus. True, you might have Arch specific code but it works, and
       | most Java does not port from Linux container to Windows for
       | example.
       | 
       | A statically compiled Binary is often easier to move across
       | systems, because a java app is rarely a single jar. It's usually
       | >5gb of app specific jvm and libs and config files.
        
         | Dracophoenix wrote:
         | kcc in this context is "kilo clock cycles", right?
        
         | Scarbutt wrote:
         | _Minimum RAM for a sever doing something normal over tcp is
         | measured in gigabytes._
         | 
         | wut? do you mean MB? most small web services(jetty, jdbc/pg
         | driver/json) I have work on use below 500MB
        
         | ElectricalUnion wrote:
         | > Trouble with java is that it does not scale up or down in
         | terms of ram.
         | 
         | > When you have big arrays of memory storing everything as
         | Objects/pointers gets messy and inefficient. But any big heap
         | is hard to manage and keep response times consistently low.
         | 
         | Java can handle very large, TB-sized heaps (under normal
         | circunstances, about 52TB). But when you're dealing with TB-
         | sized heaps, anything is slow - including programs not made in
         | Java.
         | 
         | > You can write useful C servers that are very small,
         | especially if you compile with musl. And run the same code for
         | 1000kcc (not a typo)
         | 
         | Anyone can build stuff with musl, but musl is in general a lot
         | less optimized that GNU glib, so I guess it really only makes
         | sense on resource-constrained environments - not those where
         | you're handling TBs of heap.
         | 
         | > A statically compiled Binary is often easier to move across
         | systems
         | 
         | I guess you're talking about jart/cosmopolitan here, not your
         | average musl application - a statically compiled Binary usually
         | needs to be recompiled to work on other systems.
         | 
         | > because a java app is rarely a single jar.
         | 
         | Uberjars are very common, the norm those days.
         | 
         | > It's usually >5gb of app specific jvm and libs and config
         | files.
         | 
         | On my experience even if you "accidentally" bundled the whole
         | Java SDK together with your app, you're not getting over 250MB
         | for Java.
         | 
         | Unless you're counting the whole OS, in that case, even the
         | musl application isn't that small anyways.
        
       | mihaigalos wrote:
       | Anybody have experience with the JNI interop with native libs?
       | 
       | Is it better to implement something natively in a compiled
       | library and link it in from Java or better to rewrite it in Java?
       | What about lifetimes of objects - who "owns" an object - the
       | runtime or the lib?
        
       | thex10 wrote:
       | Being taught intro Java in high school (mid 2000s for me) was
       | excruciatingly boring and caused me to write off majoring in
       | computer science or working as a programmer.
       | 
       | Today I'm a software engineer with experience in JavaScript,
       | Ruby, Python, Elixir... maybe it's time for me to give Java
       | another try.
        
         | nailer wrote:
         | > Being taught intro Java in high school (mid 2000s for me) was
         | excruciatingly boring and caused me to write off majoring in
         | computer science or working as a programmer.
         | 
         | Same here. Nothing more to add.
        
         | ramesh31 wrote:
         | >Today I'm a software engineer with experience in JavaScript,
         | Ruby, Python, Elixir... maybe it's time for me to give Java
         | another try.
         | 
         | Nah. If you _have_ to use it, Java 's really not that bad. But
         | I would never choose it for a personal project. Its' strengths
         | are in all of the concerns that come with enterprise
         | development.
        
         | rco8786 wrote:
         | It's not. Java has slightly improved since that time, for sure,
         | but you're not missing anything.
        
         | afandian wrote:
         | Try Kotlin. I love it. Feels like the best bits of Clojure,
         | Ruby, Python and Java.
        
           | seanmcdirmid wrote:
           | Kotlin is great! I cringe when I have to go back to Java
           | occasionally for some reason.
        
         | commandlinefan wrote:
         | You might want to start with C. C is a _lot_ more enjoyable to
         | learn and use, and once you know C you basically already know
         | Java. (Assuming you understand OO concepts in general, anyway)
        
         | [deleted]
        
       | [deleted]
        
       | master_jonsie wrote:
       | What does the Jet Propulsion Laboratory have to do with Java?
        
       | naikrovek wrote:
       | and it still enforces terribly strict OOP patterns onto the
       | developer which is almost never the right way to develop software
       | if you care about performance even a little.
        
         | nailer wrote:
         | Even if you don't care about performance and only care about
         | simplicity OOP is really hard to rationalise about.
        
           | commandlinefan wrote:
           | Java has supported (mostly) functional programming constructs
           | since 1.8 (which was 2014), so you can realistically use it
           | without doing too much OO.
           | 
           | I've observed, though, that people who complain about OO in
           | Java usually write top-down procedural code rather than
           | functional-style code, which is far, far worse.
        
             | nailer wrote:
             | I've observed that Java has a culture of OO, so people tend
             | to be unaware of scopes, closures etc.
        
         | bhuber wrote:
         | I'm not sure you fully appreciate how tailored the JVM, and
         | hotspot in particular, are to executing OOP oriented code. One
         | great example I can think of is polymorphic methods. In C++ for
         | example, you have to explicitly declare a class method as
         | "virtual" in order for it to be polymorphic - i.e. the version
         | called at runtime is tied to the runtime object instance, not
         | the compile time type. This is because in order to do this in
         | C++, there needs to be an extra lookup in the vtable to find
         | the function address for every virtual function call at
         | runtime. If C++ made all its methods virtual, it would take a
         | significant performance hit from the extra vtable lookup for
         | every function invocation.
         | 
         | In Java, all methods are virtual by default. Java also does the
         | equivalent of a vtable lookup at runtime for function calls,
         | but it has something C++ doesn't have - the hotspot optimizer.
         | For any call site that is executed enough to affect runtime
         | performance, the hotspot optimizer will optimize away the
         | vtable lookup if there are only 1 or 2 method versions called
         | at that site at runtime. This is true for the vast majority of
         | cases. For most of the other cases, where you have 3 or more
         | possible method implementations that could be invoked at a
         | given call site, you would probably have to have something like
         | a vtable lookup at that call site whether you use OOP or not
         | (switch statement, if-else, explicit table of function
         | pointers, etc), so you're not losing performance there either.
         | The end result is, the JVM gets polymorphic methods basically
         | for free in terms of performance.
         | 
         | This is just one example, there are many other clever things
         | the JVM does to make OOP code performant. I don't have a
         | citation, but I do recall seeing a talk (maybe by James
         | Gosling?) where he mentioned that one of the primary design
         | goals of Java was to make "doing the right thing" from an OOP
         | perspective also the best option for performance.
        
           | naikrovek wrote:
           | it doesn't matter how much the HotSpot JVM is tailored to OOP
           | code. CPUs and RAM are not tailored to OOP in any way.
           | 
           | Procedural code will always be more efficient with CPU and
           | RAM, arrays will always be faster than Lists, being able to
           | control datatype sizing to the byte will always outperform
           | classes, and so on.
           | 
           | java is very fast, please do not misunderstand me. java is
           | much better than it used to be, as well.
           | 
           | Java is not a language chosen when performance is a concern.
           | Java is chosen when you have a giant pile of developers of
           | various levels of skill and you want to pile a ton of rules
           | and linters on them all so they write software in the same
           | way.
        
             | bhuber wrote:
             | > it doesn't matter how much the HotSpot JVM is tailored to
             | OOP code
             | 
             | This is obviously false. The JVM, or any other compiler for
             | that matter, is what translates the OOP code into CPU
             | instructions. If it does that optimally, it won't matter
             | what design pattern the top-level compiled language used.
             | If it does it poorly, then it will.
             | 
             | > CPUs and RAM are not tailored to OOP in any way.
             | 
             | This is not entirely true. Intel in particular pays a lot
             | of attention to Java performance when benchmarking
             | processor designs, see for example https://www.intel.com/co
             | ntent/www/us/en/developer/articles/t... .
             | 
             | > Procedural code will always be more efficient with CPU
             | and RAM...
             | 
             | First of all, arrays vs Lists and data type sizing are
             | orthogonal to procedural vs OO code. You can write OO code
             | that uses arrays and procedural code that uses lists, and
             | datatype sizing is more related to your choice of language
             | and compiler toolchain than your design patterns.
             | 
             | I think what you're trying to say here is that the
             | performance _ceiling_ for a low level language using simple
             | language primitives (if-else and vanilla function calls
             | instead of classes and polymorphism) that compiles to a
             | binary is higher than that for a high level language that
             | compiles to an intermediate language (or an interpreted
             | language). This is generally true for small code paths - if
             | you need to do a bunch of matrix operations, or data
             | crunching for a small well defined problem, you can
             | generally do it faster in C /C++ than in Java if you put in
             | enough effort. The ceiling part matters though - in
             | general, you have to put in a lot of skill and development
             | effort to realize these differences, and this often grows
             | super-linearly with the size of your codebase for low level
             | languages. If you have a large application that has a lot
             | of code, your overall performance will usually be higher
             | with a high level language because the _average_
             | performance for any particular part will be much better.
             | Sure, given infinite time and resources you could
             | theoretically do better in C, but nobody has that.
             | 
             | This is reflected in the approach most professionals take
             | in practice when it comes to perf optimization - write most
             | of your code in a high level language like Java or Python
             | because on average it will be faster and less buggy for any
             | reasonable amount of developer effort. For pieces of code
             | that absolutely have to run as fast as possible, write them
             | in C and call out to them from the high level language.
             | 
             | I guess the point I'm trying to make here is lots of people
             | choose java precisely _because_ performance is a concern.
             | It does better than most other high level languages out
             | there, and your average performance for a large codebase
             | will be much better than something like C /C++ given the
             | same amount of effort. As others have noted, it does
             | multithreading better than most too, which is another major
             | performance consideration. I don't care if my Java code is
             | half the speed of the C equivalent if I can easily run 40
             | cores at once - or 40000. I think languages like Rust and
             | Swift may let us have the best of both worlds in the
             | future, but that remains to be seen. For now, the only time
             | lower level procedural languages win is when you need a
             | relatively small codebase to run absolutely as fast as
             | possible.
        
         | twblalock wrote:
         | OOP is fine. OOP and functional programming written by skilled
         | programmers both end up being basically the same thing -- they
         | are just different techniques to achieve encapsulation, control
         | over dispatch, control over state, etc.
        
         | jayd16 wrote:
         | What can't you do in Java that you want to do besides the fact
         | that there's no stack allocated type (which is a java thing but
         | not an oop thing)?
        
           | kaba0 wrote:
           | (Nitpick, but primitives are stack-allocated)
        
       | exabrial wrote:
       | The CDI specification is what takes Java from "good" to
       | "incredible". The dependency injection pattern makes Java a
       | hybrid functional language, where all the state can be stored in
       | the CDI container. This eliminates a whole class of bugs and
       | simplifies a codebase allowing for pervasive use of composition.
       | 
       | Stuff like Microprofile, Quarkus, ActiveMq, Tomcat, and even
       | JakartaEE are gravy on the cake.
        
       | pid_0 wrote:
        
       | mark_l_watson wrote:
       | Sun Microsystems had a link to my blog on the Java home page for
       | about a year. I had attended the first Java World Tour, blogged
       | about it, and for 15 years I was the first "hit" searching for
       | "Java consultant". Thank you Java.
       | 
       | All that said, I don't use Java much anymore, preferring to use
       | Clojure when I need the rich JVM ecosystem. I do follow new Java
       | language features and usually try them.
        
       | jrsj wrote:
       | After mostly using Node and Go for the last 3 years I kind of
       | miss Java honestly. Unfortunately it's still terminally uncool in
       | my local job market so even mentioning it would be a bad career
       | move.
        
       | mkl95 wrote:
       | I wrote a lot of small Java programs when I was in school, and
       | Eclipse felt like being on developer steroids compared to using
       | an IDE with a dynamic language. My software just worked and was
       | pretty fast. I have mostly worked with Python since I became a
       | pro developer and I often wish it was a more "boring" language.
        
       | pdntspa wrote:
       | I recently started a side new project in Java targetting GraalVM
       | with language version 17.
       | 
       | Aside from Java's innate finickyness, it has been an unexpected
       | pleasure. I think a lot of it has to do with its static typing (I
       | typically work in dynamic languages, and it's nice knowing that
       | if the program compiles it likely works), and how simple the
       | language keeps its primitives.
       | 
       | But you need really good tooling to use it, like a powerful IDE
       | with good autocompletion and refactor support. It is way too
       | verbose to type everything out yourself, and the verbosity means
       | manually refactoring takes lots of changes around the program to
       | manifest.
       | 
       | The sheer amount of code out there to import is immense, there
       | seem to be libraries for anything and everything!
       | 
       | So far, it seems like the time I lose to its pickiness, I gain
       | back with IDE features, static typing, and the ease of
       | understanding it (because it is so verbose).
       | 
       | I'm also not hot on how it seems to steer everything into a
       | factory pattern, but so far I've been able to avoid that for most
       | things.
        
         | hedora wrote:
         | My main problem with Java is that it's picky, and has some
         | static typing, but it also has heaps and heaps of loopholes in
         | the type system (that turn into runtime exceptions), so it's
         | this weird compromise where everything is substandard. I've
         | found that Go "feels" a lot more like a dynamically typed
         | language, but still has the good IDE support that you're
         | talking about.
         | 
         | If you want to see how much progress there has been in
         | production-quality statically typed languages, write some
         | multithreaded code in Rust. In addition to being memory safe
         | without a GC, the compiler also confirms that your code is
         | threadsafe.
         | 
         | Both those guarantees can be violated using the "unsafe"
         | keyword; Java has similar mechanisms that break memory safety.
         | Java doesn't provide meaningful thread safety, in the same way
         | that C's malloc/free don't provide meaningful memory safety --
         | it's possible to write thread- and memory-safe programs in both
         | languages, but the Java compiler doesn't really help out much
         | with thread safety, just like the C compiler doesn't typically
         | check for use-after-free, etc. Go's thread safety semantics are
         | closer to Java's than Rust's (though multithreaded programming
         | in Go is more ergonomic than in the other two languages).
        
           | pdntspa wrote:
           | I've read enough critiques of Rust to be put off from trying
           | it out at this time. And there's a lot of things I don't like
           | about Go. (Zig is interesting though)
           | 
           | Unfortunately Rust doesn't have the kind of library support
           | that Java does, and I don't really want to roll my own on
           | some things (the side project will never get done if I get
           | lost in the weeds)
           | 
           | For this project the choice fell between Java and C#, and
           | Java won because I was familiar with the library code that
           | does what I want to do.
           | 
           | Besides, Java has Swing, which is about the only cross-
           | platform GUI toolkit I can stand to work with (GTK as a close
           | second)
           | 
           | > but it also has heaps and heaps of loopholes in the type
           | system (that turn into runtime exceptions)
           | 
           | I've yet to run into this in places where I don't really
           | expect it. Do you have some examples of where this becomes a
           | problem? I wrote a bunch of reflection code that triggered a
           | lot of RuntimeErrors, but that was foreseeable as its
           | reflection, the whole point is to figure out types and
           | whatnot during runtime. And at that point, I just fall back
           | to how I write code in dynamic languages.
        
           | kaba0 wrote:
           | > In addition to being memory safe without a GC, the compiler
           | also confirms that your code is threadsafe.
           | 
           | No, not at all. Rust verifies that your code has no _data-
           | races_. That is an absolutely tiny subset of all race
           | conditions, that are simply not verifiable statically.
        
         | dehrmann wrote:
         | > But you need really good tooling to use it, like a powerful
         | IDE with good autocompletion and refactor support. It is way
         | too verbose to type everything out yourself, and the verbosity
         | means manually refactoring takes lots of changes around the
         | program to manifest.
         | 
         | One of the ironies of Java has been that its strictness and
         | verbosity can make it hard to develop, but that strictness also
         | enabled the development of powerful IDEs. What feels like a
         | hassle for a 100 line file becomes an asset for a million-line
         | project because of the safety, discoverability, and refactoring
         | it enables.
        
           | gorjusborg wrote:
           | > What feels like a hassle for a 100 line file becomes an
           | asset for a million-line project
           | 
           | This is true and hard to communicate to people that haven't
           | lived it.
        
           | kuboble wrote:
           | Yes. I worked many years in both Java and C#. In Java every
           | project and codebase I saw was pretty much the same.
           | 
           | In c# when I look at other people's projects I often feel
           | like it's a foreign language. You can make it look like C++
           | with unsafe blocks. You can nake it look like ruby with
           | dynamic variables. You can write sql-like statements.
           | 
           | As much as I love writing in C#, I prefer reading other
           | people's Java.
        
           | pdntspa wrote:
           | Indeed; I haven't seen a ton of bad code in it (not saying
           | that it's not out there, just that I haven't been exposed to
           | much of it), but when I needed to dig into how something
           | works, so far it has been very easy to scan and mentally
           | parse what's going on.
        
         | binkHN wrote:
         | Have you explored Kotlin? It's really not just for Android.
        
           | nerdponx wrote:
           | I've heard from a few corners that Kotlin is "Java but
           | better", but I've also heard that the tooling is pretty
           | lacking if you aren't using JetBrains stuff. True?
        
             | dboreham wrote:
             | Successfully used VSCode for Kotlin projects.
        
             | [deleted]
        
           | pdntspa wrote:
           | I have, it's a nice language but I didn't like the mental tax
           | of translating Java code to Kotlin in my head whenever I had
           | to read up on how to do something
           | 
           | I do intend to dig into it a bit more once I feel like I have
           | mastered Java
        
             | binkHN wrote:
             | I hear you, and had to do the same for a while. Eventually
             | your brain migrates over and it becomes second nature. The
             | ability to copy Java code and paste it as Kotlin helps
             | tremendously, especially in the beginning.
        
       ___________________________________________________________________
       (page generated 2022-08-09 23:01 UTC)