TLS Chapter #08 Examples in Oz % Defined in previous chapters fun {Add1 N} N + 1 end fun {IsAtomS X} if {IsAtom X} andthen {Not X == nil} then true else {IsNumber X} end end %%%%%%%%%%%%%%%%%%% The Little Schemer - Chapter - 8 %%%%%%%%%%%%%%%%%%%%%% % 8.9 - 8.10 fun {RemberF Test L A} case L of nil then nil [] H|T then if {Test A H} then T else H|{RemberF Test T A} end end end % 8.3 {Browse 3#{RemberF fun {$ X Y} X==Y end [b c a] a}} % 8.4 {Browse 4#{RemberF fun {$ X Y} X==Y end [b c a] c}} % 8.6 local Test A L in Test = fun {$ X Y} X==Y end A = 5 L = [6 2 5 3] {Browse 6#{RemberF Test L A}} end % 8.7 local Test A L in Test = fun {$ X Y} X==Y end A = jelly L = [jelly beans are good] {Browse 7#{RemberF Test L A}} end % 8.8 local Test A L in Test = fun {$ X Y} X==Y end A = [pop corn] L = [lemonade [pop corn] and [cake]] {Browse 8#{RemberF Test L A}} end % 8.21 fun {EqC A} fun {$ X} X == A end end % 8.22 local K in K = salad {Browse 22#{EqC K}} end % 8.23 EqSalad = {EqC salad} % 8.24 local Y in Y = salad {Browse 24#{EqSalad Y}} end % 8.25 local Y in Y = tuna {Browse 25#{EqSalad Y}} end % 8.27 fun {RemberFC Test} fun {$ L A} case L of nil then nil [] H|T then if {Test A H} then T else H|{{RemberFC Test} T A} end end end end % 8.28 local Test in Test = fun {$ X Y} X==Y end {Browse 28#{RemberFC Test}} end % 8.29 RemberEq = {RemberFC fun {$ X Y} X==Y end} % 8.30 local L A in A = tuna L = [tuna salad is good] {Browse 30#{RemberEq L A}} end % 8.33 local L A in A = tuna L = [shrimp salad and tuna salad] {Browse 33#{RemberEq L A}} end % 8.34 local A L in A = 'eq?' L = ['equal?' 'eq?' 'eqan?' 'eqlist?' 'eqpair?'] {Browse 34#{{RemberFC fun {$ X Y} X==Y end} L A}} end % 8.35 fun {InsertLF Test} fun {$ L New Old} case L of nil then nil [] H|T then if {Test Old H} then New|H|T else H|{{InsertLF Test} T New Old} end end end end % 8.36 fun {InsertRF Test} fun {$ L New Old} case L of nil then nil [] H|T then if H == Old then H|New|T else H|{{InsertRF Test} T New Old} end end end end % 8.42 fun {SeqL L New Old} New|Old|L end % 8.43 fun {SeqR L New Old} Old|New|L end % 8.45 fun {InsertG Seq} fun {$ L New Old} case L of nil then nil [] H|T then if H == Old then {Seq T New Old} else H|{{InsertG Seq} T New Old} end end end end % 8.46 InsertL = {InsertG SeqL} % 8.47 InsertR = {InsertG SeqR} % 8.50 InsertL1 = {InsertG fun {$ L New Old} New|Old|L end} % 8.52 fun {Subst_ L New Old} case L of nil then nil [] H|T then if H == Old then New|T else H|{Subst_ T New Old} end end end % 8.54 fun {SeqS L New Old} New|L end % 8.55 Subst = {InsertG SeqS} % 8.56 fun {SeqRem L New Old} L end fun {Rember L A} {{InsertG SeqRem} L false A} end local A L in A = sausage L = [pizza with sausage and bacon] {Browse 56#{Rember L A}} end % 8.59 fun {FirstSubExp AExp} case AExp of _|X|_ then X end end fun {SecondSubExp AExp} case AExp of _|_|Y|_ then Y end end fun {Operator AExp} case AExp of H|_ then H end end fun {Value_ NExp} if {IsNumber NExp} then NExp else case {Operator NExp} of '+' then {Value_ {FirstSubExp NExp}} + {Value_ {SecondSubExp NExp}} [] '*' then {Value_ {FirstSubExp NExp}} * {Value_ {SecondSubExp NExp}} [] '^' then {Pow {Value_ {FirstSubExp NExp}} {Value_ {SecondSubExp NExp}}} end end end % 8.61 fun {AtomToFunction AExp} case AExp of '+' then Number.'+' [] '*' then Number.'*' [] '^' then Pow end end % 8.62 local NExp in NExp = ['+' 5 3] {Browse 62#{AtomToFunction {Operator NExp}}} end % 8.63 fun {Value NExp} if {IsNumber NExp} then NExp else {{AtomToFunction {Operator NExp}} {Value {FirstSubExp NExp}} {Value {SecondSubExp NExp}}} end end % 8.66 fun {MultiRember L A} case L of nil then nil [] H|T then if A == H then {MultiRember T A} else H|{MultiRember T A} end end end fun {MultiRemberF Test} fun {$ L A} case L of nil then nil [] H|T then if {Test A H} then {{MultiRemberF Test} T A} else H|{{MultiRemberF Test} T A} end end end end % 8.67 local Test A Lat in Test = fun {$ X Y} X==Y end A = tuna Lat = [shrimp salad tuna salad and tuna] {Browse 67#{{MultiRemberF Test} Lat A}} end % 8.69 MultiRemberEq = {MultiRemberF fun {$ X Y} X==Y end} % 8.74 EqTuna = {EqC tuna} % 8.76 fun {MultiRemberT Test L} case L of nil then nil [] H|T then if {Test H} then {MultiRemberT Test T} else H | {MultiRemberT Test T} end end end % 8.77 local Test Lat in Test = EqTuna Lat = [shrimp salad tuna salad and tuna] {Browse 77#{MultiRemberT Test Lat}} end % 8.79 fun {MultiRemberAndCo Col L A} case L of nil then {Col nil nil} [] H|T then if H == A then {MultiRemberAndCo fun {$ NewLat Seen} {Col NewLat H|Seen} end T A} else {MultiRemberAndCo fun {$ NewLat Seen} {Col H|NewLat Seen} end T A} end end end % 8.80 fun {AFriend X Y} Y == nil end % 8.81 local A Lat Col in A = tuna Lat = [strawberries tuna and swordfish] Col = AFriend {Browse 81#{MultiRemberAndCo Col Lat A}} end % 8.82 local A Lat Col in A = tuna Lat = nil Col = AFriend {Browse 82#{MultiRemberAndCo Col Lat A}} end % 8.83 local A Lat Col in A = tuna Lat = [tuna] Col = AFriend {Browse 82#{MultiRemberAndCo Col Lat A}} end % 8.87 local Lat Col in Lat = [tuna] Col = AFriend fun {NewFriend0 NewLat Seen} {Col NewLat Lat.1 | Seen} end end % 8.88 fun {NewFriend NewLat Seen} {AFriend NewLat tuna | Seen} end % 8.93 fun {LatestFriend NewLat Seen} {AFriend and|NewLat Seen} end % 8.96 fun {LastFriend X Y} {Length X} end local Ls Col in Ls = [strawberries tuna and swordfish] Col = LastFriend {Browse 96#{MultiRemberAndCo Col Ls tuna}} end % 8.99 fun {MultiInsertL L New Old} case L of nil then nil [] H|T then if Old == H then New|H|{MultiInsertL T New Old} else H|{MultiInsertL T New Old} end end end fun {MultiInsertR L New Old} case L of nil then nil [] H|T then if Old == H then H|New|{MultiInsertR T New Old} else H|{MultiInsertR T New Old} end end end % 8.100 fun {MultiInsertLR L New OldL OldR} case L of nil then nil [] H|T then if H == OldL then New|OldL|{MultiInsertLR T New OldL OldR} elseif H == OldR then OldR|New|{MultiInsertLR T New OldL OldR} else H|{MultiInsertLR T New OldL OldR} end end end % 8.103 fun {MultiInsertLRAndCo Col L New OldL OldR} case L of nil then {Col nil 0 0} [] H|T then if H == OldL then {MultiInsertLRAndCo fun {$ NewLat L R} {Col New|OldL|NewLat {Add1 L} R} end T New OldL OldR} elseif H == OldR then {MultiInsertLRAndCo fun {$ NewLat L R} {Col OldR|New|NewLat L {Add1 R}} end T New OldL OldR} else {MultiInsertLRAndCo fun {$ NewLat L R} {Col H|NewLat L R} end T New OldL OldR} end end end % Note: Book doesn't give example Collector function % %% 8.104 % local Col in % Col = ... % {Browse 104#{MultiInsertLRAndCo Col nil cranberries fish chips} % end % % %% 8.111 % local Col New OldL OldR Lat in % Col = ... % New = salty % OldL = fish % OldR = chips % Lat = [chips and fish or fish and chips} % {Browse 111#{MultiInsertLRAndCo Col Lat New OldL OldR} % end % 8.114 fun {IsEven_ N} (N div 2) * 2 == N end fun {EvensOnly L} case L of nil then nil [] H|T then if {IsAtomS H} then if {IsEven_ H} then H|{EvensOnly T} else {EvensOnly T} end else {EvensOnly H}|{EvensOnly T} end end end % 8.115 local L in L = [[9 1 2 8] 3 10 [[9 9] 7 6] 2] {Browse 115#{EvensOnly L}} end % Note: Book doesn't give code for last else case %% 8.119 fun {EvensOnlyAndCo Col L} case L of nil then {Col nil 1 0} [] H|T then if {IsAtomS H} then if {IsEven_ H} then {EvensOnlyAndCo fun {$ NewL P S} {Col H|NewL H*P S} end T} else {EvensOnlyAndCo fun {$ NewL P S} {Col NewL P H+S} end T} end else {EvensOnlyAndCo Col H}|{EvensOnlyAndCo Col T} end end end % %% 8.116 % local L in % L = [[9 1 28] 3 10 [[9 9] 7 6] 2] % {Browse 116#{EvensOnlyAndCo ... L}} % end % Note: This does not give correct result (see note on 8.119) %% 8.126 fun {TheLastFriend NewL Product Sum} Sum|Product|NewL end local L in L = [[9 1 2 8] 3 10 [[9 9] 7 6] 2] {Browse 126#{EvensOnlyAndCo TheLastFriend L}} end |