1 / 29

Modules

Modules. value : type : function :: structure : signature : functor. Programming in the small Reliability Correctness ( types ) Robustness ( exceptions ) Efficiency Data Structures and Algorithms ( lists, arrays) Abstraction Data ( patterns )

ifama
Download Presentation

Modules

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Modules value : type : function :: structure : signature : functor L112Modules

  2. Programming in the small Reliability Correctness (types) Robustness (exceptions) Efficiency Data Structures and Algorithms (lists, arrays) Abstraction Data (patterns) Control (higher-order functions) Declarative (enhances programmer productivity) Programming in the large Cluster related definitions; hierarchical organization of programs (structures) Encapsulation (localization) of implementation details, for clarity and modifiability (abstype, signatures) Reusability and interchangeability of parts (functors). Separate compilation. Standard libraries. SML features L112Modules

  3. Customization of Modules • Controlling visibility of names (Managing environments) • To avoid potential name conflicts. • Multiple implementations of an ADT (e.g, Table). • Similar operations on different ADTs (e.g., delete on Set, List, Table, etc). • Programmer choice of names, to conform to domain vocabulary. • To encapsulate representation details. • To enable transparent changes to the impl. • To preserve data integrity (invariants) • Instantiation (Specializing w.r.t. types) L112Modules

  4. SML Constructs • Structure • Collection of definitions • E.g., Ada/Java packages, C++/Java classes, etc • Signature • Type declarations of the names • E.g., Ada package specification, Java interfaces, etc • Functor • Maps a structure to another structure • Parameterized structures • E.g., Ada generic units, C++ templates, Java functions with interface/class parameters, etc L112Modules

  5. structure QueueImpl = struct datatype 'a t = Q of ('a list * 'a list); exception E; val empty = Q([],[]); fun norm (Q([],ts)) = Q(rev ts, []) | norm q = q; fun enq(Q(hs,ts), x) = norm(Q(hs, x::ts)); fun null(Q([],[])) = true | null _ = false; fun hd(Q(x::_,_)) = x | hd(Q([],_)) = raise E; fun deq(Q(x::hs,ts)) = norm(Q(hs,ts)) | deq(Q([],_)) = raise E; end; L112Modules

  6. structure QueueImpl : sig datatype 'a t = Q of 'a list * 'a list exception E val deq : 'a t -> 'a t val empty : 'a t val enq : 'a t * 'a -> 'a t val hd : 'a t -> 'a val norm : 'a t -> 'a t val null : 'a t -> bool end; L112Modules

  7. Information Hiding Concerns • The implementation details of QueueImpl are exported. • Client code can use pattern matching to manipulate queues. • Client code can break if the implementation of QueueImpl is changed. • Client code can ignore the FIFO discipline. • Semantics of queue (invariants) can be violated. • Possible Solution : Restrict the view L112Modules

  8. Transparent Signature Constraints signature Qtip = sig type ’a t val deq : 'a t -> 'a t val empty : 'a t val enq : 'a t * 'a -> 'a t val hd : 'a t -> 'a val null : 'a t -> bool end; structure Queue : Qtip = QueueImpl; L112Modules

  9. - QueueImpl.norm; val it = fn : 'a QueueImpl.t -> 'a QueueImpl.t - Queue.norm;(* error *) - Queue.hd; val it = fn : 'a QueueImpl.t -> 'a - Queue.Q;(* error *) - Queue.empty = QueueImpl.Q ([],[]); - open QueueImpl; - norm(Queue.enq(Queue.empty, “a”)); val it = Q (["a"],[]) : string t L112Modules

  10. Opaque Signature Constraints structure Queue :> Qtip = QueueImpl; • This enforces data abstraction. • Only operations that are explicitly defined on Queue can be invoked on Queue-values. QueueImpl.norm(Queue.enq(Queue.empty,“a”)); (* error *) • Equality tests (based on the representation) are banned. Queue.empty = QueueImpl.Q ([],[])); (* error *) • To allow equality tests, use eqtype ’a tinstead oftype ’a t. (Cf. Ada’s Limited Private Types and Private Types) L112Modules

  11. signature SIG = sig val i : int; type t; val x : t val f:t*t -> bool end; structure STRUC = struct val i = 3; type t = int; val x = 4; fun f(a,b) = (a=b) end; open STRUC; f(x,x); f(i,x); (*val it = false : bool*) structure STRUC’:> SIG = STRUC; open STRUC’; f(i,x); (* type error *) Type t created using opaque signatures is regarded as distinct from any other type (including int and other type t created from the same structure.) L112Modules

  12. signature SIG = sig val i : int; type t; val x : t val f:t*t -> bool end; structure STRUC = struct val i = 3; type t = int; val x = 4; fun f(a,b) = (a=b) end; signature SIG’ = SIG where type t = int; structure STRUC’:> SIG’ = STRUC; open STRUC’; f(i,x); (* val it = false : bool*) Type t being int is visible because where-clause explicitly exports it. L112Modules

  13. Signature Matching structure strId : sigExp = strExp ; (* targetcandidate *) Target signature expresses a set of constraints that the candidate structure must satisfy. Informally, the candidate’s signature may have more components than are required by the target, may have more definitions of types than are required, and may have value components with more general types. L112Modules

  14. QUEUE_WITH_EMPTY matches QUEUE signature QUEUE = sig type 'a queue exception Empty val empty : 'a queue val insert : 'a * 'a queue -> 'a queue val remove : 'a queue -> 'a * 'a queue end signature QUEUE_WITH_EMPTY = sig include QUEUE val is_empty : 'a queue -> bool end L112Modules

  15. QUEUE_AS_LISTS matches QUEUE signature QUEUE = sig type 'a queue exception Empty val empty : 'a queue val insert : 'a * 'a queue -> 'a queue val remove : 'a queue -> 'a * 'a queue end signature QUEUE_AS_LISTS = QUEUE wheretype 'a queue = 'a list * 'a list L112Modules

  16. signature QUEUE = sig type 'a queue exception Empty val empty : 'a queue val insert : 'a * 'a queue -> 'a queue val remove : 'a queue -> 'a * 'a queue end signature QUEUE_AS_LIST0 = QUEUE where type 'a queue = 'a list signature QUEUE_AS_LIST = sig type 'a queue = 'a list exception Empty val empty : 'a list val insert : 'a * 'a list -> 'a list val remove : 'a list -> 'a * 'a list end Equivalent: QUEUE_AS_LIST and QUEUE_AS_LIST0 L112Modules

  17. MERGEABLE_QUEUE matches MERGEABLE_INT_QUEUE signature MERGEABLE_QUEUE = sig include QUEUE val merge : 'a queue * 'a queue -> 'a queue end signature MERGEABLE_INT_QUEUE = sig include QUEUE val merge : int queue * int queue -> int queue end L112Modules

  18. RBT_DT matches RBT signature RBT_DT = sig datatype 'a rbt = Empty | Red of 'a rbt * 'a * 'a rbt | Black of 'a rbt * 'a * 'a rbt end signature RBT = sig type 'a rbt val Empty : 'a rbt val Red : 'a rbt * 'a * 'a rbt -> 'a rbt end L112Modules

  19. (cont’d) • Every type specification (resp. datatype definition) in the target must have a matching (resp. equivalent) type specification (resp. datatype definition) in the candidate. • Every exception specification in the target must have an equivalent exception specification in the candidate. • Every value specification in the target must be matched by a value specification in the candidate with at least as general a type. L112Modules

  20. Relationship between Structures and Signatures • In ML, a signature may serve as an interface for many different structures, and that a structure may implement many different signatures. (interchangeability of components) • ML, C++, Java† : many-to-many • Modula-2 : one-to-one • Ada-95 : many-to-one. • Every structure has a principal signature, with the property that all other signatures for that structure are more restrictive than the principal signature. L112Modules

  21. Functors • A functor maps structures to structure. • A functor can be viewed as a reusable unit that contains well-defined “sockets for plug-ins”. • Parameterized/Generic modules. • Useful in “client-server paradigm” applications exploiting interchangeability of parts with common interface. • Developing floating point libraries that work with different precision implementations. • Building common test harness to verify various implementations of an abstract data type. L112Modules

  22. Example signature Order = sig eqtype et ; val le : et -> et -> bool end; functor MkOrdSet(Ord:Order) = struct exception EmptySetEX; datatype set = SET of (Ord.et list) val empty = SET nil fun insert (SET s) n = SET (n::s) fun member (SET s) n = (List.exists (fn x => (x = n)) s) fun min (SET s) = if (null(s)) then raise EmptySetEX else foldr (fn (x,r) => if (Ord.le r x) then r else x) (hd s) (tl s); end; L112Modules

  23. structure OrdInt: Order = struct type et = int; fun le (x:et) y = x <= y end; structure intset = MkOrdSet(OrdInt); open intset; (min empty); (* uncaught exception *) val s1 = (insert empty 5); val s2 = (insert s1 3); (* val s2 = SET [3,5] : set *) (min (insert s2 8)); (* val it = 3 : OrdInt.et *) L112Modules

  24. Example Functor (Component Reuse) signature ORDER = sig type t; val compare: t*t -> bool end; structure StringOrder: ORDER = struct type t = string; val compare = String.compare end; ... structure StringDict = Dictionary (StringOrder); (* structure StringDict : sig type key = StringOrder.t type 'a t exception E of key val empty : 'a t val lookup : 'a t * Key.t -> 'a val update : 'a t * key * 'a -> 'a t end *) L112Modules

  25. functor Dictionary (Key: ORDER) = struct type key = Key.t; abstype 'a t = Lf | B of key *'a*'a t *'a t withexception E of key; val empty = Lf; fun lookup (B(a,x,t1,t2), b) = (case Key.compare(a,b) of GREATER => lookup(t1, b) | EQUAL => x | LESS => lookup(t2, b)) | lookup (Lf, b) = raise E b; fun update (Lf, b, y) = B(b, y, Lf, Lf) | update (B(a,x,t1,t2), b, y) = (case Key.compare(a,b) of GREATER => B(a, x, update(t1,b,y), t2) | EQUAL => B(a, y, t1, t2) | LESS => B(a, x,t1,update(t2,b,y))); end end; L112Modules

  26. (cont’d) infix|< ; fun (d |< (k,x)) = StringDict.update(d,k,x); val dict = StringDict.empty |< (“abc”, 2) |< (“nbc”, 11) |< (“dsc”, 53) |< (“tlc”,54); (* val dict = - : int StringDict.t *) StringDict.lookup(dict, “dsc”); (* val it = 53 : int *) StringDict.lookup(dict, “cnn”); (* uncaught exception E *) L112Modules

  27. Multi-argument Functor signature INT = sig val i: int end; signature REAL = sig val r: real end; functor Foo(structure I:INT and R: REAL; val x : int) = structend; structure Int = structval i = 0 end; structure Real= structval r = 0.0 end; structure Bar = Foo(structure I = Int and R = Real; val x = 2); L112Modules

  28. Sharing Constraints (for combining / integrating modules) To express equality constraints among types names. • Type sharing sharing type <type> = … = <type> • Structure sharing sharing <structure> = … = < structure> Shorthand for sharing of identically named types within the equated structures. L112Modules

  29. signature ELEMENT = sig type element; val similar : element * element -> bool; end; signature BTREE = sig structure Element: ELEMENT; eqtype elt; sharingtype elt = Element.element; datatype bt = Empty | Node of elt * bt * bt; val leaf : elt -> bt; val build : elt * bt * bt -> bt; val lookup : elt * bt -> bool end; L112Modules

More Related