Changeset 36679 in project

10/05/18 18:10:26 (10 days ago)

Add some docs for scrutinizer

1 edited


  • wiki/scrutinizer

    r36678 r36679  
     2[[tags: internals]]
     4== Scrutinizer
     5Scrutinizer is the CHICKEN's type checker.
     7It checks type agreement in 2 situations: at function call sites and
     8at assignments (set!).
     10In addition to type checking, scrutinizer does optimizations by doing
     11tree re-writes for function calls using specializations and
     12special-cases ({{define-special-case}} in scrutinizer).
     14=== Type environment
     15This is the big greek gamma letter one can see in the literature.
     17It's basically just a mapping from variable identifiers to types.
     18Things are added to and removed from it while the node tree is walked
     19and variables enter and leave the current scope.
     21It consists of three things:
     23; type database : This is populated from the .types files before the
     24walking starts.
     25; e : The second argument to {{walk}}. id -> type alist
     26; blist : ("branch list"), when walking {{if}} nodes the variable
     27types are updated only in the current {{if}} (tree) branch.
     29New mappings are added to {{e}} when walking {{let}} nodes (only?).
     31=== Some functions
     32==== {{(match-types t1 t2 #!optional (typeenv (type-typeenv `(or ,t1 ,t2))) all)}}
     33The heart of the scrutinizer. Basically returns {{#t}} iff {{t2}} is a
     34subtype of (or of equal type to) {{t1}}.
     36In addition, mutates typeenv if unification happens.
     38==== scrutinize -> (walk n e loc dest tail flow ctags)
     39; {{n}} : the canonicalized node (tree)
     40; {{e}} : one part of "type environment". An alist from identifiers to
     41type types.
     42; {{flow}} and {{ctags}} : related to blist
     44Returns {{*}} for unknown number of return values, or {{(type ...)}} for
     45known number of return values.
     47For example walking {{(begin)}} would return {{*}}. Walking {{(cons 'a 'b)}} would
     48return {{((pair symbol symbol))}}.
     50==== (refine-types t1 t2)
     51Given a variable has type {{t1}} and it's learned that it also has type
     52{{t2}} this function returns a hopefully more detailed type for the
     55There are two cases when this function is used:
     57Refining variable's type for if's branches when the if's test was a
     60<enscript highlight="scheme">
     61(let ((x (the (list-of symbol))))
     62  (if (pair? x) <branch-c> <branch-a>))
     65Here {{pair?}} is a predicate for {{pair}}.
     67In {{<branch-c>}} we know {{x}}'s type is {{pair}} in addition to
     68{{'(list-of symbol)}}. The variable's type will be updated, in {{blist}},
     70{{(refine-types '(list-of symbol) 'pair)}} which would ideally return
     71{{(pair symbol (list-of symbol))}}.
     73For {{<branch-a>}} {{x}}'s type will be:
     75{{(refine-types '(list-of symbol) '(not pair))}} which would ideally
     76return {{null}}.
     78This kind of reasoning is called {{occurence typing}} in the
     81In {{tests/scrutinizer-tests.scm}} the last case could be asserted
     82with this: {{(test (~> (list-of symbol) (not pair) null))}}
     84Second place refine-type will be used is when calling functions with
     85{{enforce-argument-types}} declaration:
     87<enscript highlight="scheme">
     88(let ((x (foo)))
     89  (length x))
     92This will cause a {{x}}'s type to be set (in blist) to {{(refine-types
     93'* 'list)}}, which should be {{list}}. {{list}} is an alias for
     94{{(list-of *)}}.
     96* Ideally if {{t2}} is a subtype of {{t1}} (t2 <= t1 and {{(match-types t1 t2)}}
     97returns true) refine-types should return {{t2}}.
     99Simple case: {{(refine-types '(or symbol number) 'symbol) -> 'symbol}}.
     101=== TODO
     102* how function calls are checked
     103* enabling debug output
     105=== possible topics
     106* what is type
     107* subtype relation
     108* typeenv / forall / type variables
     109* how match-types works
Note: See TracChangeset for help on using the changeset viewer.