@@ -13,18 +13,19 @@ which has been one of the most wanted features.
13
13
14
14
15
15
# 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
17
17
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.
19
19
20
+ ## Declaration of typed generic inferfaces.
20
21
To annotate a generic interface, we introduce a typed counterpart for
21
22
` define/generics ` .
22
23
23
24
``` racket
24
25
(define-generics showable
25
26
(: gen-show (showable . -> . String) )
26
27
(gen-show showable)
27
- (: gen-show2 (showable showable . -> . String) )
28
+ (: gen-show2 (String showable . -> . String) )
28
29
(gen-show2 some-b showable)
29
30
#:defined-predicate tpred ;; (: tpred (-> showable (U 'gen-show 'gen-show2) * Boolean)). Note: No need to generate contracts
30
31
#:defaults
@@ -69,8 +70,11 @@ cannot tell which argument would act as the specializer based on the type of
69
70
- produce a typed immutable hash table that is assigned to ` defined-table-id `
70
71
when it is specified. The table's keys have a union type, `(U
71
72
method-id-as-symbol ...)`, and values are simply booleans.
73
+ - produce the type predicate ` showable? ` , a similar to other fellow predicates in TR,
74
+ has type ` (-> Any Boolean : showable) `
72
75
- #: derive-property , TODO
73
76
77
+ ## Typed method specialization
74
78
For method implementation in a struct's definition, the typechecking process is
75
79
also straightforward
76
80
@@ -86,13 +90,40 @@ also straightforward
86
90
)
87
91
```
88
92
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) ` .
93
+ For any structure that implemented generice interfaces, first the typechecker
94
+ ensures every ` interface-id ` in a ` #:methods ` specification is well scoped. It
95
+ then checks if every method of ` interface-id ` is implemented. There are 3
96
+ possibilities of a method to be considered implemented:
97
+
98
+ 1 . The method is defined in the ` #:methods ` specification. Then it checks if the
99
+ specializer and return type are covariant and if the rest are contraviant.
100
+ ` define/generic ` makes the local id ` super-show ` have the same type of
101
+ ` gen-show ` , namely ` (-> showable String) ` .
102
+ 2 . The interface includes a well-typed fallback implementation for the method.
103
+ 3 . In either ` #:defaults ` or ` #:fast-defaults ` , there is a type predicate for
104
+ ` T ` such that T is a super type of the current structure type.
105
+
106
+ Note that under the proposed rules, all methods of a generic interface must be
107
+ implemented, which is different from that in Racket. Consider the following code:
108
+
109
+ ```
110
+ (struct fruit (name)
111
+ #:methods gen:showable
112
+ [(define (gen-show me)
113
+ (format "~a" (fruit-name me)))])
114
+
115
+ (let ([a (fruit "apple")])
116
+ (when (showable? a)
117
+ (gen-show2 'whatever a)))
118
+ ```
119
+
120
+ Racket recognizes a ` fruit ` instance showable, despite that ` fruit ` lacks
121
+ implementation of ` gen-show2 ` . Then a subsequent call ` gen-show2 ` on that
122
+ instance raises a run-time error. However, TR should reject the program above.
123
+
93
124
94
125
Though Racket doesn't support subclass or inheritance between generic
95
- interfaces, we can still express constraints using types in ` define/ generics ` .
126
+ interfaces, we can still express constraints using types in ` define- generics ` .
96
127
97
128
```
98
129
(define-generics eq-able
@@ -145,6 +176,14 @@ because an `Dummy` instance breaks the contract of `gen-/=`.
145
176
However, the typechecker simply rejects the code. Since ` Dummy ` does not
146
177
implement ` gen:eq-able ` , it is not of a subtype of ` (Intersection eq-able ord-able) `
147
178
179
+ ## Typechecking Generic Method Application
180
+ The typechecker checks calls to a generic method in the same fashion as it does
181
+ to a plain function. Every argument type is checked against the by-position
182
+ parameter type of the method described in its interface definition. For example,
183
+ when checking ` (gen-show2 b a) ` , the typechecker checks if ` a ` is of a subtype
184
+ of ` showable ` and ` b ` is of a subtype of ` String ` .
185
+
186
+
148
187
# Reference-level explanation
149
188
Add a new prim for ` define-generics ` that supports the features mentioned in the
150
189
Guide-level explanation.
0 commit comments