% A simple calculator {Browse 9999*9999} % A variable V declare V = 9999*9999 {Browse V*V} % Variables can only be assigned once. % The following will produce an error: V=9999*9999 {Browse V} declare V = 10 W =20 local R V in R = 20 V = 30 {Browse [R V]} end {Browse V} % out of scope: % {Browse R} declare fun {Fact N} if N==0 then 1 else N*{Fact N-1} end end {Browse {Fact 100}} % Composing functions % number of combinations of r items from n declare fun {Comb N R} {Fact N} div ({Fact R}*{Fact N-R}) end {Browse {Comb 3 2}} {Browse {Comb 85 2}} % Lists declare H=1 T = [2 3 4 5] {Browse H|T} % This will show [1 2 3 4 5] {Browse [1]|[2 3 4 5]} declare L = [5 6 7 8] {Browse L.1} {Browse L.2} declare L = [[1] 2 3 4 5] {Browse L.1} {Browse L.2.1} {Browse L.1.1} % "." is not allowed for numbers: {Browse L.1.1.2} {Browse L.1.2} case L of H|T then {Browse H} {Browse T} end declare L = [1 2 3 4] {Browse L} %Oz bug!?: The following works: case L of E1|E2|T then {Browse E1} end % but the following seems to crash: case L of E1|E2|T then {Browse E1} {Browse E2} {Browse T} end case L of E1|E2|T then {Browse E2} end % the following works: case L of H1|T1 then case T1 of H2|T2 then {Browse H2} end end % inside a local statement, things work as expected: local L=[1 2 3 4] in case L of E1|E2 then {Browse E2} end case L of E1|E2|E3 then {Browse E2} end case L of E1|E2|E3|E4 then {Browse E2} end case L of E1|E2|E3|E4|nil then {Browse E2} end case L of E1|E2|E3|E4|E5 then {Browse E2} end case L of E1|E2|E3|E4|E5|E6 then {Browse E2} else {Browse 'no match'} end end % in a single statement, it works: declare L = [1 2 3 4] case L of E1|E2|E3|E4 then {Browse E2} end % but in two separate statements, it crashes: declare L = [1 2 3 4] case L of E1|E2|E3|E4 then {Browse E2} end % that seems to isolate the Mozart/Oz implementation bug! % Pascal triangle row declare fun {Pascal N} if N==1 then [1] else {AddList {ShiftLeft {Pascal N-1}} {ShiftRight {Pascal N-1}}} end end fun {ShiftLeft L} case L of H|T then H|{ShiftLeft T} else [0] end end fun {ShiftRight L} 0|L end % assumes lists of the same size fun {AddList L1 L2} case L1 of H1|T1 then case L2 of H2|T2 then H1+H2|{AddList T1 T2} end else nil end end {Browse {Pascal 5}} {Browse {AddList [1] [2 3]}} {Browse {AddList [2 3] [1]}} {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 {ShiftLeft L} {ShiftRight L}} end end end {Browse {FastPascal 5}} {Browse {FastPascal 24}} {Browse {FastPascal 86}} % Lazy evaluation declare fun lazy {Ints N} N|{Ints N+1} end declare L = {Ints 0} {Browse L} {Browse L.1} case L of A|B|C|_ then {Browse A+B+C} end {Browse L.2.2.2.2.2.2.1} % Lazy Pascal triangle declare fun lazy {PascalList Row} Row | {PascalList {AddList {ShiftLeft Row} {ShiftRight Row}}} end declare L = {PascalList [1]} {Browse L} {Browse L.1} {Browse L.2.1} {Browse L.2.2.1} % Generic programming 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 nil end end declare fun {GenericPascal Op N} if N==1 then [1] else L in L = {GenericPascal Op N-1} {OpList Op {ShiftLeft L} {ShiftRight L}} end end declare fun {Add N1 N2} N1+N2 end declare fun {Xor N1 N2} if N1==N2 then 0 else 1 end end declare fun {Pascal N} {GenericPascal Add N} end declare fun {ParityPascal N} {GenericPascal Xor N} end {Browse {Pascal 5}} {Browse {Pascal 24}} {Browse {ParityPascal 5}} {Browse {ParityPascal 24}} % Concurrent programming thread P in P = {Pascal 21} {Browse P} end {Browse 99*99}