[The Original Shootout]   [NEWS]   [FAQ]   [Methodology]   [Platform Details]   [Acknowledgements]   [Scorecard]
All Source For oz
Ackermann's Function
```%%% \$Id: ackermann.oz,v 1.0 2002/03/11 14:41:00 dada Exp \$
functor
import System Application
define
fun {Ack M N}
if M==0 then N + 1
elseif N == 0 then {Ack M-1 1}
else {Ack M-1 {Ack M N-1}}
end
end
in
local A in
[A] = {Application.getArgs plain}
{System.printInfo "Ack(3,"}
{System.printInfo A}
{System.printInfo "): "}
{System.printInfo {Ack 3 {String.toInt A}}}
end
{Application.exit 0}
end
```
Array Access
```%%% \$Id: ary3.oz,v 1.0 2002/04/02 16:17:00 dada Exp \$

%%% Code contributed by Andrew McDowell

functor
import
System
Application
define
local Args N A1 A2 in

{Application.getCmdArgs plain Args}
if {List.length Args} \= 1 then
N = 1
else
{String.toInt Args.1 N}
end

{NewArray 0 N 0 A1}
{NewArray 0 N 0 A2}

{For 0 (N - 1) 1
proc {\$ I} {Put A1 I (I + 1)} end }

{For 0 999 1
proc {\$ I}
{For (N - 1) 0 ~1
proc {\$ I} {Put A2 I ({Array.get A2 I} + {Get A1 I})} end}
end}

{System.showInfo {Get A2 0}#" "#{Get A2 (N - 1)}}
{Application.exit 0}
end
end

```
Echo Client/Server
```%%% \$Id: echo.oz,v 1.0 2002/11/05 12:26:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x echo.oz -o echo.oz.exe
%%     echo.oz.exe 100000

functor
import System Application Open OS

define

Data = "Hello there sailor\n"

Sock = {New Open.socket server(port:SPort)}
{ServerLoop Sock 0 Bytes}
end

proc {ServerLoop Sock Sum Bytes}
local Message NewSum DR DW CR ST in

%% low-level Selects seem ~6% faster total
{OS.read DR 1024 Message nil CR}

if Message == nil then %% connection has been closed
Bytes = Sum
else
NewSum = {Length Message} + Sum

{OS.writeSelect DW}{OS.write DW Message ST}
%% {Sock write(vs: Message)} %% normal write

{ServerLoop Sock NewSum Bytes}
end
end
end

local Sock in
Sock = {New Open.socket client(port:SPort)}
{ClientLoop Sock N}
end
end

proc {ClientLoop Sock N}
local Message DR DW CR ST in
if N > 0 then

{Sock getDesc(DR DW)}
{OS.writeSelect DW}{OS.write DW Data ST}

%% {Sock write(vs: Data)}     %% normal write

if Message == Data then {ClientLoop Sock N-1} end
end
end
end

in
local Args A1 A2 A3 Socket SPort Bytes ArgList Pid in
Args = {Application.getArgs plain}

if {Length Args} == 1 then
%% We are the server process

A3|nil = Args

%% Prepare to fork an OS process for the client
%%    automatically close cmd.exe
%%    start echo.oz.exe
%%    pass a flag indicating the client process
%%    pass the open server port SPort
%%    pass the number of times the client should send the data

ArgList = ["/C" "echo.oz.exe" "client" {IntToString SPort} A3]
Pid = {New Open.pipe init(cmd: "cmd.exe" args: ArgList)}

%% Synchronize with server thread completion and indirectly with
%% the client process. Wait here until the dataflow variable Bytes
%% has been given a value in the server thread. That happens after
%% the client process closes the socket connection, when the client
%% process has sent all it's data and received all the replies.

{System.showInfo 'server processed '#{IntToString Bytes}#' bytes'}

elseif {Length Args} == 3 then
%% We are the client process

%% Take the flag, server port, times-to-repeat from the args
%% and use the main thread for the client
A1|A2|A3|nil = Args
if A1 == "client" then
end
end
end
{Application.exit 0}
end
```
Exception Mechanisms
```%%% \$Id: except.oz,v 1.0 2002/08/19 16:19:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x except.oz -o except.oz.exe
%%     except.oz.exe 2000

functor
import System Application

define

LoCount
HiCount

proc {Blowup N}
if N mod 2 == 0 then raise loException() end
else raise hiException() end end
end

proc {LoFun N}
try {Blowup N} catch
loException then {Assign LoCount {Access LoCount}+1}
end
end

proc {HiFun N}
try {LoFun N} catch
hiException then {Assign HiCount {Access HiCount}+1}
end
end

proc {SomeFun N}
if N > 0 then
try {HiFun N} catch
loException then {System.showInfo 'loException should not get here'}
[] hiException then {System.showInfo 'hiException should not get here'}
end
{SomeFun N-1}
end
end
in
local Args N in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}

LoCount = {NewCell 0}
HiCount = {NewCell 0}
{SomeFun N}

{System.printInfo "Exceptions: HI="}
{System.printInfo {Access HiCount}}
{System.printInfo " / LO="}
{System.showInfo {Access LoCount}}
end
{Application.exit 0}
end

```
Fibonacci Numbers
```%%% \$Id: fibo.oz,v 1.0 2002/03/11 15:11:00 dada Exp \$
functor
import System Application
define
fun {Fib N}
case N
of 0 then 1
[] 1 then 1
else {Fib N-2} + {Fib N-1} end
end
in
local A in
[A] = {Application.getArgs plain}
{System.printInfo {Fib {String.toInt A}}}
end
{Application.exit 0}
end
```
Hash (Associative Array) Access
```%%% \$Id: hash.oz,v 1.0 2002/08/19 16:24:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x hash.oz -o hash.oz.exe
%%     hash.oz.exe 2000

functor
import System Application

define

fun {IntToHexString I Hex}
if I =< 0 then Hex else
local M D in
D = I div 16
M = I mod 16
if M < 10 then
{IntToHexString D M+&0|Hex}
else
{IntToHexString D (M-10)+&a|Hex}
end
end
end
end

proc {InsertHexKeys H N}
for I in 0..N-1 do
{Dictionary.put H {String.toAtom {IntToHexString I nil}} I}
end
end

proc {CountLookups H I S C}
if I >= 0 then
if {Dictionary.member H {String.toAtom {IntToString I}}} then
{CountLookups H I-1 S+1 C}
else
{CountLookups H I-1 S C}
end
else C = S end
end

in
local Args N H Count in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}

{NewDictionary H}
{InsertHexKeys H N}
{CountLookups H N 0 Count}

{System.showInfo Count}
end
{Application.exit 0}
end

```
Hashes, Part II
```%%% \$Id: hash2.oz,v 1.0 2002/08/19 16:26:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x hash2.oz -o hash2.oz.exe
%%     hash2.oz.exe 150

functor
import System Application

define

proc {InitHash H}
for I in 0..9999 do
{Dictionary.put H
{String.toAtom {List.append "foo_" {IntToString I}}} I}
end
end

local Key Value Tail V in
if L \= nil then
(Key#Value|Tail) = L
{Dictionary.condGet H Key nil V}
if V == nil then
{Dictionary.put H Key Value}
else
{Dictionary.put H Key Value+V}
end
end
end
end

in
local Args N H1 H2 in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}

{NewDictionary H1}
{NewDictionary H2}

{InitHash H1}
for I in 1..N do

{System.printInfo {Dictionary.get H1 'foo_1'}}
{System.printInfo ' '}
{System.printInfo {Dictionary.get H1 'foo_9999'}}
{System.printInfo ' '}
{System.printInfo {Dictionary.get H2 'foo_1'}}
{System.printInfo ' '}
{System.printInfo {Dictionary.get H2 'foo_9999'}}
end
{Application.exit 0}
end

```
Heapsort
```%%% \$Id: strcat.oz,v 1.0 2002/11/05 12:21:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Transliterated from the Mercury solution
%%
%%  Usage: start from command line with
%%     ozc -x heapsort.oz -o heapsort.oz.exe
%%     heapsort.oz.exe 1000

functor
import System Application

define
IM = 139968
IA = 3877
IC = 29573
Seed = 42

fun {Random_heap H I S0}
local R S in
if I =< {Array.high H} then
{Gen_random R S0 S}
{Random_heap {Up_heap H I R} I+1 S}
else
H
end
end
end

fun {Up_heap H N Y}
local HalfN X in
HalfN = N div 2
X = {Get H HalfN}
if 0 < N andthen X < Y then
{Put H N X}
{Up_heap H HalfN Y}
else
{Put H N Y}
H
end
end
end

fun {Heapsort H N}
if N == 0 then H
else {Heapsort {Remove_greatest H N} N-1} end
end

fun {Remove_greatest H N}
local X Y in
X = {Get H 0}
Y = {Get H N}
{Put H N X}
{Down_heap H 0 N-1 Y}
end
end

fun {Down_heap H I N X}
local L R J Y in
L = I + I + 1
R = L + 1
if N < L then
{Put H I X}
H
else
J = if R < N andthen {Get H R} > {Get H L}
then  R else L end
Y = {Get H J}
if X > Y then
{Put H I X}
H
else
{Put H I Y}
{Down_heap H J N X}
end
end
end
end

proc {Gen_random R S0 S}
S = (S0 * IA + IC) mod IM
R = {IntToFloat S} / {IntToFloat IM}
end

in
local Args N RandomHeap SortedHeap in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}
RandomHeap = {Random_heap {NewArray 0 N-1 0.0} 0 Seed}
SortedHeap = {Heapsort RandomHeap N-1}
{System.showInfo {Get SortedHeap N-1}}
end
{Application.exit 0}
end

```
Hello World
```%%% \$Id: hello.oz,v 1.0 2002/03/12 12:44:00 dada Exp \$
functor
import System Application
define
{System.printInfo "hello world"}
{Application.exit 0}
end
```
List Operations
```functor
import
System
Application
define
local Args N Size L1 L2 L3 Temp Result in
{Application.getCmdArgs plain Args}
if {List.length Args} \= 1 then
N = 1
else
{String.toInt Args.1 N}
end

Size = 10000

L1 = {NewCell nil}
L2 = {NewCell nil}
L3 = {NewCell nil}
Temp = {NewCell nil}
Result = {NewCell 0}

proc {MyMain Q}
%%
%first create a list (L1) of integers from 1 through SIZE (SIZE is currently defined as 10000).

{Assign L1 {List.number 1 Size 1}}

%copy L1 to L2 (can use any builtin list copy function, if available)

{Assign L2 {Access L1}}

%remove each individual item from left side (head) of L2 and append to right side (tail)
%  of L3 (preserving order). (L2 should be emptied by one item at a time as that item is
%  appended to L3).

{For 1 (Size - 1) 1
proc {\$ N}
{Assign Temp {List.nth {Access L2} 1}}
{Assign L2 {List.drop {Access L2} 1}}
{Assign L3 {List.append {Access L3} {Access Temp}|nil}}
end}
%remove each individual item from right side (tail) of L3 and append to right side (tail)
%  of L2 (reversing list). (L3 should be emptied by one item at a time as that item is
%  appended to L2).

{For 1 (Size - 1) 1
proc {\$ N}
{Assign Temp {List.last {Access L3}}}
{Assign L3 {List.take {Access L3} {List.length {Access L3}} - 1}}
{Assign L2 {List.append {Access L2} {Access Temp}|nil}}
end}

%reverse L1 (preferably in place) (can use any builtin function for this, if available).

{Assign L1 {List.reverse {Access L1} \$}}

%check that first item of L1 is now == SIZE.

if {Value.'\\=' {List.nth {Access L1} 1} Size} then
% {System.showInfo "Equal!"}
% else
{Assign Result 0}
end

%and compare L1 and L2 for equality and return length of L1 (which should be equal to SIZE). `

if {Value.'==' {Access L1} {Access L2}} then
{Assign Result {List.length {Access L1}}}
else
{Assign Result 0}
end
%%
end

{For 1 N 1 MyMain}

{System.showInfo {Access Result}}
{Application.exit 0}
end
end
```
Matrix Multiplication
```%%% \$Id: matrix.oz,v 1.0 2002/08/19 16:22:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x matrix.oz -o matrix.oz.exe
%%     matrix.oz.exe 300

functor
import System Application

define

proc {MakeMatrix Rows Cols M}
local Count in
{NewArray 0 Rows-1 0 M}
Count ={NewCell 0}
for I in 0..Rows-1 do
local R in
{NewArray 0 Cols-1 0 R}
{Put M I R}
for J in 0..Cols-1 do
{Assign Count {Access Count}+1}
{Put R J {Access Count}}
end
end
end
end
end

proc {MMult M1 M2 MM}
local S1 N1 Prod S2 N2 in
S1 = {Array.low M1}
N1 = {Array.high M1}
S2 = {Array.low {Get M1 S1}}
N2 = {Array.high {Get M1 S1}}
Prod = {NewCell 0}
{NewArray S1 N1 0 MM}
for I in S1..N1 do
local R in
{NewArray S1 N1 0 R}
{Put MM I R}
for J in S1..N1 do
{Assign Prod 0}
for K in S2..N2 do
{Assign Prod {Get {Get M1 I} K}*
{Get {Get M2 K} J}+{Access Prod}}
end
{Put R J {Access Prod}}
end
end
end
end
end

proc {RepeatMMult N M1 M2 MM}
local T in
if N > 1 then
{MMult M1 M2 T}
{RepeatMMult N-1 M1 M2 MM}
else {MMult M1 M2 T} MM = T end
end
end

in
local Args Repeat N M1 M2 MM in
[Args] = {Application.getArgs plain}
Repeat = {String.toInt Args}
N = 30
{MakeMatrix N N M1}
{MakeMatrix N N M2}
{RepeatMMult Repeat M1 M2 MM}

{System.printInfo {Get {Get MM 0} 0}}{System.printInfo ' '}
{System.printInfo {Get {Get MM 2} 3}}{System.printInfo ' '} % get col 3 out of row 2
{System.printInfo {Get {Get MM 3} 2}}{System.printInfo ' '} % get col 2 out of row 3
{System.showInfo {Get {Get MM 4} 4} }
end
{Application.exit 0}
end
```
Method Calls
```%%% \$Id: methcall.oz,v 1.0 2002/08/19 16:18:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x methcall.oz -o methcall.oz.exe
%%     methcall.oz.exe 1000000

functor
import System Application

define

class Toggle
attr state: true
meth state(V)
V = @state
end
meth activate
state <- {Not @state}
end
meth init(State)
state <- State
end
end

class NthToggle from Toggle
attr trigger:0 count:0
meth activate
count <- @count + 1
if @count >= @trigger then
state <- {Not @state}
count <- 0
end
end
meth init(State Trigger)
Toggle,init(State)
trigger <- Trigger
count <- 0
end
end

proc {ShowBool X}
if X then {System.showInfo "true"}
else {System.showInfo "false"} end
end

fun {MethodSends N T}
local V in
if N==0 then {T state(V)} V
else
{T activate}{T state(V)}
{MethodSends N-1 T}
end
end
end

in
local Args N in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}
{ShowBool {MethodSends N {New Toggle init(true)}}}
{ShowBool {MethodSends N {New NthToggle init(true 3)}}}
end
{Application.exit 0}
end

```
Nested Loops
```%%% \$Id: nestedloop.oz,v 1.1 2002/08/19 16:14:00 dada Exp \$
%%%
%%% Isaac Gouy suggested the use of a cell

functor
import System Application
define

local P X A B C D E F N in
[P] = {Application.getArgs plain}
N = {String.toInt P}
X = {NewCell 0}
for A in 1..N do
for B in 1..N do
for C in 1..N do
for D in 1..N do
for E in 1..N do
for F in 1..N do
{Assign X {Access X}+1}
end
end
end
end
end
end
{System.printInfo {Access X}}
end
{Application.exit 0}
end
```
Object Instantiation
```%%% \$Id: objinst.oz,v 1.0 2002/08/19 16:16:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%% Uses local variables within the Object Instantiation
%% loops. It might be quicker to create a Cell outside
%% of the loop and use {Assign T {New Toggle init(true)}}
%%
%%  Usage: start from command line with
%%     ozc -x objinst.oz -o objinst.oz.exe
%%     objinst.oz.exe 1000000

functor
import System Application

define

class Toggle
attr state: true
meth state(V)
V = @state
end
meth activate
state <- {Not @state}
end
meth init(State)
state <- State
end
end

class NthToggle from Toggle
attr trigger:0 count:0
meth activate
count <- @count + 1
if @count >= @trigger then
state <- {Not @state}
count <- 0
end
end
meth init(State Trigger)
Toggle,init(State)
trigger <- Trigger
count <- 0
end
end

proc {ShowBool X}
if X then {System.showInfo "true"}
else {System.showInfo "false"} end
end

in
local Args N T1 T2 in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}

T1 = {New Toggle init(true)}
for I in 1..5 do
local V in {T1 activate}{T1 state(V)}{ShowBool V} end
end
{System.showInfo ""}
for I in 1..N do
local T in T = {New Toggle init(true)} end
end

T2 = {New NthToggle init(true 3)}
for I in 1..8 do
local V in {T2 activate}{T2 state(V)}{ShowBool V} end
end
{System.showInfo ""}
for I in 1..N do
local T in T = {New NthToggle init(true 3)} end
end
end
{Application.exit 0}
end

```
```%%% \$Id: prodcons.oz,v 1.0 2002/11/05 12:23:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Section 11.5 of the Oz Tutorial provides these
%%  implementations of Event and UnitBufferM and states:
%%  in Oz, it is very rare to write programs in the
%%  (traditional) monitor style shown above. In general
%%  it is very awkward.
%%
%%  There's an extensive treatment of Oz concurrency in
%%  the book 'Concepts, Techniques, and Models of Computer
%%  Programming' - find it online with google.
%%
%%  Usage: start from command line with
%%     ozc -x prodcons.oz -o prodcons.oz.exe
%%     prodcons.oz.exe 100000

functor
import System Application

define

Produced
Consumed

class Event from BaseObject
prop locking
attr f r
meth init
X in f <- X r <- X
end
meth put(I)
X in lock @r=I|X r<-X end
end
meth get(?I)
X in lock @f=I|X f<-X end {Wait I}
end
meth wait
{self get(_)}
end
meth notify
{self put(unit)}
end
end

class UnitBufferM
attr item empty psignal csignal
prop locking
meth init
empty <- true
psignal <- {New Event init}
csignal <- {New Event init}
end
meth put(I)
X in
lock
if @empty then
item <- I
empty <- false
X = yes
{@csignal notify}
else X = no end
end
if X == no then
{@psignal wait}
{self put(I)}
end
end
meth get(I)
X in
lock
if {Not @empty} then
I = @item
empty <- true
{@psignal notify}
X = yes
else X = no end
end
if X == no then
{@csignal wait}
{self get(I)}
end
end
end

proc {Producer N I B}
if N > 0 then
{B put(I)}
%% {System.showInfo 'Produced '#I} %% just to check synchronization
{Producer N-1 I+1 B}
else Produced = {NewCell I} end
end

proc {Consumer N I B}
if N > 0 then
{B get(I)}
%% {System.showInfo 'Consumed '#I} %% just to check synchronization
{Consumer N-1 I+1 B}
else Consumed = {NewCell I} end
end

in
local Args N UB in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}

UB = {New UnitBufferM init}
thread {Producer N 0 UB} end
thread {Consumer N 0 UB} end

%% Oz is a dataflow language.
%% The main thread will wait until logic variables
%% Produced and Consumed have been given values
{System.showInfo {Access Produced}#' '#{Access Consumed}}
end
{Application.exit 0}
end

```
Random Number Generator
```%%% \$Id: random.oz,v 1.0 2002/03/12 10:08:00 dada Exp \$
functor
import System Application
define
fun {RandLoop N SEED R MAX}
case N
of 0 then R
else
local IA IC IM NEWSEED NEWRAND in
IM = 139968
IA =   3877
IC =  29573
NEWSEED = (SEED * IA + IC) mod IM
NEWRAND = MAX * {Int.toFloat NEWSEED}/{Int.toFloat IM}
{RandLoop N-1 NEWSEED NEWRAND MAX}
end
end
end
in
local A NUM I in
[A] = {Application.getArgs plain}
NUM = {String.toInt A}
{System.printInfo {RandLoop NUM 42 0 100.0}}
end
{Application.exit 0}
end
```
Sieve of Erathostenes
```%%% \$Id: sieve.oz,v 1.1 2002/08/19 16:33:00 dada Exp \$

%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x sieve.oz -o sieve.oz.exe
%%     sieve.oz.exe 900

functor
import System Application

define Args N Flags Start Stop in

[Args] = {Application.getArgs plain}
N = {String.toInt Args}

Start = 2
Stop = 8192

Flags = {BitArray.new Start Stop}
for I in Start..Stop do {BitArray.set Flags I} end

for I in 1..N do
for J in Start..Stop do
if {BitArray.test Flags J} then
for K in J+J..Stop;J do {BitArray.clear Flags K} end
end
end
end

{System.showInfo "Count: "#{BitArray.card Flags}}

{Application.exit 0}
end
```
String Concatenation
```%%% \$Id: strcat.oz,v 1.0 2002/11/05 12:18:00 dada Exp \$
%%%
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x strcat.oz -o strcat.oz.exe
%%     strcat.oz.exe 40000

functor
import System Application

define

fun {RepeatAppend N S}
if N == 0 then S else
{RepeatAppend N-1 {Append "hello\n" S}} end
end

in
local Args N in
[Args] = {Application.getArgs plain}
N = {String.toInt Args}

{System.showInfo {Length {RepeatAppend N nil}} }
end
{Application.exit 0}
end

```
Sum a Column of Integers
```%%% \$Id: fibo.oz,v 1.0 2002/03/12 13:35:00 dada Exp \$
functor
import
System(printInfo)
Application(exit)
Open(text file)
OS
define
class TextFile
from Open.file Open.text
end

fun {SumLines FILE SUM}
{System.printInfo "file.atEnd="}
if {FILE atEnd(\$)} == true then
{System.printInfo "Y"}
else
{System.printInfo "N"}
end
{System.printInfo "\n"}
case {FILE getS(\$)} of false then
{System.printInfo "file terminated, returning "}
{System.printInfo SUM}
{System.printInfo "\n"}
SUM
elseof LINE then
{System.printInfo "got "}
{System.printInfo LINE}
{System.printInfo "\n"}
{SumLines FILE SUM+{String.toInt LINE}}
end
end

in
local STDIN SUM in
STDIN = {New TextFile init(name:stdin)}
SUM = {SumLines STDIN 0}
{System.printInfo SUM}
end
{Application.exit 0}
end
```