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

Reply via email to