jlongster / es6-macros

A collection of sweet.js macros that implement ES6 features for ES5
BSD 2-Clause "Simplified" License
237 stars 18 forks source link

Fat arrows! #4

Closed ryanseddon closed 10 years ago

ryanseddon commented 10 years ago

Fat arrows implementation covers most cases.

Fixes #1

ryanseddon commented 10 years ago

I'd love to be able to cover no prototypes and clobbering arguments if that's possible. Any ideas?

jlongster commented 10 years ago

Yay, been looking forward to this one! I recently updated my repo to work with the latest sweet.js, and if I merge in this I'm hitting a bug with sweet.js with how my destructuring var and => plays. Once I fix that (in sweet.js I think) I'll think more about comment #2.

jlongster commented 10 years ago

I filed the bug here: https://github.com/mozilla/sweet.js/issues/271. Not sure which version of sweet you are using, but the internals have changed quite a bit in the past 2 months.

jlongster commented 10 years ago

Actually, I think it was mainly a bug in my code. The :expr on the lhs of a var was eating the whole assignment and messing up how things were expanded. This has made us think through how we handle a few things internally though.

Everything looks good, thanks a lot for this!

jlongster commented 10 years ago

We could check for arguments by parsing the function body code in a case macro. I do this in the class macro (the code is ugly right now). We could be really smart and check to see if arguments is not locally defined, and if found we would throw an error (or maybe just a warning).

This would add a bunch of code the macro, but we probably should do it at some point. I'm not too worried about it right now though.

I'm not sure if we can strip the prototype of it. Is there a valid way in ES5 to do that? Is it safe to just set f.prototype = undefined? If so we could probably get that in here.

ryanseddon commented 10 years ago

If we were to compile without hygienic renaming we could easily do the following

macro => {
  rule infix { ($value (,) ...) | {$body ...} } => {
    function($value (,) ...) {
     arguments = undefined;
     $body ...
    }.bind(this)
  }
  rule infix { ($value (,) ...) | $guard:expr } => {
    function($value (,) ...) {
     arguments = undefined;
     return $guard;
    }.bind(this)
  }
  rule infix { $param:ident | $guard:expr } => {
    function($param) {
     arguments = undefined;
     return $guard;
    }.bind(this)
  }
}

As for the prototype if we could access the function, setting the protoype to undefined would work too.