|
ShiqiCao, please refer to the Coq file. I am not overly familiar with type systems including subtyping, as you see I was even confused about the standard notation; but I like things being formal,
and at a first glance my intuition for subtyping would be this:
Inductive subtype (a b : Set) : Set :=
| ST : (a -> b) -> subtype a b.
In plain words, this says: we can demonstrate that A is a subtype of B by providing a function (as in math) from A to B. That is, A contains all the information in B and more.
jonturner, thanks for your reply. I would question the assumption that a sound type system would hinder your scenarios - ability to express JavaScript idioms, and hinder tooling. I also doubt
that a sound type system would be significantly more complex, and I would argue you do not need to expose any of the additional complexity to the user.
For example, to avoid the need for variance annotation on generics, you could simply exclude rules that depend on it from the formalized subtyping relation. It is a strategy works quite well - when the compiler is in doubt, assume a NO answer. In the limit,
it could also achieve removing subtyping altogether. You can then recover JavaScript idioms by providing an explicit "cast" primitive compiled to the identity function. That is, when the user is certain a cast is safe, but TypeScript's approximation
of subtyping fails to infer safety, the user inserts an explicit cast.
I have a strong preference for an explicit cast, because in this setup a compiling cast-free program gives me a static guarantee there will be no type errors. In current TypeScript the fact a program compiles tells me nothing about type errors - they can
still manifest themselves for certain runs of the program.
I am speaking from experience. In our company we have developed an F#->JavaScript platform, WebSharper, and have been quite happy with the explicit cast over the years. This is indeed how F# works - a sound core typesystem with use-at-your-own-risk extensions.
I have not had any problem expressing JavaScript idioims. Our programs are typically written mostly in the sound core of F#, and casts are inserted at the FFI boundary to make sense out of untyped JavaScript and bring it into the typed setting.
If anything, we have felt the need for more *safety*, not more flexibility. For example, we are now looking at implementing a contract system to check at runtime that untyped JavaScript fragments preserve the announced typing, in the spirit of Findler and
Felleisen (http://www.ccs.neu.edu/racket/pubs/icfp2002-ff.pdf).
|