tc39 / proposal-type-annotations

ECMAScript proposal for type syntax that is erased - Stage 1
https://tc39.es/proposal-type-annotations/
4.25k stars 46 forks source link

Allow type parameters on variable declarations #144

Open Superstar64 opened 2 years ago

Superstar64 commented 2 years ago

From my cursory look at the syntax, variable bindings don't seem to support type parameters. This would be quite useful to typecheckers as more then just functions can be parametric. Consider the empty array for example:

// this would be valid under a type system where arrays are immutable
const emptyArray<a> : a[] = [];
bradzacher commented 2 years ago

This would be quite useful to typecheckers

None of the current JS typecheckers have implemented this.

TBH I'm not sure what problem this feature would even solve. Why do you need a generically typed variable? Wouldn't a static type do just fine?

Superstar64 commented 2 years ago

TBH I'm not sure what problem this feature would even solve. Why do you need a generically typed variable? Wouldn't a static type do just fine?

It''s a generalization of generic functions, rather then limit generics to functions they can apply to any type(like how it works in the theory that generics are based off) It leaves room for future type checkers.

There are other languages that support generic variable. C++ and Haskell are the first 2 that come to my mind.

template <class T> T x = 0;
empty :: Maybe t
empty = Nothing

For the empty array example. You can use specialize to regular arrays like you would normal functions.

const emptyIntArray = emptyArray::<Int>;
const emptyDoubleArray = emptyArray::<Double>;

As a side note, it might be nice to add type lambda syntax for expressions too. Though I'm not sure if that would interfere with valid Javascript.

const emptyArray2 = <a> [] as a[];
bradzacher commented 2 years ago

But why do you need a generic variable when you can just cast it?

const emptyArray: readonly any[] = [];

const numberArray: readonly number[] = emptyArray;
const stringArray: readonly string[] = emptyArray;

// or
const boolArray = emptyArray as readonly boolean[];

This is why I don't see the problem it's solving - it already seems like the problem it's addressing has already been solved?

It leaves room for future type checkers.

A main criticism of this proposal is that it's already too big. The aim is to find some common subset of the current flavours of JS and go for that.

So adding NEW syntax that none of the current checkers implement would really be wholly out of scope, IMO.

Superstar64 commented 2 years ago

This is why I don't see the problem it's solving - it already seems like the problem it's addressing has already been solved?

I would argue that the type variable solution is cleaner. If you have a value of type <a> a[] you know that it must be the empty array (for a type system that has paramatricity) and that you can safely instantiate to anything without fear type errors. While any[] could be an array that has anything and can't be safely casted without potentially violating type safety.

So adding NEW syntax that none of the current checkers implement would really be wholly out of scope, IMO.

I kinda hoped this change would be small enough to be worth the potential future proofing, I can understand if you don't think it's realistic though.