Re: Re: Return value of forEach

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: Re: Return value of forEach

Naveen Chawla
In that case, there should be a new function:

"forEvery" (or "forEachAndReturn" or "each" or whatever)

that does exactly the same as "forEach" but returns the array.

This is a much needed feature for those of us that don't want to create a new array on each invocation but still have the ability to transform the contents of the array (or do some other processing) from within a .sort / .map / .filter etc. chain.

Otherwise, in complicated transformations, we have to end the chain, perform the forEach separately, and then resume the chain, making the code more messy. Sort is an example of a function that already allows mutation of the existing array and returns it, so this would be nothing extraordinary for ES.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Sebastian Malton
Would allowing for each to have the following two properties also help? 

1. Returning a falsy value ends the chain and the next element will not be called 
2. Ability to pass in a call back as parameter 4 and if present will stop the next element from being iterated over until the callback is called with a truthy value (falsey also ends)



Sent: July 6, 2017 8:44 AM
Subject: Re: Re: Return value of forEach

In that case, there should be a new function:

"forEvery" (or "forEachAndReturn" or "each" or whatever)

that does exactly the same as "forEach" but returns the array.

This is a much needed feature for those of us that don't want to create a new array on each invocation but still have the ability to transform the contents of the array (or do some other processing) from within a .sort / .map / .filter etc. chain.

Otherwise, in complicated transformations, we have to end the chain, perform the forEach separately, and then resume the chain, making the code more messy. Sort is an example of a function that already allows mutation of the existing array and returns it, so this would be nothing extraordinary for ES.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Naveen Chawla
In reply to this post by Naveen Chawla
Suitable for that would be an "until" function that returns an array with all elements of the target array until a condition is met (which can then be followed by a chained call to forEach/forEvery), not "forEach" / "forEvery" as such. Reason: readability. The counterpart could be an "after" function which returns an array with all elements after the first element that satisfies a condition. (Maybe even "untilInclusive"/"from" for the inclusive versions too).

On 6 July 2017 at 18:21, Sebastian Malton <[hidden email]> wrote:
Would allowing for each to have the following two properties also help? 

1. Returning a falsy value ends the chain and the next element will not be called 
2. Ability to pass in a call back as parameter 4 and if present will stop the next element from being iterated over until the callback is called with a truthy value (falsey also ends)



Sent: July 6, 2017 8:44 AM
Subject: Re: Re: Return value of forEach

In that case, there should be a new function:

"forEvery" (or "forEachAndReturn" or "each" or whatever)

that does exactly the same as "forEach" but returns the array.

This is a much needed feature for those of us that don't want to create a new array on each invocation but still have the ability to transform the contents of the array (or do some other processing) from within a .sort / .map / .filter etc. chain.

Otherwise, in complicated transformations, we have to end the chain, perform the forEach separately, and then resume the chain, making the code more messy. Sort is an example of a function that already allows mutation of the existing array and returns it, so this would be nothing extraordinary for ES.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Michael J. Ryan
Woudn't Array.prototype.all satisfy those use cases, they run until a falsy value is returned.

--
Michael J. Ryan - http://tracker1.info

On Thu, Jul 6, 2017 at 6:51 AM, Naveen Chawla <[hidden email]> wrote:
Suitable for that would be an "until" function that returns an array with all elements of the target array until a condition is met (which can then be followed by a chained call to forEach/forEvery), not "forEach" / "forEvery" as such. Reason: readability. The counterpart could be an "after" function which returns an array with all elements after the first element that satisfies a condition. (Maybe even "untilInclusive"/"from" for the inclusive versions too).

On 6 July 2017 at 18:21, Sebastian Malton <[hidden email]> wrote:
Would allowing for each to have the following two properties also help? 

1. Returning a falsy value ends the chain and the next element will not be called 
2. Ability to pass in a call back as parameter 4 and if present will stop the next element from being iterated over until the callback is called with a truthy value (falsey also ends)



Sent: July 6, 2017 8:44 AM
Subject: Re: Re: Return value of forEach

In that case, there should be a new function:

"forEvery" (or "forEachAndReturn" or "each" or whatever)

that does exactly the same as "forEach" but returns the array.

This is a much needed feature for those of us that don't want to create a new array on each invocation but still have the ability to transform the contents of the array (or do some other processing) from within a .sort / .map / .filter etc. chain.

Otherwise, in complicated transformations, we have to end the chain, perform the forEach separately, and then resume the chain, making the code more messy. Sort is an example of a function that already allows mutation of the existing array and returns it, so this would be nothing extraordinary for ES.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

T.J. Crowder-2
On Sat, Jul 8, 2017 at 1:40 AM, Michael J. Ryan <[hidden email]> wrote:
Woudn't Array.prototype.all satisfy those use cases, they run until a falsy value is returned.

Is there an `Array.prototype.all` proposal? I'm not seeing it on github. If you're thinking of `every` and `some`, they don't return a reference to the array, which seemed to be important to Naveen for chaining.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Naveen Chawla

Does anybody have any opinion on a new Array.prototype.each method that does the same as forEach but returns the array, thereby allowing chaining with sort, map, filter etc., while also preserving backwards compatibility?


On Sat, 8 Jul 2017, 1:08 p.m. T.J. Crowder, <[hidden email]> wrote:
On Sat, Jul 8, 2017 at 1:40 AM, Michael J. Ryan <[hidden email]> wrote:
Woudn't Array.prototype.all satisfy those use cases, they run until a falsy value is returned.

Is there an `Array.prototype.all` proposal? I'm not seeing it on github. If you're thinking of `every` and `some`, they don't return a reference to the array, which seemed to be important to Naveen for chaining.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Tab Atkins Jr.
On Sun, Jul 23, 2017 at 6:53 AM, Naveen Chawla <[hidden email]> wrote:
> Does anybody have any opinion on a new Array.prototype.each method that does
> the same as forEach but returns the array, thereby allowing chaining with
> sort, map, filter etc., while also preserving backwards compatibility?

In general, functions returning undefined are *often* safe to switch
to returning a more useful value; this is one of the recommended
patterns for upgrading DOM code that uses callbacks to using promises
instead.  We should pursue that first.  ^_^

~TJ
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

T.J. Crowder-2
On Mon, Jul 24, 2017 at 9:58 PM, Tab Atkins Jr. <[hidden email]> wrote:
> In general, functions returning undefined are *often* safe to switch
> to returning a more useful value

I think we'd struggle to prove it could be done safely. For instance, we'd have to differentiate between all the places that did something like this:

```js
someDataPromise().then(data => data.forEach(entry => console.log(entry)));
```

...that *do* and *do not* rely on the fact that promise resolves with `undefined`. (The above does not.)

Hopefully, ones that do are few and far between. But webscale is massive, "few and far between" can be an unacceptably high number.

If there were an appetite for `Array.prototype.each`, I'd like to address not just the return value but other issues with `Array.prototype.forEach` as well (like step value, per-iteration updates of the index, stopping early [using `some` or `every` is sometimes perfect, other times semantically misleading]). I have some thoughts on doing that while retaining runtime efficiency for the common case and code simplicity. But I doubt the appetite is there.

-- T.J. (er, the other one) Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Tab Atkins Jr.
On Mon, Jul 24, 2017 at 3:31 PM, T.J. Crowder
<[hidden email]> wrote:

> On Mon, Jul 24, 2017 at 9:58 PM, Tab Atkins Jr. <[hidden email]>
> wrote:
>> In general, functions returning undefined are *often* safe to switch
>> to returning a more useful value
>
> I think we'd struggle to prove it could be done safely. For instance, we'd
> have to differentiate between all the places that did something like this:
>
> ```js
> someDataPromise().then(data => data.forEach(entry => console.log(entry)));
> ```
>
> ...that *do* and *do not* rely on the fact that promise resolves with
> `undefined`. (The above does not.)
>
> Hopefully, ones that do are few and far between. But webscale is massive,
> "few and far between" can be an unacceptably high number.
>
> If there were an appetite for `Array.prototype.each`, I'd like to address
> not just the return value but other issues with `Array.prototype.forEach` as
> well (like step value, per-iteration updates of the index, stopping early
> [using `some` or `every` is sometimes perfect, other times semantically
> misleading]). I have some thoughts on doing that while retaining runtime
> efficiency for the common case and code simplicity. But I doubt the appetite
> is there.

Yeah, thus the "often". ^_^  It's been done a few times in DOM land
iirc.  Relying on a promise to resolve to undefined is probably quite
rare; it would mean that you're explicitly testing for undefined on
the far end.  Much more likely, in situations like that, is just
ignoring the resolution value, in which case switching it to an Array
is fine.

~TJ
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Naveen Chawla
I've quite frequently required an `each` that returns the array, since I do sequential transformations that involve forEach, map, filter, sort etc.

I would not overload `each` with any early termination, I would probably have an `Array.prototype.takeWhile` method for that (which returns a new array taking elements while the return value of the predicate is truthy).



On Tue, 25 Jul 2017 at 04:09 Tab Atkins Jr. <[hidden email]> wrote:
On Mon, Jul 24, 2017 at 3:31 PM, T.J. Crowder
<[hidden email]> wrote:
> On Mon, Jul 24, 2017 at 9:58 PM, Tab Atkins Jr. <[hidden email]>
> wrote:
>> In general, functions returning undefined are *often* safe to switch
>> to returning a more useful value
>
> I think we'd struggle to prove it could be done safely. For instance, we'd
> have to differentiate between all the places that did something like this:
>
> ```js
> someDataPromise().then(data => data.forEach(entry => console.log(entry)));
> ```
>
> ...that *do* and *do not* rely on the fact that promise resolves with
> `undefined`. (The above does not.)
>
> Hopefully, ones that do are few and far between. But webscale is massive,
> "few and far between" can be an unacceptably high number.
>
> If there were an appetite for `Array.prototype.each`, I'd like to address
> not just the return value but other issues with `Array.prototype.forEach` as
> well (like step value, per-iteration updates of the index, stopping early
> [using `some` or `every` is sometimes perfect, other times semantically
> misleading]). I have some thoughts on doing that while retaining runtime
> efficiency for the common case and code simplicity. But I doubt the appetite
> is there.

Yeah, thus the "often". ^_^  It's been done a few times in DOM land
iirc.  Relying on a promise to resolve to undefined is probably quite
rare; it would mean that you're explicitly testing for undefined on
the far end.  Much more likely, in situations like that, is just
ignoring the resolution value, in which case switching it to an Array
is fine.

~TJ

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

T.J. Crowder-2
On Tue, Jul 25, 2017 at 5:06 AM, Naveen Chawla <[hidden email]> wrote:
I would not overload `each` with any early termination, I would probably have an `Array.prototype.takeWhile` method for that (which returns a new array taking elements while the return value of the predicate is truthy).

This is for when you don't want to create a new array, for either semantic or memory pressure reasons.

-- T.J. Crowder

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

T.J. Crowder-2
In reply to this post by Tab Atkins Jr.
On Mon, Jul 24, 2017 at 11:39 PM, Tab Atkins Jr. <[hidden email]> wrote:

> Yeah, thus the "often". ^_^

:-)

> It's been done a few times in DOM land iirc.

Nothing's coming to mind, but I haven't watched DOM as closely as JS.
It'd be interesting to know what was done, when.

> Relying on a promise to resolve to undefined is probably quite
> rare; it would mean that you're explicitly testing for undefined on
> the far end.

Not necessarily, you could be testing for any falsy value, etc. Yes,
it's rare, but it's not limited to Promises either. People seem
obsessed with avoiding having multiple statements if they can get away
with one, even with code that makes no semantic sense; I've seen this
kind of return from methods many times:

```js
if (someCondition) return somethingKnownNotToHaveAReturnValue();
```

...where `somethingKnownNotToHaveAReturnValue` is frequently
`console.log` or `alert` or even `someArray.forEach`. Changing the
return value of `forEach` would change the return value of code doing
this with `forEach`. (I confess a small part of me *wants* to break
that code. But it's a small part, and I'm not proud of it. :-) )

Concise arrow functions have made it even more common by making it
more hidden; the promise `then` handler was meant just as an example
of a concise arrow function doing this.

For my part, I think `forEach` is too deeply entrenched with its
current return value to get a new one. But "thinking" is just that;
proper research would need to be done.

-- T.J. Crowder
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

Naveen Chawla
In reply to this post by T.J. Crowder-2
On Tue, 25 Jul 2017 at 12:09 T.J. Crowder <[hidden email]> wrote:
On Tue, Jul 25, 2017 at 5:06 AM, Naveen Chawla <[hidden email]> wrote:
I would not overload `each` with any early termination, I would probably have an `Array.prototype.takeWhile` method for that (which returns a new array taking elements while the return value of the predicate is truthy).

This is for when you don't want to create a new array, for either semantic or memory pressure reasons.

-- T.J. Crowder

For that I would have `eachWhile` which returns the original array but only iterates while the return value of the supplied callback is truthy. The difference with `takeWhile` (which should be added to ES regardless, along with `skipWhile`) is that in chaining calls `takeWhile` provides a potentially smaller array for further processing, whereas `eachWhile` doesn't. (`eachSkipWhile` could be the "skipWhile" counterpart to `eachWhile`).

I would leave `each` as a contract: always iterates through every value, always returns the original array.

For me this is better for readability.

If these chained calls `map`, `each` etc. can be integrated with async iterators (as RxJs attempts with Observables) then some really elegant stuff can happen!

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Return value of forEach

. 田生
In reply to this post by T.J. Crowder-2
i had seen some people transform
{
  doSth();
  return;
}
to
return void doSth();
for saving the `{}` and line breaks.

So maybe
return arr.forEach(...)
is just been written due to same reason.
_____________________________
From: T.J. Crowder <[hidden email]>
Sent: 星期二, 七月 25, 2017 15:21
Subject: Re: Return value of forEach
To: Tab Atkins Jr. <[hidden email]>
Cc: <[hidden email]>


On Mon, Jul 24, 2017 at 11:39 PM, Tab Atkins Jr. <[hidden email]> wrote:

> Yeah, thus the "often". ^_^

:-)

> It's been done a few times in DOM land iirc.

Nothing's coming to mind, but I haven't watched DOM as closely as JS.
It'd be interesting to know what was done, when.

> Relying on a promise to resolve to undefined is probably quite
> rare; it would mean that you're explicitly testing for undefined on
> the far end.

Not necessarily, you could be testing for any falsy value, etc. Yes,
it's rare, but it's not limited to Promises either. People seem
obsessed with avoiding having multiple statements if they can get away
with one, even with code that makes no semantic sense; I've seen this
kind of return from methods many times:

```js
if (someCondition) return somethingKnownNotToHaveAReturnValue();
```

...where `somethingKnownNotToHaveAReturnValue` is frequently
`console.log` or `alert` or even `someArray.forEach`. Changing the
return value of `forEach` would change the return value of code doing
this with `forEach`. (I confess a small part of me *wants* to break
that code. But it's a small part, and I'm not proud of it. :-) )

Concise arrow functions have made it even more common by making it
more hidden; the promise `then` handler was meant just as an example
of a concise arrow function doing this.

For my part, I think `forEach` is too deeply entrenched with its
current return value to get a new one. But "thinking" is just that;
proper research would need to be done.

-- T.J. Crowder
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss