-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[WIP] Direct representation of higher-kinded types #1337
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
Conversation
Will be used to encode higher-kinded type parameters.
Previously a refinement could only apply to a type bound in the parent. This restriction needs to be dropped for the new encoding of hk type parameters.
Treat parent like refinedInfo. Introduce isBinding convenience method in TypeBounds.
They not print similar to scalac: "?x" where `x` is a unique number. Todo: An offline explanation what they are, similar to javac. I.e. ... ?3 ... where ?3: T
Map self-references in refinements to recursive types. This commit does this for refinement types appearing in source. We still have to do it for unpickled refinements. Test apply-equiv got moved to pending because it simulates the old higher-kinded type encoding in source, which relies on the old representation in terms of self-referential refinement types. The plan is not to adapt this encoding to the new representation, but to replace it with a different encoding that makes critical use of the added power of recursive types.
In the new hk scheme, a type parameter can be represented by a refinement without a corresponding symbol. Therefore, we need to disentangle the info inherent in a type parameter from the contents of a type symbol. We achieve this by creating a common super trait "MemerInfo" of Symbol and RefinedType.
It can give false negatives.
Also change MemberInfo.exists to MemberBinding.isTypeParam.
Also fix printing of variances in typedefs and params; they were suppressed before.
The previous scheme accidentally printed <label> modifiers which ruined the Tasty tests,
There was a special case that triggered a parse error in this course def lift[T <: Type](tp: T): (RecType => T) = arg match { case rt0: RecType => tp.subst(rt0, _).asInstanceOf[T] case _ => (x => tp) } The problem was that the rhs of the first case became a Function node, which caused a premature return from the case clause sequence. I could not determine anymore what the purpose of the removed case in the parser was; all tests compile without it.
For the moment under newHK flag.
NamedTypes don't always have symbols.
The reviously first test is no longer with new recursive types scheme.
A type parameter joint with a normal refinement represents a type parameter that has been filled in. So the Binding attribute should be removed.
The new definition avoids that a higher-kinded type "isRef" of an underlying class. I.e. `[X] -> Any` is not longer a ref to `Any`.
Keep the higher-kinded application instead. This should be better for inference. We have to evaluate the performance impact. Maybe dealias if the kind stays the same?
Nothing cannot be a type constructor in a HK application because it does not have type parameters. Avoid the problemn by the reduction above.
Previously we only covered EtaExpansion/reduction. Need to generalize this to the case where a type is partially applied. Test case is pos/partialApplications.scala
Done for efficiency. Also that way we would do something meaningful if the type constructor was, say, Nothing. However, that case is now rules out anyways.
The deleted assertion could fail for code that was erroneous.
Parameter names always come in as term names, ahve to be explicitly converted to type names. The previous implementation used a cast instead of a conversion, which caused a ClassCastException. For symmetry we model readParamNames such that it returns a List[Name] which has to be explicitly converted to a List[TermName] or a List[TypeName], using a map.
PR number 1337 👍 |
TYPEALIAS Length alias_Type (COVARIANT | CONTRAVARIANT)? | ||
ANNOTATED Length underlying_Type fullAnnotation_Term | ||
ANDtype Length left_Type right_Type | ||
ORtype Length left_Type right_Type | ||
BIND Length boundName_NameRef bounds_Type | ||
// for type-variables defined in a type pattern | ||
BYNAMEtype underlying_Type | ||
LAMBDAtype Length result_Type NamesTypes // variance encoded in front of name: +/-/= |
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.
Do we never need to pickle HKApply
?
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.
It's pickled as an APPLIEDtype
On Tue, Jun 28, 2016 at 10:49 PM, Guillaume Martres <
[email protected]> wrote:
In src/dotty/tools/dotc/core/tasty/TastyFormat.scala
#1337 (comment):TYPEALIAS Length alias_Type (COVARIANT | CONTRAVARIANT)? ANNOTATED Length underlying_Type fullAnnotation_Term ANDtype Length left_Type right_Type ORtype Length left_Type right_Type BIND Length boundName_NameRef bounds_Type // for type-variables defined in a type pattern BYNAMEtype underlying_Type
LAMBDAtype Length result_Type NamesTypes // variance encoded in front of name: +/-/=
Do we never need to pickle HKApply ?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/lampepfl/dotty/pull/1337/files/4377aaa94628ed8afffdc4801e1c83996832e21c#r68840351,
or mute the thread
https://github.com/notifications/unsubscribe/AAwlVj1eixuFsgVJMW6OCsdS2nIW1JM6ks5qQYjmgaJpZM4JAdeo
.
Prof. Martin Odersky
LAMP/IC, EPFL
Is |
RecType is still necessary, as it explicitly models the recursion which would otherwise be in RefinedType. Since recursion is tricky, I think it's good to have a specific construct for it. |
Remove the code that implemented the encoding of hk types using refinements.
Crashed before when printers were turned on during test pickling mode.
Assertion failed before when printers were turned on during test pickling mode.
Taking the signature over a type with uninstantiated type variables means that the signature can change later, once we instantiate the type variable. We handle this by recording uninstantiated positions of signatures and fixing them in PostTyper, when type variables are instantiated.
Dropping this initially revealed the problems with under-determined signatures. Now that these problems are fixed, we can drop for good.
Also, drop the notion that RefinedTypes can be type parameters. This is no longer true under the new representation.
/rebuild |
Under direct hk encoding this is no longer needed.
@odersky CI can build only up to 100 commits per PR. |
/rebuild 127c8a6 |
Superseded by #1343 |
This is (hopefully the last) attempt to model higher-kinded types in dotty. This time it's done directly, having specific types for type lambdas and higher-kinded applications.
This PR is based on #1282 but undoes most of it. Nevertheless I thought it would be good to have a trace of the history how we arrived here.