PreviousUpNext

5.4.21  Package and API Subclassing

We have seen that the Mythryl include statement may be used to dump package definitions into the current namespace in order to save us the effort of writing explicit package qualifiers:

    linux$ my

    eval:  v = vector::from_list [ 1, 2, 3 ];
    #[1, 2, 3]

    eval:  include package   vector;

    including vector
      Vector  X = Vector(X);
          max_len : Int;
          from_list : List(X) -> Vector(X);
          tabulate : (Int, (Int -> X)) -> Vector(X);
          length : Vector(X) -> Int;
          get : (Vector(X), Int) -> X;
          _[] : (Vector(X), Int) -> X;
          set : (Vector(X), Int, X) -> Vector(X);
          cat : List(Vector(X)) -> Vector(X);
          keyed_apply : ((Int, X) -> Void) -> Vector(X) -> Void;
          apply : (X -> Void) -> Vector(X) -> Void;
          keyed_map : ((Int, X) -> Y) -> Vector(X) -> Vector(Y);
          map : (X -> Y) -> Vector(X) -> Vector(Y);
          keyed_fold_forward : ((Int, X, Y) -> Y) -> Y -> Vector(X) -> Y;
          keyed_fold_backward : ((Int, X, Y) -> Y) -> Y -> Vector(X) -> Y;
          fold_forward : ((X, Y) -> Y) -> Y -> Vector(X) -> Y;
          fold_backward : ((X, Y) -> Y) -> Y -> Vector(X) -> Y;
          keyed_find : ((Int, X) -> Bool)
                  -> Vector(X) -> Null_Or(((Int, X)));
          find : (X -> Bool) -> Vector(X) -> Null_Or(X);
          exists : (X -> Bool) -> Vector(X) -> Bool;
          all : (X -> Bool) -> Vector(X) -> Bool;
          compare_sequences : ((X, X) -> Order) -> (Vector(X), Vector(X)) -> Order;

    eval:  v = from_list [ 3, 4, 5 ];
    #[3, 4, 5]

The include statement is also often used to dump the contents of one package definition into another, with the idea of defining the second package just by overriding a few definitions:

    #!/usr/bin/mythryl

    api Chitchat {
        say_hello:    String -> Void;
        say_goodbye:  String -> Void;
    };

    package p1: Chitchat {

        fun say_hello   string =  printf "Hi %s!\n"      string;
        fun say_goodbye string =  printf "Goodbye %s!\n" string;
    };

    package p2: Chitchat {

        include package   p1;

        fun say_hello   string =  printf "Well hello there, %s."  string;
    };

Here we have dumped both function definitions from package p1 into p2 and then overriden just the definition of interest.

This can be a very economical mode of programming in a production setting where package p1 may be very large and the changes to be made very small.

The same technique may be used to define a new API in terms of additions or changes to an existing one. Here we define an extended api and then a matching extended package:

    #!/usr/bin/mythryl

    api Chitchat {
        say_hello:    String -> Void;
        say_goodbye:  String -> Void;
    };

    api Chitchattier {

        include api Chitchat;

        say_little:   String -> Void;
    };

    package p1: Chitchat {

        fun say_hello   string =  printf "Hi %s!\n"      string;
        fun say_goodbye string =  printf "Goodbye %s!\n" string;
    };

    package p2: Chitchattier {

        include package   p1;

        fun say_little  string =  printf "Hot enough for you, %s?"  string;
    };

This can be a very useful technique on large software projects.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext