5 Extending the Runtime Environment

5.1 How to

Since the SML programs are executed by the virtual machine of the Mozart System we have the possibility to interface to the functionality of Oz from SML programs.

There are two ways for such extensions:

Example

This has already been done for concurrency and logic variables. The approach is illustrated below.

SMLprelude.oz

% Concurrency
fun {`vc@thread` X} thread {X 'R'()} end end 
fun {`vc@delay` X} {Delay X} 'R'() end 
 
% Logical variables
fun {`vc@lvar` 'R'()} _ end 
fun {`vc@wait` X} case X of 'R'() then 'R'()
                  elseof _ then 'R'()
                  end 
     end 
fun {`vc@:~` 'R'(X Y)}
   if {IsFree X} then X = Y
   else raise `vc@Bind` 
        end 
   end 
end 
 

environment.oz

% concurrency
{VCIdStack put('thread' 'v')}
{VCIdStack put('delay' 'v')}
% logical variables
{VCIdStack put('lvar' 'v')}
{VCIdStack put('wait' 'v')}
{VCIdStack put(':~' 'v')}
 

SMLprelude.ozsml

infix 3 :~ ;

5.2 Tips

There are two functions available for importing Oz functions:

importOzFunction

importOzFunction(FunName)

Returns the corresponding curried Oz function. The argument FunName is of type String and must denote a valid Oz function.

For example:

importOzFunction("Append")

has the result

fn list1 => fn list2 => {Append list1 list2}

importOzFunctionFromRecord

importOzFunctionFromRecord(RecordName FunName)

Similar to importOzFunction, but imports an Oz function from a record; e.g., List.append. The first argument RecordName denotes the record and the second FunName the name of the feature in the record. Here RecordName is List and FunName is append.

Example

(* Waiting on logical variable until it is defined *) 
 
let 
    val x = lvar()
in 
    (*  
     * showing the variable results fin _ fwhile   
     * because it is undefined                     
     *)
 
    show x;
    (*  
     * thread waits until x is defined  
     * fand fthen print x  
     *)
 
    thread (fn () => (wait x; show x));
    (* wait 3 seconds *) 
    delay 3000;  
    (* define x *) 
    x :~ 42
end;
 
 
(* Thread syncronization *) 
 
let 
    (* new logical variable holding lazy list *) 
    val list = lvar()
    (* lazy list generator *) 
    fun producer n list = let  
                              val tail = lvar()  
                          in 
                              list :~ (n::tail);
                              delay 500;
                              producer (n + 1) tail;
                              ()
                          end 
    (* consumes the defined part fof the lazy list *) 
    fun consumer (n::rest) = (show n; consumer rest);
in 
    (* start producer fin an new thread *) 
    thread (fn () => producer 1 list);
    (* gives the producer an edge fof 3 seconds *) 
    delay 3000;
    (* start consumer *) 
    consumer list
end;


Andreas Simon and Gerhard Schneider
Generated on Thursday, November 26th 1998, 23:35:31