This guide explains how to structure modular code in Mozart/Oz using functors, how to import other modules, and how to compile and run your programs. We'll use a MergeSort example that depends on two other modules: merge.oz and split.oz.
A functor in Oz is a module definition that can import other modules and export values (usually procedures or functions). Functors are the main way to organize code into reusable, composable components.
Suppose your project looks like this:
project-root/
│
├── mergeSort/
│ └── mergeSort.oz
├── merge/
│ └── merge.oz
└── split/
└── split.oz
mergeSort/mergeSort.ozdefines the main sorting function.merge/merge.ozdefines the merging logic.split/split.ozdefines the splitting logic.
Here is an example mergeSort.oz file:
functor
import
MergeModule at '../merge/merge.oz'
SplitModule at '../split/split.oz'
export
MergeSort
define
fun {MergeSort Xs}
case Xs
of nil then nil
[] [X] then [X]
else Ys Zs in
{SplitModule.split Xs Ys Zs}
{MergeModule.Merge {MergeSort Ys} {MergeSort Zs}}
end
end
end- The
importsection brings in other functors as modules. - The
exportsection lists what this module provides to others (here, theMergeSortfunction).
Your merge.oz and split.oz files should also be written as functors, exporting their respective functions (e.g., Merge and split).
functor
export
Merge
define
fun {Merge Xs Ys}
% ... merging logic ...
end
endfunctor
export
split
define
proc {split Xs Ys Zs}
% ... splitting logic ...
end
endUse the ozc compiler to compile each .oz file to a binary .ozf (Oz functor) file.
cd merge
ozc -c merge.oz
cd ../split
ozc -c split.oz
cd ../mergeSort
ozc -c mergeSort.ozThis will produce:
merge/merge.ozfsplit/split.ozfmergeSort/mergeSort.ozf
You can run a compiled functor using the ozengine:
ozengine mergeSort.ozfIf your functor is meant to be used as a library (not a standalone program), you can link it from another script:
{Module.link ['mergeSort.ozf']}Now you can use the exported MergeSort function in your code.
- Write each module as a functor, using
importto bring in dependencies andexportto expose functions or procedures. - Compile each
.ozfile withozc -c filename.oz. - Run a module directly with
ozengine filename.ozf, or link it in another module using{Module.link ['filename.ozf']}.
Suppose you want to test your MergeSort:
Create a file called test.oz in the mergeSort directory:
{Module.link ['mergeSort.ozf']}
declare
Sorted = {MergeSort [3 1 4 1 5 9 2 6]}
{Browse Sorted}Compile and run:
ozc -c test.oz
ozengine test.ozfThis will display the sorted list in the Oz viewer.