CS 11 Ocaml track: lecture 4The idea of modulesImplementation hidingInterface vs. implementationInterface of Newlist modulenewlist.mli (types)newlist.mli (exceptions)newlist.mli (functions)Implementation of Newlistnewlist.ml (types)newlist.ml (exceptions)newlist.ml (functions) (1)newlist.ml (functions) (2)newlist.ml (functions) (3)Compiling Newlist files (1)Compiling Newlist files (2)Compiling Newlist files (3)Using the Newlist moduleSlide 19Making lists abstractnewlist2.mlitype 'a t ????newlist2.mli (new interface)Slide 24More modulesA simple Set moduleA simple Set "signature"A simple Set "signature" in OcamlA simple Set "signature" in ocamlSlide 30Set implementation (1)Set implementation (2)Set implementation (3)Using the Set implementationNoteProblemSolutionFirst try (broken)Problem with first try (1)Problem with first try (2)Problem with first try (3)Second try (working)Using IntListSetModules with polymorphic typesInterfaceImplementationNotice anything odd?However...Sets with orderable elements(Preview)Next timeCS 11 Ocaml track: lecture 4Today:modulesThe idea of modulesWhat's the idea behind a "module"?Package up code so other people/programs can use itControl what parts of code arepart of the interfacepart of the implementation onlyand hide the implementation partImplementation hidingWhy hide the implementation?Might want to change laterchange fundamental data structuresdifferent efficiency tradeoffsDon't want all code that uses module to require major changesor, ideally, any changesInterface vs. implementationIn Ocaml: interface goes into .mli filesimplementation goes into .ml filesSimple example: listsWe'll create our own list moduleCall it NewlistInterface of Newlist moduleIn newlist.mliMust specify:publicly visible typespublicly visible functionspublicly visible exceptionsDon't have to define any of these!Except: need to define types if want users to pattern-match on themnewlist.mli (types)type 'a newlist = | Nil | Cons of 'a * 'a newlistIf didn't need ability to pattern-match, could do justtype 'a newlistThis would be an abstract typenewlist.mli (exceptions)exception List_error of stringnewlist.mli (functions)val hd : 'a newlist -> 'aval tl : 'a newlist -> 'a newlistval append : 'a newlist -> 'a newlist -> 'a newlistval ( @@ ) : 'a newlist -> 'a newlist -> 'a newlistval length : 'a newlist -> intJust the signature of the functionsAny functions not mentioned here are hiddenNote: operator @@ is exportedImplementation of NewlistIn newlist.mlMust define:all typesall functionsall exceptionswhether exported by module or notCopying of code from .mli file sometimes unavoidablenewlist.ml (types)type 'a newlist = | Nil | Cons of 'a * 'a newlistHere, had to copy code in newlist.mliNo way to avoid this!newlist.ml (exceptions)exception List_error of stringAgain, had to copy code in newlist.mlinewlist.ml (functions) (1)let hd nl = match nl with | Nil -> raise (List_error "head of empty list") | Cons (h, _) -> hlet tl nl = match nl with | Nil -> raise (List_error "tail of empty list") | Cons (_, t) -> tnewlist.ml (functions) (2)let rec append nl1 nl2 = match nl1, nl2 with | Nil, _ -> nl2 | Cons (h, t), _ -> Cons (h, append t nl2)let ( @@ ) = appendnewlist.ml (functions) (3)let rec length nl = match nl with | Nil -> 0 | Cons (_, t) -> 1 + length tCompiling Newlist files (1)To compile the .mli file, just do:ocamlc -c newlist.mliThis will give a compiled interface file (.cmi file)The .cmi file is required to compile any file that uses the Newlist moduleThe same .cmi file can be used for both bytecode and native-code compilationCompiling Newlist files (2)To compile the .ml file, just do:ocamlc -c newlist.ml(for bytecode compilation), or:ocamlopt.opt -c newlist.ml(for native-code compilation)We'll mostly use the bytecode compilerCompiling Newlist files (3)To compile an .ml file that uses the Newlist module, just do:ocamlc -c foobar.ml (* bytecode compilation *)Note that don't have to put .cmi file in command linecompiler searches for it automaticallyUsing the Newlist moduleIn a file named e.g. testlist.ml:open Newlistlet test1 = Cons (1, Cons (2, Cons (3, Cons (4, Nil))))let test2 = Cons (11, Cons (12, Cons (13, Cons (14, Nil))))Using the Newlist moduleWithout the open declaration:let test1 = Newlist.Cons (1, Newlist.Cons (2, Newlist.Cons (3, Newlist.Cons (4, Newlist.Nil))))(* etc. *)Making lists abstractDefine a new module called Newlist2files: newlist2.ml, newlist2.mliWe make one change: want the type to be completely abstractDownside: can't pattern-match on values of new list typeUpside: can change implementation without affecting code that uses itBIG win!newlist2.mliexception List_error of stringtype 'a t (* abstract type *)val empty : 'a t (* the empty list *)val cons : 'a -> 'a t -> 'a tval hd : 'a t -> 'aval tl : 'a t -> 'a tval append : 'a t -> 'a t -> 'a tval ( @@ ) : 'a t -> 'a t -> 'a tval length : 'a t -> inttype 'a t ????Abstract types often given names like "t" (for "type")Makes sense when using fully-qualified type name: Newlist2.tMeans "the type t defined in the Newlist2 module"More concise than e.g. Newlist2.newlistnewlist2.mli (new interface)exception List_error of stringtype 'a t (* abstract type *)val empty : 'a t (* the empty list *)val cons : 'a -> 'a t -> 'a tval hd : 'a t -> 'aval tl : 'a t -> 'a tval append : 'a t -> 'a t -> 'a tval ( @@ ) : 'a t -> 'a t -> 'a tval length : 'a t -> intnewlist2.mli (new interface)val empty : 'a t (* the empty list *)val cons : 'a -> 'a t -> 'a tval hd : 'a t -> 'aval tl : 'a t -> 'a tThese values/functions used instead of pattern matching and type constructorsCan create and pick apart Newlist2.t valuesMuch like lists in SchemeAll vals are functions except for empty valueMore modulesWhat we've seen is the most common way to use modulesModule is implicitly defined by .ml and .mli filesIt's also possible to explicitly define module types (interfaces) and module implementations inside a body of ocaml codeThat's what we'll look at nextWill lead us to functors (next week)A simple Set moduleWhat are the characteristics of a set?collection of elementsno duplicatesthere is an empty set valuecan add elements to setcan test whether elements are in
View Full Document