←back to thread

873 points belter | 1 comments | | HN request time: 0.21s | source
Show context
Terr_ ◴[] No.42946597[source]
> Java is a great language because it's boring [...] Types are assertions we make about the world

This is less of a mind-was-changed case and more just controversial, but... Checked Exceptions were a fundamentally good idea. They just needed some syntactic sugar to help redirect certain developers into less self-destructive ways of procrastinating on proper error handling.

In brief for non-Java folks: Checked Exceptions are a subset of all Exceptions. To throw them, they must be part of the function's type signature. To call that function, the caller code must make some kind of decision about what to do when that Checked Exception arrives. [0] It's basically another return type for the method, married with the conventions and flow-control features of Exceptions.

[0] Ex: Let it bubble up unimpeded, adding it to your own function signature; catch it and wrap it in your own exception with a type more appropriate to the layer of abstraction; catch it and log it; catch it and ignore it... Alas, many caught it and wrapped it in a generic RuntimeException.

replies(13): >>42946899 #>>42946979 #>>42947054 #>>42947147 #>>42947485 #>>42947568 #>>42948130 #>>42948153 #>>42948666 #>>42951688 #>>42952999 #>>42953957 #>>42984777 #
pjc50 ◴[] No.42946979[source]
It was botched from the start because there's so many opportunities for unchecked exceptions as well. Without a more sophisticated type system that represented nullability, you can get NullPointerException anywhere. Divide by zero. And so on.

You also have a problem similar to "monads and logging": if you want to log from anywhere in your program, your logging function needs to be exception-tight and deal with all the possible problems such as running out of disk space, otherwise you have to add those everywhere.

replies(3): >>42948468 #>>42950029 #>>42960202 #
corytheboyd ◴[] No.42950029[source]
> Without a more sophisticated type system that represented nullability, you can get NullPointerException anywhere.

I started working in Java a few months ago and holy shit does this stick out like a sore thumb. Null checks cascade down from gods domain all the way to hell. But oop we missed one here and caused an outage lol add one more! So much wasted human effort around NPE, and yet, we sit around in a weekly meeting getting yelled at about how stability needs to be taken more seriously. Hrm.

replies(1): >>42950584 #
pjc50 ◴[] No.42950584[source]
C# half-fixes this with its nullable annotations. I say half-fixes, because the boundary between code that supports them and code that does not is leaky, so you can make a mistake that leaks a null into a non-nullable variable.

If you build an entire program with nullability checking on it's pretty great, though.

replies(2): >>42952074 #>>42954922 #
corytheboyd ◴[] No.42952074[source]
Java, or at least Lombok, seems to have a @NonNull annotation that does what I want— cause code not to build that fails the check, and forces propagation of the annotation.

Reality does indeed feel exactly like what you mentioned with C#, though. The annotation is going to be missing where it’s needed most unless something forces the whole project to use it.

replies(1): >>42952380 #
1. mands ◴[] No.42952380[source]
check JSpecify (https://jspecify.dev) - it's the standardised null annotation package for Java. Intellij understands the annotations so you generally get decent null-checking across your codebase.

Even better, apply at the package level via `package-info.java` (unfortunately sub-packages need to be individually marked as well)

  @NullMarked
  package com.foo;

  import org.jspecify.annotations.NullMarked;