Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] classes vs modules
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Markus Mottl <mottl@m...>
Subject: Re: [Caml-list] classes vs modules
On Sun, 27 May 2001, Tom _ wrote:
>  -- treapobj is considerably more useful and flexible
>     because the comparison function can be
>     computed dynamically; this means that the
>     compiler cannot statically determine all the
>     comparison functions that treapobj might be
>     used with, but as noted above, ML compilers
>     avoid taking advantage of that knowledge
>     anyway.

You can also make use of "dynamic" comparison functions using local
modules, e.g.:

  let f lt1 lt2 =
     let module Int1Treap = Treap (struct let lt = lt1 end) in
     let module Int2Treap = Treap (struct let lt = lt2 end) in
     ...

> So, my question is: am I overlooking something?
> Is there some way of getting the generality of the
> object-based implementation out of pre-existing
> module-based code without incurring significant
> overhead?

Well, it depends on what you mean with "overhead". OCaml may spend ages
generating closures depending on the particular case of local modules.

This, however, is a one-time effort (per call to enclosing function):
later calls to module functions do not cost any additional overhead. If
such modules are heavily used after their creation, you'll hardly
notice any difference to "statically" (misleading - see below) created
modules. With objects, you'll have a noticable overhead for every method
call (and for parameterization anyway).

> It seems that the object-style approach is somewhat like a limited
> form of first-class modules.  Is there any more information about the
> relationship between these approaches?

There is still a distinction between modules that are parameterized at
runtime and modules that can be passed to and from functions. In fact,
closures arising from functor applications are _always_ computed at
runtime even at the toplevel, because this could cause side effects
like I/O (though the latter can be considered bad practice). In the
toplevel case these closures are only generated once and for all, but
people usually don't notice the startup overhead of their programs.

In short: your object-style approach is not really so much different from
the local module approach with the exception that object method lookups
come with the usual overhead. The only bonus for objects is that they can
reside within a polymorphic function, staying polymorphic themselves. I
am not sure whether this is really such a useful thing to have.

Out of curiousity, would it be unsound to allow functions like the
following:

  let f (cmp : 'a -> 'a -> bool) =
    let module SomeSet =
      Set.Make (struct type t = 'a let compare = cmp end) in
    ()

The compiler complains with:

  File "foo.ml", line 2, characters 49-51:
  Unbound type parameter 'a

This, however, is not true (in any case): 'a is bound by the explicit
function annotation. I am currently too lazy trying to find an example
where the type system could get a hole when the upper function were
allowed. Is there any?

Regards,
Markus Mottl

P.S.:  Please correct me if I have misexplained things...

-- 
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl
-------------------
To unsubscribe, mail caml-list-request@inria.fr.  Archives: http://caml.inria.fr