% \insert 'NewPortObjectDebug.oz' % did this for testing \insert 'NewPortObject.oz' declare % We represent Arrays as Port Objects (since they have mutable state) local % SizeNListOf: }: > fun {SizeNListOf N Val} if N =< 0 then nil else Val|{SizeNListOf N-1 Val} end end % ReplaceNth: }: > fun {ReplaceNth Ls CurrentIndex N V} case Ls of H|T then if N == CurrentIndex then V|T else H|{ReplaceNth T CurrentIndex+1 N V} end else raise noSuchIndex(N) end % shouldn't happen, could omit end end in fun {NewArray Size InitialValue} {NewPortObject % used NewPortObjectDebug during testing %% The state is a contents() record holding a list of size Size %% Initially, the list holds Size copies of InitialValue contents({SizeNListOf Size InitialValue}) fun {$ contents(Ls) Msg} case Msg of set(I V) then contents({ReplaceNth Ls 1 I V}) [] get(I ?Var) then Var = {Nth Ls I} contents(Ls) [] size(?Var) then Var = Size contents(Ls) end end } end % ArraySet: }> proc {ArraySet Array Index Val} {Send Array set(Index Val)} end % ArrayGet: }: > fun {ArrayGet Array Index} {Send Array get(Index $)} end % ArraySize: }: > fun {ArraySize Array} {Send Array size($)} end end