% An open declarative unbundled stack ADT using lists declare NewStack Push Pop IsEmpty in fun {NewStack} nil end fun {Push S E} E|S end fun {Pop S E} case S of X|S1 then E = X S1 end end fun {IsEmpty S} S==nil end local S1 S2 V in S1 = {Push {Push {NewStack} 1} 2} {Browse S1} S2 = {Pop S1 V} {Browse V} {Browse S2} case S2 of H|T then {Browse H} end %insecure ADT end % 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 % A secure declarative unbundled Stack declare NewStack Push Pop IsEmpty in local Wrap Unwrap in {NewWrapper Wrap Unwrap} fun {NewStack} {Wrap nil} end fun {Push S E} {Wrap E|{Unwrap S}} end fun {Pop S E} case {Unwrap S} of X|S1 then E=X {Wrap S1} end end fun {IsEmpty S} {Unwrap S}==nil end end local S1 S2 V in S1 = {Push {Push {NewStack} 1} 2} {Browse S1} S2 = {Pop S1 V} {Browse V} {Browse S2} end % A secure stateful bundled Stack ADT declare proc {NewStack ?Push ?Pop ?IsEmpty} C={NewCell nil} in proc {Push X} {Assign C X|{Access C}} end fun {Pop} case {Access C} of X|S then {Assign C S} X end end fun {IsEmpty} {Access C} ==nil end end local Push Pop IsEmpty in {NewStack Push Pop IsEmpty} {Push 1} {Push 2} {Browse {Pop}} {Browse {IsEmpty}} {Browse {Pop}} {Browse {IsEmpty}} end % Encapsulated stateful ADT declare fun {NewCounter I} S = {NewCell I} proc {Inc} S := @S + 1 end proc {Dec} S := @S - 1 end fun {Get} @S end proc {Put I} S := I end proc {Display} {Browse @S} end in o(inc:Inc dec:Dec get:Get put:Put display:Display) end declare C1 C2 C1 = {NewCounter 0} C2 = {NewCounter 100} {C1.inc} {C1.display} {C2.dec} {C2.display} % Using a functor declare functor Counter export inc:Inc dec:Dec get:Get put:Put display:Display init:Init define S proc {Init init(I)} S = {NewCell I} end proc {Inc} S := @S + 1 end proc {Dec} S := @S - 1 end fun {Get} @S end proc {Put I} S := I end proc {Display} {Browse @S} end end declare fun {New Functor Init} M in [M] = {Module.apply [Functor]} {M.init Init} M end declare C1 C2 C1 = {New Counter init(0)} C2 = {NewCounter 100} {C1.inc} {C1.display} {C2.inc} {C2.display} % Using a higher-order procedure for a class and an object declare fun {Counter} S proc {Init init(I)} S = {NewCell I} end proc {Inc inc} S := @S + 1 end proc {Dec dec} S := @S - 1 end proc {Get get(I)} I = @S end proc {Put put(I)} S := I end proc {Display display} {Browse @S} end D = o(init:Init inc:Inc dec:Dec get:Get put:Put display:Display) in proc{$ M} {D.{Label M} M} end end declare fun {New Class InitialMethod} O = {Class} in {O InitialMethod} O end declare C1 C2 C1 = {New Counter init(0)} C2 = {New Counter init(100)} {C1 put(10)} {C1 inc} declare X {C1 get(X)} {Browse X} {Browse {C1 get($)}} % using a nesting marker {C1 display} {C2 dec} {C2 display} % Using the class linguistic abstraction declare class Counter attr val meth browse {Browse @val} end meth inc(Value) val := @val + Value end meth init(Value) val := Value end end declare C = {New Counter init(0)} {C browse} {C inc(1)} {C browse}