<<

Modules

Lecture 28: Modules • Reusable modules: CSC 131 ! Separate, but not independent compilation Fall, 2008 ! Maintain type checking ! Control over export and import of names Kim Bruce

Simula 67 Simula 67

class vehicle(weight,maxload); real weight, maxload; begin integer licenseno; Derived from Algol 60 for discrete . real load; • Boolean procedure tooheavy; tooheavy := weight + load > maxload; • Nygaard and Dahl: 2001 load := 0; (* initialization code *) end • Introduced classes and objects ref(vehicle) rv, pickup; ! No information hiding rv:- new vehicle(2000,2500); pickup:- rv; (* assignment via sharing *) pickup.licenseno := 3747; pickup.load := pickup.load +150; if pickup.tooheavy then ...

Representation Independence ADT values

• Choice of representation doesn’t a"ect • Only constructible values count. computation. E.g., rationals. • Specified abstractly • If represent new type in terms of old: ! pop#push#fst,rest$$ = rest, ! Rep may have values not corresponding to new type. ! top#push#fst,rest$$ = fst, E.g., #3,0$ ! empty#EmptyStack$ = true, Rep may have several values corresponding to same ! empty#push#fst,rest$$ = false abstract value. E.g., #1,2$ and #2,4$. ! ! Values of new type can be confused w/values of rep • Avoid previous problems because rep hidden type. Ada #1980$ Ada #1980$ generic length : Natural := 100; -- generic parameters package body stack is type element is private; procedure make_empty (S : out stack); package stack is begin type stack is private; S.top := 0; end make_empty ; procedure make_empty (S : out stack); procedure push (S : in out stack; X : in element); procedure push (S : in out stack; X : element) is procedure pop (S : in out stack; X: out element); begin function empty (S : stack) return boolean; if full(S) then stack_error : exception; raise stack_error; else private S.top := S.top + 1; type stack is record S.space(S.top) := X; end if; space : array(1..length) of element; end push; top : integer range 0..length := 0; end record; ... end stack; end stack;

Internal representation #object$ Ada #1980$ generic length : Natural := 100; -- generic parameters type element is private; -- only assignment and tests for = package stack is -- specification only procedure push (X : in element); procedure pop (X: out element); function empty return boolean; function full return boolean; stack_error : exception; end stack; v: stack(100,int); package body stack is -- begin space : array (1..length) of element; make_empty(s); top : integer range 0..length := 0; push(s, 47); if (empty(s)) then ... procedure push (X : in element) is end; begin if full() then raise stack_error; else top := top + 1; space(top) := X; end if; end push; ...

Using internal representation Modula 2

package stack1 is new stack(20,integer); package stack2 is new stack(100, character); -- Note that this initializes length in both cases to 0 use stack2; stack1.push(5) • Similar to Ada except if not stack1.empty() then stack1.pop(Z); ! no generics endif; no “private” section push('z'); !

• Internal rep like an object • Require all private types to take same amount of space !! a pointer • Changing rep requires recompilation but not changing of users. DEFINITION MODULE stackMod; IMPORT element FROM elementMod; TYPE stack; Ada vs. Modula 2 PROCEDURE make_empty (VAR S : stack); PROCEDURE push (VAR S : stack; X : element); PROCEDURE pop (VAR S : stack; X: element); PROCEDURE empty (S : stack): BOOLEAN; • Representations fairly similar END stackMod. ! can import from other units #modules or packages$ IMPLEMENTATION MODULE stackMod; and export items to other units. TYPE stack = POINTER TO RECORD space : array[1..length] of element; top : INTEGER; • For external representations not much END; di"erence. PROCEDURE make_empty (VAR S : stack); BEGIN • Private types in Ada vs opaque types in Modula. S^.top := 0; END make_empty ;

... (* can be start-up code too to initialize *) END stackMod;

Ada vs. Modula 2 Clu #1974$

• Use of opaque types require Pointer types • Cluster is used for ADT’s • Representation changes • Cluster is a type !! not hold one. ! in Ada forces recompilation of user programs • Unlike internal rep, create numerous objects ! Not in Modula 2 • Held as implicit references • Internal reps of ADT's almost identical. • Ada more flexible via generic routines ! sorted_bag = cluster [t : type] is create, insert, ... where t has ! can parameterize on types and sizes lt, equal : proctype (t,t) returns (bool); ! Create new instances of packages

ML

• datatype not provide information hiding ML & Modules • abstype similar, but provides information hiding ! Can’t get at representation #no pattern matching$ ! deprecated abstype 'a stack = mkstack of ('a list) with exception stackUnderflow ML Modules val emptyStk : 'a stack = mkstack []

fun push (e:'a) (mkstack(s):'a stack) = mkstack(e::s) • SML has two sub!languages: ! Core !! programming in the fun pop (mkstack([]):'a stack) details of types and expressions = raise stackUnderflow • | pop (mkstack(e::s):'a stack) ! Modules !! programming in the large !! architecture. = mkstack(s):'a stack • group defs of types & expressions into units w/interfaces fun top (mkstack([]):'a stack) Separate interfaces #signatures$ from = raise stackUnderflow • | top (mkstack(e::s):'a stack) = e #structures$ fun IsEmpty (mkstack([]):'a stack) = true • Can reveal implementations if want. | IsEmpty (mkstack(e::s):'a stack) = false end;

Signature Structure optional

structure IntStack: INTSTACKSIG = signature INTSTACKSIG = struct sig type intstack = int list; type intstack; exception stackUnderflow; exception stackUnderflow; val emptyStk: intstack; val emptyStk = []; val push: int -> intstack -> intstack; val pop: intstack -> intstack; fun push (e:int) (s:intstack) = (e::s); val top: intstack -> int; val IsEmpty: intstack -> bool; fun pop [] = raise stackUnderflow end; | pop (e::s) = s; ...

fun extra ... (* not visible outside *) end;

Accessing Structure Ascription

• IntStack.push 12 IntStack.emptyStk • structure IntStack: INTSTACKSIG = ... ! lets type definitions escape ! transparent • open IntStack; ! hides extra features push 12 emptyStk; • structure IntStack:> INTSTACKSIG = ... • Considered bad style to open outside structure. ! also hides type definitions ! opaque • Rather than open, rename: • Can further restrict structure by giving new ! val push = IntStack.push; name and signature val emptyStk = IntStack.emptyStk; ! structure ResStack:> RESSTACKSIG = IntStack