Go's multiple return is in itself insane from my perspective. You cannot 'do' anything with a function that has multiple return types except assign them to a variable.
That's technically not true.
You can pass multiple return values of a function as parameters to another function if they fit the signature.
for example:
func process[T any](value T, err error) {
if err != nil {
// handle error
}
// handle value
}
this can be used in cases such as control loops, to centralize error handling for multiple separate functions, instead of writing out the error handling separately for each function. for {
process(fetchFoo(ctx))
process(fetchBar(ctx))
}
What else would you want to do with them? Maybe in rare cases you'd want to structure them into an array or something, but the inverse isn't possible either [e.g. func f(a, b, c int) -> f(<destructure array into arguments>)] so it isn't like it is inconsistent.
Perhaps what you are really trying to say is that multiple function arguments is insane full stop. You can pass in an array/tuple to the single input just the same. But pretty much every language has settled on them these days – so it would be utterly bizarre to not support them both in and out. We may not have known any better in the C days, but multiple input arguments with only one output argument is plain crazy in a modern language. You can't even write an identity function.
The saddest part is that Go's designers decided to use MRV but pretty much just as bad tuples: as far as I can tell the only thing Go uses MRV for which tuple wouldn't be better as is post-updating named return values, and you could probably just update those via the container.
Common Lisp actually does cool things (if a bit niche) things with MRVs, they're side-channels through which you can obtain additional information if you need it e.g. every common lisp rounding functions returns rounded value... and the remainder as an extra value.
So if you call
you get 2, but if you you get 2 and 1.