Prior to v5, the mergeMap operator was named flatMap, which is a term coined from functional programming in general. While v5 was being developed there was a lot of discussion and in the end it was thought by a majority of the people involved that renaming it to mergeMap would help newcomers better grasp what it does, as well as align with the names of the other merge operators.
Now that's been a couple years with mergeMap, and rxjs's popularity has continued to explode, IMO mergeMap hasn't been as helpful as predicted, and I think we underestimated how many people have prior knowledge of the term flatMap, and prefer it over mergeMap. This may also change drastically if JavaScript gets Array.prototype.flatMap as proposed. Additional facts: .NET calls it SelectMany but all other Rx implementations I can find use flatMap
@staltz has a great summary below of why it was felt flatMap was too ambiguous in the context of Rx: https://github.com/ReactiveX/rxjs/issues/3006#issuecomment-339787756.
I'd like to open discussions on the _possibility_ of renaming mergeMap back to flatMap for v6. To be 100% clear, I have no official sway in the decision, except that I might bribe some of the core team members. ๐.
Civil arguments for or against are of course welcome, but please don't comment with +1 or thumbs up ๐ Use the github "reactions" on this post below
I miss flatMap. I understand it clearly and get confused about mergeMap all the time.
๐ because functional programming's flatMap is ambiguous in RxJS, it has these options: switchMap, mergeMap, concatMap, exhaustMap are all "flatMap".
In fact, Array.prototype.flatMap is much more like Rx concatMap than it is like mergeMap.
I've been teaching these operators in workshops and students really appreciate the consistency
mergeAll โ mergeMapconcatAll โ concatMapswitch โ switchMap@staltz FWIW I completely agree with your "ambiguous" argument.
How about renaming it to flatMap, making mergeMap the alias, and then switching the names around again for v7?
Edit: :stuck_out_tongue_winking_eye:
Aren't there more important things to work on?
FWIW I completely agree with your "ambiguous" argument.
Alright, me too.
There is something to be said for having a dedicated definition on the main ReactiveX site. In short, it seems beneficial for languages to make a best effort attempt to speak a "canonical" Rx language, and then dabble in language specific extensions. On a related note, check out the note about the bold "core" operators here.
More seriously, why not have two operators?
@benlesh commented on Twitter:
I think if we do
flatMap, we'll want to remove the secondary selector and provide a (yuck)thisArg, so it matches the Array proposal.
If mirroring Array.prototype.flatMap is desirable, then do so.
But why not keep mergeMap with its projection function, etc. so that it parallels concatMap and switchMap? Or would they, too, have their signatures changed?
Both names have their own advantages. Does it really incur much cognitive or maintenance overhead if both are kept?
I've seen enough confusions by having variant of operater in api aurface. While I don't have opinion on this issue itself, I am objecting having two both.
@cartant Then why not 3, or 10
Let's keep it simple shall we. My 2c on the matter is as follows:
Ever since learning RxJS last year, I have always preferred the name flatMap since it's always seemed more logical to me: it flattens a chain. If contrasted with .map, which can create unfortunate observable stacks if you accidentally returns an observable inside .map.
.flatMap flattens that stack... simple right. ๐
So I wouldn't shed any tears over mergeMap going away, but I wouldn't really mind it staying either. I think neither of them does anything towards learning RxJS. RxJS can be complicated, and its better to learn by doing. Thats how I learnt most of the operators.
@larssn
Then why not 3, or 10?
Because there are only two names under consideration and both have compelling justifications. There is no compelling justification for, say, splatMap.
I'm fine with either name. What I'm against are API inconsistencies.
As it stands, the API is inconsistent with some other Rx implementations. And that's a reasonable argument for changing to flatMap.
But changing the name to flatMap will introduce other inconsistencies:
Array.protoype have signatures that match those of the Array methods. If only the name is changed, RxJS will then have some Array methods with matching signatures and some without.flatMap will then have a signature that's significantly different to concatMap (with is nothing more than a call to mergeMap with a maximum concurrency of one) and switchMap. Should those methods be stripped of their result selector and be given a thisArg?Given that an effort to re-work the documentation has started, could improvements in the documentation address this issue? After all, flatMap is already in RxJS as an alias - hence my initial, facetious comment - see here and here. At the moment, the documentation is generated from the ESDoc, so there is no mention of flatMap. Maybe this would be less of an issue if it was included in the listing and described as an alias of mergeMap?
Anyway, here's a non-definitive list of options:
flatMap, resulting in a signature that won't match that of the Array.prototype.flatMap proposal. Even though considerable care has been taken to align RxJS's signatures with those of Array.prototype when methods have the same name.flatMap and match the Array.prototype.flatMap proposal's signature. And lose the result selector and maximum concurrecy parameter.flatMap and sort of match the Array.prototype.flatMap signature, but stick more parameters on the end.flatMap as an alias for mergeMap, but document it so that it's included in listings of operators, etc. And consider adding file-level aliases, so that flatMap can be imported.flatMap operator that matches the signature of the Array.prototype.flatMap proposal and implement it as a wrapper around mergeMap.Personally, I'd go for number 5.
PS. Bike shedding is a term I've heard used before, but I've only recently looked up it's origin and meaning. Now, whenever I hear the term, I will think of this issue.
In fact, Array.prototype.flatMap is much more like Rx concatMap than it is like mergeMap.
This is mostly by virtue of the fact that the Array is processed synchronously.
.... But I also agree with @staltz's "ambiguous" statement. flatMap could be anything that maps and flattens: concatMap, mergeMap, exhaustMap, switchMap, etc.
cc @mattpodwysocki ... I know that IxJS has added "flatMap"... but I'm wondering if you've thought about this as well. Are we doing a service to anyone by providing something with the same name as Array.prototype.flatMap (proposal), that doesn't necessarily do the same thing?
I like the current nomenclature the most
If we were to change the API, then this is my proposal:
I still vote for keeping the current nomenclature, but that was a good comment from @phaux. flatMapOldest is much better than exhaustMap, for instance.
I think we can just keep it as is. I just wanted to kick this out there.
@phaux's suggestion isn't too bad... but I think ti would just confuse the crap out of people at this point. Also the arrival of Array's flatMap might make matters more confusing still.
I think we can probably close one.
(I'll of course reopen if there are serious objections!)
I have a serious objection :trollface:
@benlesh trolling aside, can you clarify something for me. Not clear what the outcome is from your comment. Keeping it as is implies keeping mergeMap as the default but having flatMap as an alias. (i assume this is what you intended) But then you mention that Array.prototype.flatMap is going to make things more confusing (yup) and that you think we can probably "close one". Not sure what close means in this context, did you mean choose?
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
๐ because functional programming's
flatMapis ambiguous in RxJS, it has these options:switchMap,mergeMap,concatMap,exhaustMapare all "flatMap".In fact, Array.prototype.flatMap is much more like Rx
concatMapthan it is likemergeMap.I've been teaching these operators in workshops and students really appreciate the consistency
mergeAllโmergeMapconcatAllโconcatMapswitchโswitchMap