PreviousUpNext

15.3.212  src/lib/compiler/back/top/highcode/highcode-type.api

## highcode-type.api 
#
# Here and in
#
#     src/lib/compiler/back/top/highcode/highcode-type.pkg
#
# we implement the client-code interface to the
# hash-consed types implemented in
#
#     src/lib/compiler/back/top/highcode/highcode-uniq-types.pkg
#
# For general context, see
#
#     src/A.COMPILER-PASSES.OVERVIEW
#
# For authoritative background see Zhong Shao's PhD thesis:
#
#     Compiling Standard ML for Efficient Execution on Modern Machines
#     http://flint.cs.yale.edu/flint/publications/zsh-thesis.html
#
# Here we implement what his thesis calls LTY ("LEXP types").
#
# These type representations are used in all
# three of the intermediate code representations
# used in the backend tophalf:
#
#     lambdacode (polymorphically typed lambda calculus),
#     anormcode (A-Normal format)
#     nextcode ("continuation passing style")
#
# implemented respectively in
#
#     src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg
#     src/lib/compiler/back/top/anormcode/anormcode-form.pkg
#     src/lib/compiler/back/top/nextcode/nextcode-form.api
#
# This interface hides the implementation details of highcode
# Uniqkind, Uniqtype, and Uniqtypoid defined inside
# highcode_uniq_types.  The main point of this is to shield our code
# clients from the complexity of the hash-consing which we 
# implement in
#
#     src/lib/compiler/back/top/highcode/highcode-uniq-types.pkg
#
# For each entity, we provide a series of constructor functions,
# deconstructor functions, predicate functions, and
# functions that test equivalence and do pretty-printing.
#
# This interface should only refer to packages
#     debruijn_index
#     highcode_uniq_types,
#     highcode_basetypes
#     symbol 

# Compiled by:
#     src/lib/compiler/core.sublib



###              "Once code is decently formatted
###               and commented, sometimes even the
###               original author can understand it."
###
###                           Wilbur Thompson


stipulate
    package di  =  debruijn_index;                                              # debruijn_index                is from   src/lib/compiler/front/typer/basics/debruijn-index.pkg
    package hbt =  highcode_basetypes;                                          # highcode_basetypes            is from   src/lib/compiler/back/top/highcode/highcode-basetypes.pkg
    package hut =  highcode_uniq_types;                                         # highcode_uniq_types           is from   src/lib/compiler/back/top/highcode/highcode-uniq-types.pkg
    package tmp =  highcode_codetemp;                                           # highcode_codetemp             is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
    package hbt =  highcode_basetypes;                                          # highcode_basetypes            is from   src/lib/compiler/back/top/highcode/highcode-basetypes.pkg
herein

    # This api is implemented in:
    #
    #     src/lib/compiler/back/top/highcode/highcode-type.pkg

    api Highcode_Type {
        #
        #

        # Background:   Values, Types and Kinds
        #
        #     types are sets of values
        #     kinds are sets of types
        #
        # For example
        #
        #     Bool    =  TRUE | FALSE;          # A type.
        #    'Scalar' =  Bool | Int | Float;    # A kind.
        #
        # The Mythryl surface language has values and types but not kinds,
        # but within the compiler we need all three.


        # Anormcode Highcode_Kind is roughly equivalent to the following Mythryl sumtype
        #
        #    Kind 
        #      = TYPE 
        #      | BOXED_TYPE
        #      | TYPESEQ List(Uniqkind)
        #      | TYPEFUN (Uniqkind, Uniqkind)
        #      ;
        #
        # We treat Uniqkind as an abstract type
        # to isolate clients from the complexity of the
        # hashconsing machinery;  this has the downside
        # of preventing them from using pattern matching.


        # Uniqkind constructors.
        #
        # The first two are just global constants:
        #
        plaintype_uniqkind:      hut::Uniqkind;
        boxedtype_uniqkind:      hut::Uniqkind;
        make_kindseq_uniqkind:   List(hut::Uniqkind)                 ->  hut::Uniqkind;
        make_kindfun_uniqkind:  (List(hut::Uniqkind), hut::Uniqkind) ->  hut::Uniqkind;

        # Uniqkind deconstructors -- inverses to above four.
        #
        # The first two here are basically useless;
        # they just "complete the set".
        #
        unpack_plaintype_uniqkind:              hut::Uniqkind ->  Void;                                         # \\ _ = ();
        unpack_boxedtype_uniqkind:              hut::Uniqkind ->  Void;                                         # \\ _ = ();
        unpack_kindseq_uniqkind:                hut::Uniqkind ->  List(hut::Uniqkind);
        unpack_kindfun_uniqkind:                hut::Uniqkind -> (List(hut::Uniqkind), hut::Uniqkind);

        # Uniqkind predicates:
        #
        uniqkind_is_plaintype:                  hut::Uniqkind -> Bool;
        uniqkind_is_boxedtype:                  hut::Uniqkind -> Bool;
        uniqkind_is_kindseq:                    hut::Uniqkind -> Bool;
        uniqkind_is_kindfun:                    hut::Uniqkind -> Bool;

        # Uniqkind one-arm switches.
        #
        # These are if-then-else constructs;
        # The first fn is called with the kind contents
        # if it is of the appropriate flavor, otherwise
        # the second ('otherwise') fn is called. Chaining
        # these together allows a full 'case' to be simulated:
        #
        if_uniqkind_is_plaintype:       (hut::Uniqkind, (Void -> X), (hut::Uniqkind -> X)) -> X;
        if_uniqkind_is_boxedtype:       (hut::Uniqkind, (Void -> X), (hut::Uniqkind -> X)) -> X;
        if_uniqkind_is_kindseq:         (hut::Uniqkind, (List( hut::Uniqkind ) -> X), (hut::Uniqkind -> X)) -> X;
        if_uniqkind_is_kindfun:         (hut::Uniqkind, ((List( hut::Uniqkind ), hut::Uniqkind) -> X), (hut::Uniqkind -> X)) -> X;



        # Anormcode Calling_Convention Useless_Recordflag are used to
        # classify different kinds of typelocked 
        # functions and records. As of now, they are
        # roughly equivalent to:
        #
        #    Calling_Convention
        #      = FIXED_CALLING_CONVENTION
        #      | VARIABLE_CALLING_CONVENTION  { arg_is_raw:     Bool,
        #                                       body_is_raw:    Bool
        #                                     }
        #      ;
        #
        #    Useless_Recordflag = USELESS_RECORDFLAG;           # This appears to be something someone started and didn't finish. :-) -- Cynbe
        #
        # We treat both as abstract types so,
        # so again we are unfortunately not
        # able to use pattern matching with them.
        #
        # NOTE: VARIABLE_CALLING_CONVENTION flags are used by HIGHCODEs before we perform representation
        # analysis while FIXED_CALLING_CONVENTION is used by HIGHCODEs after we perform representation
        # analysis. 


        # Calling_Convention and Useless_Recordflag constructors:
        #
        make_variable_calling_convention:  { arg_is_raw: Bool, body_is_raw: Bool } -> hut::Calling_Convention;          # I don't yet get the raw/cooked type distinction.
        fixed_calling_convention:   hut::Calling_Convention;                                                            #
        useless_recordflag:     hut::Useless_Recordflag;                                                                #

        # Calling_Convention and Useless_Recordflag deconstructors.
        # The idea of these is to return the initial values used to create them:
        #
        unpack_variable_calling_convention:     hut::Calling_Convention -> { arg_is_raw: Bool, body_is_raw: Bool };     # This is never used.
        unpack_fixed_calling_convention:        hut::Calling_Convention -> Void;                                        # This is never used.
        unpack_useless_recordflag:              hut::Useless_Recordflag     -> Void;                                    # This is never used.

        # Calling_Convention and Useless_Recordflag predicates:
        #
        calling_convention_is_variable:         hut::Calling_Convention -> Bool;                                        # 
        calling_convention_is_fixed:            hut::Calling_Convention -> Bool;                                        #
        useless_recordflag_is:                  hut::Useless_Recordflag -> Bool;                                        # 

        # Calling_Convention and Useless_Recordflag one-arm switches.
        # These are if-then-else constructs which can be chained to make a full 'case' statement:
        #
        if_calling_convention_is_variable:      (hut::Calling_Convention,   { arg_is_raw: Bool, body_is_raw: Bool } -> X,   hut::Calling_Convention -> X)   ->   X;
        if_calling_convention_is_fixed:         (hut::Calling_Convention,   Void                                    -> X,   hut::Calling_Convention -> X)   ->   X;
        if_useless_recordflag_is:               (hut::Useless_Recordflag,   Void                                    -> X,   hut::Useless_Recordflag -> X)   ->   X;     # Useless and unused both.


        # Anormcode Uniqtype is roughly equivalent to the following Mythryl sumtype.
        # Note that a TYPEFUN is a type -> type compiletime function,
        # whereas an ARROW_TYPE represents a value -> value runtime function.
        #
        #    Uniqtype
        #      = TYPEVAR        (Debruijn_Index, Int)
        #      | NAMED_TYPEVAR   tmp::Codetemp
        #      | BASETYPE        hut::Basetype
        #      | TYPEFUN         (List( hut::Uniqkind ), hut::Uniqtype)
        #      | APPLY_TYPEFUN  (hut::Uniqtype, List( hut::Uniqtype ))
        #      | TYPESEQ   List( hut::Uniqtype )
        #      | TYPE_PROJECTION (hut::Uniqtype, Int)
        #      | SUM_TYPE        List( hut::Uniqtype )
        #      | RECURSIVE_TYPE  (hut::Uniqtype, Int)
        #      | TUPLE_TYPE      List( hut::Uniqtype )           #  record_flag hidden 
        #      | ARROW_TYPE     (hut::Calling_Convention, List(hut::Uniqtype), List(hut::Uniqtype))
        #      | BOXED_TYPE       hut::Uniqtype
        #      | ABSTRACT_TYPE   hut::Uniqtype 
        #      | EXTENSIBLE_TOKEN_TYPE  (Token, hut::Uniqtype)
        #      | FATE_TYPE              List(hut::Uniqtype)
        #      | INDIRECT_TYPE_THUNK   (hut::Uniqtype, hut::Uniqtypoid)
        #      | TYPE_CLOSURE  (Uniqtype, Int, Int, Uniqtype_Dictionary)
        #      ;
        #
        # We treat Uniqtype as an abstract type
        # to isolate clients from the complexity of the
        # hashconsing machinery;  this has the downside
        # of preventing them from using pattern matching.
        #
        # Type applications (APPLY_TYPEFUN) and projections 
        # (TYPE_PROJECTION) are automatically reduced as needed:
        # the client does not need to worry about whether
        # a hut::Uniqtype is in the normal form or not,
        # all functions defined here automatically 
        # take care of this.


        # Our Uniqtype constructors:
        #
        make_debruijn_typevar_uniqtype: (di::Debruijn_Index, Int)                                               -> hut::Uniqtype;
        make_named_typevar_uniqtype:     tmp::Codetemp                                                          -> hut::Uniqtype;
        make_basetype_uniqtype:          hbt::Basetype                                                          -> hut::Uniqtype;
        make_typefun_uniqtype:          (List( hut::Uniqkind ), hut::Uniqtype)                                  -> hut::Uniqtype;
        make_apply_typefun_uniqtype:          (hut::Uniqtype, List( hut::Uniqtype ))                            -> hut::Uniqtype;
        make_typeseq_uniqtype:           List( hut::Uniqtype )                                                  -> hut::Uniqtype;
        make_ith_in_typeseq_uniqtype:   (hut::Uniqtype, Int)                                                    -> hut::Uniqtype;
        make_sum_uniqtype:               List( hut::Uniqtype )                                                  -> hut::Uniqtype;
        make_recursive_uniqtype:        ((Int, hut::Uniqtype, List(hut::Uniqtype)), Int)                        -> hut::Uniqtype; 
        make_extensible_token_uniqtype:   hut::Uniqtype                                                         -> hut::Uniqtype;
        make_abstract_uniqtype:          hut::Uniqtype                                                          -> hut::Uniqtype;
        make_boxed_uniqtype:             hut::Uniqtype                                                          -> hut::Uniqtype;
        make_tuple_uniqtype:             List( hut::Uniqtype )                                                  -> hut::Uniqtype;
        make_arrow_uniqtype:            (hut::Calling_Convention, List(hut::Uniqtype), List(hut::Uniqtype))     -> hut::Uniqtype;

        # Our hut::Uniqtype deconstructors.
        # These are basically inverse to the above constructors:
        #
        unpack_debruijn_typevar_uniqtype:       hut::Uniqtype ->   (di::Debruijn_Index, Int); 
        unpack_named_typevar_uniqtype:          hut::Uniqtype ->    tmp::Codetemp;
        unpack_basetype_uniqtype:               hut::Uniqtype ->    hbt::Basetype; 
        unpack_typefun_uniqtype:                hut::Uniqtype ->   (List( hut::Uniqkind ), hut::Uniqtype); 
        unpack_apply_typefun_uniqtype:          hut::Uniqtype ->   (hut::Uniqtype, List( hut::Uniqtype ));
        unpack_typeseq_uniqtype:                hut::Uniqtype ->    List( hut::Uniqtype );
        unpack_ith_in_typeseq_uniqtype:         hut::Uniqtype ->   (hut::Uniqtype, Int); 
        unpack_sum_uniqtype:                    hut::Uniqtype ->    List( hut::Uniqtype );
        unpack_recursive_uniqtype:              hut::Uniqtype ->   (((Int, hut::Uniqtype, List( hut::Uniqtype )) ), Int); 
        unpack_extensible_token_uniqtype:       hut::Uniqtype ->    hut::Uniqtype;
        unpack_abstract_uniqtype:               hut::Uniqtype ->    hut::Uniqtype; 
        unpack_boxed_uniqtype:                  hut::Uniqtype ->    hut::Uniqtype; 
        unpack_tuple_uniqtype:                  hut::Uniqtype ->    List( hut::Uniqtype ); 
        unpack_arrow_uniqtype:                  hut::Uniqtype ->   (hut::Calling_Convention, List( hut::Uniqtype ), List( hut::Uniqtype )); 

        # Our hut::Uniqtype predicates:
        #
        uniqtype_is_debruijn_typevar:           hut::Uniqtype -> Bool;
        uniqtype_is_named_typevar:              hut::Uniqtype -> Bool;
        uniqtype_is_basetype:                   hut::Uniqtype -> Bool;
        uniqtype_is_typefun:                    hut::Uniqtype -> Bool;
        uniqtype_is_apply_typefun:              hut::Uniqtype -> Bool;
        uniqtype_is_typeseq:                    hut::Uniqtype -> Bool;
        uniqtype_is_ith_in_typeseq:             hut::Uniqtype -> Bool;
        uniqtype_is_sum:                        hut::Uniqtype -> Bool;
        uniqtype_is_recursive:                  hut::Uniqtype -> Bool;
        uniqtype_is_extensible_token:           hut::Uniqtype -> Bool;
        uniqtype_is_abstract:                   hut::Uniqtype -> Bool;
        uniqtype_is_boxed:                      hut::Uniqtype -> Bool;
        uniqtype_is_tuple:                      hut::Uniqtype -> Bool;
        uniqtype_is_arrow:                      hut::Uniqtype -> Bool;

        # Our hut::Uniqtype one-armed switches.
        # These are if-then-else constructs which may be
        # daisy-chained to implement a complete 'case' statement:
        #
        if_uniqtype_is_debruijn_typevar:        (hut::Uniqtype,  ((di::Debruijn_Index, Int)                                                     -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_named_typevar:           (hut::Uniqtype,   (tmp::Codetemp                                                                -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_basetype:                (hut::Uniqtype,   (hbt::Basetype                                                                -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_typefun:                 (hut::Uniqtype,   ((List( hut::Uniqkind ), hut::Uniqtype)                                       -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_apply_typefun:           (hut::Uniqtype,   ((hut::Uniqtype, List( hut::Uniqtype ))                                       -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_typeseq:                 (hut::Uniqtype,   (List( hut::Uniqtype )                                                        -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_ith_in_typeseq:          (hut::Uniqtype,   ((hut::Uniqtype, Int)                                                         -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_sum:                     (hut::Uniqtype,   (List( hut::Uniqtype )                                                        -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_recursive:               (hut::Uniqtype,   ((((Int, hut::Uniqtype, List( hut::Uniqtype ))), Int)                         -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_extensible_token:        (hut::Uniqtype,   (hut::Uniqtype                                                                -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_abstract:                (hut::Uniqtype,   (hut::Uniqtype                                                                -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_boxed:                   (hut::Uniqtype,   (hut::Uniqtype                                                                -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_tuple:                   (hut::Uniqtype,   (List( hut::Uniqtype )                                                        -> X),   (hut::Uniqtype -> X))   ->   X;
        if_uniqtype_is_arrow:                   (hut::Uniqtype,   ((hut::Calling_Convention, List( hut::Uniqtype ), List( hut::Uniqtype ))      -> X),   (hut::Uniqtype -> X))   ->   X;


        # Anormcode hut::Uniqtypoid is roughly equivalent to the following Mythryl sumtype
        #
        #    hut::Uniqtypoid
        #      = TYPELOCKED_TYPE        hut::Uniqtype
        #      | PACKAGE_TYPE           List( hut::Uniqtypoid )
        #      | GENERIC_PACKAGE_TYPE   (List hut::Uniqtypoid, List hut::Uniqtypoid)
        #      | TYPEAGNOSTIC_TYPE      (List hut::Uniqkind, List hut::Uniqtypoid)
        #      | INTERNAL_FATE_TYPE     List( hut::Uniqtypoid )
        #      | INDIRECT_TYPE_THUNK    (Uniqtypoid, Typoid)
        #      | TYPE_CLOSURE           (Uniqtypoid, Int, Int, Uniqtype_Dictionary)
        #      ;        
        #
        # We treat Uniqtypoid as an abstract type
        # to isolate clients from the complexity of the
        # hashconsing machinery;  this has the downside
        # of preventing them from using pattern matching.
        # 
        # Clients need not worry whether a hut::Uniqtypoid
        # is in normal form.


        # hut::Uniqtypoid constructors:
        #
        make_type_uniqtypoid:            hut::Uniqtype                                  ->   hut::Uniqtypoid;   # Heavily used!
        make_package_uniqtypoid:         List(hut::Uniqtypoid)                          ->   hut::Uniqtypoid;
        make_generic_package_uniqtypoid:(List(hut::Uniqtypoid), List(hut::Uniqtypoid))  ->   hut::Uniqtypoid;
        make_typeagnostic_uniqtypoid:   (List(hut::Uniqkind), List(hut::Uniqtypoid))    ->   hut::Uniqtypoid;    

        # hut::Uniqtypoid deconstructors.
        # These are just inverses to the above four:
        #
        unpack_type_uniqtypoid:                 hut::Uniqtypoid ->    hut::Uniqtype;
        unpack_package_uniqtypoid:              hut::Uniqtypoid ->    List(hut::Uniqtypoid);
        unpack_generic_package_uniqtypoid:      hut::Uniqtypoid ->   (List(hut::Uniqtypoid), List( hut::Uniqtypoid ));
        unpack_typeagnostic_uniqtypoid:         hut::Uniqtypoid ->   (List(hut::Uniqkind), List( hut::Uniqtypoid ));

        # hut::Uniqtypoid predicates:
        #
        uniqtypoid_is_type:                     hut::Uniqtypoid -> Bool;
        uniqtypoid_is_package:                  hut::Uniqtypoid -> Bool;
        uniqtypoid_is_generic_package:          hut::Uniqtypoid -> Bool;
        uniqtypoid_is_typeagnostic:             hut::Uniqtypoid -> Bool;

        # hut::Uniqtypoid one-armed switches.
        # These are if-then-else constructs which may be
        # daisy-chained to implement a complete 'case' statement:
        #
        if_uniqtypoid_is_type:                  (hut::Uniqtypoid,    hut::Uniqtype                                      -> X,   hut::Uniqtypoid -> X)    ->    X;
        if_uniqtypoid_is_package:               (hut::Uniqtypoid,    List(hut::Uniqtypoid)                              -> X,   hut::Uniqtypoid -> X)    ->    X;
        if_uniqtypoid_is_generic_package:       (hut::Uniqtypoid,   (List(hut::Uniqtypoid), List(hut::Uniqtypoid))      -> X,   hut::Uniqtypoid -> X)    ->    X;
        if_uniqtypoid_is_typeagnostic:          (hut::Uniqtypoid,   (List(hut::Uniqkind), List(hut::Uniqtypoid))        -> X,   hut::Uniqtypoid -> X)    ->    X;



        # Because highcode hut::Uniqtype is embedded
        # inside highcode  hut::Uniqtypoid, we supply the
        # the following utility functions on building ltys that
        # are based on simple typelocked types.  These are
        # simple compositions of previously defined functions:

        # hut::Uniqtype-hut::Uniqtypoid constructors:
        #
        make_debruijn_typevar_uniqtypoid:   (di::Debruijn_Index, Int)                                                   ->  hut::Uniqtypoid;
        make_basetype_uniqtypoid:           hbt::Basetype                                                               ->  hut::Uniqtypoid;
        make_tuple_uniqtypoid:              List(hut::Uniqtypoid)                                                       ->  hut::Uniqtypoid;
        make_arrow_uniqtypoid:             (hut::Calling_Convention, List(hut::Uniqtypoid), List(hut::Uniqtypoid))      ->  hut::Uniqtypoid;

        # hut::Uniqtype-hut::Uniqtypoid deconstructors.
        # These are just inverses to the above four functions:
        #
        unpack_debruijn_typevar_uniqtypoid: hut::Uniqtypoid ->   (di::Debruijn_Index, Int);
        unpack_basetype_uniqtypoid:         hut::Uniqtypoid ->    hbt::Basetype;
        unpack_tuple_uniqtypoid:            hut::Uniqtypoid ->    List(hut::Uniqtypoid);
        unpack_arrow_uniqtypoid:            hut::Uniqtypoid ->   (hut::Calling_Convention, List(hut::Uniqtypoid), List(hut::Uniqtypoid));

        # hut::Uniqtype-hut::Uniqtypoid predicates:
        #
        uniqtypoid_is_debruijn_typevar:     hut::Uniqtypoid -> Bool;
        uniqtypoid_is_basetype:             hut::Uniqtypoid -> Bool;
        uniqtypoid_is_tuple_type:           hut::Uniqtypoid -> Bool;
        uniqtypoid_is_arrow_type:           hut::Uniqtypoid -> Bool;

        # hut::Uniqtype-hut::Uniqtypoid one-arm switches.
        # These are if-then-else constructs which may be
        # daisy-chained to implement a complete 'case' statement:
        #
        if_uniqtypoid_is_debruijn_typevar: (hut::Uniqtypoid,   (di::Debruijn_Index, Int)                                                -> X,   hut::Uniqtypoid -> X)   ->   X;
        if_uniqtypoid_is_basetype:         (hut::Uniqtypoid,   hbt::Basetype                                                            -> X,   hut::Uniqtypoid -> X)   ->   X;
        if_uniqtypoid_is_tuple_type:       (hut::Uniqtypoid,   List(hut::Uniqtype)                                                      -> X,   hut::Uniqtypoid -> X)   ->   X;
        if_uniqtypoid_is_arrow_type:       (hut::Uniqtypoid,   (hut::Calling_Convention, List(hut::Uniqtype), List(hut::Uniqtype))      -> X,   hut::Uniqtypoid -> X)   ->   X;





        ################################################################################################
        # The following functions are written for nextcode only.
        # If you are writing code for highcode, you should not use any of these functions. 
        # The fate referred here is the internal fate introduced
        # via FPS conversion; it is different from the source-level fate 
        # (Fate(X)) or control fate (Control_Fate(X)) where are represented 
        # as xt::primTypeCon_fate and xt::primTypeCon_control_fate respectively. 


        # fate-hut::Uniqtype-hut::Uniqtypoid constructors:
        #
        make_uniqtype_fate:      List(hut::Uniqtype  ) -> hut::Uniqtype;
        make_uniqtypoid_fate:    List(hut::Uniqtypoid) -> hut::Uniqtypoid;

        # fate-hut::Uniqtype-hut::Uniqtypoid deconstructors:
        #
        unpack_uniqtype_fate:    hut::Uniqtype     -> List(hut::Uniqtype);
        unpack_uniqtypoid_fate:  hut::Uniqtypoid   -> List(hut::Uniqtypoid  );

        # fate-hut::Uniqtype-hut::Uniqtypoid predicates:
        #
        uniqtype_is_fate:        hut::Uniqtype     -> Bool;
        uniqtypoid_is_fate:      hut::Uniqtypoid   -> Bool;

        # fate-hut::Uniqtype-hut::Uniqtypoid one-arm switches:
        #
        if_uniqtype_is_fate:    (hut::Uniqtype,   List( hut::Uniqtype  ) -> X,   hut::Uniqtype   -> X)    ->    X;
        if_uniqtypoid_is_fate:  (hut::Uniqtypoid, List( hut::Uniqtypoid) -> X,   hut::Uniqtypoid -> X)    ->    X;





        ################################################################################################
        # The following functions are written for lambdacode_type only. If you
        # are writing code for highcode only, don't use any of these functions. 
        # The idea is that in lambdacode, all (value or type) functions have single
        # argument and single return-result. Ideally, we should define 
        # another set of sumtypes for types and ltys. But we want to avoid
        # the translation from lambdacode_type to highcode types, so we let them
        # share the same representations as much as possible. 
        #
        # Ultimately, highcode_type should be separated into two files: one for 
        # highcode, another for lambdacode, but we will see if this is necessary.


        # lambdacode hut::Uniqtype-hut::Uniqtypoid constructors:
        #
        make_lambdacode_arrow_uniqtype:                 (hut::Uniqtype,         hut::Uniqtype ) -> hut::Uniqtype;     
        make_lambdacode_arrow_uniqtypoid:               (hut::Uniqtypoid,       hut::Uniqtypoid) -> hut::Uniqtypoid;
        make_lambdacode_typeagnostic_uniqtypoid:        (List(hut::Uniqkind),   hut::Uniqtypoid) -> hut::Uniqtypoid;  
        make_lambdacode_generic_package_uniqtypoid:     (hut::Uniqtypoid,       hut::Uniqtypoid) -> hut::Uniqtypoid;         

        # lambdacode hut::Uniqtype-hut::Uniqtypoid deconstructors:
        #
        unpack_lambdacode_arrow_uniqtype:               hut::Uniqtype   -> (hut::Uniqtype,         hut::Uniqtype);
        unpack_lambdacode_arrow_uniqtypoid:             hut::Uniqtypoid -> (hut::Uniqtypoid,       hut::Uniqtypoid);    
        unpack_lambdacode_typeagnostic_uniqtypoid:      hut::Uniqtypoid -> (List( hut::Uniqkind ), hut::Uniqtypoid);
        unpack_lambdacode_generic_package_uniqtypoid:   hut::Uniqtypoid -> (hut::Uniqtypoid,       hut::Uniqtypoid);       

        # lambdacode hut::Uniqtype-hut::Uniqtypoid predicates:
        #
        uniqtype_is_lambdacode_arrow:                   hut::Uniqtype  -> Bool;          
        uniqtypoid_is_lambdacode_arrow:                 hut::Uniqtypoid -> Bool;
        uniqtypoid_is_lambdacode_typeagnostic:          hut::Uniqtypoid -> Bool;
        uniqtypoid_is_lambdacode_generic_package:       hut::Uniqtypoid -> Bool;            

        # lambdacode hut::Uniqtype-hut::Uniqtypoid one-arm switches:
        #
        if_uniqtype_is_lambdacode_arrow:                (hut::Uniqtype,     (hut::Uniqtype,       hut::Uniqtype  ) -> X,   hut::Uniqtype   -> X)   ->   X;
        if_uniqtypoid_is_lambdacode_arrow:              (hut::Uniqtypoid,   (hut::Uniqtype,       hut::Uniqtype  ) -> X,   hut::Uniqtypoid -> X)   ->   X;
        if_uniqtypoid_is_lambdacode_typeagnostic:       (hut::Uniqtypoid,   (List(hut::Uniqkind), hut::Uniqtypoid) -> X,   hut::Uniqtypoid -> X)   ->   X;
        if_uniqtypoid_is_lambdacode_generic_package:    (hut::Uniqtypoid,   (hut::Uniqtypoid,     hut::Uniqtypoid) -> X,   hut::Uniqtypoid -> X)   ->   X;
    };
end;

## Copyright (c) 1998 YALE FLINT PROJECT 
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext