% Pascal triangle row auxiliary functions declare fun {ShiftRight L} 0|L end declare fun {AddList L1 L2} case L1 of H1|T1 then case L2 of H2|T2 then H1+H2|{AddList T1 T2} end % the following change avoids using ShiftLeft, % courtesy of R. Lafortune else L2 end end %% exercise: make AddList commutative? % Exponential-time Pascal triangle row declare fun {Pascal N} if N==1 then [1] else {AddList {Pascal N-1} {ShiftRight {Pascal N-1}}} end end {Browse {Pascal 24}} % Polynomial-time Pascal triangle row declare fun {FastPascal N} if N==1 then [1] else local L in L={FastPascal N-1} {AddList L {ShiftRight L}} end end end {Browse {FastPascal 24}} % Lazy Pascal triangle declare fun lazy {PascalList Row} Row | {PascalList {AddList Row {ShiftRight Row}}} end declare L = {PascalList [1]} {Browse L} {Browse L.1} {Browse L.2.1} % Generic Pascal triangle row declare fun {OpList Op L1 L2} case L1 of H1|T1 then case L2 of H2|T2 then {Op H1 H2}|{OpList Op T1 T2} end else L2 end end % exercise: make OpList commutative declare fun {GenericPascal Op N} if N==1 then [1] else L in L = {GenericPascal Op N-1} {OpList Op L {ShiftRight L}} end end declare fun {Add N1 N2} N1+N2 end declare fun {FastPascal N} {GenericPascal Add N} end {Browse {FastPascal 24}} declare fun {Xor N1 N2} if N1==N2 then 0 else 1 end end {Browse {GenericPascal Xor 24}} % using Curry % recall the Curry combinator declare Curry = fun {$ F} fun {$ X} fun {$ Y} {F X Y} end end end declare FastPascal = {{Curry GenericPascal} Add} % In some functional programming languages with % first-class support for currying (e.g. Haskell): % declare FastPascal = {GenericPascal Add} {Browse {FastPascal 24}} % Concurrent programming thread P in P = {Pascal 21} {Browse P} end {Browse 99*99} thread local P in P = {Pascal 21} {Browse P} end end {Browse 99*99} thread {Browse 99*99} end local P in P = {Pascal 21} {Browse P} end thread {Browse 99*99} end {Browse {Pascal 21}} % Dataflow declare X thread {Delay 5000} X=99 end thread {Browse {Pascal 24}} end {Browse start} {Browse X*X} declare X thread {Browse start} {Browse X*X} end {Delay 5000} X=99 % State declare C = {NewCell 0} {Assign C {Access C}+1} {Browse {Access C}} declare C = {NewCell 0} fun {FastPascal N} {Assign C {Access C}+1} {GenericPascal Add N} end {Browse {FastPascal 5}} {Browse {Access C}} {Browse {FastPascal 6}} {Browse {Access C}} {Assign C {Access C}+10} %% Objects declare local C in C = {NewCell 0} fun {Bump} {Assign C {Access C}+1} {Access C} end end {Browse {Bump}} declare fun {FastPascal N} {Browse {Bump}} {GenericPascal Add N} end {Browse {FastPascal 5}} {Browse {FastPascal 4}} %% Classes declare fun {NewCounter} local C Bump in C = {NewCell 0} fun {Bump} {Assign C {Access C}+1} {Access C} end Bump end end declare Ctr1 = {NewCounter} declare Ctr2 = {NewCounter} {Browse {Ctr1}} {Browse {Ctr1}} {Browse {Ctr1}} {Browse {Ctr2}} declare fun {NewCounter} local C Bump Read in C = {NewCell 0} fun {Bump} {Assign C {Access C}+1} {Access C} end fun {Read} {Access C} end [Bump Read] end end declare Ctr3 = {NewCounter} % Bump {Browse {Ctr3.1}} % Read {Browse {Ctr3.2.1}} declare fun {NewCounter} local C Bump Read in C = {NewCell 0} fun {Bump} {Assign C {Access C}+1} {Access C} end fun {Read} {Access C} end counter(bump:Bump read:Read) end end declare Ctr4 = {NewCounter} % Bump {Browse {Ctr4.bump}} % Read {Browse {Ctr4.read}} % On records declare R=rec(f1:v1 f2:v2) {Browse R} declare R2=rec(f2:v2 f1:v1) {Browse R2} {Browse R==R2} {Browse {Arity R}} {Browse {Arity R}.1} {Browse {Label R}} {Browse {Arity Ctr4}} {Browse R.f1} {Browse R.({Arity L}.1)} % a tuple is a record % whose implicit features are 1,2,3... {Browse r(a)} {Browse r(a)==r(1:a)} {Browse r(a)==r(f1:a)} {Browse {Width R}} % a list is a tuple is a record {Browse [1]} {Browse '|'(1 nil)} {Browse '|'(1:1 2:nil)} %% 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}} % A memory store % From http://www.info.ucl.ac.be/people/PVR/ds/booksuppl.oz %--- declare fun {NewStore} D={NewDictionary} C={NewCell 0} proc {Put K X} if {Not {Dictionary.member D K}} then C:=@C+1 end D.K:=X end fun {Get K} D.K end fun {Size} @C end in storeobject(put:Put get:Get size:Size) end proc {Put S K X} {S.put K X} end fun {Get S K} {S.get K} end fun {Size S} {S.size} end %--- declare S = {NewStore} {S.put 1 a} {Browse {S.get 1}} {Browse {S.size}} {Browse {Size S}} {Put S 2 [1 1]} {Browse {Get S 2}} {Browse {Size S}}