[1] http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...
Luckily, C# learned from this mistake and made a decision to follow C much closely, having integers as proper primitives and supporting structs since day 1, and only improved since then in this area (JVM needs insane pointer compression and shadow tricks to pack integers to claw back performance, and in .NET "it just works" instead).
I wonder if Cassandra was written in .NET, it wouldn't have such a poor performance (though this can also be showcased by Garnet which beats competition written in C++ and C).
Like honestly, which ecosystem has better exceptions/error messages, in the general case? Java pinpoints the exact source of the error with useful context. It’s as good as it can get.
1. Error codes. Try debugging Win32 software and have fun working out with all those HRESULTs mean, especially as every Google hit for any given code is just endless support forums with people complaining their computer is broken.
2. Panics. You get an error message no more helpful than an exception, except with no stack trace to help you figure out what's wrong.
3. Segfaults. You get nothing.
Exceptions are the best form of error handling yet invented. Making programmers more helpful is hard, but exceptions have auto-generated error messages that at least tell you where the program died, how it got there, and very often the chain of problems that led to that surface level problem (a particular weakness of error codes where causal chains are often lost). They also often have JavaDocs explaining what they mean.
Although it's not really a weakness of Java or exceptions per se, I think some people don't like them because lazy devs don't bother translating them into something more user friendly (especially for developer tools). There are simple patterns that fix that though. My company makes a CLI developer tool written in Java+Kotlin running on the JVM (see bio) and it defines a dedicated UserError exception type. If an exception bubbles to the top level of the program and it descends from UserError then it's formatted nicely with colors and shown as you'd expect. If it's not then the exception is logged and a crash reporter is started, the user is asked if they'd like to report the crash. The exception details are then printed without the stack trace and polished slightly ("FooBarException: abc" -> "Foo Bar: abc") which often makes the messages good enough that the user can unstick themselves. There are utility methods to catch and rethrow exceptions as user errors when the underlying messages are already good enough, and the product is careful to rethrow manually if the messages need to be improved. There are also utilities to verify that a file/directory exists and if not, throw a special subtype of UserError that yields a spelling corrector [1]
The result is that if you check our homepage, you'll see at least one customer explicitly praised our error message quality! They were very happy to never see a stack trace from a developer tool, only actionable errors that tell you what to do.
So exceptions can definitely yield a great UX. You just have to care and put in a bit of effort.
IntelliJ is another example of a product where the exception UX is highly polished. Its exception reporter can figure out which plugin an error comes from, route error reports automatically, deduplicate errors based on the stack traces, attach files that the exception object advertises and so on.
[1] https://hshell.hydraulic.dev/14.1/user-interaction/#path-ass...
https://www.microsoft.com/en-my/download/details.aspx?id=100...
which effectively looks up error codes in Windows SDK header files (which need not be installed)
~> err 0x80070091
# No results found for hex 0x80070091 / decimal -2147024751
# as an HRESULT: Severity: FAILURE (1), FACILITY_WIN32 (0x7), Code 0x91
# for hex 0x91 / decimal 145
ERROR_DIR_NOT_EMPTY winerror.h
# The directory is not empty.
# 1 matches found for "0x80070091"
~> err 91
# for decimal 91 / hex 0x5b
SET_ENV_VAR_FAILED bugcodes.h
NMERR_DISCARD_FRAME netmon.h
LDAP_CONNECT_ERROR winldap.h
# for hex 0x91 / decimal 145
WIN32K_INIT_OR_RIT_FAILURE bugcodes.h
ERROR_DIR_NOT_EMPTY winerror.h
# The directory is not empty.
# as an HRESULT: Severity: SUCCESS (0), FACILITY_NULL (0x0), Code 0x91
# for hex 0x91 / decimal 145
ERROR_DIR_NOT_EMPTY winerror.h
# The directory is not empty.
# 6 matches found for "91"
which is frequently better than nothing, grep, or Google, especially for small integer error codes (and, in the case of Google, for any HRESULT Windows Update or the Microsoft Store has ever returned).I find that JavaScript, Ruby and C# are all easier to debut in practice than Java, and all three use exceptions. IMO this is mainly due to what idiomatic Java looks like and how libraries/frameworks are structured.
What most people seem to complain about when they say "Java" is actually dependency injection frameworks, not the language or even regular libraries (which typically don't use them). I also don't like Guice so can sympathise, but DI frameworks vary in quality a lot, and you don't have to abuse them. Modern frameworks are based on code generation and check much more at compile time. My app uses a compile time DI framework to set up the build task graph, but doesn't have a factory bean anywhere and has never yielded strange errors about factories that were hard to debug.
This is precisely what I said with “ due to what idiomatic Java looks like and how libraries/frameworks are structured”.
Sure, in a platonic ideal Java codebase, it’s all great, but I am talking about my actual practical experience, and I said as much in my message.
Also, where did you encounter this exception? Im really curious.
Were there other technologies that do the same thing? Sure. Were they better? In some cases. Was Java really the "first" by whatever metric? No.
But Java is where the world changed, it just is.
It also seems you are forgetting just how bad early Java was, from a programming and user standpoint. Java errors like NullPointerException became a meme because they were so prevalent in user space, and required so much energy and time to get things working. As a result, people typically refused to update any part of Java once their app was working, to avoid breaking things. And that was _if_ the install was registered with a package manager or Windows Update so updates could be reported.
Java is decent enough that even when that happens, the log/stderr will at least be actionable by devs, which is much more than many other ecosystem can say.
This applies the same to other "popular" languages like Javascript i.e. NodeJs. I'd argue Java apps being supported by large corporations actually have better documentation.
> Most only show up in old SO post, or application specific forums
And a lot of "popular" issues only show up in a hidden github issues comment that may or may not be relevant anymore.
And let's not forget the joy that is Python's many, many esoteric values due to rampant signature changes in dependency hell. Whoops! That library that just got accidentally updated renamed a critical function 2 layers deep in the 70+ transitive dependency hierarchy, and threw an error; too bad it didn't manifest before you spent 10 hours of processing time.
For SDKs themselves, they are installed in a canonical path, and only a single (latest) executable exists in path, called "muxer", also working as front-end for all commands. It then can choose corresponding SDK and runtime dependencies installed in subfolders depending on a situation. You can easily do sudo apt install dotnet-sdk-8/7/6.0 in any order and it will "just work".
quite literally; https://danbooru.donmai.us/posts/947012?q=parent%3A947012
The things that people build using “idiomatic Java” are scary.
Java is my favorite language, but this is simply untrue. Many people are confused about how object references work, problems with null are very common, generic type erasure can be _very_ confusing, and there are plenty of other rough edges.
That said, Java does get a lot of undeserved hate. It's really quite a pleasant language and it has evolved a lot over the last 10 years.
I like it because it's comprehensively organized. I mean it does everything it should and does it a nice orderly way. The whole class system and c-like system, all together, works good. And addresses everything I want it to address.
And it does that without adding a bunch of crap. Or at least I find that crap easy to ignore. But ya, they do seem to be adding a lot of crap.
In a nutshell, it's a nice neat system. Python is a mess, comparatively.
I'm looking for a new language tho. Orderly and comprehensive like Java, but succincter.
Are you referring to the newer language features? I've personally really enjoyed what's been added and felt that it's unobtrusive, though I haven't been able to use an LTS newer than 17 yet.
Alternativly python with it's typechecker in strict mode is quite organized. Though poorly typed outside dependencies are common. And ofcourse performance is much worse.
I think Go will be a great language in 5-10 years. The authors of the language wanted to make something minimal, and they did a great job of that, but it was too barebones, though they are rectifying this by adding in critical features (like IMO, generics)
I like Python for small scripts, but I feel like I'm constantly fighting the language when managing dependencies, dealing with init scripts, or figuring out which of the 10 ways I should use to perform a common task.
I don't think there is a great replacement for Java. TypeScript with Bun or Deno might be the closest alternative right now, at least for me.
C++ is much more scary than Java in a “shoot yourself in the foot” kind of way.
INTERCAL is much more scary than Java in a “this is impossible to understand code” kind of way.
Haskell is much more scary than Java in a “this language has FP constructs” kind of way.
So why is Java scary?
Java is great. Solid ecosystem, solid performance, decent memory safety story, tons of production experience, etc.
Java was just a valid target to many programs that were previously written in C++, and some of that mindset stuck.
I would argue though, that today’s java is not excessively OOP, and can be written in an elegant hybrid of OOP and FP, whichever suits the given subproblem best. (It literally has algebraic datatypes and pattern matching now).
Maven works fine, it has so much history that most problems you encounter have been solved. It's also pluggable so you can extend to your heart's desires (but you shouldn't, same as Gradle when people try to be too smart with plugins it's time to tell them to stop).
Could it be better? Of course! But just as the rest of Java: it gets the job done, and it's absolutely fine after you deal with some idiosyncrasies. Every programming language environment has their own unique set of idiosyncrasies to deal with.
Java is a workhorse, it's not sexy, it's not pretty but will get you pretty far in most production environments.
But of course, maven could also be a lot better.
Maven and Gradle both have a learning curve, but IMO they're better than what exists for C/C++ (which really don't have _any_ standard dependency management).
Of course a specialist will be “more elegant” at solving it’s intended problem, but that’s often not all we need.
And don't get me started on dependency injection systems like Guice. @Inject just means I have no way of knowing the type of an object or how it is initialized without sifting through the entire code base looking for an @Provides. And even then I can never be sure.
1) A lot of enterprise devs think all problems are best solved in Java, and refuse to acknowledge anything else (looking at the IBMers in the room) 2) Spring Boot takes what you don't like about Guice and cranks it up ten levels. It's so common in the industry that it might as well be adopted as a javax package now.
It’s not only possible, that’s where all this stuff originates from. Gang of 4 has examples in C++ for a reason.
If you're using interfaces correctly with strong contracts, the concrete implementation shouldn't matter.
This falls apart very quickly if your implementations don't match the contract.
Guice can be quite pleasant (though confusing at first) since it makes it easy to test your code and easily swap out implementations of classes, e.g. for dev vs prod.
There's a lot of Internet trolls that like to bash it and influencers e.g. on Youtube that like to use it to look hip.
It's less about the facts and more about it being the biggest target they can hit.
Coincidentally their religion is called Javascript and according to them there can only be 1 Java.
JavaScript was forced on the world by being the language of the browser, but Java was foisted on the world by Sun Microsystems in a massive marketing campaign.
And then Java was bought by the kind of person who isn't a programmer but needs to make some kind of sensible choice at some company, along with the kind of person who needs to teach freshman programming according to the latest fad.
Don't forget the millions Sun spent literally ADVERTISING Java.
For 2-3 years (2003-4?) every other tech-related book that was published had something to do with Java. I remember going into a Barnes and Noble once, back in that era, and walking down an aisle that felt like it was 30 feet long and four shelves high of just Java books. It was all marketing.
After a decade people suddenly woke up and realized "oh, Java sucks".
Then the smart kids moved on, but the rest of the world is now stuck with Java, and there will always be those kinds of people around who aren't programmers but who need to make what they think is some kind of sensible choice.
Of course, the Java community has also realized what a pile of ** Java was, so now they've added all sorts of lambdas and better syntax and whatnot, but it's band-aids on top of a fundamental misconception, which is that object-oriented programming is the best way to model software engineering problems.
Also, don't ever forget that Java was the other "language of the browser". Netscape came bundled with a Java Runtime Environment, back when everyone used Netscape. You were supposed to write your web application as Java applets, with JavaScript being the bridge between the static HTML world and the dynamic Java applet world (which also explains why its name was changed from LiveScript to JavaScript).
That is array of cat is a subtype of array of animal. And a function Foo taking an array of animals and appending a dog is legal. Because array of cat is a subtype of array of animal, you can pass an array of cats to foo and append a dog. I believe this causes a runtime type exception, in a type-checked language without using any dangerous casts.
I kind of assume modern java has addressed this somehow, I would love to hear how.
I'm not that familiar with Java, but in C#, the only ways to avoid the penalty are either making the class of the array type sealed (so the runtime knows that you can't put any subtype into it) or using a construct like this if you work with someone else's type which you can't make sealed:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static T access<T>(T[] arr, int index) {
ref T tableRef = ref MemoryMarshal.GetArrayDataReference(arr);
return Unsafe.Add(ref tableRef, index);
}
(this doesn't bounds check either, and hard-crashes on an empty array so you need to guard it appropriately)Covariance is unfortunate choice of arrays of T where T is class and is widely considered a mistake today. When you pass Memory<T> or Span<T>, there are no covariance checks involved as they disallow it.
It is also less of an issue in .NET in general because quite often T is a struct instead, which does not have covariance in the OOP meaning of the word (old-style int[] to uint[] casts are just reinterprets, they are frowned upon luckily and few codebases use them).
[0] https://sharplab.io/#v2:EYLgtghglgdgNAFxAJwK4wD4AEBMBGAWACgs...
My memory is hazy but I think there may have been more of a cult of Java when Sun was in charge of things. They knew now to inspire a following.
Well, that's just marketing department.
> I think there may have been more of a cult of Java when Sun was in charge of things.
I wouldn't call it a "cult", just normal technology hype. Yeah, it was there in the late 90s, but since at least 2010s, Java is a boring enterprise platform without much hype.
It might have before, like, 2005 when it became the default “intro to programming” language. And it might get some now that Python has taken that job. But for a while it was the “minimum requirements: fulfilled” of programming languages. There’s a lot to be said for fulfilling minimum requirements but that doesn’t tend to inspire evangelism.
It is a perfectly fine language in as much as I saw, that must be why it was selected for the sad fate of being many overwhelmed students’ first language.
I do think they’ve gained a little credibility now that we’ve inexplicably decided Electron is a serious platform and not an April Fool’s joke.