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

Opt-In Language Features to prevent Embrace and Extend -- Compiler options on tsc.js #2261

Closed
matthiasg opened this issue Mar 8, 2015 · 19 comments
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript

Comments

@matthiasg
Copy link

I am missing the ability to disable certain typescript compiler features. E.g i would like to disable all non ES6 style module features (i am not talking about require of course, just the actual typescript inventions before ES6 modules).

In general, I believe tsc.js would benefit from having an optional configuration json file to ensure that all team members are using the same subset of features.

Since typescript is seemingly becoming a hybrid compiler, mixing ES6/7 stuff with typescript inventions, it makes my unsure whether i should jump on it without a change in defaults.
I would much rather have it be a ES6 compiler first with non standard features such as e.g previous module syntaxes, AtScript or ES7 features etc as opt-in features in a compiler option file (flags on command line).

It could be argued of course to default-opt-in into some features that are basically agreed upon etc, as long as you can always opt-out of them

Without that feature i think it will be difficult for my team to switch to TS since there would be a danger of accidentally using non-standardized language features which would prevent us from choosing another ES6/7 compiler at some point.

PS: I did not find those in node tsc\tsc.js --help nor in the Wiki. Next stop would be the code.

@DanielRosenwasser
Copy link
Member

I wouldn't be opposed to introducing a flag that warns on deprecated features like pre-ES6 external module syntax.

I personally don't like the idea of introducing a flag that warns you when you use TypeScript specific features; should we warn you every time you declare an interface? What about type annotations? Neither are part of ES6, but they fundamentally make TypeScript what it is.

I hope you don't feel a sense of lock-in with us. This is a FOSS project. We strive to ensure our output looks like canonical, readable JavaScript, and we actively try to avoid adding features that would conflict with any future ECMAScript proposals.

If you're really set on using TypeScript as a strict ES6 downlevel compiler, here's a list of TypeScript-specific features that I can think of:

  • Interfaces, type aliases, type annotations
  • Generics
  • Class visibility modifiers (public/private/protected)
  • Parameter properties (constructor(public foo: number, private bar: string))
  • Default property initializers in classes (ES7 proposal, React supports it as well)
  • Enums & const enums
  • Internal modules (soon to be namespaces)
  • Optional parameters (function foo(x: number, y?: string) { })
  • Function overload signatures.
  • The declare modifier
  • Pre-ES6 external module syntax

As you can see, most of the features actually have to do with types and structuring your program. When 1.5 is released there may be more, but we are hoping that they will be folded into ES7.

@matthiasg
Copy link
Author

Thanks @DanielRosenwasser for the thoughtful response.

I have nothing specific against typeinformation and the extensions that go with it, since those all compile away. Writing a parser/compiler that simply removes those is fairly trivial.

The point is, after that step, what remains should indeed be standard ES. Whether its ES6 or even some ES7 I wouldn't care much about as long as there those features are not too hotly debated still, and there are other compilers that could be swapped in.

Looking at the typescript specs and the fact that it seemingly didn't delineate between those features that help with typing and those that move JS into a new direction (internal modules/namespaces/others?) raised some flags with me. I suddenly would have to read the spec , and every update, in its entirety to ensure no creep in unwanted directions by myself or my colleagues.

A compiler flags to remove/flag/warn on the 'non-standard/non-type' related parts would be welcome. A flag for disabling all shouldn't be needed, since that would just be normal JS and the file type could reflect that.

I think it would help for the TypeScript team,specs/documentation to think of themselves as a ES6/7 compiler with types and not as a Javascriptish language. While I would be willing to give new Microsoft another chance with TS, unclear specs and communication like this might put some people off. Especially those that haven't had the opportunity to get to know the team like me.

Choosing a platform and language is a lot about faith in the direction the creators are going for me and the ability to remain independent.

@CyrusNajmabadi
Copy link
Contributor

@matthiasg Regarding "and the ability to remain independent." It's worth noting that TypeScript acts as a transpiler. At the end of the day, nothing actually executes TypeScript code. So our entire system is designed around creating javascript. So if, at any point, you feel like you don't want to use TypeScript anymore, then simply compile your code, take the emitted javascript and just use that from now on.

I think this addressed your initial concern of:

Without that feature i think it will be difficult for my team to switch to TS since there would be a danger of accidentally using non-standardized language features which would prevent us from choosing another ES6/7 compiler at some point.

If you intend to use another ES6/7 compiler then you should always be able to do so. You just take the actual EcmaScript we produce and you go and use those compilers.

@matthiasg
Copy link
Author

Not sure that is actually usable. Of course I could compile all my coffee code to js and work from there, but it looks sufficiently different as not to be a nice environment anymore.

The original advantage of typescript for me would be, that the features are mostly extra characters with respect to Es6/7 and thus easily removable.

Regards,
Von meinem Windows Phone gesendet

-----Original Message-----
From: "CyrusNajmabadi" notifications@github.com
Sent: ‎13.‎03.‎2015 11:42
To: "Microsoft/TypeScript" TypeScript@noreply.github.com
Cc: "matthiasg" mgt576@gmail.com
Subject: Re: [TypeScript] Opt-In Language Features to prevent Embrace andExtend -- Compiler options on tsc.js (#2261)

@matthiasg Regarding "and the ability to remain independent." It's worth noting that TypeScript acts as a transpiler. At the end of the day, nothing actually executes TypeScript code. So our entire system is designed around creating javascript. So if, at any point, you feel like you don't want to use TypeScript anymore, then simply compile your code, take the emitted javascript and just use that from now on.
I think this addressed your initial concern of:
Without that feature i think it will be difficult for my team to switch to TS since there would be a danger of accidentally using non-standardized language features which would prevent us from choosing another ES6/7 compiler at some point.
If you intend to use another ES6/7 compiler then you should always be able to do so. You just take the actual EcmaScript we produce and you go and use those compilers.

Reply to this email directly or view it on GitHub.

@CyrusNajmabadi
Copy link
Contributor

You're not making an apples/oranges comparison. Coffee and TypeScript approach things in a different manner.

"The original advantage of typescript for me would be, that the features are mostly extra characters with respect to Es6/7 and thus easily removable."

This advantage should still remain. can you give examples of where it doesn't?

@danquirk
Copy link
Member

Not sure that is actually usable. Of course I could compile all my coffee code to js and work from there, but it looks sufficiently different as not to be a nice environment anymore.

If you look at the emitted JS from your TS you'll see that the situation is very different from your Coffeescript experience. It is an explicit goal that the JS you get from the TypeScript compiler is very close to what you would have written yourself had you not had the TS sugar, see goal 4 here https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

@matthiasg
Copy link
Author

I did 😉 Yes syntactically it looks nice (that's not why I brought up coffee) but were coffee is different enough when compiled due to some syntax elements, Ts can look different enough due to e.g
modules/namespaces that aren't in any js spec or solved differently now and thus there are multiple ways, all of which supported by the compiler without warnings.

Those are the things I am hesitant about. And of course other things like that during the continuing evolution of the language..

Thanks for listening to my concerns though.

All I would like is a compiler warning or deprecation warning when using certain features. Possibly the ability to switch on/off those features to ensure standardization of my team.

Regards

-----Original Message-----
From: "Dan Quirk" notifications@github.com
Sent: ‎13.‎03.‎2015 20:30
To: "Microsoft/TypeScript" TypeScript@noreply.github.com
Cc: "matthiasg" mgt576@gmail.com
Subject: Re: [TypeScript] Opt-In Language Features to prevent Embrace andExtend -- Compiler options on tsc.js (#2261)

Not sure that is actually usable. Of course I could compile all my coffee code to js and work from there, but it looks sufficiently different as not to be a nice environment anymore.
If you look at the emitted JS from your TS you'll see that the situation is very different from your Coffeescript experience. It is an explicit goal that the JS you get from the TypeScript compiler is very close to what you would have written yourself had you not had the TS sugar, see goal 4 here https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

Reply to this email directly or view it on GitHub.

@mhegazy
Copy link
Contributor

mhegazy commented Mar 13, 2015

A linter, (e.g tslint) seems like a good place to enforce your team policies.

@matthiasg
Copy link
Author

a linter is not the same as a clear compiler switch to enable warnings/errors. also it would be a separate project and by definition would have to be kept in sync ts, since it cannot see things it doesnt know about.

adding a simple switch (similar to c++ compilers /Za or http://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/C-Dialect-Options.html) would be much easier. Also I believe they are likely to have the infrastructure for that already , making this trivial.

@matthiasg
Copy link
Author

@CyrusNajmabadi as stated i was immediately alarmed due to the differing namespace and module syntaxes which are not easily removable since they influence structure. Seeing that gave me the feeling there might be other parts like that or there might be other parts like that in the future.

As for my original point. I strongly believe any language extensions of any compiler on top of any 'standardized' language should be clearly defined, clearly communicated and allow to be disabled.

We can talk hours about whether this or that extension makes sense and be defaulted on or off but thats not my point.

PS:
IMHO it seems TS team does really think of themselves as writing their own Javascriptish language where anything goes instead of respectfully adding features (Types) and not taking deviations from proposes ES6/7 syntaxes lightly but coordinate with actual node/js devs. If they dont do that TS will be perceived as arrogant and be accepted mostly by MS ecosystem devs (which i am not anymore).

@CyrusNajmabadi
Copy link
Contributor

@matthiasg You haven't really addressed the point i made. Your concern was:

Without that feature i think it will be difficult for my team to switch to TS since there would be a danger of accidentally using non-standardized language features which would prevent us from choosing another ES6/7 compiler at some point.

Right now it appears as if that concern isn't really grounded in the current state of TypeScript. Can you be more specific as to how you are actually prevented from choosing another ES6/7 compiler in the future? I've pointed out why i think you should not be concerned here, and why your response didn't really address my point. Your latest post doesn't seem to address the points i was making, so i'm still left with being uncertain about where your concerns are coming from. Clarification would definitely be appreciated. Thanks!

@matthiasg
Copy link
Author

Ok .. Let's try this really short:

  1. there are features in typescript such as modules/namespaces right now
  2. these features influence structure of the application
  3. they are not aligned with es6 modules as far as I can see
  4. language elements like this will remain even though they are outside of what I would consider type extensions or es6/7
  5. I like compilers that allow me to define what features i allow as extensions. Just like with gcc or ms c++. E.g I might like c++10 .. I might not like my team to use it everywhere though.

Basically i was trying to ask politely what the intent of the language is. And if they actually mean it to be es6++ then i would appreciate the ++ part to be well defined and in some cases even to be controlled via standard compiler switches like others have it too.

Obviously my point seems moot though. Since this discussion is not really fruitful yet. I don't actually even understand why there is a 'discussion'.. So i am inclined
to close the issue and move on.

Cheers,

Von meinem Windows Phone gesendet

-----Original Message-----
From: "CyrusNajmabadi" notifications@github.com
Sent: ‎15.‎03.‎2015 12:23
To: "Microsoft/TypeScript" TypeScript@noreply.github.com
Cc: "matthiasg" mgt576@gmail.com
Subject: Re: [TypeScript] Opt-In Language Features to prevent Embrace andExtend -- Compiler options on tsc.js (#2261)

@matthiasg You haven't really addressed the point i made. Your concern was:
Without that feature i think it will be difficult for my team to switch to TS since there would be a danger of accidentally using non-standardized language features which would prevent us from choosing another ES6/7 compiler at some point.
Right now it appears as if that concern isn't really grounded in the current state of TypeScript. Can you be more specific as to how you are actually prevented from choosing another ES6/7 compiler in the future? I've pointed out why i think you should not be concerned here, and why your response didn't really address my point. Your latest post doesn't seem to address the points i was making, so i'm still left with being uncertain about where your concerns are coming from. Clarification would definitely be appreciated. Thanks!

Reply to this email directly or view it on GitHub.

@matthiasg
Copy link
Author

btw from the original list above. I have no qualms about the type extensions. Its really only about the following where it would be totally ok to cull this list when there is consensus of these in es6/7.

•Parameter properties ( constructor(public foo: number, private bar: string) )
•Enums & const enums
•Internal modules (soon to be namespace s)
•Function overload signatures unless they are constrained to type definitions without actual branching into different code
•Pre-ES6 external module syntax

@danquirk
Copy link
Member

IMHO it seems TS team does really think of themselves as writing their own Javascriptish language where anything goes instead of respectfully adding features (Types) and not taking deviations from proposes ES6/7 syntaxes lightly but coordinate with actual node/js devs. If they dont do that TS will be perceived as arrogant and be accepted mostly by MS ecosystem devs (which i am not anymore).

This is absolutely not the case. You can find numerous requests from customers for many features, particularly expression level syntax, which we decline due to potential lack of alignment with future versions of JavaScript. See #16 (comment), #479 (comment) and many others. It is of the utmost importance that TS remains in alignment with JS. We participate in TC39 regularly to ensure we're all moving in a consistent direction and aren't at odds with one another (you can see the notes on https://esdiscuss.org/notes).

You seem mostly hung up on the module syntax which as noted in one of the comments I linked was mostly an unfortunate artifact of the ES module proposal taking a long time and TypeScript needing to make progress. You can see the discussion on the ES6 modules work here #2242 and we fully intend to promote that as the way forward and not our old module syntax that was based on what ES was doing at the time (although we will of course not be breaking that any time soon).

Function overload signatures unless they are constrained to type definitions without actual branching into different code

Function overloads are only type information. They do not affect code gen at all.

Parameter properties, enums and internal modules/namespaces are very light syntax sugar that emit essentially exactly what you would've written by hand in JavaScript. You're at no risk of using these features and being unable to just take the resulting clean JS and ignore TS going forward.

@CyrusNajmabadi
Copy link
Contributor

Hi @matthiasg , i feel like there is some frustration with my feedback so far. Allow me to try to help clarify my position, which will hopefully make things more understandable and less frustrating. Right now i'm definitely hearing from you what you want. My main issue stems from trying to determine if what you want actually makes sense and is grounded on solid reasons for why you need these changes.

Currently, i have not seen enough justification provided. The concerns you've raised have been somewhat vague so far, and this has made me prompt for more information so i can understand if your specific concerns do merit work, or if it might be the case that there aren't specific issues, and thus no work is necessary.

The best way to convince me that your concerns warrant changes are to provide specific examples of where there is a problem, and why the proposed solutions so far are insufficient. Right now you've simply listed things you don't like, but you haven't explained why the solution presented so far would not work for you. For example, you mention:

Parameter properties ( constructor(public foo: number, private bar: string) );

Currently parameter properties get rewritten to the following:

    constructor(public a: number) {}
    function C(a) {
        this.a = a;
    }

Now, you originally started with:

Without that feature i think it will be difficult for my team to switch to TS since there would be a danger of accidentally using non-standardized language features which would prevent us from choosing another ES6/7 compiler at some point.

However, if you end up wanting to choose another ES6/7 compiler you'll have to transpile your TS into a form (since TS is already not ES6/7). So, when you transpile your constructors that use parametr properties, you get clean, idiomatic JS code (as shown above). So you will not be 'prevented' from moving at all.

This is my difficulty with teh entire discussion. You've raised a very real concern (not being able to move away easily). However, that's a concern we've already thought about, and put a lot of effort to ensure won't be an issue. As an engineer, i don't want to implement another system to try to alleviate this concern when i think the existing one is already sufficient.

Looking at the rest of your examples, i'm left feeling the same way. Without specifics i'm wary about putting in a feature to solve a problem which, upon deeper inspection, may not actually exist.

Thanks!

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Out of Scope This idea sits outside of the TypeScript language design constraints labels Mar 16, 2015
@RyanCavanaugh
Copy link
Member

It would be very easy to write a linter or some other sort of tool that would fit into a build pipeline to detect certain language features you don't want to use (for whatever reason, I don't want to question that part of the premise).

I realize you've said you don't want to use a separate linter, but this is the same kind of thing that linters for other languages do already. FxCop for C#, PyLint for Python, JSHint for JavaScript, lint for C, etc etc etc -- if you want to wall off some portions of the language, this is the pattern that is broadly followed.

As others have noted, "I want to move from TypeScript back to JavaScript" is absolutely a scenario we care about. If you think there are actual concrete problems that prevent that scenario from working, please file bugs on those problems and we can try to address those.

@matthiasg
Copy link
Author

First of all thanks for the feedback.

It is true I was mostly put of by the old style module syntax, since I only looked into Ts after the angular announcement. Basically what @danquirk wrote did convince me, but I still don't understand why the compiler couldn't emit a warning for features clearly seen as legacy compatibility.

@danquirk
Copy link
Member

but I still don't understand why the compiler couldn't emit a warning for features clearly seen as legacy compatibility.

Certainly from a technical perspective we could, but this is always a tricky proposition. On one hand you would like to get people on the new hotness as soon as possible (for everyone's benefit). On the other hand we have to accept that a lot of people have working code with the old style that's still in development/maintenance but they're not going to go and rewrite all their module imports for no/minimal gain ("if it ain't broke..."). If you suddenly add a ton of warnings/errors to their project when they upgrade to a new version of TypeScript it's mostly just going to be an annoyance (and potentially actually break their build system or whatever else is hooked in to checking compile results). It's not actually going to force them to rewrite all the module imports on a large project with 100s of them. Then you just have to provide some way to turn off that warning either per location, which requires a similar amount of work for the affected folks as just rewriting the imports, or globally, in which case you eventually end up with accruing a bunch of these compiler flags over time and peoples' command lines start looking like a mess of --suppressError 1234 1237 1289 etc. And then you've made the old style an error but still didn't actually get people upgraded. The best approach is generally the carrot, making sure the new thing is better and continues to get better in a way that actually adds value and encourages you to switch (making the old thing an error is the stick approach).

You can see this situation with a lot of features in various languages. For example, C# has multiple ways to declare anonymous methods which are basically all deprecated in favor of lambdas now. Some number of those old style methods persist even in codebases that have upgraded to newer versions of C#. But it's not an error or warning to use those old styles just because a newer one has been provided.

One other factor to consider is that TypeScript is still relatively young and while we're quite happy with our current level of success we certainly hope that the amount of TypeScript in the wild today represents just a small fraction of the TypeScript that will be in the wild 3-5 years from now. Given that we'll be advocating for the ES6 style modules going forward it should hopefully be the case that relatively little TypeScript code is using the older style modules in the future even if few people update their old code to the new style.

@matthiasg
Copy link
Author

@danquirk. Pragmatic argument. Not quite what e.g Babel is doing then, but hopefully it will indeed turn out like that.

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

6 participants