I’m quite sad to see this project as it demonstrates that Go is starting to lose many of the characteristics that attracted me to it in the first place.
(For some context, I know quite a bit about functional programming and formal type theory, having studied the latter in grad school. It is intrinsically very interesting but I believe it is a net negative in most software engineering contexts.)
Exactly, the place for FP was and always will be academia.
Real programs require real, readable logic.
I'd love to be able to survey the authors of the dozen-ish variations on this posted over the last couple of years (most of the much less elaborate than this) and see how many of them are still using it in their real code. Again I'm sure the answer isn't literally zero but I bet it's statistically-significantly fewer than all of them.
For example: this entire HN thread. And all the other libraries you mention that keep soliciting conversations, nerd sniping people who could be spending that time making better products instead of quibbling over FP code golf. But maybe those folks will always find things to quibble over...
You can stop worrying about generics causing this.
Iterators may do a bit, but I still think that based on what is currently baking that people are going to find trying to do large amounts of work through iterators is not going to scratch their itch to do everything in a foreign paradigm.
If you want to work in a certain paradigm, then for pete's sake, do it. Go do it in a language where it's the best solution. Don't find the best solution in X, then try to jam it into Y at all costs. This isn't special to X = Haskell and Y = Go, it's true for all combinations of languages.
I also like using generics for API request/response code, ex: https://go.dev/play/p/OWf9eFmg1qF
With generics you don't need to return any/interface{} / type assert at runtime
func Request(req, resp any) error {
// send request (http, etc)
b, err := json.Marshal(req)
if err != nil {
return err
}
log.Printf("sent request %+v - %s", req, b)
// read response
if err := json.Unmarshal([]byte(`{"success": false, "error": "invalid login"}`), resp); err != nil {
return err
}
return nil
}
But I kind of agree it's nicer to use a return value rather than an output parameter. I'm excited to see what other new uses people come up with for generics!