340 likes | 508 Views
Soft Types for Scheme. Donna Malayeri Type Refinements Seminar October 2003. A Practical Soft Type System for Scheme . Scheme is not (statically) typed Types are good Let’s add (soft) types to Scheme! But not static types:
E N D
Soft Types for Scheme Donna Malayeri Type Refinements Seminar October 2003
A Practical Soft Type System for Scheme • Scheme is not (statically) typed • Types are good • Let’s add (soft) types to Scheme! • But not static types: “Statically typed languages provide all the benefits of types and type checking that we seek, but at the price of rejecting programs that do not satisfy the type system’s arbitrary constraints.”
Soft Types • A soft type system infers types for dynamically typed programs • Main idea: type checker does not reject ill-typed programs, instead inserts explicit run-time checks • Soft Scheme uses inferred types to eliminate run-time checks • Remaining run-time checks are flagged as potential program errors
Soft Scheme • Assigns types to Scheme programs by inserting run-time checks at applications of primitive operations • Has both an internal type language and a presentation type language • Internal type language is mapped to the programmer-friendly presentation type language • Performs a whole-program analysis • Requires no programmer-supplied type annotations
Core Scheme Syntax Const includes basic constants (numbers, #t, etc.) and primitive operations
Checked and Unchecked Operations • Primitive operations are either checked or unchecked • Checked: CHECK-ap • Unchecked: ap (ap 1 2) • meaningless: either core dumps or gives an arbitrary answer (CHECK-ap 1 2) • terminates with an error message
Challenges • Values in dynamically typed programs belong to many different semantic types • Soft type system should include union types • For typing applications: • Need to modify Hindley-Milner typing
Overview of Soft Type System • Combine union types and subtyping with Hindley-Milner polymorphism using record subtyping (Wand 1991, Rémy 1991) • (Many) union types can be expressed as terms in a free algebra (as in HM typing) • Use flag variables to encode subtyping as a subset on union types
Soft Type System • Infers types using a variant of the Hindley-Milner algorithm • Provides the illusion of a polymorphic union type system based on ordinary union types • Uses algorithms for unification, generalization and instantiation of types from Rémy [1992].
Static Types • Partition the domain into disjoint subsets • Primitive operations are (mostly?) closed over these subsets
Static Types • Define pretypes (, ) • is a flag variable and is a tag (value constructor) • Tags specify partitions of data domain • Soft types are a subset of the pretypes
Tags and Flags num true false nil cons ! • Flag indicates whether partition is part of the union • + partition is present− partition is absent (variable) may be present or absent
Tidy Types • Tidy type: tag is used at most once • Range of a type variables excludes the tags of partitions preceding it • Tidiness simplifies the pairwise unification of union types
Example In the range of excludes numbers, #t and all pairs.
Type Schemes • Type scheme: 2 (TypeVar[FlagVar) • Substitutions map type variables to types and from flag variables to flags. • 0 is an instance of type scheme
Type Schemes • Polymorphism is used for ordinary polymorphic types and for subsets of tidy union types • Simulate subtyping at function applications • Use unification to equate function input type and argument type
Example A function with type scheme can be applied to values of type
Supersets of Types • Constants and outputs of primitives may have a type that is a superset of their natural type • E.g., numbers have type scheme • Needed for typing (rather strange) expressions e.g. with type
Types of Primitive Operations Unchecked operations Checked operations (accept all inputs) Could use + instead, but the flag variable is used for a technical reason (reverse flow)
Soft Type Checking • Checker makes untypable programs typeable by replacing some unchecked operations with checked ones • Introduce a meta-function SoftTypeOffor assigning type schemes to constants • For unchecked primitives, SoftTypeOf uses absent variables to keep track of uses that may not be safe
Absent Variables and Flags • Absent variable: • SoftTypeOf of uses absent variables/flags where – or is in the input type of a primitive e.g. TypeOf(add1) SoftTypeOf(add1)
Empty Types • If the primitive operation p introduces an absent variable that is instantiated to a non-empty type, then p must be checked
Pattern Matching • “In ordinary statically typed languages, pattern matching is largely a notational convenience and could be provided as a macro.” (???) • In the soft type system, pattern matching allows the type checker to “learn” more precise types • Davies’s refinement checker also does this
Typing Match Expressions • More challenging than ML typing, because types may overlap • To type • Compute a tidy type for each pi • Combine the pattern types to obtain the match input type • If type of e is larger than , the match requires a run-time check
Pattern Matching Examples Has input type nil+[cons+(12) • However, restrictions on tidiness can lead to imprecise input types • E.g. has type cons+( (true+[false+) (true+[false+) ) Therefore, match is inexhaustive
Example: Tautology Checker • Boolean Formulae formula = .true [ false [ ((true [ false) !) taut : formula ! (true [ false)
SML Version • Wright and Cartwright claim that “these injections and projections add both unnecessary semantic complexity and run-time overhead”
Examples • Requires no run-time checks • flatten : 82.1.nil+[cons+(11) [ 2) !+ list+ (nil−[cons−[2) a: cons+( num+ (cons+(cons+(num+nil+)) (cons+(num+ nil+))) b: (list num)
Examples • Suppose we add • Soft type checker output: • Rewritten program:
Other Interesting Claims • Inherent incompleteness of static type checking “nourishes a never-ending search for better static type systems” • “Realistic statically typed languages such as C usually have some means of circumventing the type checker” • SML/NJ provides System.Unsafe.cast • Type refinements (à la Freeman and Pfenning) does “not alter the fundamental character of static type systems.”
Discussion • Soft Scheme’s whole program analysis is not scalable • Unlike with type refinements, programmers cannot specify what invariants they actually care about • Their system seems ad-hoc and overly complex • Upshot: soft types improve Scheme somewhat, if you’re foolish enough to be using Scheme in the first place