tc39 / proposal-do-expressions

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

What would a do statement return? #67

Closed Explosion-Scratch closed 3 years ago

Explosion-Scratch commented 3 years ago

In the README there is an example as such:

let x = do {
  if (foo()) { f() }
  else if (bar()) { g() }
  else { h() }
};

What would the value of x be?

Would it act like a function with return (and if so why have this)? What would the real usage of this?

nicolo-ribaudo commented 3 years ago

That code would be equivalent to this:

let x = (() => {
  if (foo()) { return f() }
  else if (bar()) { return g() }
  else { return h() }
})();

The difference bwtween do expressions and iife (other than the implicit "return") is that you can use control flow statements that affect the outer scope. For example:

function getName(str) {
  const person = do {
    let data = JSON.parse(str);
    if (!data.hasName) return null;
    data.person;
  };
  return person.name;
}

is equivalent to

function getName(str) {
  let didReturn;
  let returnValue;
  const person = (() => {
    let data = JSON.parse(str);
    if (!data.hasName) {
      didReturn = true;
      returnValue = null;
      return;
    }
    return data.person;
  })();
  if (didReturn) return returnValue;
  return person.name;
}
Explosion-Scratch commented 3 years ago

The difference between do expressions and iife (other than the implicit "return") is that you can use control flow statements that affect the outer scope. For example:

function getName(str) {
 const person = do {
   let data = JSON.parse(str);
   if (!data.hasName) return null;
   data.person;
 };
 return person.name;
}

So in this function if !data.hasName null would be returned to from the genName() function, right? Also variables in a do statement act much like a with statment in that the variables and such defined there are scoped to the parent scope, right? So this would work:

function aFunction(){
do {
let scoped = "yay";
}
return scoped
}

but this would not:

function aFunction(){
(() => {
let scoped = "yay";
})()
return scoped;//Error, scoped is not defined
}
nicolo-ribaudo commented 3 years ago

do expressions act exactly as normal block statements.

So in this function if !data.hasName null would be returned to from the genName() function, right?

Yes, exactly.

So this would work:

function aFunction(){
  do {
    let scoped = "yay";
  }
  return scoped
}

No, similarly to how this doesn't work:

function aFunction(){
  {
    let scoped = "yay";
  }
  return scoped
}

However, this would work:

function aFunction(){
  (do {
    var scoped = "yay";
  });
  return scoped
}

exactly as this currently works in JS:

function aFunction(){
  {
    var scoped = "yay";
  }
  return scoped
}
Explosion-Scratch commented 3 years ago

Okay! Thanks!