PreviousUpNext

15.3.210  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.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 upper half, namely lambdacode (polymorphically typed lambda calculus),
# anormcode (A-Normal format) and nextcode ("continuation passing style"):
#
#     src/lib/compiler/back/top/anormcode/anormcode-form.pkg
#     src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg
#     src/lib/compiler/back/top/nextcode/nextcode-form.api
#
# This interface hides the implementation details of highcode
# Uniqkind, Uniqtyp, and Uniqtype 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 datatype
        #
        #    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;                                         # fn _ = ();
        unpack_boxedtype_uniqkind:              hut::Uniqkind ->  Void;                                         # fn _ = ();
        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
        # is 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;                                                                        # "rfc" == "record flag constructor"

        # 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;                                                                    # "ffp" == "fn flag predicate"
        calling_convention_is_fixed:   hut::Calling_Convention -> Bool;                                                                 #
        useless_recordflag_is:     hut::Useless_Recordflag -> Bool;                                                                     # "rfp" == "record flag predicate"

        # 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 Uniqtyp is roughly equivalent to the following Mythryl datatype.
        # Note that a TYPEFUN is a type -> type compiletime function,
        # whereas an ARROW_TYPE represents a value -> value runtime function.
        #
        #    Uniqtyp
        #      = TYPEVAR        (Debruijn_Index, Int)
        #      | NAMED_TYPEVAR   tmp::Codetemp
        #      | BASETYPE        hut::Basetype
        #      | TYPEFUN         (List( hut::Uniqkind ), hut::Uniqtyp)
        #      | APPLY_TYPEFUN      (hut::Uniqtyp, List( hut::Uniqtyp ))
        #      | TYPESEQ   List( hut::Uniqtyp )
        #      | TYPE_PROJECTION (hut::Uniqtyp, Int)
        #      | SUM_TYPE        List( hut::Uniqtyp )
        #      | RECURSIVE_TYPE  (hut::Uniqtyp, Int)
        #      | TUPLE_TYPE      List( hut::Uniqtyp )           #  record_flag hidden 
        #      | ARROW_TYPE     (hut::Calling_Convention, List(hut::Uniqtyp), List(hut::Uniqtyp))
        #      | BOXED_TYPE       hut::Uniqtyp
        #      | ABSTRACT_TYPE   hut::Uniqtyp 
        #      | EXTENSIBLE_TOKEN_TYPE  (Token, hut::Uniqtyp)
        #      | FATE_TYPE              List(hut::Uniqtyp)
        #      | INDIRECT_TYPE_THUNK   (hut::Uniqtyp, hut::Uniqtype)
        #      | TYPE_CLOSURE  (Uniqtyp, Int, Int, Uniqtyp_Dictionary)
        #      ;
        #
        # We treat Uniqtyp 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::Uniqtyp is in the normal form or not,
        # all functions defined here automatically 
        # take care of this.


        # Our Uniqtyp constructors:
        #
        make_debruijn_typevar_uniqtyp:  (di::Debruijn_Index, Int)                                               -> hut::Uniqtyp;
        make_named_typevar_uniqtyp:      tmp::Codetemp                                                          -> hut::Uniqtyp;
        make_basetype_uniqtyp:           hbt::Basetype                                                          -> hut::Uniqtyp;
        make_typefun_uniqtyp:           (List( hut::Uniqkind ), hut::Uniqtyp)                                   -> hut::Uniqtyp;
        make_apply_typefun_uniqtyp:             (hut::Uniqtyp, List( hut::Uniqtyp ))                            -> hut::Uniqtyp;
        make_typeseq_uniqtyp:            List( hut::Uniqtyp )                                                   -> hut::Uniqtyp;
        make_ith_in_typeseq_uniqtyp:    (hut::Uniqtyp, Int)                                                     -> hut::Uniqtyp;
        make_sum_uniqtyp:                List( hut::Uniqtyp )                                                   -> hut::Uniqtyp;
        make_recursive_uniqtyp:         ((Int, hut::Uniqtyp, List(hut::Uniqtyp)), Int)                          -> hut::Uniqtyp; 
        make_extensible_token_uniqtyp:   hut::Uniqtyp                                                           -> hut::Uniqtyp;
        make_abstract_uniqtyp:           hut::Uniqtyp                                                           -> hut::Uniqtyp;
        make_boxed_uniqtyp:              hut::Uniqtyp                                                           -> hut::Uniqtyp;
        make_tuple_uniqtyp:              List( hut::Uniqtyp )                                                   -> hut::Uniqtyp;
        make_arrow_uniqtyp:             (hut::Calling_Convention, List(hut::Uniqtyp), List(hut::Uniqtyp))       -> hut::Uniqtyp;

        # Our hut::Uniqtyp deconstructors.
        # These are basically inverse to the above constructors:
        #
        unpack_debruijn_typevar_uniqtyp:        hut::Uniqtyp ->   (di::Debruijn_Index, Int); 
        unpack_named_typevar_uniqtyp:           hut::Uniqtyp ->    tmp::Codetemp;
        unpack_basetype_uniqtyp:                hut::Uniqtyp ->    hbt::Basetype; 
        unpack_typefun_uniqtyp:                 hut::Uniqtyp ->   (List( hut::Uniqkind ), hut::Uniqtyp); 
        unpack_apply_typefun_uniqtyp:           hut::Uniqtyp ->   (hut::Uniqtyp, List( hut::Uniqtyp ));
        unpack_typeseq_uniqtyp:                 hut::Uniqtyp ->    List( hut::Uniqtyp );
        unpack_ith_in_typeseq_uniqtyp:          hut::Uniqtyp ->   (hut::Uniqtyp, Int); 
        unpack_sum_uniqtyp:                     hut::Uniqtyp ->    List( hut::Uniqtyp );
        unpack_recursive_uniqtyp:               hut::Uniqtyp ->   (((Int, hut::Uniqtyp, List( hut::Uniqtyp )) ), Int); 
        unpack_extensible_token_uniqtyp:        hut::Uniqtyp ->    hut::Uniqtyp;
        unpack_abstract_uniqtyp:                hut::Uniqtyp ->    hut::Uniqtyp; 
        unpack_boxed_uniqtyp:                   hut::Uniqtyp ->    hut::Uniqtyp; 
        unpack_tuple_uniqtyp:                   hut::Uniqtyp ->    List( hut::Uniqtyp ); 
        unpack_arrow_uniqtyp:                   hut::Uniqtyp ->   (hut::Calling_Convention, List( hut::Uniqtyp ), List( hut::Uniqtyp )); 

        # Our hut::Uniqtyp predicates:
        #
        uniqtyp_is_debruijn_typevar:            hut::Uniqtyp -> Bool;
        uniqtyp_is_named_typevar:               hut::Uniqtyp -> Bool;
        uniqtyp_is_basetype:                    hut::Uniqtyp -> Bool;
        uniqtyp_is_typefun:                     hut::Uniqtyp -> Bool;
        uniqtyp_is_apply_typefun:               hut::Uniqtyp -> Bool;
        uniqtyp_is_typeseq:                     hut::Uniqtyp -> Bool;
        uniqtyp_is_ith_in_typeseq:              hut::Uniqtyp -> Bool;
        uniqtyp_is_sum:                         hut::Uniqtyp -> Bool;
        uniqtyp_is_recursive:                   hut::Uniqtyp -> Bool;
        uniqtyp_is_extensible_token:            hut::Uniqtyp -> Bool;
        uniqtyp_is_abstract:                    hut::Uniqtyp -> Bool;
        uniqtyp_is_boxed:                       hut::Uniqtyp -> Bool;
        uniqtyp_is_tuple:                       hut::Uniqtyp -> Bool;
        uniqtyp_is_arrow:                       hut::Uniqtyp -> Bool;

        # Our hut::Uniqtyp one-armed switches.
        # These are if-then-else constructs which may be
        # daisy-chained to implement a complete 'case' statement:
        #
        if_uniqtyp_is_debruijn_typevar:         (hut::Uniqtyp,   ((di::Debruijn_Index, Int)                                                             -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_named_typevar:            (hut::Uniqtyp,   (tmp::Codetemp                                                                         -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_basetype:                 (hut::Uniqtyp,   (hbt::Basetype                                                                         -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_typefun:                  (hut::Uniqtyp,   ((List( hut::Uniqkind ), hut::Uniqtyp)                                                 -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_apply_typefun:            (hut::Uniqtyp,   ((hut::Uniqtyp, List( hut::Uniqtyp ))                                                  -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_typeseq:                  (hut::Uniqtyp,   (List( hut::Uniqtyp )                                                                  -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_ith_in_typeseq:           (hut::Uniqtyp,   ((hut::Uniqtyp, Int)                                                                   -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_sum:                      (hut::Uniqtyp,   (List( hut::Uniqtyp )                                                                  -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_recursive:                (hut::Uniqtyp,   ((((Int, hut::Uniqtyp, List( hut::Uniqtyp ))), Int)                                    -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_extensible_token:         (hut::Uniqtyp,   (hut::Uniqtyp                                                                          -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_abstract:                 (hut::Uniqtyp,   (hut::Uniqtyp                                                                          -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_boxed:                    (hut::Uniqtyp,   (hut::Uniqtyp                                                                  -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_tuple:            (hut::Uniqtyp,   (List( hut::Uniqtyp )                                                          -> X),   (hut::Uniqtyp -> X))   ->   X;
        if_uniqtyp_is_arrow:            (hut::Uniqtyp,   ((hut::Calling_Convention, List( hut::Uniqtyp ), List( hut::Uniqtyp )) -> X),   (hut::Uniqtyp -> X))   ->   X;


        # Anormcode hut::Uniqtype is roughly equivalent to the following Mythryl datatype
        #
        #    hut::Uniqtype
        #      = TYPELOCKED_TYPE        hut::Uniqtyp
        #      | PACKAGE_TYPE           List( hut::Uniqtype )
        #      | GENERIC_PACKAGE_TYPE   (List hut::Uniqtype, List hut::Uniqtype)
        #      | TYPEAGNOSTIC_TYPE      (List hut::Uniqkind, List hut::Uniqtype)
        #      | INTERNAL_FATE_TYPE     List( hut::Uniqtype )
        #      | INDIRECT_TYPE_THUNK    (Uniqtype, Type)
        #      | TYPE_CLOSURE           (Uniqtype, Int, Int, Uniqtyp_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.
        # 
        # Clients need not worry whether a hut::Uniqtype
        # is in normal form.


        # hut::Uniqtype constructors:
        #
        make_typ_uniqtype:               hut::Uniqtyp                                   ->   hut::Uniqtype;     # Heavily used!
        make_package_uniqtype:           List(hut::Uniqtype)                            ->   hut::Uniqtype;
        make_generic_package_uniqtype:  (List(hut::Uniqtype), List(hut::Uniqtype))      ->   hut::Uniqtype;
        make_typeagnostic_uniqtype:     (List(hut::Uniqkind), List(hut::Uniqtype))      ->   hut::Uniqtype;    

        # hut::Uniqtype deconstructors.
        # These are just inverses to the above four:
        #
        unpack_typ_uniqtype:                    hut::Uniqtype ->    hut::Uniqtyp;
        unpack_package_uniqtype:                hut::Uniqtype ->    List(hut::Uniqtype);
        unpack_generic_package_uniqtype:        hut::Uniqtype ->   (List(hut::Uniqtype), List( hut::Uniqtype ));
        unpack_typeagnostic_uniqtype:           hut::Uniqtype ->   (List(hut::Uniqkind), List( hut::Uniqtype ));

        # hut::Uniqtype predicates:
        #
        uniqtype_is_typ:                        hut::Uniqtype -> Bool;
        uniqtype_is_package:                    hut::Uniqtype -> Bool;
        uniqtype_is_generic_package:            hut::Uniqtype -> Bool;
        uniqtype_is_typeagnostic:               hut::Uniqtype -> Bool;

        # 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_typ:             (hut::Uniqtype,    hut::Uniqtyp                                 -> X,   hut::Uniqtype -> X)    ->    X;
        if_uniqtype_is_package:         (hut::Uniqtype,    List(hut::Uniqtype)                          -> X,   hut::Uniqtype -> X)    ->    X;
        if_uniqtype_is_generic_package: (hut::Uniqtype,   (List(hut::Uniqtype), List(hut::Uniqtype))    -> X,   hut::Uniqtype -> X)    ->    X;
        if_uniqtype_is_typeagnostic:    (hut::Uniqtype,   (List(hut::Uniqkind), List(hut::Uniqtype))    -> X,   hut::Uniqtype -> X)    ->    X;



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

        # hut::Uniqtyp-hut::Uniqtype constructors:
        #
        make_debruijn_typevar_uniqtype:    (di::Debruijn_Index, Int)                                            ->  hut::Uniqtype;
        make_basetype_uniqtype:             hbt::Basetype                                                       ->  hut::Uniqtype;
        make_tuple_uniqtype:                List(hut::Uniqtype)                                                 ->  hut::Uniqtype;
        make_arrow_uniqtype:               (hut::Calling_Convention, List(hut::Uniqtype), List(hut::Uniqtype))  ->  hut::Uniqtype;

        # hut::Uniqtyp-hut::Uniqtype deconstructors.
        # These are just inverses to the above four functions:
        #
        unpack_debruijn_typevar_uniqtype:   hut::Uniqtype ->   (di::Debruijn_Index, Int);
        unpack_basetype_uniqtype:           hut::Uniqtype ->    hbt::Basetype;
        unpack_tuple_uniqtype:              hut::Uniqtype ->    List(hut::Uniqtype);
        unpack_arrow_uniqtype:              hut::Uniqtype ->   (hut::Calling_Convention, List(hut::Uniqtype), List(hut::Uniqtype));

        # hut::Uniqtyp-hut::Uniqtype predicates:
        #
        uniqtype_is_debruijn_typevar:       hut::Uniqtype -> Bool;
        uniqtype_is_basetype:               hut::Uniqtype -> Bool;
        uniqtype_is_tuple_type:             hut::Uniqtype -> Bool;
        uniqtype_is_arrow_type:             hut::Uniqtype -> Bool;

        # hut::Uniqtyp-hut::Uniqtype one-arm 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_basetype:           (hut::Uniqtype,   hbt::Basetype                                                                      -> X,   hut::Uniqtype -> X)   ->   X;
        if_uniqtype_is_tuple_type:         (hut::Uniqtype,   List(hut::Uniqtyp)                                                         -> X,   hut::Uniqtype -> X)   ->   X;
        if_uniqtype_is_arrow_type:         (hut::Uniqtype,   (hut::Calling_Convention, List(hut::Uniqtyp), List(hut::Uniqtyp))  -> X,   hut::Uniqtype -> 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::Uniqtyp-hut::Uniqtype constructors:
        #
        make_uniqtyp_fate:       List(hut::Uniqtyp) -> hut::Uniqtyp;
        make_uniqtype_fate:      List(hut::Uniqtype  ) -> hut::Uniqtype;

        # fate-hut::Uniqtyp-hut::Uniqtype deconstructors:
        #
        unpack_uniqtyp_fate:     hut::Uniqtyp -> List(hut::Uniqtyp);
        unpack_uniqtype_fate:    hut::Uniqtype   -> List(hut::Uniqtype  );

        # fate-hut::Uniqtyp-hut::Uniqtype predicates:
        #
        uniqtyp_is_fate:         hut::Uniqtyp -> Bool;
        uniqtype_is_fate:                hut::Uniqtype   -> Bool;

        # fate-hut::Uniqtyp-hut::Uniqtype one-arm switches:
        #
        if_uniqtyp_is_fate:     (hut::Uniqtyp,   List( hut::Uniqtyp) -> X,   hut::Uniqtyp -> X)    ->    X;
        if_uniqtype_is_fate:    (hut::Uniqtype,     List( hut::Uniqtype  ) -> X,   hut::Uniqtype   -> 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 datatypes for typs 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::Uniqtyp-hut::Uniqtype constructors:
        #
        make_lambdacode_arrow_uniqtyp:                  (hut::Uniqtyp,          hut::Uniqtyp ) -> hut::Uniqtyp;     
        make_lambdacode_arrow_uniqtype:                 (hut::Uniqtype,         hut::Uniqtype) -> hut::Uniqtype;
        make_lambdacode_typeagnostic_uniqtype:          (List(hut::Uniqkind),   hut::Uniqtype) -> hut::Uniqtype;  
        make_lambdacode_generic_package_uniqtype:       (hut::Uniqtype,         hut::Uniqtype) -> hut::Uniqtype;         

        # lambdacode hut::Uniqtyp-hut::Uniqtype deconstructors:
        #
        unpack_lambdacode_arrow_uniqtyp:                hut::Uniqtyp  -> (hut::Uniqtyp,          hut::Uniqtyp);
        unpack_lambdacode_arrow_uniqtype:               hut::Uniqtype -> (hut::Uniqtype,         hut::Uniqtype);    
        unpack_lambdacode_typeagnostic_uniqtype:        hut::Uniqtype -> (List( hut::Uniqkind ), hut::Uniqtype);
        unpack_lambdacode_generic_package_uniqtype:     hut::Uniqtype -> (hut::Uniqtype,         hut::Uniqtype);       

        # lambdacode hut::Uniqtyp-hut::Uniqtype predicates:
        #
        uniqtyp_is_lambdacode_arrow:                    hut::Uniqtyp  -> Bool;          
        uniqtype_is_lambdacode_arrow:                   hut::Uniqtype -> Bool;
        uniqtype_is_lambdacode_typeagnostic:            hut::Uniqtype -> Bool;
        uniqtype_is_lambdacode_generic_package:         hut::Uniqtype -> Bool;            

        # lambdacode hut::Uniqtyp-hut::Uniqtype one-arm switches:
        #
        if_uniqtyp_is_lambdacode_arrow:                 (hut::Uniqtyp,      (hut::Uniqtyp,        hut::Uniqtyp ) -> X,   hut::Uniqtyp  -> X)   ->   X;
        if_uniqtype_is_lambdacode_arrow:                (hut::Uniqtype,     (hut::Uniqtyp,        hut::Uniqtyp ) -> X,   hut::Uniqtype -> X)   ->   X;
        if_uniqtype_is_lambdacode_typeagnostic:         (hut::Uniqtype,     (List(hut::Uniqkind), hut::Uniqtype) -> X,   hut::Uniqtype -> X)   ->   X;
        if_uniqtype_is_lambdacode_generic_package:      (hut::Uniqtype,     (hut::Uniqtype,       hut::Uniqtype) -> X,   hut::Uniqtype -> X)   ->   X;
    };
end;

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


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext