5 ms·
From the Elixir's developer perspective, this is insane. The issue is solved in Erlang / Elixir by functions commonly returning {:ok, result} or {:error, descri
by d3ckard 1y ago
From the Elixir's developer perspective, this is insane. The issue is solved in Erlang / Elixir by functions commonly returning {:ok, result} or {:error, description_or_struct} tuples. This, together with Elixir's `with` statement allows to group error handling at the bottom, which makes for much nicer readability.
Go could just add an equivalent of `with` clause, which would basically continue with functions as long as error is nil and have an error handling clause at the bottom.
- throwawa14223 1y agoGo'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.
- masklinn 1y agoThe 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 (let ((v (round 5 2))) (format t "~D" v)) you get 2, but if you (multiple-value-bind (q r) (round 5 2) (format t "~D ~D" q r)) you get 2 and 1.
- bravesoul2 1y agoYou can at least in Go do this: r, err := f() r := f() _, err := f()
- masklinn 1y agoNo, you can not do the second one. The other two are completely routine and will work just fine with lists in JS or tuples in Python or Rust (barring a few syntactic alterations).
- 9rx 1y agoWhat 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.
- throwawaymaths 1y agohave a single return value and if you really need MRV, return as a tuple type, which you could destructure. (this is what zig does)
- 9rx 1y agoBut then why accept multiple input arguments? Why not limit to a single argument, accepting a tuple where multiple arguments are necessary, for input too? Where multiple input arguments are present, not having multiple output arguments is just strange.
- throwawaymaths 1y agoExactly. Why not make multiple argument function call syntatic sugar over a ~single argument tuple call? https://ziglang.org/documentation/0.14.1/#call https://ziglang.org/documentation/0.14.1/#call
- 9rx 1y agoWhat would you need syntax sugar for? If you are going to support multiple arguments you may as well do it properly or don't do it at all. A poor bandaid because you fucked up tuples is not a quality that is to strive for.
- knutzui 1y agoThat'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)) }
- prerok 1y agoWell, if fetchBar requires fetchFoo to complete successfully, you still somehow have to handle it. That said, there are libraries out there that implement Result as generic type and it's fine working with them, as well. I don't see what the hubbub is all about.
- deleted 1y ago[deleted]
- tyre 1y agoFrom all available evidence, there is no chance in hell Go could adopt a `with` statement. Go is fascinating in how long it holds out on some of the most basic, obviously valuable constructs (generics, error handling, package management) because The Community cannot agree. - Generics took 13 years from the open source release. - 16 years in there isn’t error handling. - Package management took about 9 years. There’s value to deliberation and there’s value to shipping. My guess is that the people writing 900 GH comments would still write Go and be better off by the language having something vs. kicking the can down the road.
- MeetingsBrowser 1y ago> My guess is that the people writing 900 GH comments would still write Go and be better off by the language having something vs. kicking the can down the road. My guess is they will still write Go even if error handling stays the same forever.
- Ferret7446 1y agoWe already have languages that ship features. Go is a lone lighthouse of stability in a sea of fancy languages. I'll play with your fancy languages, but I build my own projects that I actually use in Go because I can trust that it will keep working for a long time and if/when I need to go back to it to fix something in a couple of years I don't need to re-learn a bunch of crap that might have seeped through dependencies or the stdlib.
- juped 1y agoHaskellers and Rust fans think they own sum types, and people read their comments and blog posts and believe them, and decide they don't want sum types because they don't want to go down the horrifying Hindley-Milner rabbit hole. But meanwhile it's just perfectly idiomatic Erlang and Elixir, none of that baggage required. (In fact, the sum types are vastly more powerful than in the ML lineage - they're open.)