Skip to content

Commit 2c93e37

Browse files
committed
add subsections and explanation on checking #:methods
1 parent 939c36f commit 2c93e37

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

rfcs/text/0003-typing-generic-interfaces.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ which has been one of the most wanted features.
1313

1414

1515
# Guide-level explanation
16-
There are two parts of the proposal: First, we address typing declarations of
16+
There are three parts of the proposal: First, we address typing declarations of
1717
generic interfaces. Then, we show how the type checker checks structs' method
18-
definitions.
18+
definitions. Lastly, we present how type checking method application works.
1919

20+
## Declaration of typed generic inferfaces.
2021
To annotate a generic interface, we introduce a typed counterpart for
2122
`define/generics`.
2223

@@ -71,6 +72,7 @@ cannot tell which argument would act as the specializer based on the type of
7172
method-id-as-symbol ...)`, and values are simply booleans.
7273
- #:derive-property, TODO
7374

75+
## Typed method specialization
7476
For method implementation in a struct's definition, the typechecking process is
7577
also straightforward
7678

@@ -86,10 +88,37 @@ also straightforward
8688
)
8789
```
8890

89-
First, the typechecker ensures every `method-id` in a `#:methods` specification
90-
is well scoped. Then it checks if the specializer argument's and return type
91-
are covariant and if the rest are contraviant. `define/generic` makes the local
92-
id `super-show` have the same type of `gen-show`, namely `(-> showable String)`.
91+
For any structure that implemented generice interfaces, first the typechecker
92+
ensures every `interface-id` in a `#:methods` specification is well scoped. It
93+
then checks if every method of `interface-id` is implemented. There are 3
94+
possibilities of a method to be considered implemented:
95+
96+
1. The method is defined in the `#:methods` specification. Then it checks if the
97+
specializer and return type are covariant and if the rest are contraviant.
98+
`define/generic` makes the local id `super-show` have the same type of
99+
`gen-show`, namely `(-> showable String)`.
100+
2. The interface includes a well-typed fallback implementation for the method.
101+
3. In either `#:defaults` or `#:fast-defaults`, there is a type predicate for
102+
`T` such that T is a super type of the current structure type.
103+
104+
Note that under the proposed rules, all methods of a generic interface must be
105+
implemented, which is different from that in Racket. Consider the following code:
106+
107+
```
108+
(struct fruit (name)
109+
#:methods gen:showable
110+
[(define (gen-show me)
111+
(format "~a" (fruit-name me)))])
112+
113+
(let ([a (fruit "apple")])
114+
(when (showable? a)
115+
(gen-show2 'whatever a)))
116+
```
117+
118+
Racket recognizes a `fruit` instance showable, despite that `fruit` lacks
119+
implementation of `gen-show2`. Then a subsequent call `gen-show2` on that
120+
instance raises a run-time error. However, TR should reject the program above.
121+
93122

94123
Though Racket doesn't support subclass or inheritance between generic
95124
interfaces, we can still express constraints using types in `define/generics`.
@@ -145,6 +174,8 @@ because an `Dummy` instance breaks the contract of `gen-/=`.
145174
However, the typechecker simply rejects the code. Since `Dummy` does not
146175
implement `gen:eq-able`, it is not of a subtype of `(Intersection eq-able ord-able)`
147176

177+
## Typechecking Method Application
178+
148179
# Reference-level explanation
149180
Add a new prim for `define-generics` that supports the features mentioned in the
150181
Guide-level explanation.

0 commit comments

Comments
 (0)