Loading ...
Sorry, an error occurred while loading the content.

Modules

Expand Messages
  • jonboy3182
    How do I have multiple implementations of a module use one interface (without using Objects). For instance: Interface: Tree Implementations: BinaryTree,
    Message 1 of 17 , May 1 8:50 AM
    • 0 Attachment
      How do I have multiple implementations of a module use one interface
      (without using Objects). For instance:

      Interface: Tree
      Implementations: BinaryTree, AvlTree, RedBlackTree, AATree

      I can do this with OO programming, but I wanted to try to do it
      without. I now it's kind of contrived, but I'm trying to really
      understand this modules thing.

      --Jonathan Bryant
    • Jon Harrop
      ... Yes, you just need to define a module signature Tree and then modules BinaryTree etc. which adhere to this signature: module type TREE = sig val foo : int
      Message 2 of 17 , May 1 9:21 AM
      • 0 Attachment
        On Sunday 01 May 2005 16:50, jonboy3182 wrote:
        > How do I have multiple implementations of a module use one interface
        > (without using Objects). For instance:
        >
        > Interface: Tree
        > Implementations: BinaryTree, AvlTree, RedBlackTree, AATree
        >
        > I can do this with OO programming, but I wanted to try to do it
        > without. I now it's kind of contrived, but I'm trying to really
        > understand this modules thing.

        Yes, you just need to define a module signature Tree and then modules
        BinaryTree etc. which adhere to this signature:

        module type TREE = sig
        val foo : int
        ...
        end

        module BinaryTree : TREE = struct
        let foo = 3
        ...
        end

        and so on.

        --
        Dr Jon D Harrop, Flying Frog Consultancy Ltd.
        Objective CAML for Scientists
        http://www.ffconsultancy.com/products/ocaml_for_scientists
      • William D.Neumann
        ... There are a couple of ways you can do this, e.g. functors would work, but they re likely overkill for this. The best way is to probably use module types.
        Message 3 of 17 , May 1 9:34 AM
        • 0 Attachment
          On May 1, 2005, at 9:50 AM, jonboy3182 wrote:

          > How do I have multiple implementations of a module use one interface
          > (without using Objects). For instance:
          >
          > Interface: Tree
          > Implementations: BinaryTree, AvlTree, RedBlackTree, AATree

          There are a couple of ways you can do this, e.g. functors would work,
          but they're likely overkill for this. The best way is to probably use
          module types. Here's a really quick example using a couple of terrible
          implementations of stacks:

          module type BadStack =
          sig

          type 'a t
          exception Empty
          exception Full

          val empty : 'a t
          val push : 'a t -> 'a -> 'a t
          val pop : 'a t -> 'a * 'a t
          val isEmpty : 'a t -> bool
          end;;

          module BadListStack =
          struct
          type 'a t = 'a list
          exception Empty
          exception Full

          let empty = []

          let push s v = v :: s

          let pop = function
          [] -> raise Empty
          | h::t -> h,t

          let isEmpty = function
          | [] -> true
          | _ -> false
          end;;

          module BadArrayStack =
          struct
          type 'a t = { stack : 'a array; count : int}
          exception Empty
          exception Full

          let empty = { stack = [||]; count = 0}

          let push s v =
          if s.stack = [||] then { stack = Array.make 100 v; count = 1} else
          if s.count > 99 then raise Full else
          (s.stack.(s.count) <- v; { s with count = s.count + 1 })

          let pop s =
          if s.count = 0 then raise Empty else
          s.stack.(s.count - 1),{ s with count = s.count - 1}

          let isEmpty s =
          s.count = 0
          end;;

          module BSA = (BadListStack : BadStack);;
          module BSL = (BadArrayStack : BadStack);;

          # let s1 = BSL.empty;;
          val s1 : 'a BSL.t = <abstr>
          # let s1 = BSL.push s1 10;;
          val s1 : int BSL.t = <abstr>
          # let s1 = BSL.push s1 20;;
          val s1 : int BSL.t = <abstr>
          # let s1 = BSL.push s1 30;;
          val s1 : int BSL.t = <abstr>
          # BSL.isEmpty s1;;
          - : bool = false
          # let v,s1 = BSL.pop s1;;
          val v : int = 30
          val s1 : int BSL.t = <abstr>
          # let v,s1 = BSL.pop s1;;
          val v : int = 20
          val s1 : int BSL.t = <abstr>
          # let v,s1 = BSL.pop s1;;
          val v : int = 10
          val s1 : int BSL.t = <abstr>
          # let v,s1 = BSL.pop s1;;
          Exception: BadListStack.Empty.
          # BSL.isEmpty s1;;
          - : bool = true

          # let s2 = BSA.empty;;
          val s2 : 'a BSA.t = <abstr>
          # let s2 = BSA.push s2 10;;
          val s2 : int BSA.t = <abstr>
          # let s2 = BSA.push s2 20;;
          val s2 : int BSA.t = <abstr>
          # let s2 = BSA.push s2 30;;
          val s2 : int BSA.t = <abstr>
          # BSA.isEmpty s2;;
          - : bool = false
          # let v,s2 = BSA.pop s2;;
          val v : int = 30
          val s2 : int BSA.t = <abstr>
          # let v,s2 = BSA.pop s2;;
          val v : int = 20
          val s2 : int BSA.t = <abstr>
          # let v,s2 = BSA.pop s2;;
          val v : int = 10
          val s2 : int BSA.t = <abstr>
          # let v,s2 = BSA.pop s2;;
          Exception: BadArrayStack.Empty.
          # BSA.isEmpty s2;;
          - : bool = true

          It's a pretty ugly example, so let me know if you have more questions.
          For more information, read chapter 2 of the OCaml manual.

          William D. Neumann

          "You've got Rita Marlowe in the palm of your hand."
          "Palm of my hand? You haven't seen Rita Marlowe..."

          -- Will Success Spoil Rock Hunter?
        • Matt Gushee
          ... Well, a couple of others have given good answers, so I won t repeat what they said. You should know, however, that when you are using implicit interfaces
          Message 4 of 17 , May 1 11:05 AM
          • 0 Attachment
            jonboy3182 wrote:
            > How do I have multiple implementations of a module use one interface
            > (without using Objects). For instance:
            >
            > Interface: Tree
            > Implementations: BinaryTree, AvlTree, RedBlackTree, AATree

            Well, a couple of others have given good answers, so I won't repeat what
            they said. You should know, however, that when you are using implicit
            interfaces and implementations (i.e. the module is inferred from the
            .ml/.mli file, rather than defined with the 'module' keyword), you don't
            get to choose which is bound to which. I.e., if you had 'tree.mli' and
            'binarytree.ml', etc. You would have to copy 'binarytree.ml' to
            'tree.ml' in order to bind it to the 'tree.mli' interface. This is
            unfortunate, but it seems that it would be difficult to allow
            flexibility in matching .ml and .mli compilation units.

            --
            Matt Gushee
            Englewood, CO, USA
          • jonboy3182
            ... what ... don t ... ml/mli files: That s what I was wondering about (sorry i left that important detail out...). I knew about the toplevel idea, but
            Message 5 of 17 , May 1 12:33 PM
            • 0 Attachment
              --- In ocaml_beginners@yahoogroups.com, Matt Gushee <mgushee@h...> wrote:
              > jonboy3182 wrote:
              > > How do I have multiple implementations of a module use one interface
              > > (without using Objects). For instance:
              > >
              > > Interface: Tree
              > > Implementations: BinaryTree, AvlTree, RedBlackTree, AATree
              >
              > Well, a couple of others have given good answers, so I won't repeat
              what
              > they said. You should know, however, that when you are using implicit
              > interfaces and implementations (i.e. the module is inferred from the
              > .ml/.mli file, rather than defined with the 'module' keyword), you
              don't
              > get to choose which is bound to which. I.e., if you had 'tree.mli' and
              > 'binarytree.ml', etc. You would have to copy 'binarytree.ml' to
              > 'tree.ml' in order to bind it to the 'tree.mli' interface. This is
              > unfortunate, but it seems that it would be difficult to allow
              > flexibility in matching .ml and .mli compilation units.
              >
              > --
              > Matt Gushee
              > Englewood, CO, USA

              ml/mli files:
              That's what I was wondering about (sorry i left that important detail
              out...). I knew about the toplevel idea, but thanks.
            • Oliver Bandel
              Hello, ... Well, there is an include for signature, but not for structures. Wouldn t it make sense to have something like that? Include_struct tree.ml or
              Message 6 of 17 , May 2 12:33 AM
              • 0 Attachment
                Hello,


                On Sun, May 01, 2005 at 12:05:57PM -0600, Matt Gushee wrote:
                > jonboy3182 wrote:
                > > How do I have multiple implementations of a module use one interface
                > > (without using Objects). For instance:
                > >
                > > Interface: Tree
                > > Implementations: BinaryTree, AvlTree, RedBlackTree, AATree
                >
                > Well, a couple of others have given good answers, so I won't repeat what
                > they said. You should know, however, that when you are using implicit
                > interfaces and implementations (i.e. the module is inferred from the
                > .ml/.mli file, rather than defined with the 'module' keyword), you don't
                > get to choose which is bound to which. I.e., if you had 'tree.mli' and
                > 'binarytree.ml', etc. You would have to copy 'binarytree.ml' to
                > 'tree.ml' in order to bind it to the 'tree.mli' interface. This is
                > unfortunate, but it seems that it would be difficult to allow
                > flexibility in matching .ml and .mli compilation units.

                Well, there is an "include" for signature, but not
                for structures.

                Wouldn't it make sense to have something like that?

                Include_struct "tree.ml"
                or
                Include_file "tree.ml"

                ??

                Ciao,
                Oliver
              • Frederic GAVA
                ... open Tree or #load file-name ;; Load in memory a bytecode object file (.cmo file) produced by the batch compiler ocamlc. #use file-name ;; Read, compile
                Message 7 of 17 , May 2 2:18 PM
                • 0 Attachment
                  > Include_struct "tree.ml"
                  > or
                  > Include_file "tree.ml"

                  open Tree
                  or
                  #load "file-name";;
                  Load in memory a bytecode object file (.cmo file) produced by the batch compiler ocamlc.
                  #use "file-name";;
                  Read, compile and execute source phrases from the given file. This is textual inclusion: phrases are processed just as if they were typed on standard input. The reading of the file stops at the first error encountered.


                  >
                  > ??
                  >
                  > Ciao,
                  > Oliver
                  >
                  >
                  > Archives up to September 30, 2004 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners/
                  > The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
                  > Attachments are banned and you're asked to be polite, avoid flames etc.
                  > Yahoo! Groups Links
                  >
                  >
                  >
                  >
                  >
                  >
                  >
                  >
                  >
                • Oliver Bandel
                  ... [...] But these commands are only working i the toplevel... Ciao, Oliver
                  Message 8 of 17 , May 2 2:43 PM
                  • 0 Attachment
                    On Mon, May 02, 2005 at 11:18:12PM +0200, Frederic GAVA wrote:
                    >
                    >
                    >
                    > > Include_struct "tree.ml"
                    > > or
                    > > Include_file "tree.ml"
                    >
                    > open Tree
                    > or
                    > #load "file-name";;
                    > Load in memory a bytecode object file (.cmo file) produced by the batch compiler ocamlc.
                    > #use "file-name";;
                    > Read, compile and execute source phrases from the given file. This is textual inclusion: phrases are processed just as if they were typed on standard input. The reading of the file stops at the first error encountered.
                    [...]

                    But these commands are only working i the toplevel...


                    Ciao,
                    Oliver
                  • Virgile Prevosto
                    ... Actually, it seems to be the inverse: ... let foo = 0 ... include Incl let bar = foo + 1 ... ocamlc -c incl.ml ocamlc -c incl2.ml but you cannot have an
                    Message 9 of 17 , May 3 2:14 AM
                    • 0 Attachment
                      Le 05/02/2005, à 09:33:44 AM, Oliver Bandel a écrit:
                      > Well, there is an "include" for signature, but not
                      > for structures.
                      >
                      Actually, it seems to be the inverse:
                      the following works:
                      ---- file incl.ml
                      let foo = 0
                      ---- /file

                      ---- file incl2.ml
                      include Incl
                      let bar = foo + 1
                      ---- /file
                      ocamlc -c incl.ml
                      ocamlc -c incl2.ml

                      but you cannot have an incl2.mli with
                      include Incl
                      val bar: int
                      since Incl refers to a module (even if you write and compile an
                      incl.mli), not a module type.

                      Back to the original topic, it is always possible to encapsulate
                      everything in a module without relying on the one implicitely defined by
                      the .ml file, more or less like in SML:
                      ---- file tree.mli
                      module type TREE = sig ... end
                      ---- /file

                      ---- file binary_tree.mli
                      module BT : Tree.TREE
                      ---- /file
                      ---- file binary_tree.ml
                      module BT = struct ... end
                      ---- /file

                      --
                      E tutto per oggi, a la prossima volta
                      Virgile
                    • Chris Campbell
                      Hi, The more I use Ocaml modules the more I m suprised how limited they are. For example, you can t pass a module to a function, modules can only be
                      Message 10 of 17 , Sep 16, 2005
                      • 0 Attachment
                        Hi,

                        The more I use Ocaml modules the more I'm suprised how limited they
                        are. For example, you can't pass a module to a function, modules can
                        only be parameterised by other modules (not values) and you can't
                        return modules from functions (this is partially solved by functors).
                        I was just wondering what the reasons for the 'limitiations' were?
                        Maybe it's performance? Or due to the ML roots?

                        From past experience, I tend to think of modules as glorified records
                        and keep trying to use Ocaml modules like that before reminding myself
                        you can't do that.


                        Regards,
                        Chris
                      • Jon Harrop
                        ... I m very rusty on this but I believe the ML module system, like the rest of ML, was carefully designed to achieve a particular trade-off. In this case,
                        Message 11 of 17 , Sep 17, 2005
                        • 0 Attachment
                          On Saturday 17 September 2005 01:26, Chris Campbell wrote:
                          > The more I use Ocaml modules the more I'm suprised how limited they
                          > are. For example, you can't pass a module to a function, modules can
                          > only be parameterised by other modules (not values) and you can't
                          > return modules from functions (this is partially solved by functors).
                          > I was just wondering what the reasons for the 'limitiations' were?
                          > Maybe it's performance? Or due to the ML roots?
                          >
                          > From past experience, I tend to think of modules as glorified records
                          > and keep trying to use Ocaml modules like that before reminding myself
                          > you can't do that.

                          I'm very rusty on this but I believe the ML module system, like the rest of
                          ML, was carefully designed to achieve a particular trade-off. In this case,
                          perhaps having modules as first class values (which is essentially what
                          you're suggesting) would make the type system undecideable.

                          There are many aspects of ML that look as though they could be improved upon
                          but you'll often find that the "improvement" can only be made by sacrificing
                          something else.

                          --
                          Dr Jon D Harrop, Flying Frog Consultancy Ltd.
                          Objective CAML for Scientists
                          http://www.ffconsultancy.com/products/ocaml_for_scientists
                        • Damien Guichard
                          Hi Chris, You mean you need first-class modules? Many Scheme extensions offer them. Either you have to adapt your programming style to ML pecularities or you
                          Message 12 of 17 , Sep 17, 2005
                          • 0 Attachment
                            Hi Chris,

                            You mean you need first-class modules?
                            Many Scheme extensions offer them.
                            Either you have to adapt your programming style to ML pecularities or
                            you have to switch back to Scheme.
                            That's the "evolution of a programmer", no matter how long we dream
                            about it, we can't have all facilities in one single language.

                            Regards,

                            - damien


                            --- In ocaml_beginners@yahoogroups.com, Chris Campbell
                            <cyberdanx@g...> wrote:
                            > Hi,
                            >
                            > The more I use Ocaml modules the more I'm suprised how limited they
                            > are. For example, you can't pass a module to a function, modules can
                            > only be parameterised by other modules (not values) and you can't
                            > return modules from functions (this is partially solved by functors).
                            > I was just wondering what the reasons for the 'limitiations' were?
                            > Maybe it's performance? Or due to the ML roots?
                            >
                            > From past experience, I tend to think of modules as glorified records
                            > and keep trying to use Ocaml modules like that before reminding myself
                            > you can't do that.
                            >
                            >
                            > Regards,
                            > Chris
                          • Chris Campbell
                            ... No. I don t *need* them, I can use records or objects instead. It just seems like they /might/ be useful. ... Of course. ... I realised that, however I
                            Message 13 of 17 , Sep 17, 2005
                            • 0 Attachment
                              On 17/09/05, Damien Guichard <alphablock@...> wrote:
                              >
                              > Hi Chris,
                              >
                              > You mean you need first-class modules?

                              No. I don't *need* them, I can use records or objects instead. It
                              just seems like they /might/ be useful.

                              > Many Scheme extensions offer them.
                              > Either you have to adapt your programming style to ML pecularities or
                              > you have to switch back to Scheme.

                              Of course.

                              > That's the "evolution of a programmer", no matter how long we dream
                              > about it, we can't have all facilities in one single language.

                              I realised that, however I just wondered if there was a reason for not
                              having first class modules out of curiosity. This isn't a bash ocaml
                              thing, just curiosity.
                            • Chris Campbell
                              ... In this case, I think that s exactly what interests me.
                              Message 14 of 17 , Sep 17, 2005
                              • 0 Attachment
                                On 17/09/05, Jon Harrop <jon@...> wrote:

                                > There are many aspects of ML that look as though they could be improved upon
                                > but you'll often find that the "improvement" can only be made by sacrificing
                                > something else.

                                In this case, I think that's exactly what interests me.
                              • Brian Hurt
                                ... They re not glorified records. Nor are they broken and weird objects. They are a way to parameterize code based on other code, to create new types and
                                Message 15 of 17 , Sep 17, 2005
                                • 0 Attachment
                                  On Sat, 17 Sep 2005, Chris Campbell wrote:

                                  > Hi,
                                  >
                                  > The more I use Ocaml modules the more I'm suprised how limited they
                                  > are. For example, you can't pass a module to a function, modules can
                                  > only be parameterised by other modules (not values) and you can't
                                  > return modules from functions (this is partially solved by functors).
                                  > I was just wondering what the reasons for the 'limitiations' were?
                                  > Maybe it's performance? Or due to the ML roots?
                                  >
                                  >> From past experience, I tend to think of modules as glorified records
                                  > and keep trying to use Ocaml modules like that before reminding myself
                                  > you can't do that.

                                  They're not glorified records. Nor are they broken and weird objects.
                                  They are a way to parameterize code based on other code, to create new
                                  types and enlist the type checker to ensure certain constraints are met.
                                  The golden example of what modules are good for is Set.compare, which
                                  needs to ensure you only compare two sets that hold the same type and have
                                  the same ordering.

                                  I comment that you can instantiate on a value:

                                  module type Length = sig
                                  val len : int
                                  end;;

                                  module MakeVector(Len: Length) = struct
                                  type t = float array
                                  let make () : t = Array.make (Len.len) 0.
                                  let add a b =
                                  let c = make () in
                                  for i = 0 to Len.len - 1 do
                                  c.(i) <- a.(i) +. b.(i)
                                  done;
                                  c

                                  ...
                                  end;;

                                  It just isn't that much use. The only valid use I've ever seen for this
                                  feature is vectors and matricies. But even there I disagree that it's
                                  that big of an advantage. Unrolling loops is of signifigantly less value
                                  on modern superscalar, out of order, speculatively executing CPUs. Loop
                                  branching is highly predictable and therefor pretty much free. But
                                  increased code size, leading to cache misses and 100-350+ clock cycle main
                                  memory accesses, is a much bigger problem. If the number of different
                                  sizes of vectors and matricies is small, a better solution would almost
                                  certainly be specialized code. Providing unique code to handle 2-vectors,
                                  3-vectors, and 4-vectors isn't that big of a hassle, especially
                                  considering for maximal performance you probably want to drop to C, and
                                  then to inline SSE assembly.

                                  Another thing modules are good for- changing algebras for your algorithms.
                                  An example of this could be:

                                  module type Algebra = sig
                                  type t
                                  type dt
                                  val sub : t -> t -> t (* subtract *)
                                  val solve : a: dt -> b: t -> t (* solve for ax = b *)
                                  val epsilon_equals: t -> t -> bool (* are two number sufficiently
                                  close? *)
                                  end

                                  module Newtons(Alg: Algebra) = struct
                                  let rec meth f df x =
                                  let y = Alg.solve (df x) (f x) in
                                  let x' = Alg.sub x y' in
                                  if (epsilon_equals x x') then
                                  x'
                                  else
                                  meth f df x'
                                  end;;

                                  Here I've just written a generic Newton's method, that given a basis
                                  algebra to work in, solves for f x = 0. It's simplistic and has problems,
                                  but it shows the idea. One implementation could be floats- another could
                                  be matricies (here df would return the matrix of partial differentials).

                                  Note that the advantage here is that it's much easier, using modules, to
                                  wrap types. Note that floats don't automatically have epsilon_equals
                                  functions, or solve functions. Let's just consider Newton's Method, as
                                  defined above, with the following definitions:

                                  module Float =
                                  type t = float
                                  type dt = float (* derivitives are floats too *)
                                  let sub a b = a -. b
                                  let solve a b = b /. a
                                  let epsilon_equals a b = (abs_float (a -. b)) < 1e-14;;
                                  end;;

                                  module FloatNewtons = Newtons(Float);;

                                  Note that from inside FloatNewtons.meth, we only have those operations
                                  defined in Algebra- but from outside of FloatNewtons.meth, we know that
                                  it's just dealing with floats. So we pass in a method of type float ->
                                  float, and an initial guess as a float, and it returns a float. Which
                                  means we can write code like:

                                  let f x = (x *. x) -. 2
                                  and df x = 2. *. x
                                  in
                                  exp (FloatNewtons.meth f df 1.0) (* calculate e^sqrt(2) *)

                                  exp being the predefined function that works on floats. Now, let's
                                  consider implementing this as an object, even in an object-dominated
                                  language like Java. Obviously, Newtons is it's only object- but that it
                                  has to work, not on floats, but on an interface. And then we have to
                                  subclass floats to implement the new interface. So far, we're more or
                                  less equivelent to the above solution- an interface instead of a module
                                  signature, and two classes instead of two modules.

                                  But then I go and define:
                                  let ln x = (* find e^y = x *)
                                  FloatNewtons.meth (fun y -> (exp y) -. x) exp 1.0
                                  ;;

                                  The problem here is that the function exp is of type float -> float, not
                                  type SubclassOfFloat -> SubclassOfFloat. Automatic upcasting can deal
                                  with the problem of the parameter being the wrong type, but the float
                                  object allocated inside the exp function, and returned from the exp
                                  function, isn't of type SubclassOfFloat. So it turns out we don't
                                  really want a SubclassOfFloat, we want a FloatDecorator. Now we're off to
                                  the races.

                                  For real fun, try to write a Set.compare function that the compiler can
                                  catch that you're comparing two sets of different types of objects, or two
                                  sets with different orderings. You can do it with C++ templates,
                                  signifigantly less cleanly and with all of the standard problems C++
                                  templates bring with them (massive code bloat, etc.). I'm not sure what
                                  the solution to that problem in Java or Python is.

                                  On a more general note, one of the things you need to get used to in Ocaml
                                  is the lack of golden hammers. The classic example of a golden hammer in
                                  language design is objects- the assumption that everything should be
                                  objects. Ocaml has a surprising lack of golden hammers, and a plethora of
                                  different, more specialized tools. It has both modules and objects.
                                  Because sometimes it's better to use objects, and sometimes it's better to
                                  use modules. And sometimes you use both.

                                  Brian
                                • Jon Harrop
                                  ... Yes. More specifically, that is an example of functors, which are part of ML s module system. ... Nowadays, the advantage of unrolling loops comes from
                                  Message 16 of 17 , Sep 17, 2005
                                  • 0 Attachment
                                    On Sunday 18 September 2005 03:02, Brian Hurt wrote:
                                    > The golden example of what modules are good for is Set.compare, which
                                    > needs to ensure you only compare two sets that hold the same type and have
                                    > the same ordering.

                                    Yes. More specifically, that is an example of functors, which are part of ML's
                                    module system.

                                    > The only valid use I've ever seen for this
                                    > feature is vectors and matricies. But even there I disagree that it's
                                    > that big of an advantage. Unrolling loops is of signifigantly less value
                                    > on modern superscalar, out of order, speculatively executing CPUs. Loop
                                    > branching is highly predictable and therefor pretty much free.

                                    Nowadays, the advantage of unrolling loops comes from optimisations than can
                                    be applied to the unrolled code, rather than diminishing the cost of the
                                    branch. Several bits of the OCaml stdlib have been manually unrolled and this
                                    gives a significant performance boost.

                                    > Another thing modules are good for- changing algebras for your algorithms.

                                    I'm currently using functors to derive progressively more specialised types of
                                    balanced binary tree.

                                    > For real fun, try to write a Set.compare function that the compiler can
                                    > catch that you're comparing two sets of different types of objects, or two
                                    > sets with different orderings. You can do it with C++ templates,
                                    > signifigantly less cleanly and with all of the standard problems C++
                                    > templates bring with them (massive code bloat, etc.). I'm not sure what
                                    > the solution to that problem in Java or Python is.

                                    For Java, almost certainly run-time checking.

                                    > On a more general note, one of the things you need to get used to in Ocaml
                                    > is the lack of golden hammers. The classic example of a golden hammer in
                                    > language design is objects- the assumption that everything should be
                                    > objects. Ocaml has a surprising lack of golden hammers, and a plethora of
                                    > different, more specialized tools. It has both modules and objects.
                                    > Because sometimes it's better to use objects, and sometimes it's better to
                                    > use modules. And sometimes you use both.

                                    Absolutely. Given the choice, I use modules far more than objects.

                                    --
                                    Dr Jon D Harrop, Flying Frog Consultancy Ltd.
                                    Objective CAML for Scientists
                                    http://www.ffconsultancy.com/products/ocaml_for_scientists
                                  • dmitry grebeniuk
                                    Shalom, Chris. ... CC No. I don t *need* them, I can use records or objects instead. It CC just seems like they /might/ be useful. OCaml developers thought
                                    Message 17 of 17 , Sep 19, 2005
                                    • 0 Attachment
                                      Shalom, Chris.

                                      >> You mean you need first-class modules?
                                      CC> No. I don't *need* them, I can use records or objects instead. It
                                      CC> just seems like they /might/ be useful.

                                      OCaml developers thought exactly like you: first-class modules
                                      might be useful, but implementing them is not so easy (and there can
                                      raise problems with typing and so on), and there was no heavy reason
                                      to do it ("might be useful" is not a heavy reason), and other language
                                      capabilities can solve most of problems where such modules can be useful.

                                      --
                                      WBR,
                                      dmitry mailto:gds-mlsts@...
                                    Your message has been successfully submitted and would be delivered to recipients shortly.