Live data from Hacker News

Excessive nil pointer checks in Go

konradreiche.com

71–80 of 116 posts

Re: Excessive nil pointer checks in Go

#72
I am very ambivalent on this post. On one hand, I agree that excessive defensiveness stinks up a code base. On the other, I am a huge fan of local reasoning. Especially in the world of LLMs, I don't want to rely on my, my teammate's or my LLM agent's ability to know every single code path that results in `Allow` begin called.

Of course, this really comes down to the type system and the fact that non-nullable pointers are missing.

The one definite thing I would say, swallowing the error and just trying to do a reasonable thing is the most wrong thing here. At the least, there ought to be an ERROR log, even if one was trying to be defensive against outright panics.

Re: Excessive nil pointer checks in Go

#73
post #9

This is the mess a language lands on when it conflates optionality (a semantic concept) with references/pointers (purely a machine concept). In Go, the requirement " need (non-optional) a reference to an object" is simply not expressible. This is a solved problem in other languages, for example `&T` vs. `Option ` in Rust.

I like using Go for many reasons, but exactly this one is making me sad every time. I can’t accept interface and be sure it’s non-nil at the same time. I think this is a flaw and it’s just a shame.

Re: Excessive nil pointer checks in Go

#75
post #49

To avoid propagating the pointer I would change *RateLimiter to RateLimiter DecodeRequest can return Request instead of *Request, or error if not valid Also I would replace `if userID == "" {` with `if err != nil {`. If an object is not loaded successfully returning error I think is more standard

Not that deep into Go, but I also wondered why passing by value is not the preference here. It’s already non-nil. I get it - copying large structs is bad, but are large structs the common case? I think not, also the GC will love the copy instead of pointer escape-analysis.

Re: Excessive nil pointer checks in Go

#76
post #45

Earlier quoted context omitted.

It's so bad that here we are in the 21st century and there are even still people who insist it wasn't a mistake e.g.: https://www.gingerbill.org/article/2026/01/02/was-it-really-...

It's quite a delusional take from Bill. Wow. Using non-nullable (a sane language default) pointers in Zig is liberating experience. And it's still as low level as in C but instead of ship-and-pray you could state your intention with a type system.

Is it? I program in C a lot, and null pointer dereferences are not really an issue in my experience. And any option type (which you could also have in C) does not really change the fundamental problem that you have some exceptional state you need to handle at some point and if this is happens at a point where this is not expected, this blows up - also in other languages. I also once believe that complex type systems are the answer, but over time I realized this is not really true.

Re: Excessive nil pointer checks in Go

#77
post #70

The design of error handling in Go is interesting because they wanted to force people to actually handle errors by returning them as values, but then you as the programmer have to decide whether an error should be returned or a panic should be used. It reminds me of the original intention of checked exceptions in Java: checked exceptions are for things you force the caller to handle, unchecked exceptions are for "you…

> NPEs in Java have become rarer and rarer recently with the introduction of records While this is true, I think it goes back farther than that. NPEs became rarer since java.util.Optional and people taking the time to use JSR 305 nullability annotations. I do this on regular basis and haven’t seen NPEs in my work for ages now. Because I’ve taken on projects with large Java codebases often written by people with poor…

Kotlins nice, mutability in the collections and nullable types are nice but they still lack some form of checked error handling. I really wish they would have taken checked errors exceptions further and made them usable.

Re: Excessive nil pointer checks in Go

#78
post #76
post #45

Earlier quoted context omitted.

It's quite a delusional take from Bill. Wow. Using non-nullable (a sane language default) pointers in Zig is liberating experience. And it's still as low level as in C but instead of ship-and-pray you could state your intention with a type system.

Is it? I program in C a lot, and null pointer dereferences are not really an issue in my experience. And any option type (which you could also have in C) does not really change the fundamental problem that you have some exceptional state you need to handle at some point and if this is happens at a point where this is not expected, this blows up - also in other languages. I also once believe that complex type systems…

Yes it is.

1) Most of pointers in real apps are non-nullable and it's nice to have enforcement from a compiler.

2) Good compilers verify you actually check nullable (optional) values have a corresponding check. In particular Zig literally forces you to unwrap value, so no unexpected state.

It's a really amazing QoL.

And no, optionality doesn't make type system any harder. Also C lacks alignment enforcement on type level and it's a real footgun which Zig also fixed. Zig has many warts but this part (optionality, alignment and slices) makes a big difference comparing to C without Rust/C++ level of type acrobatics.

> I also once believe that complex type systems are the answer, but over time I realized this is not really true.

It's suboptimal decision, you load your brain with stuff compiler should resolve for you.

Edit: ahah, just noticed your nick. Really appreciate your work on C improvements. Please ignore my yapping :) I literally know nothing comparing to you.

Re: Excessive nil pointer checks in Go

#79
post #70

The design of error handling in Go is interesting because they wanted to force people to actually handle errors by returning them as values, but then you as the programmer have to decide whether an error should be returned or a panic should be used. It reminds me of the original intention of checked exceptions in Java: checked exceptions are for things you force the caller to handle, unchecked exceptions are for "you…

> NPEs in Java have become rarer and rarer recently with the introduction of records While this is true, I think it goes back farther than that. NPEs became rarer since java.util.Optional and people taking the time to use JSR 305 nullability annotations. I do this on regular basis and haven’t seen NPEs in my work for ages now. Because I’ve taken on projects with large Java codebases often written by people with poor…

Oh yeah, I agree with you on all those points. I guess what I'm trying to say is I feel like modern Java pushes you towards writing null-safer code than something like Go. I don't see the same push in modern Go.

This blog post is a great reference for "when to actually handle the nil case in Go" (and I think these ideas can even be applied to other languages), but there's nothing pushing anyone towards doing it the correct way in Go other than a documented team coding standard or an AGENTS.md/SKILL.md file.

In older Java applications there's also nothing pushing developers towards "correct null handling." A legacy Java application has a bunch of POJOs with getters and setters where all the fields start as null. That's why I think using records+JSpecify+NullAway is incredibly powerful in a Java project. NullAway really forces you to correctly and fully null annotate your code.

Self-discipline is great but static analysis tools actually enforce doing something "the right way." Things slip through code review, but a failing pipeline has to be fixed before the merge can happen.

Re: Excessive nil pointer checks in Go

#80
post #78
post #76

Earlier quoted context omitted.

Is it? I program in C a lot, and null pointer dereferences are not really an issue in my experience. And any option type (which you could also have in C) does not really change the fundamental problem that you have some exceptional state you need to handle at some point and if this is happens at a point where this is not expected, this blows up - also in other languages. I also once believe that complex type systems…

Yes it is. 1) Most of pointers in real apps are non-nullable and it's nice to have enforcement from a compiler. 2) Good compilers verify you actually check nullable (optional) values have a corresponding check. In particular Zig literally forces you to unwrap value, so no unexpected state. It's a really amazing QoL. And no, optionality doesn't make type system any harder. Also C lacks alignment enforcement on type le…

My worries about coding all these things into type systems is that this freezes the semantics at a time during development where one is still figuring out the ideal semantics.

In any case, I wonder what you think about my experimental maybe type? https://godbolt.org/z/MTdj81841

Post reply on HN