PreviousUpNext

10.11.4  Package Sealing

The main use of an API is to seal a package, restricting the set of externally visible package elements to just those listed in the API. This allows us to impose implementation hiding by protecting package-internal types, values and functions from external view.

Here is an example:

    api Counter {

        Counter;

        make_counter:      Void -> Counter;
        increment_counter: Counter -> Void;
        decrement_counter: Counter -> Void;
        counter_value:     Counter -> Int; 
    };

    package counter: Counter {

        Counter = COUNTER { count: Ref(Int), calls: Ref(Int) };

        fun make_counter () =  COUNTER { count => REF 0, calls => REF 0 };

        fun increment_counter (COUNTER { count, calls })
            =
            {   count := *count + 1;
                calls := *calls + 1;
            };

        fun decrement_counter (COUNTER { count, calls })
            =
            {   count := *count - 1;
                calls := *calls + 1;
            };

        fun counter_value (COUNTER { count, calls })
            =
            *count;
    };

Here we are keeping both a counter value and also a count of calls made, perhaps for debugging purposes, but our API declares type Count to be abstract, hiding its internal structure from external view, so if we later decide to remove the calls field, we can be assured that we will not break any external code in other packages by so doing.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext