effect icon indicating copy to clipboard operation
effect copied to clipboard

Reconsider naming of `T.forEach` / `T.collect` / `T.tuple`

Open schickling opened this issue 3 years ago • 5 comments

Related terms:

  • Iterable
  • Map

Problems:

  • forEach has a clear pre-existing meaning in the JS world - doesn't imply return value
  • T.collect and T.forEach a similar in behaviour but "not close" in naming
  • T.collect and T.tuple are basically doing the same but have different type-level behaviour. There is some inherent friction here (in case there's no way around having both variants, we should at the very least have jsdoc comments in all variants mentioning the others)

Goals for new naming:

  • "Close proximity" re discoverability (e.g. both starting with a similar prefix - or possibly suffix)
  • Intuitive for JS/TS developers

schickling avatar Oct 09 '22 16:10 schickling

Maybe collectEach?

mattiamanzati avatar Oct 09 '22 20:10 mattiamanzati

We could consider a more fp-ts-like naming for these combinators:

  • forEach -> traverse
  • collect -> filterMap

IMax153 avatar Oct 15 '22 18:10 IMax153

collect => filterMap I am ok with it but forEach => traverse I am not because traverse is a different function as it preserves the input structure while forEach accepts iterables

mikearnaldi avatar Dec 14 '22 12:12 mikearnaldi

also I think @schickling intended to mention collectAll and not collect, so filterMap would be a better name for collect but collectAll / tuple are still variants of the same thing, a traditional name for collectAll is sequence but as per traverse in reality sequence preserves the input type and collectAll accepts iterables.

Maybe the category grouping helps here.

mikearnaldi avatar Dec 14 '22 12:12 mikearnaldi

FWIW, I would expect an implementation of forEach to have a type sort of like this in Haskell (though note that I haven't really used it since Monad got superclasses):

Monad m => (YourStructure a, a -> m b) -> m ()

(I've tupled the argument's because curried functions are not idiomatic for TypeScript, which is also why I've placed the function after the data structure. I would have tried to write this in TypeScript but I don't know how to use your libraries ... yet. Also, maybe these days you don't use Monad for this?)

And I would expect my passed-in function to be called in an order that makes sense for the data structure in question: if it's a sequence type, sequential order; if it's a binary-search-tree like haskell's Set, then sorted order; if it's an order-preserving set, then in the preserved order, but if it's just an unordered hash-based set, I wouldn't expect any particular order.

I guess I would expect similar things from a mapping structure, but the signature wouldn't seem to match this one because you'd want to provide both the keys and the values to the callback? (Hmm, I once toyed with trying to design my own collection classes for Haskell and I believe I spent a lot of time thinking about how I might unify key/value collections with value-only collections ...)

Anyway, that's just approximately what I'd expect given my knowledge of JavaScript and Haskell, the name forEach, and my almost complete ignorance of how you encode type classes in effect.

Hope that helps a little.

SamB avatar Mar 09 '23 17:03 SamB