Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ES6 / ES7 support via BabelJS #11

Open
idibidiart opened this issue Sep 23, 2015 · 12 comments
Open

ES6 / ES7 support via BabelJS #11

idibidiart opened this issue Sep 23, 2015 · 12 comments
Labels

Comments

@idibidiart
Copy link

Is it possible to use ES6/7 features like async/await ? Can you show a working example?

@anko
Copy link
Owner

anko commented Sep 23, 2015

Not yet.

I've been targeting ES5 only so far, because the estree spec and related tooling are still catching up with ES6 (e.g. estools/esvalid#7). So if it existed, it would have to be behind an --experimental flag.

However, it should be quite possible to add even now: All the built-in macros just emit estree objects that are compiled by escodegen. There is an experimental estree spec for async/await and escodegen seems to support it!

I'll try it sometime soonish—PR welcome too.

@anko anko added the idea label Sep 23, 2015
@lhorie
Copy link

lhorie commented Nov 3, 2015

It looks like as of version 6.0, Babel is no longer ESTree compliant. I opened an issue over there but the author said he's not willing to support the standard format anymore.

@anko
Copy link
Owner

anko commented Nov 4, 2015

Perhaps we should altogether move to target Babel's AST spec?

Pros:

  • Much easier to use experimental features.
  • Can use other stuff in Babel's ecosystem, though I'm not familiar with it.

Cons:

  • It's work.
  • Lose estools-compatibility. The ones we're using are—
    • esvalid for readable errors, but Babel might too.
    • esutils for isExpression, but it's fairly simple to reimplement.

@lhorie
Copy link

lhorie commented Nov 4, 2015

That's a possible solution. Another solution is to write a compatibility layer that takes a estree ast as input and outputs a babel ast.

@hzoo
Copy link

hzoo commented Nov 4, 2015

@lhorie not sure if you saw my comment in the issue (maybe missed it since it was right before yours) but basically I'l be doing a compatibility layer

@lhorie
Copy link

lhorie commented Nov 4, 2015

Ooh nice. That's awesome to hear. I totally did miss your comment. @hzoo

@hzoo
Copy link

hzoo commented Nov 6, 2015

@lhorie babel/acorn-to-esprima#3 - I'l need to add a lot more tests since I know some of the loc/range info is wrong now.

anko added a commit that referenced this issue Nov 6, 2015
This change allows macros to return arbitrary [estree][1] objects as an
alternative to returning arrays and objects as usual.

This means you can now write macros that support estree features that
eslisp doesn't yet (e.g. ES6 arrow functions), as long as [escodegen][2]
supports them.  You can even use crazy experimental estree extensions
(e.g.  Facebook's [JSX][3], or #11; ES7 async/await), as long as your
macro can do the appropriate transformation to the core eslisp standard
that escodegen understands before returning.

[1]: https://github.com/estree/estree
[2]: https://github.com/estools/escodegen
[3]: https://github.com/facebook/jsx
anko added a commit that referenced this issue Nov 6, 2015
This is a major rework of the macro API to clean up abstractions.  I
tried to avoid making a single large commit, but because the macro API
touches almost everything, this was hard to chunk.

Summary of changes
------------------

These changes eliminate the technical distinction between user-defined
and built-in macros.  Now all macros take JS objects as arguments and
output either those same JS objects or estree objects.

S-expressions are now always represented in the form

    {
      type : "list",
      values : [
        { type : "atom", value : "f" },
        { type : "string", value : "hi" }
      ]
    }

This unification of macro formats also means dropping the "capturing
macros" vs "non-capturing macros" distinction.  Macro return values can
now contain calls to any macro in their outer environment (also macros
defined after them), which fixes #27.

User macros being able to return estree objects also enables
experimental estree extensions like JSX or ES6/7 features (#11).  As
long as you can come up with a way of converting them to valid estree
that [escodegen][1] understands, anything goes.

Now that user macros can access the full compilation environment that
built-in macros use, they can do low-level stuff like create new macro
environments with `env.derive`, and query the macro table with
`env.findMacro`.  These can be very helpful when debugging.

Also threw away some tests that were just showing off rather than
actually testing something, and made some others more specific.

Still-awkward points
--------------------

These will be addressed in soon forthcoming commits.

The macro environment (containing stuff like the `compile` and
`evaluate` functions) is currently passed to macros as the first
argument, which is super clumsy to use, but was great for
integration-testing that these changes are OK otherwise, since that's
how all the built-in macros received their env.  The environment should
be passed as `this`.

The "type-value"-object format is quite annoying to write out in full,
and is fragile to future changes.  It might be cleaner to expose S-expr
AST-node constructors on the environment object, so they could be
constructed with a simple `env.atom("hi")` call and typechecked with
`instanceof`.

 [1]: https://github.com/estools/escodegen
@dead-claudia
Copy link
Contributor

Update: escodegen fully supports ES6 AFAICT, and I've already started some of this process in #41.

@11111000000
Copy link

#41 merged, any news here?

@anko
Copy link
Owner

anko commented Jun 14, 2016

@11111000000

#41 isn't merged, and so the macros that eslisp comes with don't support ES6 yet. The current approach in #41 still introduces ambiguity, as outlined in the description of my PR dead-claudia#1. I think that path isn't going to work out, since most of ES6 changes are at the syntactic level.

I'd bet on an eventual solution coming through #24.

For now, if you're desperate, with #34 merged you can write macros that return ES6 estree objects. If you like, you could try returning such an object from your own macros, like this.

@11111000000
Copy link

@anko: thanks, watch closely

@dead-claudia
Copy link
Contributor

May I also point out that the isExpression, etc. are part of Babel, anyways (and they've been that way since at least 5)? I'm not a huge fan of Babel, but I just thought I'd point that out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants