20.1 Interface and Implementation

The fragment system can be used to separate interface from implementation. In the putBoxed example above we included the implementation of the operation in the interface. We can move the implementation of putBoxed to another file using a dopart slot. This is specified as follows:

putBoxed: 
     (* print the text with a box surrounding: 
      * 'text'->putBoxed results in '[text]'
      *)
    (# t: ^Text;
    enter t[]
    <<SLOT putBoxed: dopart>>
    #);

Here we have described only the interface of putBoxed, i.e. it can be seen that the operation takes a text as a argument (and the comment states that the operation will print the text with a surrounding box). The implementation is hidden. The implementation can be described in a dopart fragment:

---putBoxed: dopart---
    do '['->put; t[]-> puttext; ']'->put;

In order to make things work we must specify where the implementation can be found. This is done using a BODY specification in the putBoxed.bet file:

The file with the ---putBoxed: dopart--- fragment must specify where the dopart fragment is to be filled. This is done using the ORIGIN:

Program 34: putBoxed.bet

ORIGIN '~beta/basiclib/betaenv';
BODY 'putBoxedBody'
---LIB: Attributes---
  putBoxed: 
     (* print the text with a box surrounding: 
      * 'text'->putBoxed results in '[text]'
      *)
    (# t: ^Text;
    enter t[]
    <<SLOT putBoxed: dopart>>
    #);

Program 35: putBoxedBody.bet

ORIGIN 'putBoxed'
---putBoxed: dopart---
    do '['->put; t[]-> puttext; ']'->put;

Another major advantage of separating the implementation from the interface is separate compilation. The putBoxed.bet and the putBoxedBody.bet file can be separately compiled, and the putBoxedBody.bet file can be changed and recompiled without recompiling the interface file putBoxed.bet or any of the programs that are using the library putBoxed.

The HelloWorld program using the putBoxed library has not changed:

Program 36: HelloWorld.bet

ORIGIN '~beta/basiclib/betaenv'
---- program: descriptor ----
(# 
   (*  HelloWorld.bet:
    *  =======================            
    *   Author: J.Vaucher
    *
    *   Purpose: 
    *    This is the simplest program possible.
    *    Being able to compile and run it shows that the
    *    compiler exists and that PATHS and ALIASES have been 
    *    correctly set.  It also brings out "meta-programming" 
    *    considerations like the "fragment" system.
    *
    *********************************************************)
do  
   'Hello world !' -> putline  
#)

And the expanded BETA program, using the files: betaenv, HelloWorld, putBoxed, and putBoxedBody is (exactly as above):

Program 37: HelloWorld with filled program and LIB slot

(* The basic BETA environment betaenv *)
(# ...
   put: (# c: @char; enter c do ... #);
   puttext: (# t: ^text; enter t[] do ... #);
   putline: (# t: ^text; enter t[] do t[]->puttext; newline #);
   newline: (# do ... #);
   text: (# ... #);
   putBoxed: 
     (* print the text with a box surrounding: 
      * 'text'->putBoxed results in '[text]'
      *)
    (# t: ^Text;
    enter t[]
    do '['->put; t[]-> puttext; ']'->put;
    #);
   ...
do (* initialize for execution *)
   (#
   do 'Hello World!'->putline;
   #)
   (* terminate execution *)
#)

The fragment system is described in abstract terms in the BETA book [MMN 93]. That description also suggests many ideas of how to use the fragment system. The current implementation of the fragment system is described in the compiler manual [MIA 90-2].


Libraries Tutorial
© 1994-2002 Mjølner Informatics
[Modified: Thursday October 19th 2000 at 14:10]