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

Suggestion: 6to5 instead of built-in transforms #1641

Closed
jods4 opened this issue Jan 11, 2015 · 13 comments
Closed

Suggestion: 6to5 instead of built-in transforms #1641

jods4 opened this issue Jan 11, 2015 · 13 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead

Comments

@jods4
Copy link

jods4 commented Jan 11, 2015

This is a radical suggestion but I think it makes sense.
Today, Typescript does two different things: it provides an awesome strongly-typed experience for coding javascript applications and it transpiles your code into equivalent javascript for various targets (es3, es5, es6).

These things are not strongly related and could easily be split into two distinct parts. In fact, lots of projects already try to do the second part. Notably 6to5, which is certainly the best es6 transpiler that exists today.

My suggestion is to drop any transpiling at all, drop the target options and always emit ES6 code. Because TS tries to align with ES, the emit code would mostly just remove the type annotations. This ES6 result can then be piped into 6to5 and we'll get our final js code, compatible with the browsers that we intend to support.

Why would you do that?

@basarat
Copy link
Contributor

basarat commented Jan 12, 2015

Sounds like an idea for a _great_ community TypeScript project!

@sebmck
Copy link

sebmck commented Jan 13, 2015

There's so much duplication of effort in transpiling ES6. It's tough to actually get a solid ES6 implementation and it's much harder than most people think. 6to5 has built-in support for parsing flow types so if complete ES6 and types is something that tickles your fancy then you can just switch to flow.

@basarat
Copy link
Contributor

basarat commented Jan 13, 2015

6to5 has built-in support for parsing flow types

wouldn't it be able to just parse TypeScript as well?

@sebmck
Copy link

sebmck commented Jan 13, 2015

@basarat Probably, I'm not familiar with TypeScript types or any of the other features.

@fdecampredon
Copy link

I'm not 100% confortable with this idea for few reasons :

  • I'm pretty sure that there is type construct that are not supported by 6to5 parser
  • 6to5 emit code that is not as close to the source than typescript emitter
  • There is a lot of typescript construct that are specific to typescript and those are not supported by 6to5 (private/public/protected, property initialization in class, literal module etc...)
  • Double parsing is not a good idea (for perf obviously), sure typescript could emit spider-monkey AST instead of code but that is a bit complicated in my point of view.

@jods4
Copy link
Author

jods4 commented Jan 13, 2015

@fdecampredon To be clear, because the comments have strayed away a little bit:

  • My suggestion was not to parse Typescript with 6to5. My suggestion was to have Typescript compile to ES6 code (which it already does) and then (optionnally) have 6to5 compile the pure ES6 (no type at all) to ES5. I.e. drop the ES5 and ES3 targets and focus on developing TS, not yet another transpiler.
  • Do you have examples where 6to5 is very different from the original JS? Because 6to5 prides itself in being the transpiler that is closest to its source.
  • I didn't say TS should do no transform at all. Again my idea was that TS emits valid ES6 code. Obviously private/public/protected would be removed, types would be removed, property initialization would be emitted inside the ES6 constructor, etc.
  • Yes there is a perf hit. I'm pretty confident it's going to be acceptable for our use case (offline compilation of source files). Moreover, soon enough nobody will use 6to5. As you said perf tweaks are possible. Not sure what is simplest between generating AST and text -- but surely we already have one of those coded, so...

@fdecampredon
Copy link

Do you have examples where 6to5 is very different from the original JS? Because 6to5 prides itself in being the transpiler that is closest to its source.

from 6to5 repl:

class Test {
  test() {

  }
}
// === compiled ==
var _prototypeProperties = function (child, staticProps, instanceProps) {
  if (staticProps) Object.defineProperties(child, staticProps);
  if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};

var Test = (function () {
  function Test() {}

  _prototypeProperties(Test, null, {
    test: {
      value: function () {},
      writable: true,
      enumerable: true,
      configurable: true
    }
  });

  return Test;
})();

I didn't say TS should do no transform at all. Again my idea was that TS emits valid ES6 code. Obviously private/public/protected would be removed, types would be removed, property initialization would be emitted inside the ES6 constructor, etc.

Basicly it's already something you can do with the recent ES6 target minus the features that are not implemented (yet).
So why not letting the typescript team maintains the ES3 and ES5 target for those whom not want to use 6to5 ? :)

Yes there is a perf hit. I'm pretty confident it's going to be acceptable for our use case (offline compilation of source files). Moreover, soon enough nobody will use 6to5. As you said perf tweaks are possible. Not sure what is simplest between generating AST and text -- but surely we already have one of those coded, so...

With all the effort the ts team has put in providing an efficient compiler with incremental parsing etc I doubt they would agree that the perf hit is acceptable but why not.

@NoelAbrahams
Copy link

The 6to5 emit looks like someone's eaten a pretty cake and spat it all out.

@RyanCavanaugh RyanCavanaugh added the By Design Deprecated - use "Working as Intended" or "Design Limitation" instead label Jan 13, 2015
@RyanCavanaugh
Copy link
Member

This isn't a road we're going down. I think fdecampredon touched on all the relevant points here. In an alternate universe where we hadn't even written a compiler yet and ES3 were actually 100% dead, it might be a different conversation, but we can't recover that sunk cost or force IE8 to disappear any more quickly. The performance aspect is also very critical and I'm skeptical about whether we could ever make this arrangement fast enough.

@jods4
Copy link
Author

jods4 commented Jan 13, 2015

@fdecampredon
That emit is not as dirty as you think.

_prototypeProperties is a helper method that you only need to include once in your project so you must not see it as part of the emit for your class code. If that really bothers you, you should know TS does the same, e.g. with __extends for class inheritance.

The wrapper function and so on? TS does exactly the same.

So we're left with the little verbose writable / enumerable / configurable bit. It's really not a big difference but I agree TS is terser here. Here's the catch though: 6to5 is correct, TS is not. See #1601.

Basicly it's already something you can do with the recent ES6 target minus the features that are not implemented (yet).
So why not letting the typescript team maintains the ES3 and ES5 target for those whom not want to use 6to5 ? :)

I listed why in my original suggestion. To repeat myself: transpiling is a complicated problem that has no lasting value and is already solved -- in a more correct way -- elsewhere. Like others (see #1644) I would like to see the TS team make faster progress in their implementation and the transpiling is just a waste of their time that we could do without.

With all the effort the ts team has put in providing an efficient compiler with incremental parsing etc I doubt they would agree that the perf hit is acceptable but why not.

I think you take a very quick shortcut here that is not an honest argument:

  1. About the rewrite: sorry but their old compiler was way too slow. I used it on medium to even small (but complex) codebases and it was so slow that I actually gave up on TS. I just couldn't get work done fast enough.
  2. Moreover you blindly mix up several use cases. Incremental parsing is most relevant in the live coding experience. It's of the utmost importance that TS is fast when I type, that my IDE is responsive and quick to provide feedback (highlight errors and so on). The emit of ES5 javascript only happens on full file compilation, let's say on save or during your build process. So it's irrelevant to this use case. The requirements for speed are much less here.
  3. This question can only be addressed with real, measured numbers. The only real additional cost here is the parsing of the JS file and some analysis that TS would have already done. Parsing a JS file is fast operation. As you said optimization opportunities exist here.

@jods4
Copy link
Author

jods4 commented Jan 13, 2015

@RyanCavanaugh fair enough. Sunk costs are not recoverable indeed but you know that you have a lot of work ahead of you. "Throwing good money after bad" comes to mind.

Anyway, whatever you do I hope you'll be able to speed up the implementation of ES6. Looking at the issues here, it's easy to see that many people are eager to get those features.

With fully compliant browsers coming this year, good transpilers already available, the Flow project, more and more projects going this way (Angular 2 and Durandal nextgen)... the pressure raises.

@DanielRosenwasser
Copy link
Member

@jods4 if you're truly missing any specific features, you're more than welcome to send us a pull request at any time.

@Arnavion
Copy link
Contributor

@jods4

To repeat myself: transpiling is a complicated problem that has no lasting value and is already solved -- in a more correct way -- elsewhere.

Agreed, and it's been solved multiple times in different ways. There's a lot of ES6->5 transpilers out there, varying in the readability of their output and the features they support with what compatibility. Rather than fix on one, it's better for TS to remain independent. You can always tell TS to emit ES6 and use your preferred transpiler on its output as part of your build process.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead
Projects
None yet
Development

No branches or pull requests

8 participants