type.txt 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. The Type System
  2. Scheme 48 has a rudimentary type system. Its main purpose is to
  3. generate helpful compile-time diagnostics.
  4. Currently you don't get much checking beyond wrong number of arguments
  5. warnings unless you're compiling a package that has an (OPTIMIZE ...)
  6. clause in its definition (e.g. (OPTIMIZE EXPAND) or (OPTIMIZE
  7. AUTO-INTEGRATE)). The reason that type checking is disabled most of
  8. the time is that it increases compilation time by about 33%.
  9. A design goal is to assign types to all valid Scheme programs. That
  10. is, type warnings should not be generated for programs that could work
  11. according to Scheme's dynamic semantics. For example, no warning
  12. should be produced for
  13. (define (foo x y) (if x (+ y 1) (car y)))
  14. Warnings could in principle be produced for particular calls to FOO
  15. that would definitely go wrong, such as (foo #t 'a).
  16. The type system assumes that all code is potentially reachable. This
  17. means that there will be some warnings for programs that cannot go
  18. wrong, e.g. (if #t 3 (car 7)).
  19. Additionally, it's assumed that in a (BEGIN ...) or combination, every
  20. argument or command will always be executed. This won't be the case
  21. if there can be a throw out of the middle. For example, in
  22. (call-with-current-continuation
  23. (lambda (k)
  24. (if (not (number? x))
  25. (k #f))
  26. (+ x 1)))
  27. the type system might deduce that X must be a number (which is false).
  28. The type reconstruction algorithm (such as it is) is in
  29. bcomp/recon.scm. The implementation finds some specific procedure
  30. types for LAMBDA expressions, but generally gives up pretty quickly.
  31. Notation
  32. --------
  33. F : T means that form F has static type T. T1 <= T2, or T1 is under
  34. T2, means that T1 is a subtype of T2; that is, if a form of type T2 is
  35. acceptable in some context, then so is a form of type T1.
  36. Non-expressions
  37. ---------------
  38. Not every valid Scheme form is an expression. Forms that are not
  39. expressions are syntactic keywords, definitions, types, and structure
  40. names.
  41. If a name is bound to a macro or special operator, then an occurrence
  42. of that name has type :SYNTAX. E.g.
  43. cond : :syntax
  44. Definitions have type :DEFINITION. E.g.
  45. (begin (define x 1) (define y 2)) : :definition
  46. Thus type checking subsumes syntax checking.
  47. Types (other than :TYPE itself?) have type :TYPE.
  48. The type of a structure is its interface. E.g.
  49. (define-structure foo (export a b) ...)
  50. foo : (export a b)
  51. Values
  52. ------
  53. All expressions have type :VALUES. They may have more specific
  54. types as well.
  55. If E1 ... En have types T1 ... Tn with Ti <= :VALUE, then
  56. the expression (VALUES E1 ... En) has type (SOME-VALUES T1 ... Tn).
  57. If T <= :VALUE then (SOME-VALUES T) is equivalent to T.
  58. Procedure types
  59. ---------------
  60. Procedure types have the form (PROCEDURE T1 T2), where T1 and T2 are
  61. under :VALUES. Examples:
  62. (lambda (x) (values x 1)) :
  63. (procedure (some-values :value) (some-values :value :number))
  64. cons : (procedure (some-values :value :value) :pair)
  65. Fixed-arity procedure types (PROCEDURE (SOME-VALUES T1 ... TN) T) are
  66. so common that the abbreviated syntax (PROC (T1 ... Tn) T) is
  67. defined to mean the same thing. E.g.
  68. cons : (proc (:value :value) :pair)
  69. E : (PROCEDURE T1 T2) means that in a call to a value of E, if the
  70. argument sequence has any type other than T1, then the call can be
  71. expected to "go wrong" (provoke a type error) at run time. This is
  72. not to say it will definitely go wrong, but that it is just a matter
  73. of luck if it doesn't. If the argument sequence does have type T1,
  74. then the call might or might not go wrong, and any return value(s)
  75. will have type T2.
  76. For example,
  77. (lambda (x) (+ (begin (set! x '(3)) 5) (car x))) :
  78. (proc (:pair) :value),
  79. because if the arguments to + are evaluated from right to left, and X
  80. is not a pair, then there will be a run time type error.
  81. Some primitive procedures have their own special typing rules.
  82. Examples include VALUES, CALL-WITH-VALUES, and PRIMITIVE-CATCH.
  83. Variable types
  84. --------------
  85. Assignable variables have type (VARIABLE T), where T for now will
  86. always be :VALUE. In (SET! V E), V must have type (VARIABLE T) for
  87. some T.
  88. Loopholes
  89. ---------
  90. The construct (loophole T E) is considered to have type T no matter
  91. what type E has. Among other things, this allows a rudimentary static
  92. abstract data type facility. For example, record types defined using
  93. DEFINE-RECORD-TYPE (rts/bummed-jar-defrecord.scm) are established as
  94. new base types.
  95. Type lattice
  96. ------------
  97. The subtype relation is implemented by the procedure COMPATIBLE-TYPES?
  98. (in bcomp/mtypes.scm). If (COMPATIBLE-TYPES? T1 T2) is 'definitely,
  99. then T1 <= T2. If it's #T, then T1 and T2 intersect.
  100. The type lattice has no bottom or top elements.
  101. The types :SYNTAX, :VALUES, :DEFINITION, :STRUCTURE, and :TYPE are
  102. incomparable and maximal.
  103. The following are a comprehensive set of subtyping rules for the type
  104. system as it stands. Additional rules may be added in the future.
  105. - (SOME-VALUES T1 ... Tn) <= :VALUES.
  106. - If T1 <= T1', ..., Tn <= Tn' then (SOME-VALUES T1 ... Tn) <=
  107. (SOME-VALUES T1' ... Tn').
  108. - T <= (SOME-VALUES T).
  109. - Basic value types, which include :NUMBER, :CHAR, :BOOLEAN, :PAIR,
  110. :STRING, and :UNSPECIFIC, are all under :VALUE.
  111. - If T1' <= T1 and T2 <= T2', then (PROCEDURE T1 T2) <= (PROCEDURE
  112. T1' T2').
  113. - (VARIABLE T) <= T.
  114. - :ZERO, the result type of infinite loops and calls to
  115. continuations, is under :VALUE, but perhaps shouldn't be. (E.g.
  116. maybe it should be just under :VALUES instead.)
  117. - (EXPORT (<name> T) ...) is under :STRUCTURE.
  118. [Not yet implemented.]
  119. Type well-formedness
  120. --------------------
  121. In (SOME-VALUES T1 ... Tn), T1 ... Tn must be under :VALUE.
  122. In (PROCEDURE T1 T2), T1 and T2 must be under :VALUES.
  123. In (VARIABLE T), T must be under :VALUE.
  124. Module system
  125. -------------
  126. The rules for interfaces and structures are not yet very well worked
  127. out.
  128. Interfaces are types. The type of a structure is its interface.
  129. (Compare with Pebble's "bindings" and "declarations".)
  130. An interface has the basic form (EXPORT (<name> <type>) ...).
  131. There are two kinds of abbreviations:
  132. - (EXPORT ... <name> ...) means the same as
  133. (EXPORT ... (<name> :VALUE) ...)
  134. - (EXPORT ... ((<name1> <name2> ...) <type>) ...) means the same as
  135. (EXPORT ... (<name1> <type>) (<name2> <type>) etc. ...)
  136. Distinct interfaces are not comparable.
  137. If a form S has type (EXPORT ... (name T) ...), then the form
  138. (STRUCTURE-REF S name) has type T. Note that T needn't be a :VALUE
  139. type; e.g.
  140. (structure-ref scheme cond) : :syntax
  141. When a package is loaded or otherwise compiled, the type that is
  142. reconstructed or inherited for each exported name is checked against
  143. the type specified in the signature. (Cf. procedure SCAN-STRUCTURES
  144. in bcomp/scan.scm.)
  145. <explain the role of the expander in type checking... compile-call
  146. doesn't do much checking if the arguments aren't expanded...>
  147. Future work
  148. -----------
  149. There probably ought to be dependent sums and products and/or
  150. universal and existential types. In particular, it would be nice to
  151. be able to get static checking for abstract types, even if they're not
  152. implemented using records.
  153. Type constructors (like STREAM-OF or COMPUTATION-OF) would be nice.
  154. There are many loose ends in the implementation. For example, type
  155. and type constructor names aren't always lexically scoped; sometimes
  156. their scope is global. Packages that open the LOOPHOLES structure
  157. (which exports LOOPHOLE) don't always open TYPES (which would be a bad
  158. idea given the way TYPES is currently defined); LOOPHOLE works in
  159. spite of that.
  160. Figure out whether :TYPE : :TYPE.
  161. -----
  162. Original by JAR, 20 July 93.
  163. Updated by JAR, 5 December 93.