I do not believe `.forEach` with a return value would satisfy this usage because with `.tap`, the callback is called only once, with the first argument being the *entire* array.
On Sun, Jul 16, 2017 at 3:37 PM, Vinnymac <[email protected]> wrote: > I have been reading over the `.forEach` with a return value discussion. I > imagine if that was added it would work with chaining and do everything > that `.tap` would be capable of. Unless I have missed something? > > On Jul 16, 2017 3:55 PM, "Eli White" <[email protected]> wrote: > >> This is definitely something that can be polyfilled (with different >> levels of naivety) but requires modifying built-ins which is a no-no. >> >> Here is an example that is more valuable in production than just >> debugging. >> >> Many other languages that support `.tap` enable a value to be returned. >> If it is, that value is passed down the rest of the chain instead of the >> initial value (but the return value is optional). This is also functionally >> similar to `.tee` in many languages (and bash). >> https://en.wikipedia.org/wiki/Tee_(command) >> >> One of the other common use cases for `.tap` is to be able to chain >> methods that act on the entire array. For example, if `.reverse` wasn't >> part of `Array.prototype` and instead you had a user function >> `myReverse(arr) => arr'`, then if you wanted to convert `[1,2,3]` into >> `["6","4","2"]`, then you'd have to do the following. It is a bit of a >> contrived example since I'm avoiding just calling `myReverse` before or >> after the chain. Imagine a more complex example and longer chain. >> >> ``` >> const value = [1, 2, 3].map(String); >> myReverse(value).map(num => num * 2); >> ``` >> >> With `.tap`, it can be part of the chain: >> >> ``` >> const value = [1, 2, 3] >> .map(String) >> .tap(myReverse) >> .map(num => num * 2); >> ``` >> >> Obviously this could be done with reduce, but it would require >> `myReverse` to have a different signature. >> >> Just trying to provide some reasoning why `.tap` is for more than just >> debugging. :) >> >> >> On Sun, Jul 16, 2017 at 12:00 PM, Bob Myers <[email protected]> wrote: >> >>> ```js >>> Object.defineProperty(Array.prototype, 'tap', { >>> value: function(fn) { fn(this); return this;} >>> }); >>> ``` >>> >>> On Mon, Jul 17, 2017 at 12:15 AM, Logan Smyth <[email protected]> >>> wrote: >>> >>>> You could always hack it and use the third argument :D >>>> >>>> ``` >>>> var tap = f => (v, i, arr) => { >>>> if (i === arr.length - 1) f(arr); >>>> >>>> return v; >>>> }; >>>> ``` >>>> >>>> Fine for debugging at least, but not necessarily your overall goal. >>>> >>>> On Sun, Jul 16, 2017 at 11:20 AM, Eli White <[email protected]> wrote: >>>> >>>>> That leads to a different result. Map is called once for every item in >>>>> the array. >>>>> >>>>> ``` >>>>> const tap = f => x => { >>>>> f(x); >>>>> return x; >>>>> } >>>>> >>>>> [1, 2, 3] >>>>> .map(num => num * 2) >>>>> .map(tap(console.log.bind(console))) >>>>> .reduce((a, b) => a + b); >>>>> ``` >>>>> >>>>> Results in: >>>>> >>>>> ``` >>>>> 2 >>>>> 4 >>>>> 6 >>>>> ``` >>>>> >>>>> Whereas >>>>> >>>>> ``` >>>>> [1, 2, 3] >>>>> .map(num => num * 2) >>>>> .tap(console.log.bind(console)); >>>>> .reduce((a, b) => a + b); >>>>> ``` >>>>> >>>>> would result in >>>>> >>>>> ``` >>>>> [2, 4, 6] >>>>> ``` >>>>> >>>>> This is what makes it hard about being a userland function. Tap >>>>> enables the developer to act on the *entire* array, not individual items. >>>>> >>>>> On Sun, Jul 16, 2017 at 11:10 AM, Elie Rotenberg <[email protected]> >>>>> wrote: >>>>> >>>>>> Sorry I meant: >>>>>> >>>>>> const tap = f => x => { >>>>>> f(x); >>>>>> return x; >>>>>> } >>>>>> >>>>>> >>>>>> Elie ROTENBERG >>>>>> Directeur général adjoint >>>>>> [email protected] >>>>>> 336 89 29 98 19 >>>>>> twitter elierotenberg facebook elie.rotenberg skype elie.rotenberg >>>>>> github elierotenberg >>>>>> 2, rue Paul Vaillant Couturier - CS 60102 - 92532 Levallois-Perret >>>>>> Cedex - T: 33 811 69 41 42 >>>>>> >>>>>> >>>>>> On Sun, Jul 16, 2017 at 8:09 PM, Elie Rotenberg <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> I think the most common use of this pattern would be debugging, and >>>>>>> in this context you don't really care to use a little helper and >>>>>>> Array.prototype.map, eg: >>>>>>> >>>>>>> const tap = f => ...args => { >>>>>>> f(...args); >>>>>>> return x; >>>>>>> }; >>>>>>> >>>>>>> [1, 2, 3] >>>>>>> .map(num => num * 2) >>>>>>> .map(tap(console.log.bind(console))); >>>>>>> .reduce((a, b) => a + b); >>>>>>> >>>>>>> >>>>>>> On Sun, Jul 16, 2017 at 8:00 PM, Eli White <[email protected]> >>>>>>> wrote: >>>>>>> >>>>>>>> I'd like to propose a `.tap` method on the Array prototype. I was >>>>>>>> able to find some previous discussion here but it was off the main >>>>>>>> topic >>>>>>>> and seemed to die out: https://mail.mozilla.org/ >>>>>>>> pipermail/es-discuss/2015-October/044454.html >>>>>>>> >>>>>>>> A tap method enables the user to inspect an array in the chain. >>>>>>>> >>>>>>>> For example, inspection: >>>>>>>> >>>>>>>> If you have a chain like this: >>>>>>>> >>>>>>>> ``` >>>>>>>> [1, 2, 3] >>>>>>>> .map(num => num * 2) >>>>>>>> .reduce((a, b) => a + b); >>>>>>>> ``` >>>>>>>> >>>>>>>> When you want to see what the value of the array is between the map >>>>>>>> and reduce, you would typically do this: >>>>>>>> >>>>>>>> ``` >>>>>>>> const value = [1, 2, 3] >>>>>>>> .map(num => num * 2); >>>>>>>> >>>>>>>> console.log(value); >>>>>>>> >>>>>>>> value.reduce((a, b) => a + b); >>>>>>>> ``` >>>>>>>> >>>>>>>> With `.tap`, you'd be able to do this: >>>>>>>> >>>>>>>> ``` >>>>>>>> [1, 2, 3] >>>>>>>> .map(num => num * 2) >>>>>>>> .tap(console.log.bind(console)); >>>>>>>> .reduce((a, b) => a + b); >>>>>>>> ``` >>>>>>>> >>>>>>>> `.tap` would be called once, passed the entire array as the first >>>>>>>> argument to the callback, and would return the array after the >>>>>>>> callback was >>>>>>>> finished. >>>>>>>> >>>>>>>> This isn't something that can cleanly be done with a user-land >>>>>>>> function since it would have to wrap the chain, or replace all of the >>>>>>>> chained functions like underscore does. >>>>>>>> >>>>>>>> An example of wrapping the chain: >>>>>>>> >>>>>>>> ``` >>>>>>>> myTap( >>>>>>>> ( >>>>>>>> [1, 2, 3] >>>>>>>> .map(num => num * 2) >>>>>>>> ), >>>>>>>> console.log.bind(console); >>>>>>>> ) >>>>>>>> .reduce((a, b) => a + b); >>>>>>>> ``` >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> es-discuss mailing list >>>>>>>> [email protected] >>>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> es-discuss mailing list >>>>> [email protected] >>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> es-discuss mailing list >>>> [email protected] >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>>> >>> >> >> _______________________________________________ >> es-discuss mailing list >> [email protected] >> https://mail.mozilla.org/listinfo/es-discuss >> >>
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

