5 ms·
It’s still missing null safety, right? Which means it’s still a hard no for me.
by gentlewater 16d ago
It’s still missing null safety, right? Which means it’s still a hard no for me.
- marginalia_nu 16d agoHave you tried not returning null or constructing incomplete objects?
- gentlewater 16d agoCan I trust code I’ve written myself with no guarantees from the language? Maybe. Can I trust code written by dozens of other developers (and/or agents) working on the same project over multiple years? Definitely not.
- marginalia_nu 16d agoWhy don't you have any coding standards? If you're working with agents in particular, catching and enforcing this stuff should be easier than ever.
- saghm 16d agoMost engineers do not have the ability to impose rules by fiat on all of their coworkers. It seems like you're misunderstanding the nature of working on a codebase as an IC when other developers contribute to it. If all of my coworkers don't want a lint rule I propose, I don't get to add it. If all of my other coworkers want to write code in a certain way and approve each other's MRs with code written in that way, I don't get to veto it.
- ndriscoll 16d agoMost engineers don't get to decide to use a language either. Usually someone with the clout to pick a language has the clout to set style requirements too.
- saghm 16d agoI don't disagree, but that sounds more like a response to the person asking "what's the argument for picking Java?" than one to the someone who finds "Have you tried not returning null or constructing incomplete objects?" and "Why don't you have any coding standards?" to be poor takes.
- ndriscoll 16d agoIf someone's asking "why Java" or is saying nulls make it a hard no, then you'd assume that they have a choice in the first place, which generally means they also have some ability to set coding standards at the same time that they're choosing a language. Scala technically allows you to use nulls or throw exceptions pretty much wherever (necessary for Java compatibility), but it's not an issue because people simply don't outside of super niche situations (generally some low-level thing, or a shim). Similar to `unsafe` in Rust. Or casts in all sorts of languages.
- saghm 16d ago> If someone's asking "why Java" or is saying nulls make it a hard no, then you'd assume that they have a choice in the first place, which generally means they also have some ability to set coding standards at the same time that they're choosing a language. I don't understand that logic. I sometimes ask people to explain why they think a certain policy should be implemented by the government after they state their support for it, but I don't have the ability to set government policy. I have trouble imagining you genuinely assume that any time someone asks you why something should be the way you say that you think they have the ability to change it if you convince them.
- ndriscoll 16d agoOf course you assume that; if you're talking about what a policy should be, then you work in a hypothetical world where the policy can be chosen. You don't say "but what about some other minor detail! That would require an additional policy choice, and we can't change related policies." Like if I think my business should open an hour earlier, and you say "but the employees won't be there yet so who will open the doors!" obviously the solution is to also change the work schedule. When you have closely related policies, generally the same person/people are empowered to make both changes.
- mahboi 16d agoEveryone has to deal with other code that might not even be from the same org. The "check it in CI" answer isn't an excuse either. You're bolting on so much extra crap that way. I just don't see why nullability is a problem in the first place.
- gjadi 16d agoNull Analysis can be checked and enforced by the CI.
- mahboi 16d agoCan you explain what the issue is with nullability here? Is the concern that someone's code returns null in normal circumstances but doesn't document that well, so you don't check if null? Cause if it's an error situation, one way or another some exception has to be thrown.
- saghm 16d agoDo you never use external libraries?
- what_hn 16d agoWith agents, we're getting there.
- saghm 16d agoI admit I haven't worked in Java for years, but no project I've seen at my current company (the only one I've worked at since agents have been a useful thing) is anywhere close to removing all dependencies. From what I've seen, people want to spend tokens on new things, not things that are already known to exist. Even if you can reinvent the wheel, it's not something that an employer is going to be particularly happy to subsidize.
- marginalia_nu 16d agoI don't think I've encountered an external library that returned partially constructed objects returned nulls (at least not without a @Nullable). There are probably cases of this existing, but those types of libraries don't tend to see a lot of users.
- mrkeen 16d agoThe standard library writers can go first.
- LelouBil 16d agoYou can either use Kotlin then, or simply use java and nullability annotations, they have good support in both IDEs and analysis tools
- gentlewater 16d agoI use Kotlin as my main language and I’m very satisfied with it.
- well_ackshually 16d agoAny serious project will be using NullAway and annotating everything (or, indeed, using Kotlin). Otherwise, yeah, you're still in for a world of pain.
- winrid 16d agoI have a couple 50k+ loc java projects written entirely by LLMs at this point that have never thrown an NPE.
- what_hn 16d agoSame here with go, then Again go doesn't throw!
- xdavidliu 16d agosurely 'throw a npe' means something very similar to something that Go does
- mahboi 16d agoIt's a panic in Go, not an exception. In practice that's usually a whole process crash. You can catch panics and kinda use them like exceptions, but it's not conventional.
- samus 15d agoSo the whole webserver dies instead of just a worker thread unwinding its stack?
- mahboi 15d agoOh, net/http recovers from a panic inside a handler and sends error 500. I don't know if that was always the default. Where I worked before, our own Go servers didn't recover, and it did cause outages. This is kinda bad practice. Go and Rust panics are similar, they aren't exceptions that you can safely recover from. Say there's a panic in the middle of modifying some global state like a database connection. Hence complaints about the net/http recover like https://github.com/golang/go/issues/25245 https://github.com/golang/go/issues/25245 . But I guess they decided it's worse to let servers crash from trivial mistakes.
- wavemode 16d agoNullability annotations + tooling makes this a non-issue in practice.
- misiek08 16d agoI’m not sure how long it will take, but please - can we stop saying that annotations like @IHopeThisWontBeNull is a toy for kids and, having so many years of incidents caused by those and having LLMs to write and fix the code, we can rely on language and compiler already?
- wavemode 16d agoYou're drawing a distinction that doesn't matter in practice. If you encounter a NullPointerException incident then you either didn't annotate your code or you didn't run the tooling. (In fact before even running your CI suite, any serious IDE will tell you immediately that you've mishandled null somewhere.) I get that some people feel like it ought to be built-in to the language rather than a separate tool... but people's personal feelings are irrelevant to the lived experience of my day-to-day work, where worrying about null is truly a thing of the past.
- msgilligan 16d agoThe ecosystem has (at long last) standardized on JSpecify (https://jspecify.dev https://jspecify.dev) for nullability annotations. JSpecify allows you to annotate a package or module with `@NullMarked` and your IDE and build (via ErrorProne+NullAway, typically) will check for null safety. If you develop a library in Java and use it from Kotlin, the built-in Kotlin null-safety will recognize the JSpecify annotations on the library. Null-restricted types are on the roadmap. See: https://openjdk.org/jeps/8303099 https://openjdk.org/jeps/8303099
- ivan_gammel 16d agoIt is really not a big deal nowadays, the problem of the same scale as having index out of bounds error (no language has good defence against this, yet it is not a catastrophe).
- pmontra 16d agoThat's expected (the index out of bound). You have an array, and maybe it grows, you read a number from input, you don't check it against the size of the array because you want to torture the language, use it to get the element at that index and... I'm sure that there is a surprisingly number of different designs of what it should happen and a number of designed ways to ensure that it doesn't happen. But a runtime error is expected.
- ivan_gammel 16d agoyes, so are the NPEs - both are runtime errors indicating a bug in the code. NPE was a major source of irritation 20 years ago, but what many people do not know is that debugging NPEs in Java is easier now - they carry more information about the source. And the culture has evolved.
- cesarb 16d ago> but what many people do not know is that debugging NPEs in Java is easier now - they carry more information about the source Unfortunately, no, they don't. Not after your application has been running for a while; newer JVMs arbitrarily decide you don't need the stack trace anymore, and all you see in your logs is "NullPointerException" (unless you still have the logs from several weeks ago, just after the last JVM restart, which might still have the full stack trace). Older JVMs were better, since they always had the full stack trace; debugging NPEs was easier with them.
- gf000 15d agoI think parent was referring to this: https://www.baeldung.com/java-14-nullpointerexception https://www.baeldung.com/java-14-nullpointerexception
- PaulHoule 16d agoReally? Unlike C it is trivial to catch a NullPointerException and confine the crash to the unit of work. And unlike C you are not talking about insanely dangerous pointers, you're just talking about an NPE. I'll admit it's a hassle when something wasn't initialized properly and then you get a null pointer exception at some unrelated code much later. It's not always easy to debug. Catastrophic? No! There are a lot of third party tools that can check for null safety and a lot of work is being done to make Java's initialization safer but also a little more flexible, there is https://openjdk.org/jeps/8303099 https://openjdk.org/jeps/8303099 and there are all sorts of practical answers. Nulls in Java are low on my list of annoyances, way behind front end programmers who pepper my CSS files with "!important" because they don't know about precedence (though maybe they think my .clazz.clazz.clazz selector is brain dead!)
- munksbeer 16d agoWe have a java monorepo of relatively large size and sophistication, driving our entire fintech, and I haven't seen a NPE for years. Use NullAway and it basically makes the problem go away. Our application won't build if it detects a potential NPE.
- unscaled 16d agoCongratulations. You've added another build tool and sprinkled your code with ugly annotations and ifs and Optional Optional.of(x).map(y) all over the place to get the same thing you'd get by moving to Kotlin. I get it why this seems like a less drastic change, but this saddens me. Kotlin solves more issues with the type system (smart casts, reified types, immutability by default), without sacrificing readability. Unless I can see a solution in Java that makes dealing with NPEs as easier for lazy developers as ignoring them, I don't consider it a solved issue.
- smrtinsert 15d agoMore Java strawman arguments. How do we live with BuilderFactoryFactoryBuilders! Every day we cry ourselves to sleep!
- munksbeer 16d agoI don't really think about it too much, it works fine. We don't use Optionals, I'm not sure why you brought that up. I'm not a dogmatic person in this respect, rather pragmatic. I'm sure Kotlin is great, and I'd enjoy writing it, but for now, the vast majority of the finance world runs on Java, so it's what we use. I find it easy to work with, which counts for a lot.
- samus 15d ago> Congratulations. You've added another build tool and sprinkled your code with ugly annotations and ifs and Optional Optional.of(x).map(y) all over the place to get the same thing you'd get by moving to Kotlin. You deserve the strawman award of the year. NullAway and JSpecify encourage making as many types non-nullable as possible, thus they can actually also advice about removing redundant null checks. Nullable types become the painful exception that visibly spreads through the codebase, which discourages writing code that relies on null. Optional doesn't enter the picture at all. NullAway kills their usecase within ones own code. They are anyway only recommend as return types to force others to check for an emoty case, but I think Optional will become fully optional when the Java platform gets nullable types on its own. Google Error Prone is a code linting tool that's very useful in its own right, and NullAway is just another plugin.