6 ms·
Absolutely correct. And frankly I don't understand the hate people have against Java. Especially the new generation developers. Maybe the language part only. Bu
by yakorevivan 4y ago
Absolutely correct. And frankly I don't understand the hate people have against Java. Especially the new generation developers. Maybe the language part only. But have seen much hate towards JVM too.
With projects like loom, valhalla, graalVM, JVM/Java is everything a modern language/runtime needs, plus a lot lot more.
I frankly believe the only other commercially viable language that has similar philosophy to JVM development, is Rust.
Opinions?
- pjmlp 4y ago> I frankly believe the only other commercially viable language that has similar philosophy to JVM development, is Rust. Not really, .NET ecosystem is the only match to Java in tooling. Hence why during the last 20 years I enjoy both platforms.
- doctor_eval 4y agoFor my part the problems with the JVM are manifold: - it’s a heavyweight blob that you have to ship with your binary. It can be many times the size of the thing I’m trying to run. - it’s a word salad of technologies that apparently I’m supposed to care about - many of the claims of how great it is are really just ongoing claims of how great it’s going to be. To the latter point, value types (discussed in this thread) have been discussed since I was still using Java - a quick Google shows results from 2014. I haven’t written Java code commercially since 2018. I can’t find anything suggesting it’s here yet. Keeping track of all these technologies and trying to understand when they will arrive and make my day to day life better was a nightmare. Compared to that, I can build a Go binary, scp it to some machine and run it. That’s not possible in the JVM world, at least not without a level of calisthenics I’m simply no longer willing to deal with. GraalVM and friends may be wonderful technologies, but honestly I don’t care. I don’t want to have to thread the needle of this ecosystem every time I have work to get done.
- brabel 4y agoWhat do you mean by similar philosophy? The JVM and Rust are quite different in every aspect, practical and philosophically speaking... except for both having lots of corporate backing perhaps? Perhaps you meant to say WASM, which is indeed very similar to the JVM in goals and philosophy.
- pantulis 4y agoMy opinion: people dislike the Java platform mainly for the language, perhaps too ceremonial and verbose for today's trends. Also older developers remember Java from the J2EE/Struts/applets days as something overarchitected, slow and with cumbersome tooling, but that would not apply to the younger cohorts. Maybe a new programmer just sees Java and thinks "legacy", and we love to feel we are on the edge of technology.
- pjmlp 4y agoWe also remember that when compared with CORBA and DCOM, it was a pleasure to work with.
- nmhancoc 4y agoI agree, it's mostly the language. However, remember that newer developers get onboarded by older developers. I lead the charge a few years ago to get my then team to adopt Java8 style streams and Vertx, otherwise the stack was the typical SpringBoot annotation affair with the downsides you mention. In a similar vein, one of Java's touted strengths is the package ecosystem but those packages often are written in the same class-hierarchy-heavy style. When the code you see and use is written in that style, writing in that style becomes the default unless you actively choose to do something else.
- vips7L 4y ago> I agree, it's mostly the language. Which I don't understand at all. Modern Java is far more expressive than Go which everyone seems to love. Streams, switch expressions, records, pattern matching, and variable type inference all make Java an extremely expressive and fun language to write while also maintaining readability for when you come back to the code later.
- pron 4y agoI'm not sure I understand the comparison to Rust. The JVM is a virtual machine, analogous to the LLVM virtual machine that Rust targets. But that aside, I don't agree with the sentiment. Rust and C++ are languages that emphasise full low-level control. As such they offer different constructs the programmer chooses from for different characteristics -- e.g. virtual vs static dispatch -- in cases that are abstracted into a single abstraction in the JVM which then relies on the JIT compiler to profile the execution and pick the best implementation (virtual or static dispatch). Java, therefore, aims for a balance between ease of use and performance -- with an emphasis on _amortised_ performance -- whereas C++/Rust aim for maximum control with an emphasis on the worst case. As for the hatred to Java, some of it is due to experience with "old Java" which is then negatively compared to some "new X" (rather than comparing "new X" to "new Java"). Some just comes from popularity. In 20222 Java is the dominant server-side language, with no other language coming remotely close in that domain. In 2002 Java was also the most popular server-side language. Very few languages have ever achieved such success for such a long time (e.g. COBOL and PHP never did), and I believe the list includes just C, Java, JavaScript, and, to a lesser extent, Python. Of those four, only C, Java, and JavaScript are commonly/mostly used in large projects, and people often hate large codebases. Those three languages receive roughly equal amounts of hate. C++, which isn't as popular but is also mostly used in large projects, also receives a lot of hate. I think people believe that some language X easily fixes some flaw they see in Java, but so far it's come at the cost of other shortcomings they don't see, which explains why X never becomes as popular -- which makes those people disappointed -- which, in turn, means that it rarely has big, old codebases, and so is never hated but just fades to remain fondly-remembered, or lingers as a niche language (although sometimes a not very small niche). This is somewhat like the Betamax vs. VHS debate. A relatively small group of ardent fans liked Betamax because it was superior in a metric they cared about, but was inferior in metrics other people -- a larger group than the first -- cared about. In short, I think it's a combination of unfamiliarity with "new Java", the language's extended popularity, and its use in large codebases.
- pjmlp 4y agoForgetting about .NET?
- edg5000 4y agoThe JVM is a beautiful place for code to run, and the language is great as well. The only and main weakness is interfacing with the OS and libraries. TCP and file access is builtin and is no problem, but to access a serial device you'd need JNI. To interact with OpenGL, you need JNI. To interact with the Linux kernel, JNI. C/C++ library: JNI. JNI is fine if you have no other choice (e.g. to invoke Android's Java-only SDK's, e.g. for Bluetooth), but voluntarily, much less so. It is much less of a pain to invoke Linux or Windows C libraries (or Apple's Obj-C APIs) from, say, C++ than it is from Java.
- origin_path 4y agoPanama is giving Java/JVM a much better FFI. You won't need JNI anymore after that. That said, it won't let you call C++ classes. But that's of course normal.
- pjmlp 4y agoWhat I miss from Panama, is that it is still early steps, even with jextract it is a bit more involved than using P/Invoke.
- samus 4y agoTCP and file system access use JNI under the hood as well. For most other use cases there are already libraries that provide wrappers. And after Panama is shipped, they will eventually be upgraded to use that faster FFI. Btw, aren't serial devices treated as files under Unix?
- batmanturkey 4y agoI dislike everything the JVM stands for and is. There’s no real gentle way to put that. I don’t support the notion of a fat runtime platform. The LLVM IR code is a much better conceptualization of where and WHEN code executes. My feelings about Oracle and the entities around Java are also less than optimal. I only feel free to be so blunt as you asked for opinions. I gather that you disagree. Rust is rather unrelated. It’s a compiled static language with no runtime, in which you manage memory. The JVM is a thick VM and you basically only get to script it, which is fine and all considering it’s Turing complete, etc, but you really aren’t anywhere near the metal where rust can go bare metal with no OS or stdlib
- origin_path 4y agoIt's highly ineffective to be close to the metal for most software. Progress comes through abstraction. Even video games is like that these days. Not many companies writing their own game engines anymore: they all ship with giant "runtimes" like Unreal.
- chrisseaton 4y ago> The LLVM IR code is a much better conceptualization of where and WHEN code executes. Funny - because LLVM IR makes the 'when' (the required partial ordering of instructions) implicit and so both too loose and too constrained at the same time, because it's a linear IR, while the JVM's Graal and C2 IRs makes the 'when' completely explicit and a first-class part of the representation, because they're graphical IRs.
- kaba0 4y agoCould you please expand on this/link me somewhere? I am not familiar with LLVM, and I am only familiar with the JVM spec (currently in the process of writing a templated interpreter), but not yet familiar with OpenJDK’s existing code base, nor a complete JIT compiler.
- chrisseaton 4y agoGiven this C code: int foo(int a, int b, int c, int d) { return a * b + c * d; } LLVM gives you a single total-ordering of all operations in this code, which makes it appear like computing %5 has to happen before %6, but in reality it doesn't - they could be swapped. define dso_local i32 @foo(i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3) local_unnamed_addr #0 !dbg !7 { %5 = mul nsw i32 %1, %0, !dbg !18 %6 = mul nsw i32 %3, %2, !dbg !19 %7 = add nsw i32 %6, %5, !dbg !20 ret i32 %7, !dbg !21 } Java's IRs instead tell you that %5 and %6 need to be computed before %7, but don't apply an ordering between them otherwise. They can do this because they use a graph of instructions, not a linear list of instructions. https://chrisseaton.com/truffleruby/basic-graal-graphs/ https://chrisseaton.com/truffleruby/basic-graal-graphs/
- Banana699 4y agoI think you're (perhaps intentionally) overestimating the hate the JVM gets to paint Java critics as unreasonable, but the fact of the matter is that the JVM and Java the language are light years apart in quality and (subsequently) the attitude they get from their users. One is a decent VM with man-centuries of work and inspiration from academia (Self, whose VM heavily influenced hotspot), the other is an ugly mess of a language whose syntax and semantics is pure unfiltered paperwork and bureaucracy. I have elaborated plenty of times on why Java is a 1980s language that were obsolete as soon as it was released, the latest is my comment on https://news.ycombinator.com/item?id=32128271 https://news.ycombinator.com/item?id=32128271, which I reproduce in full at the very bottom of this comment to save you a ctrl-f. >loom, valhalla, graalVM Every single one of those has nothing to do with Java and everything to do with the JVM as a high-tech psedo-OS that challenges the classic preconceptions about performance-productivity tradeoffs. I don't want to attribute dishonesty to you, but again, I see absolutely no reason to confuse a VM with a (incredibly inferior and badly designed) human-level programming language just because it happens to be the first language to run on the VM. >frankly believe the only other commercially viable language that has similar philosophy to JVM development, is Rust. Come again? How is Rust similar or even comparable to the JVM ? ---------- Reproduced Comment ---------- >>>>I'm a Java hater. Here are the reason I hate it for - Baking the difference between primitives and objects into the language itself : an ugly mistake with far reaching consequences, made by a language designed in 1995 while another designed in 1980 (smalltalk), in 1991 (Python) and 1995 (Ruby) all didn't fall for it. The difference is an irrelevant VM-level optimization detail, there is no reason to uglify the human-level language with it. Once the initial mistake has been made, the correct response was NOT to make the even uglier hack of wrapper classes, but to make the primitives objects in the newer releases of the language, this won't break old code, as valid uses of objects are a superset of valid uses of primitives, except perhaps that objects need to be allocated explictely with "new", but this can be a special case for primtives (i.e. "int is a special kind of object that you don't need to allocate explicitly"). The compiler can figure out whether it needs to be represented as objects or as primitives, you can leave hooks and knobs for people to tell the compiler they need to the primitives to be represented as primitves, but it shouldn't be mandatory. - Baking in choices about object representations : Like the fact that objects are always passed by reference, or that they are always allocated on the heap. Why the "always" part ? why not give developers the choice between pass-by-value and pass-by-reference like C# does ? why not give developers the choice to allocate on the stack (and complain as loud as you want when they want to do something unsafe with it, like escaping from methods), which, unfortunately, even C# doesn't ? Everytime you see something like "foo deepCopy()" that's a failure of the language, forcing you to explicitely pay attention to the fact that foo objects need to be copied deeply everytime they are copied, instead of just once when you define the object by marking it as a "struct" or whatever word to signify that object has value semantics, and then deep copy is just assignment or passing as a parameter. Why make it the default to be inefficient with the heap when it's very easy to give developers the choice to be efficient in situations where it's always safe ? - No operator overloading : I get the hate, it's a powerful tool. But it's misguided to ban it, operators should not be special, languages like Haskell and Raku go even further and allow you to define new operators entirely and control their predence and other things. You don't need to go that far, why can't objects use the already built-in symbols the language support ? because it might be confusing ? anything can be confusing, you can write assembly in any programming language, and it will be even worse than assembly because of the more powerful and obscure abstractions. - Generics : The overall theme of forcing you to do things its way seems to a staple with java. Why do I need to use type-erased generics ? why shouldn't I get the choice to specify whether I need a new class generated for runtime efficiency or use the type-erased catch-all for size efficiency? there is no need to bake VM-level support for this, it can all be done at compile time (possibly with help of additional metadata files or special fields in the .class of the generic type). - Overall verbosity : Why "extends" and "implements" ? do you really need to know whether you're inheriting a class or an interface ? and can't those be lighter symbols like "<" and ":" perhaps ? why is "private/public/protected" a must in front of every method and field ? most people align fields and methods by their visibility, C++'s way is that you declare "public:" and then everything declared below that is public. In the worst case you can always recover Java's way by "public : <method> ; private : <method> ; public : <method>" and so on, but it's nice to at least have the choice of not repeating yourself. Why aren't any constructors generated ? there are at least 2 very obvious ones : the empty one, and the one that assigns all the non-defaulted fields (and can take optional arguments to override the default fields). Why aren't generated getters and setters available with a small and light request, like C#'s "get ; set ;" ? Java's design is just full of things like this. It feels like a weird sort of disrespect for your time, "yeah you must write those routine 25 lines of code all by yourself, you have anything better to do?", how about actually writing my application instead of pleasing your language with weird and unnecessary incantations ? It's like a modern COBOL. - Horrible OOP excesses : Not really the language's fault (except that it encourages verbosity and loves it) and already mentioned, but worth mentioning again. Overall, I treat java as assembly. I write kotlin in my spare time, and whenever I'm confused about the semantics of some construct I make intellij show the bytecode then hit "decompile" to see a Java rendition of the code, the exact semantics will be obvious but verbose. A language that took this literally is Xtend, a high-level augmented java which transpiles to java and is a strict superset of it, but with option that the Xtend compiler figures out all the verbosity for you. Groovy also takes the "Superset and Augment" approach but doesn't transpile. And off course Kotlin is very good with it's interoperability, every JVM language is but Kotlin's mixture of being close to Java semantics (unlike say, Scala or Clojure) and Intellij excellent support for mixed projects makes it at least somewhat special. I like the JVM and it's cutting edge research and performance, and these days the Java standard writers seem to show signs of finally waking up to reality after years of being behind every mainstream language, and they regularly augment and modernize the language. But you can't undo 20 years or so of bad design, not easily and not painlessly. >Indeed, tooling is the new syntax. Very much agreed, long long gone are the days when a compiler or an interpeter is the only thing expected out of a language. But it's not a panacea to treat any bad design, at best it's just a band-aid for bad designs that makes them barely berable. The language has to be designed from the start with the knowledge of "this is going to run in an IDE" baked in to make full use of the full range of fantastic things an IDE can do. ---------------------
- hawk_ 4y ago> And frankly I don't understand the hate people have against Java. There are two kinds of programming languages : ones that people complain about and ones that no one uses.