What's the difference between returning a two element struct and a pair of value and error?
I never understood why "multiple return values" is a thing anyone should care about.
What's the difference between returning a two element struct and a pair of value and error?
I never understood why "multiple return values" is a thing anyone should care about.
2. Without first-class support, it's very difficult to assert that the error is actually being checked. Consider:
int someVal = getSomeVal(...).v;
doSomethingWith(someVal);
vs. (int someVal, error e) = getSomeVal(...);
doSomethingWith(someVal);
Which is easier to catch at code-review time, or even at linter time?In most languages that don't support multiple return values, both problems are solvable with templates or local equivalent - see, for instance, absl::StatusOr for C++ (https://abseil.io/docs/cpp/guides/status).
one trivial possibility/option is to define in-out parameters, and just return errors:
<error-type/int/…> foo(T*, <params>)
will that not be ok ?I wonder if typeof in c23 has changed this at all. Previously there was no sense in defining an anonymous struct as a function's return type. You could do it, but those structs would not be compatible with anything. With typeof maybe that's no longer the case.
e.g. with clang 16 and gcc 13 at least this compiles with no warning and g() returns 3. But I'm not sure if this is intended by the standard or just happens to work.
struct { int a; int b; } f() {
return (typeof(f())){1,2};
}
int g() {
typeof(f()) x = f();
return x.a + x.b;
}
edit: though I suppose this just pushes the problem onto callers, since every function that does this now has a distinct return type that can only be referenced using typeof(yourfn).> In most languages that don't support multiple return values, both problems are solvable with templates or local equivalent
I don't really see the difference between tuples in C++ and multiple return values in Go (since you cite C++ as a language that doesn't have multiple return values).
val, err := do_something()
or auto [val, err] = do_something();
What's the real difference there? Syntactic sugar?For the same reason people care about multiple parameters. There's no reason that the data coming out of a function should be in any way more constrained than the data going into the function.
package hello
func good() (int, error) {
return 0, nil
}
func bad() *struct {
int
error
} {
return nil
}