super return

# Sebastian Malton (7 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20170828/cbb63387/attachment

# Michael J. Ryan (7 years ago)

Well, there's already .map(), .find() and .filter() for returning values from arrays

# Sebastian Malton (7 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20170828/3e3c5d7c/attachment-0001

# Tab Atkins Jr. (7 years ago)

On Mon, Aug 28, 2017 at 12:29 PM, Sebastian Malton <sebastian at malton.name> wrote:

I have seen some people want to modify some of the array prototype functions, especially forEach, so that returning from them returns a value. However, I have also seems that this could break things since in some cases, again forEach, the return value in explicitly defined.

Thus I propose the new syntax super return and any other positive number of supers. This syntax is currently not valid in any scenario and with the current meaning of super seems, to me at least, relativity easy to understand.

The outcome of this basically means "return from current context up one level and then return from there".

A current method of doing this is by using try / catch but it is not ideal. Using the above method I believe that it would be able to be better optimized.

This has been suggested in the past, by adding a fourth argument to the callback signature passing an opaque "halt" value. Returning the halt value would end execution of the looping function prematurely. No reason to add new syntax for this, plus hooks for userland to take advantage of it, when we can just use something that userland could adopt today.

(As an added bonus, it would make the callback arguments be Element, Index, Collection, Halt, finally spelling out Brendan's full last name. ^_^)

# Sebastian Malton (7 years ago)

This could be done but I see a few problems with it:

  1. Though it does make ending from some functions like forEach able to be done it does not all returning from other functions like map or sort
  2. It does not directly allow the returning of values but this might be rectified by having it be a function that you call and when it calls it stops any further calls and then returns the first parameter past

Original Message   From: jackalmage at gmail.com Sent: August 28, 2017 4:17 PM To: sebastian at malton.name Cc: es-discuss at mozilla.org Subject: Re: super return

On Mon, Aug 28, 2017 at 12:29 PM, Sebastian Malton <sebastian at malton.name> wrote:

I have seen some people want to modify some of the array prototype functions, especially forEach, so that returning from them returns a value. However, I have also seems that this could break things since in some cases, again forEach, the return value in explicitly defined.

Thus I propose the new syntax super return and any other positive number of supers. This syntax is currently not valid in any scenario and with the current meaning of super seems, to me at least, relativity easy to understand.

The outcome of this basically means "return from current context up one level and then return from there".

A current method of doing this is by using try / catch but it is not ideal. Using the above method I believe that it would be able to be better optimized.

This has been suggested in the past, by adding a fourth argument to the callback signature passing an opaque "halt" value. Returning the halt value would end execution of the looping function prematurely. No reason to add new syntax for this, plus hooks for userland to take advantage of it, when we can just use something that userland could adopt today.

(As an added bonus, it would make the callback arguments be Element, Index, Collection, Halt, finally spelling out Brendan's full last name. ^_^)

# Michael J. Ryan (7 years ago)

if (arr.find(e => typeof e != 'number')) throw new Error('...');

return arr.map(e => { if (!...) throw new Error(...); return e * 2; });

Odds are you need a conditional block, might as well be try catch.

# Tab Atkins Jr. (7 years ago)

On Mon, Aug 28, 2017 at 1:27 PM, Sebastian Malton <sebastian at malton.name> wrote:

This could be done but I see a few problems with it:

  1. Though it does make ending from some functions like forEach able to be done it does not all returning from other functions like map or sort

map() and forEach() have exactly the same signatures for their callbacks; you can definitely do the same thing in both of them.

You're right about sort(), but returning early from a sort() call seems like a really small niche; I think it's the sort of thing you'll only do in an error situation, in which case throwing is the correct way to handle it. (On the other hand, returning early from a forEach() can be due to perfectly normal reasons, the same sorts of things that cause you to break from a loop.)

  1. It does not directly allow the returning of values but this might be rectified by having it be a function that you call and when it calls it stops any further calls and then returns the first parameter past

It's the outer function's responsibility to return appropriate values. A map() call that didn't return an array would cause a lot of problems; a forEach call that returned something meaningful would be weird. In either case, it's a bad code smell to try and override what the outer function is doing. If you're stopping because of an error, and so whatever the function is trying to do isn't relevant anymore, you should throw an error instead.

# Naveen Chawla (7 years ago)

Returning early should be implemented via a new takeWhile call

# Andreas Rossberg (7 years ago)

On 28 August 2017 at 21:29, Sebastian Malton <sebastian at malton.name> wrote:

Thus I propose the new syntax super return and any other positive number of supers. This syntax is currently not valid in any scenario and with the current meaning of super seems, to me at least, relativity easy to understand.

The outcome of this basically means "return from current context up one level and then return from there".

What if that context is no longer live? A function can outlive its creation scope. You could even try returning twice from the same function.

Allowing returns from outer functions has been discussed extensively in the ES6 phase (e.g. under the term "blocks"), but has been decided against in favour of arrow functions. One problem is that it introduces quite complex dynamic behaviour in general (it's halfway to introducing delimited continuations), and many new ways to fail.

A current method of doing this is by using try / catch but it is not ideal.

Using the above method I believe that it would be able to be better optimized.

That's unlikely, since it is just as dynamic in the general case (and the less general cases can be optimised equally well for both).

# Sebastian Malton (7 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20170829/2931f49c/attachment

# Andreas Rossberg (7 years ago)

On 29 August 2017 at 14:30, Sebastian Malton <sebastian at malton.name> wrote:

If a function outlives its creation scope then this would do exactly what a normal return would do.

That makes no sense, because that's a completely different continuation, usually expecting different, unrelated types of results. It needs to be an error at least. (In a language with proper continuations the outer continuation would be captured by the inner closure and invoking it later would reestablish the execution context to return to. But TC39 always agreed that we don't want full-blown continuations in JS.)

# Allen Wirfs-Brock (7 years ago)

On Aug 28, 2017, at 12:29 PM, Sebastian Malton <sebastian at malton.name> wrote:

The outcome of this basically means "return from current context up one level and then return from there”.

This would be a terrible violation of functional encapsulation. How do you know that the (e.g.) forOf function isn’t internally using a encapsulated helper function that is making the actual call to the call back. You simply have no way to predict where returning from the current context “up one” means.

A current method of doing this is by using try / catch but it is not ideal. Using the above method I believe that it would be able to be better optimized.

This technique provides a meaningful semantics because it allows the controlling outer function to define what early return means.

# Naveen Chawla (7 years ago)

takeWhile would work as follows:

myArray.takeWhile(element=>true) //Simplest case. Iterates over all

elements and returns a new array of them

It returns a new array with the consecutive elements from the start all of whose predicates returns truthy. Thusly it allows iteration with a custom exit condition, e.g.

myArray
    .takeWhile(
         element=>{
             let condition
             //calculate condition
             return condition
         }
    )

Prior art: Java 9, rxjs, lodash and possibly others

# Alexander Jones (7 years ago)

Perhaps if the nested function is lexically inside such super function it can be fair game and actually quite powerful and liberating.

Unconstrained 'upleveling' is IIRC valid in such wonderful languages as Tcl. This unverified fact is presented without opinion :D

# Sebastian Malton (7 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20170830/917682d7/attachment-0001

# Steve Fink (7 years ago)

On 08/29/2017 08:56 AM, Allen Wirfs-Brock wrote:

On Aug 28, 2017, at 12:29 PM, Sebastian Malton <sebastian at malton.name <mailto:sebastian at malton.name>> wrote:

The outcome of this basically means "return from current context up one level and then return from there”.

This would be a terrible violation of functional encapsulation. How do you know that the (e.g.) forOf function isn’t internally using a encapsulated helper function that is making the actual call to the call back. You simply have no way to predict where returning from the current context “up one” means.

I agree. I think this would be much better as

function someThing(doWith) {
return doWith.map(elem => {
         typeCheckLabel:
         return elem * 2;
});

     come from typeCheckLabel if (typeof elem !== "number");
return "Not all are numbers" ;
}

:-)

(I agree with the encapsulation argument.)