Live data from Hacker News

NilAway: Practical nil panic detection for Go

uber.com

91–100 of 262 posts

Re: NilAway: Practical nil panic detection for Go

#92
post #84
post #82

Earlier quoted context omitted.

That's what the `func foo() (*T, error)` pattern is for. It's actually better than syntactic sugar for optional values because now you also have a descriptive reason for why the value is nil. But if you really cannot afford to return more than one bit of information, do `func foo() (*T, bool)`.

> a descriptive reason for why the value is nil. Result does this. I forget exactly why Result is actually different from, and in fact superior to, `func foo() (*T, error)` but IIRC it has to do with function composition and concrete vs generic types.

Don’t rely on half remembering how specific languages implement things, try and internalise the fundamentals. Go functions tend to return a tuple which is a product type, while rust’s result type is sum type. Product types contain. Both things (a result and an error) while a sum type contains a result or an error.

Re: NilAway: Practical nil panic detection for Go

#93
post #78

It amazes me that in 2023 this is not a solved problem by design of the language. Why go doesn’t adapt the “optional” notion of other languages so that if you have a variable you either know it is not null or know that you must check for nullness. The technology exists

There's much I don't love about Rust, but I feel golang could steal the ? operator and keep the spirit of go.

Effectively,

instead of

    result, err := doSomething()
    if err != nil {
        return nil, err
    } 
you'd get the same control flow with

    result := doSomething()?

Re: NilAway: Practical nil panic detection for Go

#94
post #84
post #82

Earlier quoted context omitted.

That's what the `func foo() (*T, error)` pattern is for. It's actually better than syntactic sugar for optional values because now you also have a descriptive reason for why the value is nil. But if you really cannot afford to return more than one bit of information, do `func foo() (*T, bool)`.

> a descriptive reason for why the value is nil. Result does this. I forget exactly why Result is actually different from, and in fact superior to, `func foo() (*T, error)` but IIRC it has to do with function composition and concrete vs generic types.

Result is in one of two states: It either has value of type T, or error of type E.

(*T, error) is either T (non-nil, nil), or error (nil/undefined, non-nil), or both (non-nil, non-nil), or neither (nil, nil). By convention usually only the first two are used, but 1) not always, 2) if you rely on convention why even have type system, I have conventions in Python.

Leaving aside pattern matching and all other things which make Rust way more ergonomic and harder to misuse, Go simply lacks a proper sum type that can express exactly one of two options and won't let you use it wrong. Errors should have been done this way from the start, all the theory was known and many practical implementations existed.

Re: NilAway: Practical nil panic detection for Go

#95

Earlier quoted context omitted.

Dart has a great write up on how they fixed the null problem by adding non-nullable types: https://dart.dev/null-safety/understanding-null-safety

Several language have "fixed the null problem" after the fact, though usually as an opt-in e.g. typescript, C#. The problem with Go (for this specific issue, there are lots of problems with Go) is that they have wedded themselves extremely strongly to zero-defaulting, it's absolutely ubiquitous and considered a virtue. But without null you can't 0-init a pointer, so it's incompatible with null-safety. I think C# pret…

This is a good point. Null pointers are the billion-dollar mistake, but the real billion-dollar mistake is having "zero values" in your language. In addition to the problems with null pointers, zero values make loose constructor semantics like C# and Java tempting, where objects can exist in a not-fully-initialized state, leading to lots of room for confusing bugs. Without zero values to fall back on as a crutch, the language design is forced to tighten that up so that objects are either completely initialized or completely uninitialized, like in ML or Rust†, which is a much cleaner semantics. (The funny thing is, Go has the tools to get rid of zero values by virtue of not having constructors, but it chose not to use them for that!)

† Strictly speaking, objects can be partially initialized and partially uninitialized in Rust, but this is harmless as the borrow checker statically ensures that uninitialized fields of objects are never accessed.

Re: NilAway: Practical nil panic detection for Go

#97

Earlier quoted context omitted.

Several language have "fixed the null problem" after the fact, though usually as an opt-in e.g. typescript, C#. The problem with Go (for this specific issue, there are lots of problems with Go) is that they have wedded themselves extremely strongly to zero-defaulting, it's absolutely ubiquitous and considered a virtue. But without null you can't 0-init a pointer, so it's incompatible with null-safety. I think C# pret…

This is a good point. Null pointers are the billion-dollar mistake, but the real billion-dollar mistake is having "zero values" in your language. In addition to the problems with null pointers, zero values make loose constructor semantics like C# and Java tempting, where objects can exist in a not-fully-initialized state, leading to lots of room for confusing bugs. Without zero values to fall back on as a crutch, the…

Yeah technically you can always default init fields to None, but then you have to type everything as an Option and the ergonomics are so bad you're really incentivised not to do that. In that case you bundle that in a transient structure (a builder) and you get rid of it afterwards.

Re: NilAway: Practical nil panic detection for Go

#98
post #84
post #82

Earlier quoted context omitted.

That's what the `func foo() (*T, error)` pattern is for. It's actually better than syntactic sugar for optional values because now you also have a descriptive reason for why the value is nil. But if you really cannot afford to return more than one bit of information, do `func foo() (*T, bool)`.

> a descriptive reason for why the value is nil. Result does this. I forget exactly why Result is actually different from, and in fact superior to, `func foo() (*T, error)` but IIRC it has to do with function composition and concrete vs generic types.

As others have mentioned, Result is a sum type so you either have a T or an E, there's no situation in which you can get both or neither.

The second part is that it's reified as a single value, so it works just fine as a normal value e.g. you can map a value to a result, or put results in a map, etc... , language doesn't really care.

And then you can build fun utilities around it e.g. a transformer from Iterator> to Result, E> (iterates and collects values until it encounters an error, in which case it aborts and immediately returns said error).

Re: NilAway: Practical nil panic detection for Go

#99
post #78

It amazes me that in 2023 this is not a solved problem by design of the language. Why go doesn’t adapt the “optional” notion of other languages so that if you have a variable you either know it is not null or know that you must check for nullness. The technology exists

It's because it's golang and that's how they oninonatedly want it. (Seriously, the community is incredibly stubborn and controlling)

Re: NilAway: Practical nil panic detection for Go

#100
post #78

It amazes me that in 2023 this is not a solved problem by design of the language. Why go doesn’t adapt the “optional” notion of other languages so that if you have a variable you either know it is not null or know that you must check for nullness. The technology exists

There are several language design problems solved in the 20th century that Go designers decided to ignore, because they require PhD level skills to master, apparently.

Hence why the language is full of gotchas like these.

Had it not been for Docker and Kubernetes success, and most likely it wouldn't have gotten thus far.

Post reply on HN