News for hackers. Stuff that matters.
Re:A rough proposal for sum types in Go (2018) by bborud on Monday November 15, 2021 @05:50PM (#29233981)
I disliked it initially. After 5-6 years of using Go as my primary language I’ve come to appreciate it. It is clearer than having to figure out what is returned. And if an error can be returned. It’s easier when it is right there in the function signature.
Re:A rough proposal for sum types in Go (2018) by baby on Monday November 15, 2021 @06:19PM (#29234278)
I don't think it's clearer personally, but the problem is really that it's not secure. If you forget to check the `err` (or the `nil`) then you might shoot yourself in the foot. As a pentester, most of the bugs I found in Golang codebases would have been avoided with sum types.
Re:A rough proposal for sum types in Go (2018) by monocasa on Monday November 15, 2021 @06:01PM (#29234095)
But a Result<foo*, error> is clearer than foo*, error. I think that's the point the parent is making.
Re:A rough proposal for sum types in Go (2018) by bborud on Tuesday November 16, 2021 @04:23AM (#29238552)
Yes, and the point I was making was that I don't think it actually makes things much clearer. One has more syntax and alters the effective return value, the other just states what you will get back regardless of result. From a practical point of view when you are consuming an API, which requires more concentration?
Re:A rough proposal for sum types in Go (2018) by Zababa on Tuesday November 16, 2021 @05:16AM (#29238891)
> From a practical point of view when you are consuming an API, which requires more concentration?

I think the current Go one requires more concentration, or at least more work. Lots of functions return data, err. You have to check for each of these functions if the presence of err means that data is going to be invalid/nil or add it to your code.

The same argument could be made for nil by the way. Since everything can be nil, you have to check for nil often. In languages that make a difference between a type, and a type or nil, this is easier.

Re:A rough proposal for sum types in Go (2018) by monocasa on Tuesday November 16, 2021 @11:26AM (#29242427)
The one that doesn't attempt to tell me which will be valid in relation to eachother, so I have to go divine that rather than just reading the function signature?
Re:A rough proposal for sum types in Go (2018) by kadoban on Monday November 15, 2021 @06:09PM (#29234157)
Exactly, at least it's clearer in the vast majority of cases where that's what I actually mean (but golang won't let me encode easily).

The way golang ~makes me encodes it makes using these functions annoying, because then you ~need to test for the nonsense cases where you have neither an error or a result, and maybe where you have both.

Re:A rough proposal for sum types in Go (2018) by bborud on Tuesday November 16, 2021 @02:55AM (#29238027)
But how is it clearer? I can see the point of where you get neither error nor result, but you can get that in both scenarios, so I don't see how anything is gained. And you still have the same burden of checking whether an error condition did arise. That is the bit that usually matters when you call a function: knowing if it has error conditions (many functions don't) and checking if/what they are.

I don't see any practical advantage here. Explain it to me like I'm five :)

Re:A rough proposal for sum types in Go (2018) by lmm on Tuesday November 16, 2021 @03:50AM (#29238359)
> I can see the point of where you get neither error nor result, but you can get that in both scenarios

No you can't? The whole point of a sum type is that it's definitely exactly one of a result or an error; the language will not let it be both or neither.

Re:A rough proposal for sum types in Go (2018) by bborud on Tuesday November 16, 2021 @04:15AM (#29238515)
Look at it from the receiving end: you are calling a function and you need to decide what to do with the response. The only thing that's different is that you get a single value you have to check for errors rather than a separate value. It is the same amount of code.

I can appreciate that people interested in language design think this is an important distinction, but in practice it really doesn't make a huge difference when you consume an API.

And if we move to the more general case, where a function in essence has multiple return types (albeit narrowed to a set of possible types), you still end up with something akin to a type switch. Yes, you can skip a default clause and you can have the compiler complain if you don't handle all types explicitly, but it is unclear to me if that doesn't just create new kinds of annoyances.

(I deal a lot with sum types in Protobuffers and it isn't always as nice as I had hoped. In fact, I use them for entirely different reasons than correctness and clarity)

Re:A rough proposal for sum types in Go (2018) by wlamartin on Tuesday November 16, 2021 @04:40AM (#29238664)
> The only thing that's different is that you get a single value you have to check for errors rather than a separate value..

The type system confines you to a set of reasonable cases that allow a caller to reason about the state of the program. This has two benefits for the caller:

1. It is required that the caller check whether a return value is success or failure in order to access the value they want. There is no possibility to mistake one case for another.

2. In the space of valid return values for idiomatic Go function signatures, 50% of them are unidiomatic and end up being ignored. It is far clearer for a caller to understand what is expected of them when valid values exactly overlap with the space. It is far clearer for an author to convey expectations to a caller for the same reason.

Now I must admit, good conventions and tooling in Go account for the vast majority of cases and I don't personally mind that much, but that's a different conversation than API design.

Re:A rough proposal for sum types in Go (2018) by lmm on Tuesday November 16, 2021 @07:58PM (#29248259)
I'm coming at it solely on the basis of practical experience. Removing a single boilerplate check might seem insignificant, but it compounds: when these types are lightweight to work with you can extract more tiny helper functions, and then you have a whole vocabulary of common operations / ways of doing composition, and you can write these really readable functions that just get all the plumbing out the way (but without making it completely invisible) and let you focus on the business logic.
Re:A rough proposal for sum types in Go (2018) by Zababa on Tuesday November 16, 2021 @05:07AM (#29238850)
The thing sum types would allow is to make a clear distinction between functions that return either a result or an error and functions that can return both a result and an error. Many functions in Go will always return either res, nil or nil, err. Those functions would benefit from a way to show that in the signature, to differentiate them from the functions that can return res, err at the same time. This is not a replacement for multiple return values, as there are many cases where multiple return value are useful.
Re:A rough proposal for sum types in Go (2018) by BobbyJo on Monday November 15, 2021 @08:24PM (#29235456)
I can't count the number of times this has forced me to make a better interface/abstraction that the one I was making. It's too bad this idiom is going to be the 'wrong way' to do things soon, because, for some reason, every code Guru out there thinks number of characters/lines is the single defining cost function for software maintenance, and that's who the kids coming out of college are going to listen to.
Re:A rough proposal for sum types in Go (2018) by kadoban on Monday November 15, 2021 @10:37PM (#29236489)
It's just fundamentally the wrong type for what it's supposed to represent. What I'd prefer isn't any more concise in lines or characters, it simply actually represents what it's supposed to.

"a*, error" has 4 different members, if you consider just "exists" vs "doesn't exist" for each. Of those, "nil, nil" and "&a{}, errors.New("whatever")" are broken. Fully half of the things you can represent are just wrong.

(Yes there are times when those are valid returns, but easily 99% of the time they're not. The type system should be able to represent both ways.)

Re:A rough proposal for sum types in Go (2018) by BobbyJo on Tuesday November 16, 2021 @11:44AM (#29242719)
> The type system should be able to represent both ways.

Go's type system can already do that, the (x, error) idiom is just standard practice in the absence of Generics and Throwables. Adding generics simply flips the default and exception.

Currently, the exception is to define a custom type which captures and constrains your possible return states, and the default is to return a value plus an error. When that flips, and the default is to collapse error states into a single return value, that will cease to give me the same signals (or at least make them less obvious) as to whether or not my abstraction sucks, which I will sorely miss :P

Re:A rough proposal for sum types in Go (2018) by kadoban on Tuesday November 16, 2021 @06:53PM (#29247793)
How does go's type system allow the "exactly one of these two" case? What's the syntax?
Re:A rough proposal for sum types in Go (2018) by BobbyJo on Thursday November 18, 2021 @10:20PM (#29273421)
I'm not sure what you're asking. I was pointing out that if you need to enforce a return result that will have either a value or an error, you can simple write a struct/interface that does that.

Like, you can create an interface that's read only for the return result like:

interface ReadableResult { HasResult() bool Result() whatever Error() error }

Then to create the result you have a writable interface for setting values, and enforce the 'only one of the two' semantics from the setters:

interface WritableResult { SetResult(whatever) SetError(error) }

Struct MyResult{ err error result whatever }

.... Implementation here.

It's extra code, but it should be a rare necessity, at least in my experience. Res, err := getResult() always worked fine for me.

Re:A rough proposal for sum types in Go (2018) by bborud on Tuesday November 16, 2021 @03:04AM (#29238090)
How can you know that half the things I can represent are wrong? There are many situations where both returning a value and not returning a value are both valid. And where errors conditions may not dictate what the returned value should be.

Language design choices have to make sense. And this doesn't make practical sense to me since I've written code, just in the past 24 hours, that contradicts your assertion. And no, I don't think the code would be better if we robbed Go of expressive power - adding complexity elsewhere is just moving the problem if poor discipline around.

Re:A rough proposal for sum types in Go (2018) by lmm on Tuesday November 16, 2021 @03:54AM (#29238382)
> How can you know that half the things I can represent are wrong? There are many situations where both returning a value and not returning a value are both valid. And where errors conditions may not dictate what the returned value should be.

In cases where it's valid, you use a type that makes it valid. Much of the point of having a type system is that the return type tells you exactly what the valid things for the function to return are.

Having an explicit declaration of which functions might return both a result and an error and which functions will definitely return one or the other but not both makes your code easier to understand and work with. As it stands, I would bet that most Go programmers ignore the possibility of returning both a result and an error even in functions that do it deliberately, because the idiomatic thing a function with that signature does is return one or the other but not both.

Re:A rough proposal for sum types in Go (2018) by Huggernaut on Tuesday November 16, 2021 @04:12AM (#29238495)
I agree. I would be extremely surprised and look for refactoring opportunities if I came across a function that returned a success case that was expected to be used in combination with an error value.

If anyone has an example of this being a pattern used somewhere that they think is good I'd love for them to share it.

Re:A rough proposal for sum types in Go (2018) by kadoban on Tuesday November 16, 2021 @08:12AM (#29240114)
The only case I can think of is partial success.

Probably bad example off the top of my head: You're returning say a "User" which has a user_id, name, and a list of recent purchases.

If the function errors out on the recent purchases, the caller may prefer that it still gets back a "User" object with the other information filled in, and then an "error" also set so the caller knows the information isn't complete.

Re:A rough proposal for sum types in Go (2018) by xh-dude on Tuesday November 16, 2021 @05:42PM (#29247229)
A reduced version of this is maybe where Go and Rust have a pretty similar contract for things that “Read” and lean hard into permitting partial success. Both allow for some relatively sharp edge cases with zero-sized reads.

The contract is always right … how well it is expressed through language mechanics is maybe another way to contrast things here. (FWIW I think Go could tighten up a few things - dropping or shadowing errors is a bit worrying - but I’m fairly convinced sum vs product is a little too harsh of a reduction; a useful distinction but not a complete one.)

Re:A rough proposal for sum types in Go (2018) by kadoban on Tuesday November 16, 2021 @07:57AM (#29239967)
> How can you know that half the things I can represent are wrong? There are many situations where both returning a value and not returning a value are both valid. And where errors conditions may not dictate what the returned value should be.

That's why I wrote: Yes there are times when those are valid returns, but easily 99% of the time they're not. The type system should be able to represent both ways.

The golang type system can _already_ encode the case you're talking about, and that should stay. My complaint is that is the _only_ case it can represent, it cannot represent the more common case.

Re:A rough proposal for sum types in Go (2018) by OceanSpray on Tuesday November 16, 2021 @03:46AM (#29238341)
Are you implying that sum types wouldn't be expressed in a function signature?
Re:A rough proposal for sum types in Go (2018) by bborud on Tuesday November 16, 2021 @04:18AM (#29238530)
No, I'm pointing out that some functions don't return errors.