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

Cost benefit analysis #43

Open
LifeIsStrange opened this issue Mar 9, 2022 · 51 comments
Open

Cost benefit analysis #43

LifeIsStrange opened this issue Mar 9, 2022 · 51 comments

Comments

@LifeIsStrange
Copy link

A non erased javascript support for type would enable features such as type reflection and reified generics, which improve the expressivity of the language and make it more on par with modern languages.
However, currently this proposal is not making any use of the types despite them needed to be parsed or at least properly ignored.

The remaining stated benefit is that this support might (to be defined) reduce transpilation needs for e.g TypeScript.
However if I am understanding correctly, in all intellectual honesty this proposal should state that it is not a free lunch and that the cost of transpilation is offsetted to the Javascript parser/interpreter, which must now properly ignore those unused type informations.
Therefore you are offloading a one time cost (server side) to N billions of clients times.
While support for runtime type reflection might justify such added cost, without it this proposal seems like a net performance loss for end users.
There already exist plenty of fast server side TS transpilers such as SWC, esbuild, etc which make the proposal benefit seems even less interesting.
What do you think about this?

@y-nk
Copy link

y-nk commented Mar 9, 2022

to add on this, types as comments would require comments to be shipped as part of the js files, adding on loading time to some significant extend. they'd also need to be parsed, and for what end else than type errors thrown at runtime anyway.

@extremeheat
Copy link

to add on this, types as comments would require comments to be shipped as part of the js files, adding on loading time to some significant extend. they'd also need to be parsed, and for what end else than type errors thrown at runtime anyway.

That’s not any different with any other non-type comment in the code. Commenting code is not bad and should not be avoided to save a few bytes. Use a bundler as usual if this is a concern. For development and server side code, this is not a constraint to worry about either.

@ptomato
Copy link
Collaborator

ptomato commented Mar 9, 2022

This seems like both the disadvantage and advantage are well-covered in the FAQ already: https://github.com/giltayar/proposal-types-as-comments#will-the-ability-to-deploy-typed-source-code-directly-result-in-bloated-applications

@fabiospampinato
Copy link

fabiospampinato commented Mar 9, 2022

The remaining stated benefit is that this support might (to be defined) reduce transpilation needs for e.g TypeScript.

Besides the elephant in the room IMO is that it's good practice to bundle and minify anyway. This may get rid of tsc, if you write a subset of TS that most people may not actually restrict themselves to, but what for, a few seconds saved from compilation? That's something that can be solved by rewriting tsc with performance in mind already.

@edmundmunday
Copy link

@fabiospampinato - yes, but this would also allow you to remove an entire step from your tool-chain. A step many consider to be particularly laborious to deal with. I like the idea of types, I even like the idea of Typescript (incrementally), but the Typescript compiler often annoys the hell out of me.

If I could get 90% of the benefit of types in JS without having to have the whole extra step of managing the Typescript toolchain, I would use it.

@fabiospampinato
Copy link

fabiospampinato commented Mar 10, 2022

@edmundmunday I understand the sentiment but you are seeing benefits that don't exist into this:

  • First of all this doesn't let you run TS code in the browser, for example the following trivial function, which I'd expect to find in most code bases, would be unsupported:

    function isUndefined ( x: unknown ): x is undefined {
      return x === undefined;
    }
  • This doesn't remove the need for a build step either, even if you restrict yourself to the impractical subset of TS that this proposal proposes to spec. You are going to want to bundle and minify your code anyway, at some point shipping your app as thousands of files becomes nonsensical. And if you care about performance at all you are going to want to minify regardless of the size of your app.

  • Also this sounds pretentious maybe, but making the bundler parse TS code for you once you have a bundler is trivial really, and nowadays even configuring the bundler is pretty much a non problem with things like Parcel and Vite.

  • Besides if we are talking about shipping code to the browser whose codebase doesn't use JSX nor anything else that requires a build step anyway? The proposal maybe doesn't make this point clearly enough, most people's code wouldn't be fully covered by this proposal at all.

@orta
Copy link
Collaborator

orta commented Mar 10, 2022

I don't think the subset for TypeScript to fit in types-as-comments JS would be considered impractical. The set of features mentioned in the proposal so far are mainstream language features used all the time. With respect to syntax like assertion functions, something like:

function isUndefined ( x: unknown ): (x is undefined) {
  return x === undefined;
}

Could fit within the syntax space, and it's likely that this is a strategy for how ambiguity can be handed. For cases which can't be covered, .d.ts files and imported types are working reasonably well for folks using JSDoc types today (with TypeScript, but that doesn't mean it has to be the only solution)

but making the bundler parse TS code for you once you have a bundler is trivial really

In some ways, yes, but it requires updating regularly. This proposal would allow you to write that parser once for JS, and while doing so taking into account the specified way to not parse code in the type hole. You'd then have a parser for any other exploratory type-systems and future versions of them

@fabiospampinato
Copy link

fabiospampinato commented Mar 10, 2022

I don't think the subset for TypeScript to fit in types-as-comments JS would be considered impractical. The set of features mentioned in the proposal so far are mainstream language features used all the time.

Yes, that's not what makes the subset impractical, it's impractical because most codebases use features that aren't part of the subset. This may be an interesting experiment to run actually, one could scrape public TS repositories on github and check how many of them use only this subset of the language, I'd guess fewer than 5% of them do, and looking only at codebases that have 10K+ lines of code I'd guess fewer than 1%, maybe even less that 0.1%.

In some ways, yes, but it requires updating regularly.

I don't know I don't remember the last time I touched the code that configures webpack in my codebase, the last time I edited the section that takes care of handling TS was probably when I first configured webpack really. Besides I'm not sure I agree that's even a problem to being with, dependencies which are maintained eventually get updated, and you can choose to update them, that's just normal.

You'd then have a parser for any other exploratory type-systems and future versions of them

That seems a little optimistic, and if it were true it would imply that it would restrict what types added to JS could look like forever basically, which would be a risky bet to make, especially when this proposal doesn't actually bring any runtime benefits at all, nor it does seem to be written with performance considerations in mind, which is probably the main thing people think about when talking about adding types to JS.

Besides stripping out types is pretty much a solved problem already, there are various tools that can strip away TS-like types. There's no need to have the browser do that too really.

@orta
Copy link
Collaborator

orta commented Mar 10, 2022

it's impractical because most codebases use features that aren't part of the subset. [..] I'd guess fewer than 5% of them do

I'd imagine the number will be significantly higher than that, given that it wouldn't be worth the effort for projects like TypeScript or Flow to work within the constraints set by this proposal. Most standard TypeScript syntax is supported, and reaching out to .d.ts files would still be feasible for cases when syntax cannot legally fit the constraints we're looking at.

Perhaps you're including all projects which use a bundler to include specific runtime behavior (like importing a .css files in webpack) or further extensions like JSX? Which is definitely a non-trivial amount of projects, this proposal is about improving JavaScript and that should help projects which use bundlers to do additional work by being easier to parse and without having specifics about different tools which use the syntax space e.g. knowing which TS/Flow syntax to remove or #48

You'd then have a parser for any other exploratory type-systems and future versions of them

That seems a little optimistic

That is the goal of this proposal, to define that syntactic space within JavaScript for type-systems and other tools to safely exist in a way that engines can know how to ignore them.

especially when this proposal doesn't actually bring any runtime benefits at all, nor it does seem to be written with performance considerations in mind

Runtime perf improvements haven't been a goal for any large-scale JavaScript type system so far, the v8 team talked about why its not feasible for that to be the case in https://v8.dev/blog/react-cliff#value-representation - that's not to say it's not possible, but it might require someone to work on that problem via a different tool than just a type system (which this proposal would give syntactic space to work within

Besides stripping out types is pretty much a solved problem already, there are various tools that can strip away TS-like types. There's no need to have the browser do that too really.

I think there's a lot of value in having all different JS tools ranging from REPLs to browsers being able to reliably know how to skip types regardless of whether it's a popular implementation or a less popular one. A browser which knows how to strip TypeScript types for example would have to keep up to date with the TypeScript implementation which could add new syntax every quarter. After the proposal, it would not.

@fabiospampinato
Copy link

fabiospampinato commented Mar 10, 2022

I'd imagine the number will be significantly higher than that, given that it wouldn't be worth the effort for projects like TypeScript or Flow to work within the constraints set by this proposal. Most standard TypeScript syntax is supported, and reaching out to .d.ts files would still be feasible for cases when syntax cannot legally fit the constraints we're looking at.

Unless I see some hard evidence of that my line of thought is the following: most TS projects that ship to the browser probably use at least one unsupported feature: type guards, enums, JSX etc. many projects may well use multiple ones of those features, I mean, who doesn't use type guards? It only takes one missing feature to have a syntax error. Is this reasoning flawed somehow?

FWIW what percentage of existing open-source TS projects do you expect to find using the subset of features mentioned in this proposal?

Perhaps you're including all projects which use a bundler to include specific runtime behavior (like importing a .css files in webpack) or further extensions like JSX? Which is definitely a non-trivial amount of projects, this proposal is about improving JavaScript and that should help projects which use bundlers to do additional work by being easier to parse and without having specifics about different tools which use the syntax space e.g. knowing which TS/Flow syntax to remove or #48

That's another good point, you are probably going to need to use a bundler anyway, and if you don't need to you probably should use one anyway. Shipping an app as thousands of files is impractical, and minifying code is basically always a net positive for performance.

That is the goal of this proposal, to define that syntactic space within JavaScript for type-systems and other tools to safely exist in a way that engines can know how to ignore them.

Maybe languages that want to add types to JS should be free to decide on their own what types should look like though? Not that saving them from having to write a tool that strips types out is particularly valuable anyway.

Runtime perf improvements haven't been a goal for any large-scale JavaScript type system so far, the v8 team talked about why its not feasible for that to be the case in v8.dev/blog/react-cliff#value-representation - that's not to say it's not possible, but it might require someone to work on that problem via a different tool than just a type system (which this proposal would give syntactic space to work within

With some success this has been tried already, ASM.js comes to mind. Potentially there are other avenues to explore in this space. I don't think this proposal doesn't get in the way of that, for one it claims for itself some syntax which we may want to use for something else in the future, but also it makes the language more of a mess to implement and to teach, for example having a language with two type systems, one that doesn't do anything and one that improves performance would be pretty confusing to say the least.

I think there's a lot of value in having all different JS tools ranging from REPLs to browsers being able to reliably know how to skip types regardless of whether it's a popular implementation or a less popular one. A browser which knows how to strip TypeScript types for example would have to keep up to date with the TypeScript implementation which could add new syntax every quarter. After the proposal, it would not.

And why is that? Any language that changes how JS works today comes with its own bundler plugin basically, sometimes there are third-party ones, and these plugins are neither hard to write nor to use. If you think they are hard to write and that types should be TS-like the good news is that stuff like esbuild and others already basically implement this function for us, it's a solved problem.

Like this seems similar to agreeing on what types should look like, having a single tool that strips them out, and sticking that in the browser and speccing it. And like:

  • It's impossible to unanimously agree on this, maybe somebody who hasn't even started working on this yet will want to make a very different kind of type system on top of JS and this proposal will get on their way. What would be our answer to them then, "sorry maybe we messed up and we can't fix it for backwards compatibility"?
  • Whether the browser implementors or somebody else writes this program that strips types is irrelevant, the program would work just the same.
  • Sticking this program in the browser has all these negative consequences, and for what, allowing a small set of people that restrict themselves to the syntax specced in this proposal and that should probably use a bundler to begin with to not use a bundler? That doesn't make a lot of sense to me.

@ethanresnick
Copy link

I'm coming to this as a Typescript user and Typescript advocate, who is comfortable with bundlers. I do see some value in this proposal, but my initial take is also that this will probably make the ecosystem more complicated, for not enough gain.

Benefits

  • server-side scripts will be able to benefit from TS without having to add a build step. Since server-side JS does not need minification or bundling, setting up a TS build step really is just overhead for no user-facing win.

  • copying and pasting TS code into the browser dev tools. This applies when the code needs to run in the browser/against the DOM, and I want to be able to copy it from my editor, perhaps tweak it in the browser console's repl, but have the types be ignored.

  • perhaps this proposal will make possible a lot of other innovation in the carved out syntax space (per Hijacking ignored type annotations for other features #48), but I'm not evaluating it from that perspective; I'm looking at it solely as a Typescript user. The kind of uses proposed by Hijacking ignored type annotations for other features #48 are interesting, but strike me as a very double edged sword (fragmenting JS into more dialects), with many cases probably better handled by something like babel macros (where at least the transform code is explicitly referenced and viewable).

Costs

  • Many Typescript constructs will end up with two different syntaxes that have identical meanings, but only one of which works without a compiler. One example is for generic invocation, as described in the README, which will retain its current syntax (usable with tsc) and have some second syntax that's allowed in raw JS. Another example is the one @orta gave, where the is predicate will have to be wrapped in parentheses, but only when running without a compiler/bundler. In all these cases, devs — including new devs copying from tutorials etc. — will have to know/remember that one syntax doesn't work unless they're using a compiler.

    • Presumably, the syntax that works with and without the compiler will become the "preferred" one (in the same way that as has become the preferred way to type cast, simply because it works in both JSX and non-JSX contexts). But that would be unfortunate, I think, because the raw/uncompiled syntax is likely to be uglier than the existing syntax, given that it would be a constrained adaptation of that syntax, which was already chosen to be most intuitive.
  • Similarly, devs will have to remember that the subset of Typescript that effects runtime behavior (enums, etc) doesn't work without a bundler/compiler. I can understand why this is — and personally wish most of these runtime constructs had never been added, so it doesn't hugely bother me if they become discouraged — but I think it will be confusing to new TS devs.

  • Even with all this duplicate syntax and potential confusion about what works where, it still feels like this proposal will end up handicapping innovation (or at least ideal syntax) in Typescript going forward. Consider, e.g., the new Typescript satisfies proposal, which I find quite nice, but which would seem to need contortions to fit into the syntactic space carved out by this proposal. There's also the new instantiation expressions feature, which adds new syntax that might not be covered by whatever solution is used to handle generic invocations (since there's no parentheses after the generic).

  • Finally, this proposal does claim a lot of syntax space that JS might eventually be able to put to better use. I know people have wanted many things from "types in JS" (runtime enforcement or reflection, engine performance hints, etc), and none of those have yet been workable. But it's possible to imagine some workable version in the future, and this proposal would foreclose that possiblity.

Conclusion

Imo, the use cases that this proposal enables (no build step for server-side code, pasting code straight into a browser) already have decent solutions. E.g., server-side code can be executed through ts-node with no build step, or can use JSDoc syntax (I've done both). And copying code into the browser console isn't too bad, if you run it through the TS playground first. (Of course, for non-browser cases, there are already REPLs that directly accept TS code, like ts-node or repl.it's typescript repl, or deno.) Of course, these solutions are imperfect/less good than what this proposal would enable. But I don't think the difference here justifies all the additional complexity this proposal would seem to bring.

@giltayar
Copy link
Collaborator

Out of scope of this discussion, I know, but for me the question is not just a question of cost. It goes to the "soul" of JavaScript: do we want it to be a language that HAS to be run with tools and can't just run "natively"? I for one, do not.

In a way, this proposal looks towards both the future and the past. Towards the future, because the community has (arguably) decried that the future has some typing in it. And to the past, when newcomers could just take some code and run it, without needing to run complex toolchains that they (and, frankly, most js developers) cannot comprehend or configure.

So even if the cost is not "justified", I would still want types incorporated into native JS.

@fabiospampinato
Copy link

server-side scripts will be able to benefit from TS without having to add a build step

I'd like to hammer on this point: the current proposal absolutely would not allow TS code in general to be executed by the engine. The proposed grammar is pretty strict, just to mention one feature: whose codebase doesn't use type guards? If yours does then you wouldn't be able to run TS server-side as is.

@fabiospampinato
Copy link

copying and pasting TS code into the browser dev tools.

Same point as above, the grammar is pretty strict, you would only be able to do that only for some TS code.

By the way there are much cleaner ways to have that without messing with the spec. For example one could install an editor extension that strips out types on copy, or a browser extension API could be added that allows to transform inputs before executing them, that would allow for making a browser extension that strips types out automatically.

@fabiospampinato
Copy link

perhaps this proposal will make possible a lot of other innovation in the carved out syntax space

That would be impractical at best. The only way to do that would be to call toString on functions and parse the output, this already kills any possible application of this where performance is not irrelevant basically.

Potentially some APIs could be added to make this sort of reflection cheap, but those are not part of this proposal at all, and hoping that they will be implemented in simply wishful thinking.

@ethanresnick
Copy link

I'd like to hammer on this point: the current proposal absolutely would not allow TS code in general to be executed by the engine. The proposed grammar is pretty strict, just to mention one feature: whose codebase doesn't use type guards? If yours does then you wouldn't be able to run TS server-side as is.

@fabiospampinato You keep repeating this, but I think you missed @orta's reply about user-defined type guards (i.e., that they could still work if the is predicate is wrapped in parentheses). This suggests more generally that a very large amount of TS functionality — enough to be a truly usable subset — could be supported in one form or another, although existing code would likely have to go through a one-time code mod to use the new syntax (i.e., to wrap its type predicates in parentheses, to use whatever the ultimate alternate syntax is for generic invocations, etc). To me, a one time code mod like that isn't a dealbreaker.

But the bigger issue, imo — which I tried to point out above — is that you'd end up with a lot of duplicate syntax (the existing syntax for these features and the new one that works in raw js), which is confusing. Plus, the new syntax would be less concise/intuitive (being more constrained syntactically) yet might become the recommended form because of it's broader compatibility.

That would be impractical at best. The only way to do that would be to call toString on functions and parse the output, this already kills any possible application of this where performance is not irrelevant basically.

You're assuming that these transforms would happen at runtime, as opposed to by some other compile-time toolchain. Still, I think any discussion about other (non-type-checking) uses of this space should be kept to #48.

@ethanresnick
Copy link

ethanresnick commented Mar 11, 2022

In a way, this proposal looks towards both the future and the past. Towards the future, because the community has (arguably) decried that the future has some typing in it. And to the past, when newcomers could just take some code and run it, without needing to run complex toolchains that they (and, frankly, most js developers) cannot comprehend or configure.

@giltayar I'm not opposed to this vision, I just don't think this proposal can get us there: for client-side code, you'll still want a bundler in production. And I don't think it adds a ton of value for server-side code, where you can already do ts-node --transpile-only myScript.ts, which I really don't think is too hard for most devs (and maybe should be recommended more prominently by the TS team).

If this proposal didn't come at the cost of complicating the TS syntax with redundant forms and lots of rules about which syntax works in which contexts, then I'd be all for it. But I just don't see how it saves enough complexity on the bundler side to justify that.

@fabiospampinato
Copy link

fabiospampinato commented Mar 11, 2022

@fabiospampinato You keep repeating this, but I think you missed #43 (comment) (i.e., that they could still work if the is predicate is wrapped in parentheses).

I might be indeed misunderstanding the situation on this, I took @orta's comment as a suggestion about how the proposal might evolve to account for that too. The readme doesn't seem to mention this use case, the grammar file is a little difficult to parse for me, I'm not sure if this is actually taken into account already or not 🤔

You're assuming that these transforms would happen at runtime, as opposed to by some other compile-time toolchain. Still, I think any discussion about other (non-type-checking) uses of this space should be kept to #48.

If the heavy lifting is done with a compile-time transform then it can be done already, there's no need for this proposal at all.

@ethanresnick
Copy link

I took @orta's comment as a suggestion about how the proposal might evolve to account for that too.

@fabiospampinato Yes, fair enough. I actually haven’t even looked at the proposed grammar, so I don’t know if it covers that case either. My assumption though has been that this proposal is still very preliminary, so we shouldn’t put too much focus yet on its current grammar. My point is that even if we did get a grammar that covers a lot of use cases, it’d still probably end up with a mess of duplicate syntax forms and rules about what works where

If the heavy lifting is done with a compile-time transform then it can be done already

Yes, although the author of #48 has some arguments about why this proposal would still make building such transforms easier…but again, I don’t really wanna focus on cases beyond the proposal’s main stated goal (of type annotations without a build step).

@giltayar
Copy link
Collaborator

@ethanresnick

@giltayar I'm not opposed to this vision, I just don't think this proposal can get us there: for client-side code, you'll still want a bundler in production. And I don't think it adds a ton of value for server-side code, where you can already do ts-node --transpile-only myScript.ts, which I really don't think is too hard for most devs (and maybe should be recommended more prominently by the TS team).

It's not just ts-node. It's that fact that linters need to be aware of the ever changing grammar of TypeScript. And editors, and all the other tools that try to parse JS. And when running Mocha, or Jest, I have to think of how to use TS there. Each tool has a separate way and configuration to run TS. It's a complicated mess, which we don't see anymore because we've gotten used to it.

If this proposal didn't come at the cost of complicating the TS syntax with redundant forms and lots of rules about which syntax works in which contexts, then I'd be all for it. But I just don't see how it saves enough complexity on the bundler side to justify that.

These are minor changes to the TS syntax, and which Microsoft themselves are behind. I think it's worth the chance of significantly simplifying our toolchain. Of mending the rift between our code (that is TypeScript code), and our runtime (which understands only JS).

My point is that even if we did get a grammar that covers a lot of use cases, it’d still probably end up with a mess of duplicate syntax forms and rules about what works where

My guess is that a few years after this proposal lands in JS (🙏🤞), there will not be duplicate syntax. There will be only one TS syntax, which is the JS one. Especially given that Microsoft is a champion of this proposal.

@giltayar
Copy link
Collaborator

@fabiospampinato

I'd like to hammer on this point: the current proposal absolutely would not allow TS code in general to be executed by the engine. The proposed grammar is pretty strict, just to mention one feature: whose codebase doesn't use type guards? If yours does then you wouldn't be able to run TS server-side as is.

As mentioned above, type guards will be allowed. A goal of this proposal is to have most TS code pass with little or minor (backward compatible) changes in JS without any modifications. And since we have Microsoft as champion, I'm pretty sure we can achieve that.

@PSanetra
Copy link

@giltayar Do you believe that some time in the future bundlers and minifiers will not be necessary anymore? I think they will always be necessary as you want to ship as small JS files as possible. You don't want to ship comments to the browser either. So if this is the case, why would you want to require browsers to support types as comments if parsing type comments in the browser is useless anyway? What is the purpose of supporting that syntax at runtime?

In my mind there will be always be a preprocessing step that may optionally support any kind of non-standard-JavaScript syntax (e.g. TS, but also JSX or svelte files).

It's not just ts-node. It's that fact that linters need to be aware of the ever changing grammar of TypeScript. And editors, and all the other tools that try to parse JS.

ok, the main issue I see here is that TypeScript is still evolving. But this would not be a problem anymore if TypeScript was getting more stable, right? I would expect that TypeScript will be pretty stable at some point. I don't see that introducing types as comments to JavaScript is a solution to a TypeScript-specific issue.

@PSanetra
Copy link

@benjamingr partially. But I think the README is mixing up the JavaScript language with the general JavaScript development ecosystems.

Citing the Readme:

The JavaScript ecosystem has been slowly moving back to a transpilation-less future.

I can only agree that transpilation from JavaScript to a different JavaScript version will become less necessary in the future. The issue I see here is that this types-as-comments proposal does not address this specific transpilation requirement at all. Also all other requirements for transpilation (minification, bundling, JSX, new TypeScript versions) remain valid in the future. So I don't know how this proposal is helping the JavaScript language or even the general frontend development ecosystem.

The key motivation for this proposal that I could find in the README, seems to be this one:

This proposal will reduce the need to have a build step which can make some development set-ups much simpler. Users can simply run the code they wrote.

I disagree that future development set-ups will or even should be simpler due to the requirements I mentioned (minification, bundling, ...). In the end TypeScript transpilation to JavaScript is also just minification. Backend development set-ups are already simple due to tooling like ts-node. You can already run TypeScript as it is.

@extremeheat
Copy link

I disagree that future development set-ups will or even should be simpler due to the requirements I mentioned (minification, bundling, ...). In the end TypeScript transpilation to JavaScript is also just minification. Backend development set-ups are already simple due to tooling like ts-node. You can already run TypeScript as it is.

I very much disagree. It's going to vary by person, but the advantage of not having a typechecker or compilation step saves time. And that time adds up. It also helps immensely with server side code and removes the overhead with tools like ts-node where you may have to wait a few seconds every time code runs ala compiling Java or C++. Things like ts-node also have to do hacks to get proper error stack trace lining among other things. While it may seem transparently easy to use, all that cruft that happens behind the scenes is unnecessary overhead.

@giltayar
Copy link
Collaborator

@PSanetra I do believe that minifying code in production will always be necessary. But NOT in development. We want the source code to be, well, the same, when we develop, so we won't need source maps. Or transpilation time.

I've seen someone say, and I have to agree: the objection to types as something that must be minified in production, and thus should not be in the language, is the same as the objection to indentation as something that must be minified in production, and thus should not be in the language.

@nweldev
Copy link

nweldev commented Mar 13, 2022

the objection to types as something that must be minified in production, and thus should not be in the language, is the same as the objection to indentation as something that must be minified in production, and thus should not be in the language.

IMO, this comparison is irrelevant, as indentation is very simple to "minify"/remove, while minifying types would be very complex.

The same goes with "Types as Comments". Comments (i.e. /* ... */· and //) can be detected and removed with a simple regular expression. Detecting and removing "Types as Comments" is way more complicated. Most minifiers won't be able to do the required development rapidly enough, making many people move to TypeScript tools. Consequently, I believe there is a good chance this proposal gives an enormous advantage to TypeScript (and therefore Microsoft), endangering the whole ecosystem and Open Standard principles.

Also, when talking about readability, nothing could replace indentation in development, while JSDoc can be used instead of Types as Comments. We don't need to discuss the pros and cons of transpilation, as we can already use JSDoc when we want to avoid it. The real question is: Is the cost-benefit ratio of this proposal compared to JSDoc positive?

@extremeheat
Copy link

IMO, this comparison is irrelevant, as indentation is very simple to "minify"/remove, while minifying types would be very complex.

It's not very difficult to do with a parser (with a well defined grammar). Maybe with regex indeed, however you should not be writing parsers in regex.

Consequently, I believe there is a good chance this proposal gives an enormous advantage to TypeScript (and therefore Microsoft), endangering the whole ecosystem and Open Standard principles.

What's stopping anyone from building their own parsing/analysis tool to utilize the specified type information? (See Python)

The real question is: Is the cost-benefit ratio of this proposal compared to JSDoc positive?

The amount of people using TypeScript over JSDoc I believe addresses this concern. Less text is easier to read for humans and parsers that must ultimately utilize the information.

@nweldev
Copy link

nweldev commented Mar 13, 2022

@extremeheat

It's not very difficult to do with a parser (with a well defined grammar). Maybe with regex indeed, however you should not be writing parsers in regex.

Of course, I was only talking about regexp to underline its simplicity. I believe TypeScript has a lot of specificities that would make the JS grammar way more complex. Yet, I'm not an expert in this area, and I would love to see what contributors to these minifiers think about that.

What's stopping anyone from building their own parsing/analysis tool to utilize the specified type information? (See Python)

Time, money, knowledge... Do we really need to debate about individuals and small communities having less power to contribute to a project than a huge corporation with paid employees?

The amount of people using TypeScript over JSDoc I believe addresses this concern.

  1. This is an argumentum ad populum. A lot of factors contribute to this situation. It doesn't mean transpiling from TypeScript is necessarily better than using JSDoc.
  2. « The aim of this proposal is to enable developers to run programs [...] without any need for transpilation » Right now, we can do that using JSDoc. We need to take it into account when discussing this proposal.

Less text is easier to read for humans and parsers that must ultimately utilize the information.

Readability doesn't only depend on the number of characters you use. The structure is way more important. But other issues are more adapted to debate this.

@extremeheat
Copy link

extremeheat commented Mar 13, 2022

re @noelmace

Time, money, knowledge... Do we really need to debate about individuals and small communities having less power to contribute to a project than a huge corporation with paid employees?

Not understanding the point here. Sure, Microsoft/big companies might have more development resources to spend. But that doesn't stop anyone from utilizing the information. For example, if I want to build a documentation generator with a simple AST parse it should be possible extract and display the type information nicely. I'm sure a basic type system could also be implemented, of course with less magic than TypeScript.

With respect to the JSDoc, you end up spending 5-6 lines describing type information verbosely, in a more difficult to parse syntax mixed in with standard JS comments for humans to read.

Readability doesn't only depend on the number of characters you use. The structure is way more important. But other issues are more adapted to debate this.

Exactly, building a well defined structure for expressing type information makes it easier for both humans and the computer to parse. Do you really want to write out 2 lines of code for every variable you want to define and a function prologue for every function you want to get type hints on? Most people don't. If we can more succinctly express this information in a standardized way into the language, similar to other languages like Python, it greatly reduces program verbosity.

@giltayar
Copy link
Collaborator

Of course, I was only talking about regexp to underline its simplicity. I believe TypeScript has a lot of specificities that would make the JS grammar way more complex. Yet, I'm not an expert in this area, and I would love to see what contributors to these minifiers think about that.

This proposal does not propose to copy the TypeScript grammar as is. That would limit TypeScript's (and other's) ability to evolve in the future. it defines a very simple grammar that is type-system-agnostic, and which lets parsers know which area of the code to ignore without having to understand the intricacies of the grammar.

So once minifiers get the grammar in their code, this will be forever there, regardless of the version of TypeScript or any other type system used. In a way, it lessens the need to follow Microsoft's TypeScript's evolution, as all the existing bundlers that recognize TypeScript have to do.

I would believe that all the new bundlers like swc, esbuild, vite, that recognize the TypeScript syntax today, would be very happy to stop following Microsoft's TypeScript evolution constantly, and just base their parsing one some simple grammar rules that let them ignore the types.

@PSanetra
Copy link

PSanetra commented Mar 14, 2022

@giltayar The main issue I see that this proposal may improve are development feedback cycle times -> the ability to execute something like TypeScript fast without transpiling it to JavaScript. Wouldn't it be better to extend the ability of browsers to execute any language e.g. via language engine plugins? This way developers could write their code in any language, would have fast feedback cycles using those plugins and can ship transpiled code, that can be executed on every browser without plugins, to production.

Maybe this could even improve development speed with languages that would be compiled to web assembly instead of JavaScript (just a guess).

@benjamingr
Copy link
Collaborator

Wouldn't it be better to extend the ability of browsers to execute any language e.g. via language engine plugins?

That would be super complicated for many reasons. Even if we ignore the security implications of something like language-engine plugins it would bring us back ±20 years to times where code would run on one browser and not others (like with vba for example). There is tremendous value in standards bodies specifying the way to write interoperable code across browsers.

@giltayar
Copy link
Collaborator

Wouldn't it be better to extend the ability of browsers to execute any language e.g. via language engine plugins?

Maybe, but that is definitely out of scope of TC39, which does not standardize browser engines, but the JS language.

@PSanetra
Copy link

@benjamingr Regarding the security implications: I would never expect those plugins to be used by non-developers executing other peoples code, therefore I don't think the security constraints need to be as strict as in production scenarios. Developers are also executing code with node.js, which has nearly none restrictions security-wise.

it would bring us back ±20 years to times where code would run on one browser

If an approach like language-engine plugins would be chosen, then I would expect that multiple browsers could support the same engine, maybe even standardize the api for such plugins.

@giltayar It might be out of scope of TC39, but may be a better approach to gain the same and even more benefit than the approach of this proposal. The goal is to have fast feedback cycles during development. So the runtime environments (browsers) during development are not out of scope.

@giltayar
Copy link
Collaborator

@PSanetra

may be a better approach to gain the same and even more benefit than the approach of this proposal.

Maybe, but TC39 is not the place to discuss this. Try WHATWG or other browser-focused standards groups. TC39, because their mandate is the JS language, can't and don't do anything outside that scope.

@PSanetra
Copy link

@giltayar I think the TC39 should still consider that there may be alternative approaches to achieve the same goal as this proposal. This proposal would change the JavaScript language syntax forever, which might not be necessary.

@giltayar
Copy link
Collaborator

@PSanetra that is where we differ. I think it is necessary to change the language, so as to mend the existing rift we have between developers who write TypeScript and runtimes that execute JavaScript. I want all that TypeScript code that developers write today to become JavaScript. If we don't do that, I am afraid we could lose control of the language to third party type checkers.

@PSanetra
Copy link

@giltayar I want to mention that I value this proposal at least for exploring the direction it takes and it should be considered by the TC39. The TC39 should just also consider possible alternatives and take the implicated costs of this proposal into account. 😄

@giltayar
Copy link
Collaborator

@PSanetra I would love to see alternative proposals being submitted to TC39!

(A place where this has happened is in the pipe proposal, where two (maybe even three!) proposals to do the pipe operator were submitted to TC39, and now the committee is trying to figure out which proposal is the better one for JavaScript: https://github.com/tc39/incubator-agendas/blob/main/notes/2022/01-27.md#background)

@mindinsomnia
Copy link

mindinsomnia commented Mar 21, 2022

However if I am understanding correctly, in all intellectual honesty this proposal should state that it is not a free lunch and that the cost of transpilation is offsetted to the Javascript parser/interpreter, which must now properly ignore those unused type informations.

Indeed, in addition, for JS interpreters to even be able to handle this code being optionally present they will need to be checking for it, so even if you do not include types in your JS code, CPU cycles will still be spent checking for the existence of syntax that would might not be there, and even if they are, should be ignored anyway because they will have zero impact on how the code is interpreted in the browser...

That's a lot of compute cycles being spent by client CPUs on checking for the existence of something that may not be there, and has zero impact even if it is.

At least JSDoc comments are already ignored because they are part of comments.

I think it'd be better to have a separate mime type of 'application/typescript', just add a TS mode to the JS interpreters. We're already discussing adding about 70% of a TS interpreter to JS interpreters that will be optional ignored anyway, so why not just make it a separate mode for the interpreter and be done with it?

@ljharb
Copy link
Member

ljharb commented Mar 21, 2022

MIME types don’t really apply outside of a browser; a separate mode would still need to be specified, and such a specification wouldn’t be able to make breaking changes, which TS needs to do with some regularity. Specifying TS isn’t a solution.

@extremeheat
Copy link

extremeheat commented Mar 21, 2022

@mindinsomnia

CPU cycles will still be spent checking for the existence of syntax

CPU cycles occur on the timescale of nanoseconds. In fact, modern websites take up bundles of several megabytes to load, which is much bigger of a problem than wasting a few "clock cycles". Every feature that gets added to JS, every abstraction, wrapper, comment, keyword you write and so forth adds onto the time. Fortunately these details only matters on heavily repetitive code or where the CPU is blocked waiting for an interrupt, which we don't have to deal with here.

@dpchamps
Copy link
Contributor

If we don't do that, I am afraid we could lose control of the language to third party type checkers.

@giltayar would you be open to expanding on this fear? I wonder if this might get misinterpreted as "I'm afraid that TypeScript might get replaced by another typechecker", rather than what I think you mean, which is:

"I'm afraid we might lose control of ECMAScript if we don't introduce type annotations"

@giltayar
Copy link
Collaborator

@dpchamps You're right. As I said in that comment: I think it is necessary to change the language, so as to mend the existing rift we have between developers who write TypeScript and runtimes that execute JavaScript. I want all that TypeScript code that developers write today to become JavaScript.

@mindinsomnia
Copy link

@dpchamps You're right. As I said in that comment: I think it is necessary to change the language, so as to mend the existing rift we have between developers who write TypeScript and runtimes that execute JavaScript. I want all that TypeScript code that developers write today to become JavaScript.

How do you respond to people who would disagree with you on the fundamental level of whether or not typescript code should ever be valid javascript code and hold the position that javascript and typescript should remain distinctly separate languages?

@boehs
Copy link

boehs commented Apr 29, 2022

I already upvoted this and I hate plus ones as the next guy, but I wanted to write it out. I don't like this and I hope it does not get merged. Not to mention the client costs:

  • Additional javascript in bundle
    • Mitigating this requires a minfier, so at that point the performance enhancements server side are very very marginal (as OP stated at the cost of the client)
  • O(1) vs O(n) (client vs server compilation)
  • Javascript is growing like cancer, we need to start asking do we need this
  • Browser support issues for no real gain

@sousa-andre
Copy link

I already upvoted this and I hate plus ones as the next guy, but I wanted to write it out. I don't like this and I hope it does not get merged. Not to mention the client costs:

  • Additional javascript in bundle

    • Mitigating this requires a minfier, so at that point the performance enhancements server side are very very marginal (as OP stated at the cost of the client)
  • Javascript is growing like cancer, we need to start asking do we need this

  • Browser support issues for no real gain

About the additional javascript bundle; in the real world you will always minify your code and even if you don't (which you totally should) type annotations would be smaller than JSDoc in terms of file size.

@boehs
Copy link

boehs commented Apr 29, 2022

About the additional javascript bundle; in the real world you will always minify your code and even if you don't (which you totally should) type annotations would be smaller than JSDoc in terms of file size.

I totally agree, but one of the arguments here is that you don't need to setup the infrastructure for typescript, rapid development if you will. Well, if you have a minifier/bundler you have already done most of structure work, than that you can also have typescript with an incredibly marginal amount of work

@jimmywarting
Copy link

I somewhat agree with you @boehs. i think javascript is growing like cancer too. other browser vendors can't keep up and there is now basically a monopoly on which browser everyone should run cuz there are no other alternatives.

I wish the web could just take one year off at only doing performance related, solving bugs/WPT test and add those things that are missing instead of coming up with new features all the time. Let the other players catch up.

I wish to use safari b/c of it speed and less RAM usage but i'm only using chrome b/c of its features and what it can do.

I don't want this to be merged either. Type annotation dose nothing useful for the engine itself other than adding more cost and breaking the web.

I'm however supportive of "real types" like

https://github.com/sirisian/ecmascript-types
The explicit goal of this proposal is to not just to give developers static type checking. It's to offer information to engines to use native types and optimize callstacks and memory usage. Ideally engines could inline and optimize code paths that are fully typed offering closer to native performance.

Or i would just code in another language that have real types and assemble it to WASM to get that extra native performance. But i do wish there where some native api's do communicate with web api's (DOM) rather than making a js-bridge

using dom::IndexedDB;
using dom::String;
using dom::WebRTC;

// ...

everyone else who likes a typed language should try WASM instead. Then you can code in whatever language you want and get real speed.

But i also like javascript for it dynamic loosed typed features that enables you to do literally anything and cutting corers.

Most often it's possible to write type safety without even annotating the code at all with either ts/jsdoc.

@hinell

This comment was marked as abuse.

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

No branches or pull requests