-
Notifications
You must be signed in to change notification settings - Fork 14
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
[WIP] Infer instantiations for polymorphic arguments to polymorphic functions [rebase of Alex Knauth's PR on bitbucket] #29
base: master
Are you sure you want to change the base?
Conversation
f5ad50a
to
6247b62
Compare
d97427f
to
9d812c0
Compare
The reason why However, I suspect that this restriction only concerns type variables which were in the original signature of the function being called, not type variables which belong to arguments. The last commit (9d812c0) therefore checks whether the X which may cause an error belongs to I am not 100% sure this is the right thing to do, however, and cannot guarantee that this does not open the door to unsoundness with weird edge cases. |
Yes, the examples in Is this still WIP? |
Yes, it's still WIP. Sorry for the delay, hopefully I'll be able to finish it soon. |
No rush, just checking. |
(check-not-type (λ ([x : X]) (λ ([y : Y]) x)) : (→/test X (→ X X))) | ||
|
||
(check-type | ||
((λ ([x : X]) (λ ([y : Y]) y)) 1) | ||
: (→/test Y Y)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would the original test still pass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that's one of the remaining issues.
With @AlexKnauth's change which lifts nested ∀ from the function's return type, the outer lambda has type (∀ (X Y) (→ X (→ Y Y)))
, but then the value restriction kicks in, and prevents Y from appearing in covariant positions (in case the body was a let-over-lambda capturing the Y type).
If I revert that commit, then the outer lambda's type is (∀ (X) (→ X (∀ (Y) (→ Y Y))))
(which sounds good to me as I used Typed Racket a lot, but @AlexKnauth I'm not sure if it is okay to revert that commit). The problem then becomes that (∀ (Y) (→ Y Y))
cannot be annotated as (→ Int Int)
, because the former is not a subtype of the former (an explicit instantiation is needed instead).
So I'm trying to see if I can find some combination of changes to solve
+ add-constraints
+ subtyping which makes everything work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, yes I'm playing around a bit more and see the behavior you mention. I'm starting to remember now and I think that was one of the original holdups because it means programs like (((λ ([x : X]) (λ ([y : Y]) y)) 1) 1)
will be rejected which is not ideal.
Thanks for the update and thanks for work on this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type of the outer lambda should be (∀ (X Y) (→ X (→ Y Y)))
so that type inference can instantiate either X
or Y
if it needs to. Here it needs to instantiate X
as Int
, but Y
isn't constrained. So why is Y
also solved to Int
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AlexKnauth I'm not sure what you mean by "why is Y also solved to Int here?", could you clarify? Thanks!
Tentative answer: In that test, the (check-type … : (→ Int Int))
places an expected-type on the outer lambda's return value, which allows the Y
to be instantiated to Int
(but then the return type cannot be left as (→ Y Y)
, as the value restriction forces it to be monomorphic, IIUC).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right. So the test could just as easily be (check-type … : (→ String String))
and it would still pass. The Y
in the answer we want should a non-generalizable type variable, like the ones notated '_a
in the "Relaxing the Value Restriction" paper.
Hello,
I took @AlexKnauth somewhat outdated PR https://bitbucket.org/stchang/macrotypes/pull-requests/21 and rebased it onto master. There were a few simple conflicts, so it's possible that I accidentally discarded or damaged part of the original patch.
The changes are only applied to the macrotypes/ subfolder for now. Is there an automated translation between the macrotypes/ and turnstile/ folders, or is the procedure simply to manually apply the changes in both directories?
After a few adjustments, most tests seem to succeed (I still have a few to fix).
it seems incapable of typechecking
(Cons (λ ([x : X]) x) Nil)
, regardless of how manyann
andinst
I add to the expression. I suspect that this is because the∀
are now lifted outwards as much as possible, but thesolve
andadd-constraints
probably need some adjustment to work with that.