Proposal: Syntax sugar for single exit and early exit functions.

# Biju (11 years ago)

I wish, I could write elegant two of the code pattern I use frequently.

Patten 1. HTML button click event handler should always return false (ie, when you never want the submit action). So I always write.

function someClickHandler(){ try { doStuff(); doAnotherStuff(); doYetAnotherStuff(); } catch(e){ } return false; }

Patten 2. I do like to code functions with early exit, like

function someValidationProcess(){

doStuff();
if(condition_1()){
    doCleanUp_1();
    doCleanUp_2();
}

doAnotherStuff();
if(condition_2()){
    doCleanUp_1();
    doCleanUp_2();
 }

doYetAnotherStuff();
if(condition_3()){
    doCleanUp_1();
    doCleanUp_2();
 }

doMoreStuff();
doCleanUp_1();
doCleanUp_2();

}

Proposal: I wish there was some syntax sugar like

function someClickHandler(){ doStuff(); doAnotherStuff(); doYetAnotherStuff(); } finally { return false; }

function someValidationProcess(){

doStuff();
breakif(condition_1());

doAnotherStuff();
breakif(condition_2());

doYetAnotherStuff();
breakif(condition_3());

doMoreStuff();

} finally { doCleanUp_1(); doCleanUp_2(); }

Cheers

# Frankie Bagnardi (11 years ago)

Returning false isn't the common way to prevent the default action anymore, event.preventDefault() is. In that case you'd just preventDefault at the top of your function.

The other use cases can be satisfied with simple high order functions like andReturn(f, x) or compose(f, g).

# Alex Kocharin (11 years ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20141117/c9ac768c/attachment-0001

# Andreas Rossberg (11 years ago)

On 17 November 2014 17:29, Alex Kocharin <alex at kocharin.ru> wrote:

17.11.2014, 03:07, “Biju” bijumaillist at gmail.com:

I wish, I could write elegant two of the code pattern I use frequently. [...] Patten 2. I do like to code functions with early exit, like

function someValidationProcess(){

doStuff();
if(condition_1()){
    doCleanUp_1();
    doCleanUp_2();
}

doAnotherStuff();
if(condition_2()){
    doCleanUp_1();
    doCleanUp_2();
 }

doYetAnotherStuff();
if(condition_3()){
    doCleanUp_1();
    doCleanUp_2();
 }

doMoreStuff();
doCleanUp_1();
doCleanUp_2();

}

Sounds like you would like to have monad comprehension syntax. :)

How about a loop?

function someValidationProcess() { do { doStuff() if (condition_1()) break

doAnotherStuff()
if (condition_2()) break

doYetAnotherStuff()
if (condition_3()) break

doMoreStuff()

} while(0)

doCleanUp_1() doCleanUp_2() }

No need for a fake loop:

function someValidationProcess() { validate: { doStuff() if (condition_1()) break validate doOtherStuff() if (condition_2()) break validate // etc. } doCleanUp_1() doCleanUp_2() }

But I'd rather use a separate function for the clean-up.

# Jeremy Martin (11 years ago)

validate: { ... }

Is that an ES7 feature? I don't recognize it from ES6, and can't seem to find a relevant proposal with that syntax...

# Jeremy Martin (11 years ago)

OH JEEZ. Please ignore previous email.

# Biju (11 years ago)

On 17 November 2014 11:29, Alex Kocharin <alex at kocharin.ru> wrote:

If you do the same stuff after each function, some functional programming could help:

function someValidationProcess() { ;[doStuff, doAnotherStuff, doYetAnotherStuff, doMoreStuff] .forEach(function(fn) { fn() doCleanUp_1() doCleanUp_2() }) }

In this case doStuff would have to set a flag instead of condition_1() probably.

Just want to add, usually in corporate world a .Net or Java developer is who code JavaScript. The code above may be little complex for them.

# Garrett Smith (11 years ago)

On 11/16/14, Biju <bijumaillist at gmail.com> wrote:

[...]

Proposal: I wish there was some syntax sugar like

function someClickHandler(){ doStuff(); doAnotherStuff(); doYetAnotherStuff(); } finally { return false; }

function rf() { try { throw-an-error; } finally { return false; } }

rf(); // false

# Christian Mayer (11 years ago)

Am 18.11.2014 um 06:50 schrieb Biju:

Just want to add, usually in corporate world a .Net or Java developer is who code JavaScript. The code above may be little complex for them.

What I actually sometimes really miss in JavaScript (having a big C++ background) are destructors.

(I haven't checked if they are in any new version proposal, though)

# Steve Fink (11 years ago)

I have wanted something similar to this. But I think of it as having RAII in JS.

So what I would like is:

function f() { let x = g(); finally { x.cleanup(); } let y = h(); finally { y.cleanup(); } doStuff(x, y); }

You can sort of do this with try..finally:

function f() { let x, y; try { x = g(); y = h(); doStuff(x, y); } finally { x.cleanup(); y.cleanup(); } }

The difference is that my 'finally' (1) may be placed directly after the related setup code, and (2) is lexically scoped. (Also note that my syntax suggestion probably wouldn't work, because a finally directly after a try..catch block is ambiguous -- or would it work, because they have identical behavior?)

As for:

function f() { if (cond) { finally { print(1); } } else { finally { print(2); } } }

I was kind of hoping that each finally{} could use a minimal surrounding lexical scope (so here, the bodies of the 'if' consequents), so only one of these finally{} blocks would run. But perhaps that's a new sort of scope from what already exists? There could be tension between finally{} and let scoping.

Also, in

for (var x of foo()) { finally { print(x); } }

I would expect the finally{} block to run on every iteration.

Could something like this fly?

# Christian Mayer (11 years ago)

Am 18.11.2014 um 22:03 schrieb Brendan Eich:

Christian Mayer wrote:

What I actually sometimes really miss in JavaScript (having a big C++ background) are destructors.

(I haven't checked if they are in any new version proposal, though)

No, as JS has no stack storage class, only we-hope-unobservable GC, no destructors.

I fully understand that something called at GC time won't work - but that's not a real destructor for me, that would be a sort of "destroyer"... :)

The destructor should IMHO be called when the JS internal ref count gets to 0, i.e. when the object gets released to the GC to do it's job when it wants to. (This could actually be generalized by offering a callback function that gets called every time the internal refcount gets decreased... The current ref count could be passed as a parameter then)

One very obvious use case for me would be debugging and making sure that my objects aren't leaking. But anything could make sense where destructors are usually used for.