Hacker News new | past | comments | ask | show | jobs | submit login

Honest question as a non Go user: how would generics (from a C# perspective) help? I assume that Go generics would be analogous those in C#.

Edit: spelling, genetics to generics.




Rust has a wrapper type `Result<ReturnType, ErrorType>`[0] that essentially works the same was as Go's `return value, err` idiom, but is safer because the type is defined so that you can't access the returned value unless you also handle the error condition, and it can have a convenience syntax for chaining since it is a dedicated unambiguous type. The compiler also specifically warns you about unused `Result`s, to avoid unhandled errors, and the API is structured so that nonsensical states such as `(nil, nil)` or `(value (!= nil), error (!= nil))` are impossible (unless specifically opted into).

Without generics you would have to either throw away the type information, reimplement a `Result` type for every value type, or copy/paste the implementation at each usage site (the common Go pattern).

Go's support for multiple returns itself is also a hack around the lack of support for tuples (which would be trivial to implement if you had generics).

[0]: https://doc.rust-lang.org/std/result/enum.Result.html


That reminds me of Scala's `Either` type, which I'm sure is also present in other languages (and more functional circles which I'm not familiar with at all).

I think the important part there - and the contrast with e.g. exceptions - is that an error is treated as normal, as one possible outcome of calling a method, instead of exceptional as exception-based languages seem to be. I mean yeah of course a file can not be available to open, that can be expected. (That is the simple use case of course, I'm sure there's much more complicated situations).


> a hack around the lack of support for tuples (which would be trivial to implement if you had generics)

To a first approximation, the purpose of Go is to stop every codebase from reinventing its own tuples or Result<> type.

Go does have generics, the Go compiler could add a chaining syntax for trailing err interfaces (like rust ? / try!) without needing to allow user-defined generic types.


> To a first approximation, the purpose of Go is to stop every codebase from reinventing its own tuples or Result<> type.

Rust has this too. You can throw away type information and incur a runtime cost just like with Rust by using "Trait Objects", which are Rusts version of interfaces, basically. Luckily most choose not to use this for error communication.

However I struggle to understand that throwing type information away and incurring runtime cost is the pinnacle of error communication.

Furthermore, the idea that this somehow prevents codebases from "reinventing" anything is absolute nonsense. Basically every Go lib out there has different error handling. Hell, I wrote a library of my own (similar to pkg/errors). The very items I listed in my OP showed how every lib has it. You have no idea how each Go lib reinvented the wheel to know how you handle their errors. All with runtime checking. Madness.


I hope it's not literally to prevent people reinventing these simple data structures.

The ecosystem exerts a lot of pressure on developers to not reinvent fundamental things, in Haskell I practically never reach for a StrictTuple or StrictEither even when I'd like strictness specifically because they are clunkier and less well integrated with other libraries.

Scala is the only language that comes to mind with this issue (scalaz vs Cats) and my impression is that even they have mostly converged.

I would say Go has much stronger idioms than either of these languages, and wouldn't need to be afraid of people inventing their own fundamental types provided they're included in the standard library.


> Scala is the only language that comes to mind with [the issue of needlessly reinvented fundamentals]

C/C++ is another example. There are a plethora of string types mostly tied to which base set of libraries you're using. If you're using the C++ stdlib, you have std::string. But if you're using Qt, you're using QByteArray and QString instead. And probably similar for GLib/GTK.

(Does std::string even have any encoding support yet? When I last used it, it was just a string of bytes without any encoding awareness.)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: