alice
manual.


Alice Project

mozart
interoperability


________ Overview ____________________________________________________

The current Alice system is based on the Mozart Programming System and supports interoperability between Oz and Alice.

The Alice compiler translates components into pickled Oz functors. It is possible to mix Oz and Alice code on a per-component basis. This document explains:


________ Data representation _________________________________________

Basic types

Values of basic types are mapped to corresponding Oz basic types. To support word operations, Mozart has been extended by a corresponding basic type.

Alice TypeOz Representation
intInfinite-precision integer
charInfinite-precision integer
wordProvided by boot module x-oz://boot/Word
realFloat
stringByte string

Tuples and records

Alice records are translated to Oz records by mapping all labels consisting only of digits to the corresponding integer feature, and all labels containing a letter to the corresponding atom feature.

Alice TypeOz Representation
Unit value () resp. {} Literal unit
TupleTuple with label '#'
RecordRecord with label '#'

Procedures

Conceptually, all Alice functions are unary. The typical idiom is to pass multiple arguments as a tuple of arguments. This case is treated specially by the Alice compiler.

Alice ProcedureOz Representation
Function in which every pattern is either an explicit n-tuple or a wildcard n+1-ary procedure, having n input arguments and one output argument
Any other functionBinary procedure

When applying functions in Alice, a calling convention conversion is performed: If a single-argument function is applied to several arguments (that is, a manifest tuple), these arguments are tupled to form a single argument. Conversely, when a multiple-argument function (that is, a function expecting a manifest tuple) is applied to a single argument, it is deconstructed as a tuple.

Note that care must be taken when calling a first-class function defined in Alice from an Oz procedure: calling procedures from Oz does not perform calling convention conversion automatically. Therefore, the user must write code to do this explicitly using the Procedure.arity and Procedure.apply builtins. For instance, if F is to be called with three arguments, but may have been defined in Alice:

      X = case {Procedure.arity F}
	  of 4 then {F A B C}   % call with three arguments directly
	  [] 2 then {F A#B#C}   % call with one (constructed) argument
	  end

Note that a three-argument Alice function is a four-argument Oz procedure (because of the return value), and that a one-argument Alice function is a two-argument Oz procedure.

Constructors

With a few exceptions simplifying interoperability, constructors of closed datatypes are mapped to atoms and constructors of extensible datatypes are mapped to names.

Alice TypeOz Representation
true, false Literals true, false
::, nil '|', nil
Other constructors of closed datatypes Atoms with corresponding print name
Constructors of extensible datatypesNames

Constructed values

Conceptually, all Alice constructors are unary. For interoperability, constructors syntactically declared taking a record as argument are treated as n-ary constructors.

Alice Constructed ValueOz Representation
Constructed value of an n-ary constructor, n > 0 Record with the literal corresponding to the constructor as label and the argument record's labels as features
ref x{NewCell x}

For example, assuming a declaration

        datatype t1 = C1 of int * int

the Alice expression C1 (1, 2) evaluates to the Oz value 'C1'(1 2) due to the constructor C1 being binary. However, assuming the declaration

        datatype 'a t2 = C2 of 'a

the Alice expression C2 (1, 2) evaluates to the Oz value 'C2'(1#2) because the constructor C2 is unary.

Futures

Alice futures map directly to Oz transients. Promises are transparent on the Oz side.

Alice FutureOz Representation
FutureFuture
By-need futureBy-need future
Promise Record with label 'Promise__' and two subtrees, a boolean cell and a logic variable.
The cell is true if the promise has either been fulfilled or failed

Other library types

Some abstract library types are implemented natively:

Alice Library TypeOz Representation
refCell
arrayArray
vectorTuple with label '#[]'
Thread.threadThread
Atom.tAtom

Modules

Alice modules are translated to Oz data structures such:

Alice ModuleOz Representation
StructureRecord
FunctorBinary procedure

Structure members are represented under record features. The feature names are computed as shown in the following table:

Alice Identifier ClassOz Feature Representation
Value or constructor,
e.g., val x, constructor C
Identifier name as atom,
e.g., 'x', 'C'
Type,
e.g., datatype t
Dollar-prefixed identifier as atom,
e.g., '$t'
Structure or functor,
e.g., structure M
Dollar-suffixed identifier as atom,
e.g., 'M$'
Signature,
e.g., signature S
Dollar-pre- and -suffixed identifier as atom,
e.g., '$S$'

Components

Alice components are translated into Oz functors:

Alice ComponentOz Representation
Compiled componentPickled functor

The export of the generated functor is the record corresponding to the component considered as a single structure.

Exceptions

Alice exceptions are wrapped into alice(...) and raised as Oz error exceptions.


________ Oz from Alice _______________________________________________

Alice compiled components are annotated with signatures denoting the expected signatures of the component it imports and the actual signature of the structure it computes. Compatibility of actual and expected signatures is checked at link-time to guarantee type safety. The actual export signature is also loaded at compile time to perform binding analysis and type-checking.

For this reason, export signatures must first be provided for Oz functors before they can be imported into Alice components. This will be shown by an example.

Assume the following Oz functor is stored at URL F.ozf:

        functor
        import
           System(show)
        export
           show: Show
        define
           fun {Show X} {System.show X} unit end
        end

To import this component into Alice, we would write a signature file F.asig containing:

        signature F_COMPONENT =
            sig
                val show: 'a -> unit
            end

We can now import the component into Alice using an import announcement of the form

        import val show from "F"

This will read the signature from F.asig, and consider the structure exported from F.ozf to conform to this signature. (Note that the name of the signature is ignored.) If the signature does not truthfully describe the Oz component, run-time errors will occur.


________ Alice from Oz _______________________________________________

Since Oz does not type-check its imports at link-time, Alice components can be directly imported into Oz functors without conversion.

For example, assume the following Alice component is available at URL Example.ozf:

        structure Example =
            struct
                fun count f xs =
                    List.foldr (fn (x, n) =>
                                if f x then n + 1 else n) 0 xs
            end

An Oz functor could now import it as follows:

        functor
        import
            System(show)
            ExampleComponent('Example$': Example) at 'Example.ozf'
        define
            {System.show
             {{Example.count fun {$ X} X == 0 end} [1 0 2 0]}}
        end


last modified 2004/04/13 11:29