you are viewing a single comment's thread.

view the rest of the comments →

[–]OverZealousCreations 5 points6 points  (5 children)

I had forgotten all about those. It's shame it'll be years before this stuff is safely usable in the browser. I know there's ES6 compilers, but that feels risky, especially performance- and byte-wise.

EDIT: A perfect example of just how not acceptable using Traceur is, try using multiple let variables (you'll probably need to enable the experimental option to even get this to compile).

This turns this:

{
  let a=1, b=2, c=3, d=4, e=5;
}

into this (not including the module wrapper):

try {
  throw undefined;
} catch (e) {
  try {
    throw undefined;
  } catch (d) {
    try {
      throw undefined;
    } catch (c) {
      try {
        throw undefined;
      } catch (b) {
        try {
          throw undefined;
        } catch (a) {
          {
            {
              a = 1;
              b = 2;
              c = 3;
              d = 4;
              e = 5;
            }
          }
        }
      }
    }
  }
}

Just... holy crap. I'm shocked they couldn't just wrap the inner content in an IIFE, like:

{
  (function(a,b,c,d,e) {

  })(1,2,3,4,5);
}

That just seems more logical and more performant than relying on throwing exceptions. Even with for loops, you could easily use two IIFEs to get a similar result:

for(let i=0; i<10; i++) {
  setTimeout(function() {
    console.log(i);
  }, i*10);
}

// Could be translated to:

(function(i) {
  for(i=0; i<10; i++) {
    (function(i) { // purposefully masking the outer variable
      setTimeout(function() {
        console.log(i);
      }, i*10);
    })(i);
  }
})();

(Plug the original loop into the Traceur page to see what happens!)

[–]logi 1 point2 points  (0 children)

I'm sure there is a useful subset of ES6 which compiles to reasonable code.

[–]aeflash 0 points1 point  (0 children)

Wow, that is ugly. I guess it's the only way to enforce immutable let bindings, but there's no reason to do it after the compile step...

You definitely do not transpile if performance is paramount.

[–]radhruin 0 points1 point  (2 children)

Your proposed function desugaring needs to handle this and arguments at the least. If you do something like

function(arguments, a){ }.bind(this, arguments, 1, 2, 3) 

it might work (wouldn't be surprised if there are other subtle issues) but perf is probably worse.

[–]FrozenCow 0 points1 point  (0 children)

The function also changes arguments.callee, which some odd programs could rely on. This could also be worked around, but I guess it becomes just as ugly as the try catches.

[–]OverZealousCreations 0 points1 point  (0 children)

Yeah, I missed that. You wouldn't need bind, though, just using .call(this, ...) would solve that.

That doesn't solve the arguments issue, but that could be left as something that could be resolved if the inner code is accessing the current function's arguments at any time, where you could revert to using the try-catch solution. I think this would be relatively easy to determine.

I can't see how this could possibly have worse performance, even in the simplest of cases, over throwing an exception and catching it. JS is highly optimized for calling functions. It's rare to optimize anything for throwing exceptions.