Do Expression with Alternative Syntax - Immediately Invoked Arrow Functions



I had an idea to allow returns from statements and decided to do a research and found Do Expression proposal very similar and more complex than my idea.

My idea is basically to create a new keyword syntax as a shortcut for an executed arrow function. It behaves same as arrow function.


 b = do if(a) return 1; else return 0;;


 b = (()=> {if(a) return 1; else return 2})();

We can also use alternative names or keywords for this new feature.


  • ->
  • => (preceded by an expression and followed by a block or a statement)
 b = -> if(a) return 1; else return 0;;
 b = => if(a) return 1; else return 0;;


 b = =>{ if(a) return 1; else return 0;};

We might call => syntax a Immediately Executed Arrow Function or Immediately Invoked Arrow Function

We can even pass parameters as an object:

 b = {value:a} => if(value) return value; else return 0;

Match Example:

const a=1,b=2;
const c = 
    {a,b}=> {
        if(a) return a; 
        else if(b) return b; 
        else return 0;

Pipe and Chaining Example

Consecutive chains inherit the single parameter of single field object of parent chain, each assigning return value to that single field object property and passing that as parameters to next chain. We can enforce rule for my proposal to only have one object with one field as the parameter, that field can be be assigned as any object of course.

const value=1;
const c = {value} 
    => value+1
    => value+1
    => value+2
console.log(c) //5

Alternative Syntax:

const c = value
    -> value+1
    -> value+1
    -> value+2
console.log(c) //5

We can use for chaining ==> syntax to avoid specifying the parameter with the method:
{value} ==> Filter ==> Map = {value} => Filter(value) => Map(value)

We can of course discuss the syntax, my proposal has 3 suggestions: =>, ->, do. The reason I prefer => is because my method is actually based on anonymous method, just immediately executed, and allowing flexibility.

Thank you,

=> is not an option, because it strongly suggests it will work like an arrow function - but the point of do-expressions is to not require a function call, not add a stack frame, etc, so "sugar for an immediately invoked arrow function" wouldn't achieve that goal.

do without curly braces i believe would be ambiguous, both for parsers and more importantly, for humans.

Your suggested transpilation wouldn't work if the do expression contained break, continue, yield, await,, etc.

1 Like

Hi @ljharb, Thanks for input, I just posted the issue here as well for input from other and future reference and discussion.

1 Like

Thank you,

Proposed alternate syntax:

let foo = do function(){
    return "bar"
let baz = do () => "qux";

console.log(foo) // "bar"
console.log(baz) // "qux"

This I think is nicer, but even so, a little unnecessary. To me, this would be identical to (() => "qux")(). I admit, the do syntax is a lot cleaner, but it raises a few questions.

How would this work?

do someFunction

Here, there is hardly an advantage to using do than simply ().

And there's also an issue with returning values. In a do-while loop, it will end the loop AND the function.

function func1(){
    do {
        return "value"
    } while(true);
function func2(){
    let a = do return "value"; // Using your proposed syntax

func1() // "Unreached" is never logged
func2() // What happens here?

In my opinion, this seems like it could cause a lot of confusion. Though I would like to see some cleaner method for creating IIFEs, I don't think this is the way to do it.