paulstansifer / unseemly

Macros have types!
http://unseemly.github.io/
MIT License
129 stars 5 forks source link

Lone foralls should be allowed on both sides of subtyping. (allow `⋯ <: ∀ Y. ⋯`) #53

Open paulstansifer opened 2 years ago

paulstansifer commented 2 years ago

This comes up when implementing a function application macro and trying to use it on a function with a generic type, so this is blocking making any good example languages.

But a simpler example is this: ∀T. *[a: Int b: T]* should be a subtype (or maybe a supertype? I can never get this straight) of *[a: Int b: ∀T. T]*. (In fact, in this case the types are equal, but they should at least compare in some direction.)

paulstansifer commented 2 years ago

Implementation... ugh, this seems tricky. We don't want to accidentally make *[b: Int]* a subtype of *[b: ∀T. T]* (or maybe I have that backwards). The point is that the underdetermined types on the RHS need to be "inside" the underdetermined types on the RHS (in fact, this should replace the current system where, when we ask whether ∀A B C . ??? <: ∀ X Y Z . ???, we just match up the variables in question).

This seems like perhaps another argument in favor of doing the normal thing that real languages do with generic types.

paulstansifer commented 2 years ago

Actually, I think that we have the exact same problem if we do the "normal" thing: we'd effectively be moving all of the ∀s up to the top, but we'd still need to figure out whether a particular specialization is valid or not.

paulstansifer commented 2 years ago

I wonder if the subtyping system is much too complicated. According to page 222 of https://www.cs.cmu.edu/~rwh/pfpl/2nded.pdf, the subtyping rule for foralls is really simple. Now, this particular problem (and the broader feature where Seq<Int> <: ∀T. Seq<T> without requiring some syntax for "hey, let's explicitly specify a type here") isn't covered, but maybe it's not too hard?

We could have