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
Bad interaction between local abstract type and self-type #5773
Comments
Comment author: @garrigue Always the same problem: named type variables have scope the whole function, so you cannot generalize them locally. |
Comment author: @alainfrisch Ah thanks! I feel like a newbie now :-) I'm wondering whether it would make sense to restrict the scope of a type variable to the smallest possible subexpression (i.e. the smallest subexpression which contains all occurrences of that variable). Would that break existing code? Would it actually solve the kind of issue I'm raising here? (It is not clear to me how to implement that in the current type-checker without an extra pass.) |
Comment author: @garrigue This is the Standard ML semantics. It makes sense, but this is a pain to implement, since you need two passes over the syntax. I tended to think that locally abstract types already solved the problem since they have a local scope, however they do not allow unification, so they cannot be easily used in this kind of situation. So maybe the minimal scope approach is the solution, if we can find a way to implement it simply. |
Comment author: @alainfrisch What about the following workarounds?
1 and 2 are not very satisfactory, but 3 would make sense and is easy |
Comment author: @garrigue I thought about (1) or (3) and eliminated because of (1) new syntax for limited use and (3) new scoping rules. In particular, for (3) you can write things like Actually I think that (2) covers enough use cases that it would be interesting. |
Comment author: @alainfrisch
Waow, never saw this pattern! Any reference to a documented use case? Anyway, 3 was only about changing the scope of the self pattern type variables for object expressions, not class definitions. 2 is indeed not too intrusive, but it only solves the problem "globally". If you are within a local function, or a GADT branch for instance, it doesn't help. Do you think there is a way to avoid an extra pass to implement the "smallest" scope solution? For instance, by introducing a fresh variable for each occurrence, and "merging" them (lowering their level) on nodes where the same name is introduced in several sub-expressions. |
Comment author: @alainfrisch Actually, I'm wondering if it would be wise to introduce a dedicated way to declare that an object implements an interface (class type). The pattern is: object(_ : 'this) Such declarations are not only useful for information and to get good error messages, but also to let the type-checker know about polymorphic functions, to restrict the type of method to avoid unbound variables, etc. object and to make it work, one can simply declare purely virtual classes instead of class types. Is there a fundamental difference between virtual classes with no concrete fields and class types? Since a class declaration also defines a class type of the same name, wouldn't it make sense to say that "inherit" in objects refers to a class type instead of a class? (With a different behavior when the class type comes from a class declaration?) |
Comment author: @garrigue I suppose that for most people, implementing SML semantics would be the most natural. Concerning the part about implementing interfaces, there are already many ways to do it, some not using 'this. Some extensions could help. Or we could indeed add a construct "inherit virtual" for inheriting all fields from a class type as virtual. |
Comment author: @alainfrisch
Thanks, I did not think about it! |
Original bug ID: 5773
Reporter: @alainfrisch
Assigned to: @garrigue
Status: closed (set by @xavierleroy on 2016-12-07T10:34:19Z)
Resolution: not a bug
Priority: normal
Severity: minor
Version: 4.01.0+dev
Target version: 4.02.0+dev
Category: typing
Bug description
This works fine:
But as soon as the self type is bound, this does not work anymore:
The text was updated successfully, but these errors were encountered: