20 The Fragment System

Every BETA program uses the Fragment System. A fragment can be viewed as a piece of a BETA program ist of one or more fragments.

The basic BETA environment, called betaenv, supplies basic BETA patterns, such as integer, char, boolean, and text. In order to use these basic patterns, the program must specify that the betaenv environment is to be used. The following example illustrates how:

Program 29: 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  
#)

The example consists of two parts, the specification of ORIGIN and the descriptor [4] called program.

The specification of ORIGIN tells that the program uses the fragment file ~beta/basiclib/betaenv. The descriptor program tells that following the line

---program: descriptor---

comes a BETA descriptor, i.e. (# ... #), that will be named program. The name is used to identify the descriptor for the purpose of binding it to an unbound hole in the betaenv environment. A simple betaenv environment could have the following outline:

(* 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: (# ... #);
   ...
   <<SLOT LIB: Attributes>>
   ...
do (* initialize for execution *)
   <<SLOT program: descriptor>>
   (* terminate execution *)
#)

The betaenv environment consists of a single descriptor with two holesÑslots. One named program of type descriptor and one named LIB of type Attributes.

The program slot is empty and can be filled (or bound) by a BETA program by defining an descriptor like:

---program: descriptor---
(# ... #)

as illustrated above. Every BETA program must have exactly one such construct in order to fill the empty slot in betaenv.

Filling a slot can be compared to a textual replacement [5]. The Hello World example program above, thus replaces the program slot in betaenv, resulting in the following expanded BETA program:

Program 30: HelloWorld with filled program 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: (# ... #);
   ...
do (* initialize for execution *)
   (#
   do 'Hello World!'->putline;
   #)
   (* terminate execution *)
#)

The LIB slot can be used to define libraries that may used in other BETA programs. If we want to add an operation called putBoxed to the basic environment, we can fill the LIB slot:

Program 31: putBoxed.bet

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

The HelloWorld program can then use this library by including it:

Program 32: 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  
#)

Resulting in the following output:

[Hello World!]

The HelloWorld example program using the putBoxed library, results in the following expanded BETA program:

Program 33: 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 program can be made even more simpler by having ORIGIN in the putBoxed.bet file:

ORIGIN 'putBoxed'
---program: descriptor---
(#
do 'Hello World!'->putBoxed;
#)

This works because the putBoxed.bet has ORIGIN in the betaenv environment, so the HelloWorld program will also have access to the betaenv environment.

The ---LIB: Attributes--- may be multiply specified in the same file or in different files. The way to make libraries in BETA is thus to define the pattern declarations in a fragment called LIB. The file containing the ---LIB: Attributes--- fragment can then be included in your program and the declarations can be used.


[4] descriptor is an alias for ObjectDescriptor, i.e.
--program:ObjectDescriptor-- is also legal

[5] Textual replacement is not exactly correct due to the scope rules. Please see the BETA book chapter 17 for a description of these rules


Libraries Tutorial
© 1994-2004 Mjølner Informatics
[Modified: Thursday January 16th 2003 at 10:23]