1 lobby ensureNamespace: #Types.
2 Types addDelegate: lobby.
3 "This ensures that type annotation expressions can occur in this namespace and
6 Types define: #Type &parents: {Cloneable}.
7 "Types are Slate's basic type system for minimal inference purposes.
8 A type's rules object delegates to its supertypes' rules objects."
10 "Older versions of slate used some rules delegate slot
11 and overrode derive. It seemed broken and overly complicated.
12 I think we can just use traits here instead -- Timmy"
16 I can't bootstrap so i need to redefine this for now
18 type@(Types Type traits) clone
22 type@(Types Type traits) derive &mixins: types &rejects: rejectSlots
26 selector@(Symbol traits) asInferenceRule
28 ('__' ; selector name) intern
31 selector@(Symbol traits) inferOn: types
32 "Take the selector and argument types and locate an inference rule,
33 and then return a type based on that as possible."
35 "inform: (selector printString ; ' on:')."
36 "types do: [|:type| inform: (' ' ; type printString) ]."
37 (selector asInferenceRule findOn: types)
39 ifNotNilDo: #(applyTo: types) `er
42 x@(Types Type traits) union: y@(Types Type traits)
43 "Returns the type-theoretic union of the two types. Everything satisfying
44 either of the component types should satisfy the union."
51 x@(Types Type traits) intersection: y@(Types Type traits)
52 "Returns the type-theoretic intersection of the two types. Everything
53 satisfying both of the component types should satisfy the intersection."
60 supertype@(Types Type traits) subsumes: subtype
61 "Returns whether the first type subsumes the second, by type-intersection."
63 (supertype intersection: subtype) = subtype
66 _@(Types Type traits) representative
67 "Return some representative object satisfying the Type."
72 _ satisfies: _@(Types Type traits)
73 "The default (safe) answer to whether an object satisfies, or belongs to,
77 Types define: #Any &parents: {Types Type}.
78 "Objects of type Any can be any value."
80 _ satisfies: _@(Types Any traits)
81 "Any object belongs to this type."
86 _@(Types Any traits) intersection: type
89 type intersection: _@(Types Any traits)
92 any@(Types Any traits) union: _
95 _ union: any@(Types Any traits)
98 Types define: #None &parents: {Types Any}.
99 "Objects of type None have no value (Nil) or represent an error."
101 _@Nil satisfies: _@(Types None traits)
104 _@(Types None traits) complement
107 _@(Types None traits) union: type
110 type union: _@(Types None traits)
113 none@(Types None traits) intersection: _
116 _ intersection: none@(Types None traits)
119 Types define: #Not &parents: {Types Any} &slots: {#argument -> Types Any clone}.
120 "A complement of a type, which may reduce itself automatically."
122 type@(Types Any traits) complement
123 "The most generic type-complementation."
127 ifFalse: [Types Not clone `>> [argument := type. ]]
130 type@(Types Not traits) complement
131 "A simple reduction: the complement of a complement is the original."
136 not@(Types Not traits) union: type
143 not@(Types Not traits) intersection: type
150 Types define: #Union &parents: {Types Any} &slots: {#args -> ExtensibleArray new.}.
152 union@(Types Union traits) copy
153 [union clone `>> [args := union args copy. ]].
155 union@(Types Union traits) representative
156 "Pick a representative from a random argument."
158 (union args atRandom) representative
161 type1@(Types Any traits) union: type2@(Types Any traits)
162 "The most generic method for union."
164 type1 == Types Any \/ [type2 == Types Any]
166 ifFalse: [Types Union clone `>> [| :newU | args := {type1. type2} as: newU args. ]]
169 union@(Types Union traits) union: type
170 [union copy `>> [args add: type. ]].
172 union1@(Types Union traits) union: union2@(Types Union traits)
173 [union1 copy `>> [args addAll: union2 args. ]].
175 union@(Types Union traits) subsumes: type
176 "Unions subsume their arguments."
178 (union args anySatisfy: #(subsumes: type) `er)
182 type subsumes: union@(Types Union traits)
184 union args allSatisfy: #(type subsumes: _) `er
187 Types define: #Intersection &parents: {Types Any} &slots: {#args -> ExtensibleArray new}.
188 "An intersection of types, which may reduce itself automatically."
190 intersection@(Types Intersection traits) copy
191 [intersection clone `>> [args := intersection args copy. ]].
193 type1@(Types Any traits) intersection: type2@(Types Any traits)
194 "The most generic method for intersection."
197 [type1 == Types Any] -> [type2].
198 [type2 == Types Any] -> [type1]
200 [Types Intersection clone `>>
201 [| :newT | args := {type1. type2} as: newT args. ]]
204 intersection@(Types Intersection traits) intersection: type
205 [intersection copy `>> [args add: type. ]].
207 int1@(Types Intersection traits) intersection: int2@(Types Intersection traits)
208 [intersection copy `>> [args addAll: int2 args. ]].
210 type subsumes: intersection@(Types Intersection traits)
211 "Each argument of an intersection subsumes it."
213 (intersection args anySatisfy: #(type subsumes: _) `er)
217 intersection@(Types Intersection traits) subsumes: type
219 intersection args allSatisfy: #(subsumes: type) `er
222 Types define: #Clone &parents: {Types Any} &slots: {#prototype.}.
224 "The Clone type represents clone families, tracking some original prototype."
226 x@(Types Clone traits) = y@(Types Clone traits)
228 x prototype == y prototype
231 c@(Types Clone traits) of: prototype
232 "Create a new Clone type using the given object as a prototype."
233 [c clone `>> [prototype := prototype. ]].
235 c@(Types Clone traits) representative
236 "Use the prototype as a representative of the Clone family."
241 Types define: #Range &parents: {Types Any} &slots: {#type. #start. #end.}.
242 "Ranges are parametrizable types over linearly-ordered domains (Magnitudes,
243 such as Numbers, Integers, and Characters(?)). They express a range of values."
245 range@(Types Range traits) representative
246 "Use the range's start, coerced to be of the same prototype as the base type's representative."
248 range start as: range type representative
251 x@(Types Range traits) = y@(Types Range traits)
252 "Equal Range types must have a same basis and boundaries."
255 /\ [x start = y start]
259 range@(Types Range traits) of: type from: start to: end
260 "Create a new Range type for the type, between the given boundaries."
261 [range clone `>> [type := type. start := start. end := end. ]].
263 x@(Types Range traits) union: y@(Types Range traits)
264 "Create a new Range type over the base Types' union if applicable."
265 "TODO: this depends on x and y's boundaries being comparable. Fixing this
267 [x of: (x type union: y type)
268 from: (x start min: y start)
269 to: (x end max: y end)
272 x@(Types Range traits) intersection: y@(Types Range traits)
273 "Create a new Range type over the base Types' intersection if applicable."
274 "TODO: this depends on x and y's boundaries being comparable. Fix this."
276 (type ::= x type intersection: y type) == Types None
278 ifFalse: [(start ::= x start min: y start) > (end ::= x end max: y end)
280 ifFalse: [x of: type from: start to: end]]
283 Types define: #Member &parents: {Types Any} &slots: {#elements -> Set new}.
284 "The Member type represents the elements of some finite set."
286 member@(Types Member traits) representative
287 "Take any element and call it a representative."
289 member elements anyOne
292 x@(Types Member traits) = y@(Types Member traits)
293 "Equality as a collection."
295 x elements = y elements
298 member@(Types Member traits) of: elements
299 "Create a new Member type over the given collection, implicitly copying it
300 with as:-conversion."
301 [member clone `>> [elements := elements as: member elements. ]].
303 x@(Types Member traits) union: y@(Types Member traits)
305 (x elements anyOne isSameAs: y elements anyOne)
306 ifTrue: [x of: (x elements \/ y elements)]
310 x@(Types Member traits) intersection: y@(Types Member traits)
312 (x elements anyOne isSameAs: y elements anyOne)
313 ifTrue: [x of: (x elements /\ y elements)]
314 ifFalse: [Types None]
317 Types define: #Singleton &parents: {Types Any} &slots: {#identity}.
319 "The singleton type, representing single objects only."
321 singleton@(Types Singleton traits) representative
322 "Answer the only possible element."
327 x@(Types Singleton traits) = y@(Types Singleton traits)
328 "Equality by the one element's unique identity."
330 x identity == y identity
333 singleton@(Types Singleton traits) of: identity
334 "Create a new Singleton type over the given object."
335 [singleton clone `>> [identity := identity. ]].
337 member@(Types Member traits) union: singleton@(Types Singleton traits)
338 "Create a new type between a Member and a Singleton type, a new Member type
339 or the existing one if the Member type is a supertype of the singleton."
341 (member elements includes: singleton identity)
343 ifFalse: [(member elements anyOne isSameAs: singleton identity)
344 ifTrue: [member clone `>>
345 [elements := member elements copyWith: singleton identity. ]]
349 c@(Types Clone traits) union: s@(Types Singleton traits)
351 (c prototype isSameAs: s identity)
356 singleton@(Types Singleton traits) union: type
359 type union: singleton
362 x@(Types Singleton traits) union: y@(Types Singleton traits)
363 "Create a new Member type of the two as necessary."
365 x identity == y identity
368 [(x identity isSameAs: y identity)
369 ifTrue: [Types Member of: {x identity. y identity}]
373 member@(Types Member traits) intersection: singleton@(Types Singleton traits)
374 "Based on inclusion of the Singleton in the Member, return the Singleton or
375 None type as intersection."
377 (member elements includes: singleton identity)
379 ifFalse: [Types None]
382 c@(Types Clone traits) intersection: s@(Types Singleton traits)
384 (c prototype isSameAs: s identity)
386 ifFalse: [Types None]
389 singleton@(Types Singleton traits) intersection: type
392 type intersection: singleton
395 x@(Types Singleton traits) intersection: y@(Types Singleton traits)
396 "Return the intersection, None if not equal, either one if equal."
398 x identity == y identity
400 ifFalse: [Types None]
403 Types define: #Array &parents: {Types Any} &slots: {#type}.
404 "Array types are parametrized by their element types, and cover arrays of all
405 lengths with that element type."
407 array@(Types Array traits) representative
408 "Answer an empty Array literal."
409 "TODO: parametrize even the empty array?"
414 array@(Types Array traits) of: type
415 "Answer a new Array type over the given element type."
416 [array clone `>> [type := type. ]].
418 x@(Types Array traits) = y@(Types Array traits)
419 "Array types are equal simple on their underlying types."
424 x@(Types Array traits) union: y@(Types Array traits)
425 "The union of Array types is the Array type of the union of the element types."
427 x of: (x type union: y type)
430 x@(Types Array traits) intersection: y@(Types Array traits)
431 "The intersection of Array types is the Array type of the intersection of the
432 element types, or None if the intersection is None."
434 (type ::= x type intersection: y type) = Types None
436 ifFalse: [x of: type]
439 Types define: #Block &parents: {Types Any} &slots: {#argumentTypes. #resultType}.
440 "The Block type represents code closures, with input types and a return type,
443 block@(Types Block traits) representative
444 "The representative block is the do-nothing block."
449 block@(Types Block traits) from: argumentTypes to: resultType
450 "Return a new Block type with the given type-signature."
453 [argumentTypes := argumentTypes as: Array.
454 resultType := resultType. ]
457 x@(Types Block traits) = y@(Types Block traits)
458 "Equal Block types must have equal type-signatures."
460 x resultType = y resultType /\ [x argumentTypes = y argumentTypes]
463 x@(Types Block traits) union: y@(Types Block traits)
464 "x and y must have the same number of arguments. This returns a Block type
465 with a union of their signature types."
467 x argumentTypes size = y argumentTypes size
471 with: y argumentTypes
472 collect: #union: `er)
473 to: (x resultType union: y resultType)]
477 x@(Types Block traits) intersection: y@(Types Block traits)
478 "x and y must have the same number of arguments. This returns a Block type
479 with an intersection of their signature types."
481 x argumentTypes size = y argumentTypes size
483 [(resultType ::= x resultType intersection: y resultType) == Types None
487 with: y argumentTypes
488 collect: #intersection: `er)
490 ifFalse: [Types None]