% Concurrent programming thread {Browse 999*999} end {Browse 'Hi'} % Dataflow declare X thread {Delay 5000} X=99 end thread {Browse 999*999} end {Browse start} {Browse X*X} declare X thread {Browse start} {Browse X*X} end {Delay 5000} X=99 %% Non-determinism declare C = {NewCell 0} thread {Assign C 1} end thread {Assign C 2} end % displays 1 or 2? {Browse {Access C}} declare C = {NewCell 0} thread I in I = {Access C} {Assign C I+1} end thread J in J = {Access C} {Assign C J+1} end {Browse {Access C}} % Atomicity declare C = {NewCell 0} L = {NewLock} thread lock L then I in I = {Access C} {Assign C I+1} end end thread lock L then J in J = {Access C} {Assign C J+1} end end {Browse {Access C}} % % Declarative Concurrency % % creating threads declare proc {Loop P N} if N > 0 then {P} {Loop P N-1} else skip end end thread {Loop proc {$} {Browse 1} end 1000} end thread {Loop proc {$} {Browse 2} end 1000} end % dataflow variables declare X {Browse X} local Y in thread {Delay 1000} Y = 10*10 end X = Y + 100*100 end declare X0 X1 X2 X3 {Browse [X0 X1 X2 X3]} thread Y0 Y1 Y2 Y3 in {Browse [Y0 Y1 Y2 Y3]} Y0 = X0 + 1 Y1 = X1 + Y0 Y2 = X2 + Y1 Y3 = X3 + Y2 {Browse completed} end X0 = 1 X1 = 2 X2 = 3 X3 = 4 % concurrent map declare fun {Map Xs F} case Xs of nil then nil [] X|Xr then thread {F X} end|{Map Xr F} end end declare F X Y Z {Browse thread {Map X F} end} X = 1|2|Y fun {F X} X*X end Y = 3|Z Z = nil % concurrent fibonacci declare fun {Fib X} if X=<2 then 1 else thread {Fib X-1} end + {Fib X-2} end end {Browse {Fib 6}} {Browse {Fib 20}} {Browse {Fib 26}} {Browse {Fib 27}} % Ports abstraction (asynchronous FIFO channel) declare P S in {NewPort S P} {Browse S} % will it always display 1|2|_? thread {Send P 1} end thread {Send P 2} end % A simple active object declare P in local Xs in {NewPort Xs P} thread {ForAll Xs proc {$ X} {Browse X} end} end end % After eta-reduction: declare P in local Xs in {NewPort Xs P} thread {ForAll Xs Browse} end end {Send P foo(1)} thread {Send P bar(2)} end % Port implementation using cells % % A wrapper/unwrapper implementation using higher-order programming % declare NewWrapper in proc {NewWrapper ?Wrap ?Unwrap} Key={NewName} in fun {Wrap X} fun {$ K} if K==Key then X end end end fun {Unwrap C} {C Key} end end declare NewPort Send in local Wrap Unwrap in {NewWrapper Wrap Unwrap} proc {NewPort S P} C={NewCell S} in P={Wrap C} end proc {Send P X} C={Unwrap P} Old in {Exchange C X|Old Old} end end declare P S in {NewPort S P} {Browse S} {Send P 1} thread {Send P 2} end