benbjohnson / immutable

Immutable collections for Go
MIT License
713 stars 32 forks source link

List: higher level functions #37

Closed laher closed 1 year ago

laher commented 1 year ago

Some https://github.com/benbjohnson/immutable/issues/27 for Lists

.Map(), .Filter(), .Each(). Seems enough for many use cases. Each() provides the means to approximate other HOFs like Reduce - you could use a closure on a target variable.

Note that Go generics don't allow you to introduce a new generic type in method definitions (although bare functions are allowed to declare generic types), so we're limited in what we can do in these methods. So it's not straightforward to .Map() to a list of a different type, or to .Reduce() to a different type. It's easiest to just support Each() and leave it to the caller to use closures.

laher commented 1 year ago

Some open points:

  1. I don't know what to do with Maps and Sets. Should those also have equivalent HOFs? Or instead should there be a way to easily convert them to lists, and back again? e.g. func (s Set[T]) AsList() List[T], func (m Map[K,V]).AsEntries() List[Entry[K,V]] (I guess this would warrant an an Entry type). I like the conversion to list, because it means less code for each HOF. Also I think it would be beneficial to easily transform between Lists/Sets/Maps.

  2. You can't introduce a new generic type as part of a method declaration, but you can in a bare function. What do we think about a bare func which converts a list of one type to a list of another type? e.g.

func immutable.MapTo[F any, T any](from immutable.List[F], mapper func (F) T) List[T] { ... }
laher commented 1 year ago
  1. I have gone ahead and added HOFs for each type: Filter,Map,Reduce,ForEach for sets, maps, lists...

  2. I won't do anything about type transformations here. I think it's valid to have a Map function which returns the same type. If we ever want to offer HOFs with different destination types, then I think we could introduce some Transformer types, something like immutable.ListTransformer[A,B]{}.Map(myList, fn). But maybe it's something for an auxiliary package to implement (by wrapping ForEach)

benbjohnson commented 1 year ago

@laher Sorry for the delay. I'm still planning on reviewing this and it's in my TODO list. It'll probably be later this week though.

laher commented 1 year ago

Hey. I don't think I'm keen on using this library any more, so I'm closing this. You're welcome to reopen & merge the PR, but I've decided this library isn't for me. I think what I really want is something more like the Guava (Java) immutable collections rather like than like immutable.js, i.e. no 'add/delete' support is needed, and none of the internal smarts for efficient modifications. Just a thin layer to provide convenient & read-only access to maps/slices, and a way to get a copy of the data back out again. I might work on something like that instead.

Sorry for the issue with the previous PR with the varargs, I misunderstood the clone() behaviour. I also appreciate you're a busy man - I can still help with any tidyup if needed.

Cheers

benbjohnson commented 1 year ago

Thanks for your work, @laher! 🙏