== Summary == We explored modular design in some detail; developing interfaces for numbers that support various operations. - we designed an "Addable" interface - we brainstormed different implementations: ints, floats, fractions, complex numbers, matrices, vectors - we separated the interface into a "Core" interface that must be implemented and an "Extension" interface that can be derived from the Core. We will revisit this in more detail next lecture - we extended the interface to create a "Multipliable" interface using the "include" statement - we used the "MT with type t := t'" syntax, used to modify a module type by replacing it with another type throughout. For example, by writing module Int : Addable with type t := int we exposed the fact that Int.t = int, allowing Int functions to be used with regular ints. == Additional reading == Real World OCaml, chapter 9, discusses many of the techniques we covered in this lecture (and the next). == Provided code == I have extended the file algebra.mli that we developed in class. Just as we added multiplication to the addable interface to create the multipliable interface, I have separately added ordering and division. I have taken out the concrete implementations (Ints, Floats, etc.) We will re-add them (and more!) next time. You are encouraged to add some on your own! I have also added implementations of all the Extension interfaces in the .ml file; I will discuss these further next time. == Foreshadowing the payoff == The payoff of designing the code this way may not be apparent until after the next lecture. You can start to see it by looking at the amount of effort we have saved an implementor of the Number type. There are 18 functions required in the Number interface: utop # #use "algebra.ml";; utop # module Int : Number = struct end;; Error: Signature mismatch: Modules do not match: sig end is not included in Number The field `>=' is required but not provided The field `<=' is required but not provided The field `>' is required but not provided The field `<' is required but not provided The field `compare' is required but not provided The field `from_int' is required but not provided The field `<>' is required but not provided The field `-' is required but not provided The field `/' is required but not provided The field `to_float' is required but not provided The field `isPositive' is required but not provided The field `one' is required but not provided The field `*' is required but not provided The field `=' is required but not provided The field `zero' is required but not provided The field `~-' is required but not provided The field `+' is required but not provided The field `inv' is required but not provided The field `t' is required but not provided but only 9 required in the NumberCore interface: utop # module IntCore : NumberCore = struct end;; Error: Signature mismatch: Modules do not match: sig end is not included in NumberCore The field `to_float' is required but not provided The field `isPositive' is required but not provided The field `one' is required but not provided The field `*' is required but not provided The field `=' is required but not provided The field `zero' is required but not provided The field `~-' is required but not provided The field `+' is required but not provided The field `inv' is required but not provided The field `t' is required but not provided Since there will be many number implementations (some more complex than others!) reducing the amount of work (and potential for bugs) in half is a big win.