Skip to content

Instantly share code, notes, and snippets.

@DmitrySoshnikov
Last active April 16, 2016 12:00
Show Gist options
  • Save DmitrySoshnikov/de4727f57c5acc17e9469d1a91743125 to your computer and use it in GitHub Desktop.
Save DmitrySoshnikov/de4727f57c5acc17e9469d1a91743125 to your computer and use it in GitHub Desktop.
ES: Expression only

"Everything is an expression"... since ES1?

Many languages support "expression-only" semantics, allowing to use any construct in an expression position.

NOTE: the difference between expressions and statements is that the former produce a value, while the later don't.

For example, Ruby's if-expression:

x = 10

a = if x == 10
  100
elsif x > 10
  200
else
  300
end

puts "a is #{a}" # a is 100

JavaScript developers asked for this feature for a long time, however it's not possible to use if as an expression..

... or is it?

In fact, since even earlier versions, ECMAScript supports evaluation of blocks returning the value of the last evaluated statement in it. Which is the exact semantics of such expressions in other languages.

There is a proposal for do-expressions now, though even today, it's possible, and always was. However, with the approach described, it is yet impractical since uses eval to achieve this.

Still though, proving the concept:

let x = 10;

let a = eval(`
  if (x === 10) {
    100;
  } else if (x > 10) {
    200;
  } else {
    300;
  }
`);

console.log(`a is ${a}`); // a is 100

This directly corresponds to the do-expression that brings a bit of a sugar:

let x = 10;

let a = do {
  if (x == 10) {
    100;
  } else if (x > 10) {
    200;
  } else {
    300;
  }
};

console.log(`a is ${a}`); // a is 100

Or even switch-expression:

let x = 10;

let a = eval(`
  switch (x) {
    case 10: 100; break;
    case 20: 200; break;
    default: 300;
  }
`);

console.log(a); // 100

As we see, there is no any magic here, the feature is and was always specified by the ES standard. It is very convenient and useful, so we look forward to get do-expressions soon.

Also if you use Babel, it already supports it as an experemental plugin.

Have fun with ES ;)

@KittyGiraudel
Copy link

Pardon my ignorance, but what about an IIFE instead of eval(..)?

let a = (function do () {
  if (x == 10) return 100;
  else if (x > 10) return 200;
  return 300;
}());

@DmitrySoshnikov
Copy link
Author

@hugogiraudel, yep, this works too of course, though is overloaded with a function activation, and syntactically with a bunch of returns inside. The eval is not better of course, that's why a special syntactic construct, such as the do-expression would help.

@lewisje
Copy link

lewisje commented Apr 6, 2016

That particular example would throw an error, because do is a reserved word and therefore cannot be the name of a function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment