Skip to content

Instantly share code, notes, and snippets.

@ygrenzinger
Last active May 9, 2018 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ygrenzinger/b697c38b127ab951915f782a3622b720 to your computer and use it in GitHub Desktop.
Save ygrenzinger/b697c38b127ab951915f782a3622b720 to your computer and use it in GitHub Desktop.
NCraft Oz Demo
%http://rigaux.org/language-study/syntax-across-languages-per-language/Oz.html
% https://mozart.github.io/mozart-v1/doc-1.4.0/tutorial/index.html
% Function which produce number with closure and
declare ProduceNumbersUntil
fun {ProduceNumbersUntil N}
local Produce in
fun {Produce L}
{Delay 500}
if L == N then N|nil else L|{Produce L+1} end
end
{Produce 2}
end
end
% Higher order programming for fun
declare Consumer
proc {Consumer F S}
case S of
nil then skip
[] H|T then
{F H} {Consumer F T}
end
end
% Small recursive function
% (no state like a real Functionalist)
fun {IsPrime N Primes}
case Primes of
nil then true
[] H|T then
if (N mod H) == 0 then false
else {IsPrime N T}
end
end
end
% declare an Agent (or Actor) for storing and getting primes
% it will act like a "database"
declare PrimeDatabase
fun {PrimeDatabase}
Port FunctionsStream PrimesStore Functions
in
{Browse ['Stream of functions : ' FunctionsStream]}
% Create a 'Cell' where the inside assignment can change
PrimesStore={NewCell nil}
/*
Create of a 'Port'
an asynchronous channel that supports many-to-one communication
the client can 'Send' thing to the 'Port'
*/
Port={NewPort FunctionsStream}
proc {Functions F}
case F
of get(R) then
R = @PrimesStore
[] add(P) then
PrimesStore := P|@PrimesStore
end
end
% A port associated to a thread is an Agent
% going through all message sent to the agent following the stream
thread {ForAll FunctionsStream Functions} end
Port
end
% Where the magic happens
% recursivily checking if number is prime
% by using our primes database
fun {CheckAndAddPrime Numbers PrimesStore}
case Numbers of
nil then nil
[] H|T then
local Primes in
{Send PrimesStore get(Primes)}
if {IsPrime H Primes} then
{Send PrimesStore add(H)}
H|{CheckAndAddPrime T PrimesStore}
else
{CheckAndAddPrime T PrimesStore}
end
end
end
end
% plug everything together using mostly asynchronous thread
local Numbers Primes PrimesStore Displayer in
PrimesStore={PrimeDatabase}
{Browse ['Producing numbers : ' Numbers]}
{Browse ['List of primes : ' Primes]}
{Delay 2000}
thread Numbers={ProduceNumbersUntil 20} end
thread Primes={CheckAndAddPrime Numbers PrimesStore} end
% Function as a primitive
Displayer = proc {$ N} {Browse ['Found prime ' N]} end
thread {Consumer Displayer Primes} end
end
declare MathEval StatelessAgent
proc {MathEval M}
case M
of add(N M A) then A=N+M
[] mul(N M A) then A=N*M
end
end
fun {StatelessAgent EvalFunction}
Port Messages
in
Port={NewPort Messages}
thread {ForAll Messages EvalFunction} end
Port
end
local R1 R2 Actor in
Actor = {StatelessAgent MathEval}
{Send Actor add(10 10 R1)}
{Browse ['eval add(10 10 R) R = ' R1]}
{Send Actor mul(10 10 R2)}
{Browse ['eval mul(10 10 R) R = ' R2]}
end
declare ProduceNumbersUntil
fun {ProduceNumbersUntil N}
local Produce in
fun {Produce L}
{Delay 200}
if L == N then N|nil else L|{Produce L+1} end
end
{Produce 1}
end
end
% Higher order programming for fun
declare Consumer
proc {Consumer F S}
case S of
nil then skip
[] H|T then
{F H} {Consumer F T}
end
end
local Numbers Displayer in
{Browse ['Producing : ' Numbers]}
thread Numbers={ProduceNumbersUntil 10} end
% Function as a primitive
Displayer = proc {$ N} {Browse ['Consuming ' N]} end
thread {Consumer Displayer Numbers} end
end
declare A B C
{Browse ['A = ' A]}
{Browse ['B = ' B]}
{Browse ['C = ' C]}
thread C = A + B end
A = 1
B = 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment