{"action":"created","issue":{"url":"https://api.github.com/repos/ReactiveX/RxJS/issues/167","labels_url":"https://api.github.com/repos/ReactiveX/RxJS/issues/167/labels{/name}","comments_url":"https://api.github.com/repos/ReactiveX/RxJS/issues/167/comments","events_url":"https://api.github.com/repos/ReactiveX/RxJS/issues/167/events","html_url":"https://github.com/ReactiveX/RxJS/issues/167","id":100899612,"number":167,"title":"Bike-Shedding: renaming `flatMap`, `flatMapLatest` for consistency and ease of adoption","user":{"login":"blesh","id":1540597,"avatar_url":"https://avatars.githubusercontent.com/u/1540597?v=3","gravatar_id":"","url":"https://api.github.com/users/blesh","html_url":"https://github.com/blesh","followers_url":"https://api.github.com/users/blesh/followers","following_url":"https://api.github.com/users/blesh/following{/other_user}","gists_url":"https://api.github.com/users/blesh/gists{/gist_id}","starred_url":"https://api.github.com/users/blesh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blesh/subscriptions","organizations_url":"https://api.github.com/users/blesh/orgs","repos_url":"https://api.github.com/users/blesh/repos","events_url":"https://api.github.com/users/blesh/events{/privacy}","received_events_url":"https://api.github.com/users/blesh/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ReactiveX/RxJS/labels/type:%20discussion","name":"type: discussion","color":"207de5"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-08-14T00:19:07Z","updated_at":"2015-08-14T07:38:46Z","closed_at":null,"body":"### Proposed Change\r\n\r\nThis was brought up by @jhusain and I agree, `flatMap` isn't the easiest way to explain the operator.\r\n\r\nThe proposal is to change to a structure of `[mergeStrategy][MappingStrategy]` for names:\r\n\r\nmerging strategies are:\r\n\r\n- merge\r\n- concat\r\n- latest (or switch)\r\n- zip\r\n- combine\r\n\r\nmapping strategies are:\r\n\r\n- All - no mapping is done\r\n- Map - a function is called to do the mapping\r\n- MapTo - a value is provided to do the mapping\r\n\r\nSo for example:\r\n\r\n- `flatMap(x => someObservable(x))` -> `mergeMap(x => someObservable(x))`\r\n- `flatMap(Observable.just(32))` -> `mergeMapTo(Observable.just(32))`\r\n- `flatMapLatest(x => someObservable(x))` -> `latestMap(x => someObservable(x))` (or `switchMap(x => someObservable(x))`)\r\n- `a.zip(b, (a,b) => a + b)` -> `a.zipMap(b, (a,b) => a + b)`\r\n- `Observable.zipArray(a, b, c)` -> `Observable.zipAll(a, b, c)`\r\n- `a.combineLatest(b, (a, b) => a + b)` -> `a.combineMap(b, (a, b) => a + b)`\r\n- `a.combineLatest(b, (a, b) => [a, b])` -> `a.combineAll(b)`\r\n- `a.withLatestFrom(b, (a, b) => a + b)` -> `a.withMap(a, (a, b) => a + b)`\r\n\r\n### Other questions\r\n\r\n- What about `zip`, `combineLatest` and `withLatestFrom`? which are all merge strategies... how can we fit them into this idiom? Are they different enough they don't require change?\r\n\r\ncc/ @trxcllnt \r\n\r\n(edit: adding zip and combine) I suppose we can merge them with All defaulting to an Array."},"comment":{"url":"https://api.github.com/repos/ReactiveX/RxJS/issues/comments/131006378","html_url":"https://github.com/ReactiveX/RxJS/issues/167#issuecomment-131006378","issue_url":"https://api.github.com/repos/ReactiveX/RxJS/issues/167","id":131006378,"user":{"login":"staltz","id":90512,"avatar_url":"https://avatars.githubusercontent.com/u/90512?v=3","gravatar_id":"","url":"https://api.github.com/users/staltz","html_url":"https://github.com/staltz","followers_url":"https://api.github.com/users/staltz/followers","following_url":"https://api.github.com/users/staltz/following{/other_user}","gists_url":"https://api.github.com/users/staltz/gists{/gist_id}","starred_url":"https://api.github.com/users/staltz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/staltz/subscriptions","organizations_url":"https://api.github.com/users/staltz/orgs","repos_url":"https://api.github.com/users/staltz/repos","events_url":"https://api.github.com/users/staltz/events{/privacy}","received_events_url":"https://api.github.com/users/staltz/received_events","type":"User","site_admin":false},"created_at":"2015-08-14T07:38:46Z","updated_at":"2015-08-14T07:38:46Z","body":"> The proposal is to change to a structure of [mergeStrategy][MappingStrategy] for names\r\n\r\nBig thumbs up for this proposal.\r\n\r\n- mergeMap :+1:\r\n- mergeMapTo :+1: although I'd use the example `mergeMapTo(Observable.from([10,20,30]))` because the `just` example seems redundant (doesn't show mergeMapTo's usefulness) since we can write just `.mapTo(32)`\r\n- switchMap :+1: I prefer this one over `latestMap` because `latestMap` might get confused with `combineLatest`, these are two very different things.\r\n- zipMap :-1: I think the name `zip` is perfect\r\n- combineMap :-1: but soon I'll say it's :+1:, I'll explain.\r\n- combineAll :-1:\r\n- withMap :-1:\r\n\r\nI think these are two different categories:\r\n- `mergeMap`, `concatMap`, `switchMap`\r\n- `zip`, `combineLatest`, `withLatestFrom`\r\n\r\nThe first always takes one Observable as input, the second category always takes at least two Observables as input. I'd say the former are **expansion-mapping** operators, and the latter are **combination** operators. (word \"expansion\" because a value from the source Observable is mapped to an Observable of *many* values on the resulting Observable)\r\n\r\nWhile I think `zip` name is perfect (really easy to explain with the zipper metaphor), I think we could do something about `combineLatest` and `withLatestFrom`.\r\n\r\nI think Kefir has the best combinator operator.\r\n[`combine`](http://rpominov.github.io/kefir/#combine) takes a set of active Observables and a set of passive Observables:\r\n`Kefir.combine(obss: Observable<any>[], passiveObss?: Observable<any>[], combinator?: Function)`\r\nActive Observables, when emitting `next, are those that produce a `next` event on the resulting Observable, with the combination of the latest value from all (either active or passive) Observables. Passive Observables, when emitting `next`, do not incur a `next` event on the resulting Observable.\r\n\r\nSo the static `combineLatest(a$, b$, combinator)` is `combine([a$, b$], [], combinator)` and instance `a$.withLatestFrom(b$, combinator)` is `combine([a$], [b$], combinator)`.\r\n\r\nHence `combine` is more general, so `combineLatest` and `withLatestFrom` are just special cases of it.\r\n\r\nI like Elm's name for combineLatest, which is `map2`, `map3`, `map4`, etc depending on how many Signals are being combined. Perhaps one candidate for `combineLatest`, in this light, would be `multiMap` or `combineMap`, because the idea here is \"map many Observables together, combined\". So while I said up there that I didn't like `combineMap`, that's because it is not in the **expansion-mapping** category, so it should not be read as [mergeStrategy][mappingStrategy]. On the other hand, if it's called `combineMap`, it can and probably will be easily confused to be in the expansion-mapping category.\r\n\r\nFinally, I have been teaching `withLatestFrom` as `simplyMapThisObservableButPleaseAlsoUseTheLatestEventsFromTheseObservables`. People totally get it like that, so maybe we need the name `map` in `withLatestFrom`. Also noteworthy: `withLatestFrom` is always an instance Observable, so the way `a.withLatestFrom(b, fn)` will be read is always \"Observable A with the latest from Observable B\". Candidates: `mapUsingLatest` (\"A mapped using the latest B\"), `mapWithLatest` (\"A mapped with the latest B\").\r\n\r\nAnother way of thinking about the combine flavors is: combineLatest is symmetric (all members are active), withLatestFrom is asymmetric (some are active, some are passive). So, tossing `symmetricCombine` and `asymmetricCombine` just as ideas, even though they are finger-twisters to type.\r\n\r\nYet another tossed idea is to have `map` be polymorphic:\r\n- `map(selectorFn)` plain ol' map\r\n- `map(observables: Observable<any>[], selectorFn)` is combineLatest, name inspired by Elm's `map2`, `map3`, etc, dropping the numbers.\r\n\r\nI'm not entirely convinced of all these names, so I'm open to hear some comments, but here is my best bet so far:\r\n\r\nExpansion-mapping operators:\r\n- mergeMap (instance)\r\n- concatMap (instance)\r\n- switchMap (instance)\r\n\r\nCombination operators:\r\n- combine (static)\r\n- combineMap (instance)\r\n- mapWithLatest (instance)"}}