tc39 / proposal-do-expressions

Proposal for `do` expressions
MIT License
1.12k stars 14 forks source link

Shorthand function `do` syntax #17

Closed pitaj closed 3 years ago

pitaj commented 6 years ago

The current shortest syntax for creating a do-expression function is this:

function functionName(...args) {
  return do {
    // body
  };
}

I think it would be useful to have a shorter syntax for functions that are entirely do expressions. This seems like the best way in my opinion.

// my preference, this way `do` comes right before the block
function functionName(...args) do {
  // body
}

This doesn't conflict with async functions, and would be an error today in every case I can think of.

ljharb commented 6 years ago

One of the motivators for do expressions, as I understand them, is to avoid function overhead.

I'm not sure it's really worth the complexity to add this support for functions solely so they can omit return.

kasperpeulen commented 6 years ago

@ljharb It may be one reason, but the main reason seems to allow expression orientated programming.

It seems natural to me to allow a complete function to be "expression orientated".

lyleunderwood commented 6 years ago
const functionName = (...args) => do {
  // body
};

is how I write mine.

MaxGraey commented 5 years ago

What about move forward and replace function with do for this case. I mean

const func = do (...args) {
   if (args.length == 1)
      true;

   false;
};
pitaj commented 5 years ago

That looks quite unclear syntactically.

bakkot commented 3 years ago

[ deleted this because it was false and I didn't want to mislead; see edit history if you're curious ]

pitaj commented 3 years ago

How are those equivalent? do is an expression, it's not just a block, right?

Are you saying in the following:

let f = (b) => do { if (b) { 5 } else { 7} };
let x = f(true);

x === undefined, just as if the do was not there?

I thought this was a core premise of the proposal.

bakkot commented 3 years ago

Ah, sorry, you're entirely correct. I was thinking about a different case and confused myself.

I'm still not clear on why you'd want this, though. Why would you prefer

let f = (b) => do { if (b) { 5 } else { 7} };

over

let f = (b) => { if (b) { return 5 } else { return 7} };

? It works fine and perhaps reads a bit nicer, if you're familiar with both arrows and do, but I'm not sure it warrants any further syntax just to support it.

pitaj commented 3 years ago

For the same reason I prefer

let f = |b| { if b { 5 } else { 7 } };

to

let f = |b| { if b { return 5 } else { return 7 } };

In rust.

Also, as far as arrow functions go, wouldn't this arrow syntax be an emergent property of arrow functions taking an expression and do expressions, well, being expressions?

pitaj commented 3 years ago

Yes it's just syntactically nicer to read and write, but that's kinda the purpose of adding syntax including this whole proposal.

bakkot commented 3 years ago

wouldn't this arrow syntax be an emergent property of arrow functions taking an expression and do expressions, well, being expressions

Right, it is. What I meant is, this issue is asking for further syntax, rather than just the things which arise naturally from allowing do anywhere you can use an expression. Using => do seems like it works well enough, for cases where you want to be maximally concise.

pitaj commented 3 years ago

Ah I didn't realize you were talking more generally. Yeah I don't think this idea is really that useful.