Hacker News new | ask | show | jobs
by chrismorgan 1570 days ago
Hmm. Implemented on a custom type that wraps []T, so you have to create a List to get the methods, meaning more boilerplate (a common theme in Go); eager, like JavaScript’s Array methods rather than like the iterator methods in Rust or most/all functional programming languages; and since methods can’t have generics (which really surprised me in the Go generics proposal), Map() can only work on the same type (T → T, rather than T → U), and Reduce()’s output type is a generic parameter on the list, so you can only ever reduce to one type (unless you deconstruct and reconstruct the List) which must be specified at instantiation time.

As one who works mostly in Rust and JavaScript and is passingly familiar with Go (I used it for a couple of projects eight and nine years ago), these seem some pretty severe limitations.

Rust’s trait-based iterator system is delightful, so that you can map, filter, reduce, &c. on any iterator, lazily, and even define an extension trait to define your own methods on any iterator, thereafter accessible by just importing that trait.

In the end, I think the current scope of generics and interfaces won’t be enough to produce any feeling other than “shoehorned” for this functional style in Go. It’s just not a style that works well in all types of programming languages.

4 comments

I don't love libraries like this and feel like they work against the idiom in Go; I'm skeptical that things like this will be part of the idiom going forward. But Rust isn't all wine and roses with this stuff either; obviously, it's a much more powerful generics system, but closures are much more annoying to work with than they are in Go, where everything just magically escapes to the heap when you need it to.
I used to hate the closure from rust but I learned to love it. With golang its a PITA to track down performance issues die to heap escape where it is explicit in rust.
Right, go is just not designed for this kind of functional style, and it will always require a lot of boilerplate and fighting the language to try to write code like this.

I predict that production go code will continue to use for loops for this kind of thing, even once generics are widely established.

I agree, the current implementation is really not sufficient, at least for this. I played around with lazy iteration a while back and found the current restrictions would make working with it an annoyance.

I've placed some thoughts in the Readme [1] so I don't forget. Hopefully at least some of the restrictions will be dropped.

1: https://github.com/urandom/iter

After taking a stab at some more functional approach with generics in Go — https://github.com/gtramontina/go-extlib — I do agree that some of it does feel shoehorned. Although for some other constructs, it feels quite nice. As I mentioned on the readme of the linked repository, this post https://hypirion.com/musings/type-safe-http-servers-in-go-vi... presents pros and cons nicely.