tc39 / ecma262

Status, process, and documents for ECMA-262
https://tc39.es/ecma262/
Other
15k stars 1.28k forks source link

Request: Optional Static Typing #45

Closed ghost closed 9 years ago

ghost commented 9 years ago

Hi,

I understand this is an ambitious request, and probably aimed at ES8 or even ES9, but considering the direction many web based technologies are heading, this request definitely makes sense in my mind.

This request is for optional, TypeScript-esque, static typing for ECMAScript.

There are tools and transpilers that already support optional static typing, and Google are also looking at supporting optional static typing directly in their virtual machine with SoundScript. That being said, a formal and specified syntax for optional static typing in ECMAScript would obviously be beneficial in numerous ways. It would allow developers to remove one or more layers from their workflow, therefore improving productivity across the board, and it would also allow virtual machines to produce highly optimized native code from the source files it consumes. I am honestly struggling to think of downsides.

I believe the time is now right to consider adding option static typing to ECMAScript. The language is evolving extremely well now, and optional static typing is one feature that is still sorely missed.

If required, I am willing to compose a full proposal to support this request.

themihai commented 9 years ago

@si-robertson, there is already a proposal[0] [1] for ES7.

[0] https://github.com/tc39/ecma262/blob/master/README.md -> Typed Objects
[1] http://wiki.ecmascript.org/doku.php?id=harmony:typed_objects

ghost commented 9 years ago

Hi @themihai,

Due to the verbosity of that proposal, it is difficult to tell if it is actually for optional static typing. On the surface, it appears to be more of a convoluted boilerplate solution than anything else.

Could someone please confirm if this request and the Typed Objects proposal are, in fact, requesting the same functionality to be added to ECMAScript.

thomasfoster96 commented 9 years ago

@si-robertson I'm fairly certain that the Typed Objects proposal isn't anything like TypeScript's static typing. Typed Objects doesn't let you specify the type of a variable or any other sort of type annotations (in function params, etc.), rather it generalises typed arrays to objects (well, objects that act like structs) rather than just one dimensional arrays.

That said, there might be some proposals based on and/or extending Typed Objects that do what you're proposing, but I haven't seen them.

chicoxyzzy commented 9 years ago

check out SoundScript https://developers.google.com/v8/experiments

ghost commented 9 years ago

Ah, SoundScript, that's the name of the Google tech I couldn't remember.

Thanks Sergey, I will update my original post with the link.

rwaldron commented 9 years ago

SoundScript is the work of TC39 members. Closing this because it's effectively a duplicate of several proposals in progress.

nervgh commented 8 years ago

Closing this because it's effectively a duplicate of several proposals in progress.

What is current status these proposals?

azu commented 8 years ago

I've collected status of Static Typing Proposals.

Status Name Description Recent Changes
NaN Typed Objects > All top-level names are defined in a typed objects module. See also Typed Objects Explainer Out of date. :link:Typed Objects information in proposal table is out of date · Issue #223 · tc39/ecma262
NaN SoundScript > We want to try implementing an optional type system for JavaScript, directly in the VM. V8 will remove support for strong mode. :link: An update on strong mode
NaN Type and Type Annotations > Reserve syntax used by TypeScript, Flow, etc. for some form of annotation by Jonathan Turner Jonathan Turner leave Microsoft. :link: Off to new adventures
NaN Optional Static Typing @sirisian's proposal ?
PierBover commented 6 years ago

Anyone knows of any progress in optional static typing?

NameFILIP commented 6 years ago

Currently, there are 2 equally popular ways: Flow and TypeScript. They both are great!

The problem is that two groups of very smart people are working on kind of similar solutions. The whole JS community is divided. I think everyone will clearly benefit from a standardized type system.

Is it possible to bring the relevant Microsoft and Facebook teams together and ask them to consolidate and merge the two approaches pulling out the best parts of each?

nicolo-ribaudo commented 6 years ago

Competition make both of them evolve to try to be better than the other :wink:

PierBover commented 6 years ago

We don't need people making TypeScript or Flow better, or even both teams working together to create TypeFlow or any other thing. Any third party solution will be a workaround with different problems.

The real solution is simply having optional static types natively in the language that will be compatible with the ecosystem and will not require extra configurations.

NameFILIP commented 6 years ago

tl;dr What if each browser had their own scripting language with different features? (wasn't it the reason for creating ECMAScript standard?)

Competition make both of them evolve to try to be better than the other

That's a good point. But it also leads to duplication of effort and wasted human resources of type system developers as well as consumers. Catching bugs in the code is another more healthier motivation to evolve the system. Having a common syntax can at least get rid of duplication for consumers (same type definitions for libraries). This way different implementations can still compete in performance, etc.

having optional static types natively in the language

Yes!

ljharb commented 6 years ago

@NameFILIP both of those teams have conveyed that they think standardizing types of any kind would be a bad idea (at least that’s my current understanding)

mathiasbynens commented 6 years ago

+@samuelgoto

NameFILIP commented 6 years ago

Could you please give more details why it is a bad idea? (@mroch, @gabelevi, @samwgoldman, @ahejlsberg, @DanielRosenwasser, @andy-ms)

I might be missing something, but competing against each other instead of combining forces towards a common goal sounds like a bad idea to me.

WebReflection commented 6 years ago

FWIW, just my 2 cents, I'd love to see progress on this area too and I wouldn't even mind a minimal / incremental implementation similar to what PHP did at its time, where typeof like based hints would already be a reasonable starting point.

In JS, that would be:

const b:boolean = true || false;
const f:function = (() => {}) || function () {} || class {};
const n:number = 123 || 1.23;
const o:object = {} || [] || null;
const s:string = '' || "" || ``;
const u:undefined = void 0;
const y:symbol = Symbol();

from that point on classes, global, scoped, or namespaced, could be a natural follow up.

Why? Well, AFAIK flow and ts are still changing/improving after years of usage so that having the whole thing landing all at once doesn't seem practical or ever happening so that maybe little steps forward, are better than whole thing at once or no steps at all.

P.S. the undefined use case is for any ... it could be called any too, I was just sticking for consistency with the known JS type

rahbari commented 5 years ago

@NameFILIP both of those teams have conveyed that they think standardizing types of any kind would be a bad idea (at least that’s my current understanding)

I think not having optional static types in JS is a bad idea. Just install a npm module which is written in TypeScript and you see there are one JS file per each TS file which leads to a lot of misconceptions in IDEs (even smart one like intellij). And for JS modules which usually use different versions of JSDocs to cover lack of static types, type hinting is not much better.

I have java background and I've really missed code [auto complete - generation - signature - documentation] just with single mouse click. Having no static type was good enough for some event handling in browser back in the old days, but nowadays that web apps got so complicated and npm modules have so many dependencies it is actually a real need to track code development!

The popularity of TS shows high interest rate of developers about optional typing, why not add it to the underlying language and prevent further division in the coming years.

samuelgoto commented 5 years ago

FWIW, we worked on a couple of proposals this year between a few of us.

Here are two different perspectives/proposals with a varying degree of standardization.

https://github.com/samuelgoto/proposal-optional-types https://github.com/samuelgoto/proposal-pluggable-types

Sam

On Sat, Nov 17, 2018 at 8:40 AM rahbari notifications@github.com wrote:

Install several npm package and

@NameFILIP https://github.com/NameFILIP both of those teams have conveyed that they think standardizing types of any kind would be a bad idea (at least that’s my current understanding)

I think not having optional static types in JS is a bad idea. Just install a npm module which is written in TypeScript and you see there are one JS file per each TS file which leads to a lot of misconceptions in Smart IDEs. And for JS modules which usually use different versions of JSDocs to cover lack of static types type hinting is not much better.

The popularity of TS shows high interest rate of developers about optional typing, why not add it to the underlying language and prevent further division.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tc39/ecma262/issues/45#issuecomment-439630045, or mute the thread https://github.com/notifications/unsubscribe-auth/AAqV6t9KdChrgF37pD-OxC7bTxdE-6NBks5uwDwFgaJpZM4FCnQx .

-- f u cn rd ths u cn b a gd prgmr !

PierBover commented 5 years ago

FWIW, we worked on a couple of proposals this year between a few of us. Here are two different perspectives/proposals with a varying degree of standardization.

(Not sure if this is the place to discuss this. If not, please let me know.)

In those 2 proposals, is there a justification for non nullable types or multiple types? For example in making things easier for the type checker and adding performance?

All ES inspired languages with optional types support nullable types. TypeScript, ES4/AS3, and Haxe (for some targets). In C# and Java reference types are also nullable, while primitives are not.

As for multiple types, I personally think that would only add more confusion.

bakkot commented 5 years ago

In C# and Java reference types are also nullable

In C#'s case, not for much longer. Same in TypeScript if you pass --strictNullChecks (which you absolutely should).

"types can be made nullable by using explicitly the union type" (or possibly some syntax sugar meaning the same thing) is a much better approach than "all types are implicitly | null".

Edit: the right place for these discussions would be as an issue on the proposal repo, rather than this thread.

samuelgoto commented 5 years ago

That s probably best to follow up in those repos themselves. I'd be happy to have that discussion there .

(apologies for the brevity, sent from phone)

On Tue, Nov 20, 2018, 10:51 AM Pier Bover <notifications@github.com wrote:

FWIW, we worked on a couple of proposals this year between a few of us. Here are two different perspectives/proposals with a varying degree of standardization.

(Not sure if this is the place to discuss this. If not, please let me know.)

In those 2 proposals, is there a justification for non nullable types or multiple types? For example in making things easier for the type checker and adding performance?

All ES inspired languages with optional types support nullable types. TypeScript, ES4/AS3, and Haxe (for some targets). In C# and Java reference types are also nullable, while primitives are not.

As for multiple types, I personally think that would only add more confusion.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tc39/ecma262/issues/45#issuecomment-440388676, or mute the thread https://github.com/notifications/unsubscribe-auth/AAqV6kIdcu58lALpRe7xGGpd67SCpbZEks5uxE8XgaJpZM4FCnQx .

Vanuan commented 3 years ago

It's interesting that static type annotations seem to be cursed in EcmaScript.

Is it a time yet for ESNext type annotations?

Jack-Works commented 3 years ago

TypeScript is now de facto typed version of JavaScript with a growing community and good IDE support. Isn't that enough? 🤔

Vanuan commented 3 years ago

@Jack-Works no, because you have to deploy multiple versions of npm packages, for both typed and non-typed JS. Now, add the "type: module"/michael jackson files into the mix. This is not sustainable. JS should support the type annotation syntax even if it doesn't have any runtime meaning.

Vanuan commented 3 years ago

Of course, the threat is that when the type annotation syntax is used in real websites, you won't be able to introduce runtime errors later. This can be mitigated by introducing some experimental syntax flag to prevent browsers from supporting it without transpiling.

ctjlewis commented 3 years ago

TypeScript is now de facto typed version of JavaScript with a growing community and good IDE support. Isn't that enough?

No, anything short of full integration comes with tons of drawbacks. I ran into a problem in the wild where react-native-fs package ships an entry point that contains Flow typing by accident, which threw at runtime (because it literally was not valid ES). Clearly the ecosystem wants static typing, even if it has no runtime impact - why not accept that rather than lean on third party solutions?

I believe the TypeScript team should be heavily involved in this effort, but no, it is not "good enough." If you don't believe me, set "module": "esnext" in tsconfig and let me know how it goes unless you confusingly import your local TS modules as ./myModule.js.

TheBoneJarmer commented 3 years ago

I agree with @ctjlewis. I have switched back and forth between TS and JS but eventually settled down with JS. There was a time that TS had bigger advantages over JS due to the lack of classes, private fields, interfaces, static types etc. But that was a long time ago. JS now supports like everything except interfaces and static typing. And for what it is worth, if that would be introduced I would not even consider TS anymore.

@ctjlewis is on point here. TS may provide static types but that comes with a big drawback. I had a not such a pleasant experience getting my rather basic express app up 'n running in TS due to the differences between module imports. Also, the whole bunch of options in the config made it only more confusing for me. Also, you are required to install 3rd party type defs for Express.js in order to get the whole thing up 'n running in the first place.

And then, when you finally got the goddamn thing booted up it will crash right away because of the module import issues he describes. TS does not add the .js extension itself during transpiling so as a result you get an error because the js file "./folder/mymodule" could not be found. And there has been a huge discussion about this already in the TS repo. And all of em got closed. Some users even got so frustrated they decided to create a wrapper around the TSC cli tool. I mean, how ridiculous do you want to have it?

I don't have that shit with plain JS. I simply write my code, run "node index.js" and it runs. And it does so very fast. If I have to transpile TS into JS right before I can run "node index.js" I lose time with each debug round. Also, speaking of which. I need to enable maps in order to debug my typescript code. Something that is conveniently disabled by default and nobody tells you until you Google it up.. I mean c'mon.

ctjlewis commented 3 years ago

Great notes @TheBoneJarmer, I actually ran into that ESM output issue myself and patched the error message since it would explicitly instruct users to write TS that compiled to invalid ES:

https://github.com/microsoft/TypeScript/pull/42184

But it just prevents a misleading error, and you must work around the core issue manually. I could run the idea by the TS team of making it an error-level warning to use relative imports (./myModule) over the workaround forced-JS import (./myModule.js) when moduleKind >= ModuleKind.ES2015, which would prevent it from emitting broken ESM finally, but it would be a breaking change and therefore a likely unpopular suggestion.

Not to derail this conversations into the limitations of TS, but it's good to get into the nitty-gritty of why anything short of doing this properly (adding optional static typing to JS itself) causes massive interop issues and limits adoption of ESM. Think of how many projects are shipping shipping CJS over ESM purely because TS can't properly emit ES modules!

TheBoneJarmer commented 3 years ago

Read the PR and the linked issue. Way to go dude!! One of my complaints in one of these issues I mentioned was that nothing tells you to add a .js extension. But with your change it would make the whole subject a bit more clear for sure. That said, TS devs need to fix that shit. Its a definitely a bug when the TS generates broken javascript. It is sad that they do not acknowledge that problem though..

trusktr commented 2 years ago

It is sad that they do not acknowledge that problem though..

There are quite a number of issues in TypeScript that are not acknowledged, or even annoyingly resolved as "working as intended".

cc @JSMonk (author of Hegel.js, an alternative to TS/Flow with amazing type inference). There is an opportunity to align a new tool with specs here.


Regarding this problem,

the threat is that when the type annotation (without runtime errors) syntax is used in real websites, you won't be able to introduce runtime errors later.

Can we avoid this problem by making these runtime-ignored types usable only in ES Modules where a certain new string directive is used? The syntax could be invalid without having the directive. Later, when we're ready to introduce errors, we can allow people to remove the directive. If anyone tries to use type syntax without the directive, but before runtime errors are implemented, they will get a syntax error.

For example:

"use type annotations";
import Foo from 'foo';

// code using type syntax, but with no runtime meaning:
const foo: Foo = new Foo

While runtime errors are not yet released into the wild, this causes an error:

import Foo from 'foo';

// code using type syntax, but with no meaning to the interpreter:
const foo: Foo = new Foo // Error: Unexpected type annotation

Is something like this doable, so that we can have syntax, but let userland libraries compete at type system implementations, then eventually iron out which concepts are the best and introduce the best ones into ES for users without the directives?

Another idea is that we could do the opposite, and require a directive in order to opt into the type errors, but I like that idea less.

Plus, having the "use type annotations" directive, or similar, would allow people to opt out of the built-in type checking and still use some userland tool for backwards compatibility, or for taking advantage of new features not yet available natively.

trusktr commented 2 years ago

@ljharb Do you have any thoughts on the string pragma/directive idea? I wonder if it could be achieved that way, such that we avoid the problem that adding optional types first then making them type errors later would break people's programs.

Having a syntax for optional types, then a whole different syntax for actual type checking, would be seriously detrimental to the developer experience, and hence the language as a whole. Plus, would there even be any syntax space left after optional types? For example, if optional types were in TypeScript format, then what would runtime type syntax be in?

trusktr commented 2 years ago

@sirisian, it would be nice to get your thoughts here (f.e. the pragma idea) since your proposal is currently the most active and largest.

ljharb commented 2 years ago

@trusktr my thoughts are "no new modes, ever, forever, period".

trusktr commented 2 years ago

@ljharb In that direction, how would you imagine to prevent that optional-now-errors-later issue?

ljharb commented 2 years ago

@trusktr at present i don't believe it can ever possibly be prevented.

This is not the right venue to discuss feature requests. Please see https://github.com/tc39/ecma262/blob/main/CONTRIBUTING.md#creating-a-new-proposal for the proper place to discuss such things.

trusktr commented 2 years ago

Alright, let's continue here:

https://es.discourse.group/t/optional-typing/1137

Are you able to lock this?