Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] functors with style?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Francisco Valverde Albacete <fva@t...>
Subject: Re: [Caml-list] functors with style?
Hi, please read on,

William Harold Newman wrote:

> I have some questions about functorial programming style.
>
> First, a general question. I've used the ocaml-3.02 source as an
> example when I couldn't guess something about normal style, but it
> doesn't seem to use functors much. Since it looks like a great deal of
> work has been done on functors, I expect that there are applications
>

> which depend on them. Is there any publicly available Ocaml code which
> someone could recommend as an example of good functorial style?

But I think functors are about SW reuse, and most of the solutions in the
distribution should be handcrafted...

|Then, some specific questions about this toy confidence_interval.mli:

>
> module type ORDERING =
>   sig
>     type t
>     val are_ordered: t -> t -> bool
>   end

I suggest you adopted a total ordering like the one in Pervasives.compare here...
It's more useful...
module type TOTAL =
    sig
        type t
        val compare : t -> t -> int
        (* See the conventions in the manual *)
    end


> module F:
> functor (Ordering: ORDERING) ->
>   sig
>     type t
>     val new_t: Ordering.t -> Ordering.t -> t
>     val lo: t -> Ordering.t
>     val hi: t -> Ordering.t
>   end
>
> module Int:
>     sig
>       type t
>       val new_t: int -> int -> t
>       val lo: t -> int
>       val hi: t -> int
>     end
>
> module Float:
>     sig
>       type t
>       val new_t: float -> float -> t
>       val lo: t -> float
>     end
>
> As you can see from this example, my impulse is to give names to
> modules like $Confidence_interval.Int$ and $Confidence_interval.Float$
> (which are defined in confidence_interval.ml as $F(Int_ordering)$ and
> $F(Float_ordering)$), but that leads to annoyances:
>  * It's annoying to have to specify the redundant signatures for
>    $Int_confidence_interval$ and $Float_confidence_interval$.
>    They're exactly parallel by intent, so I'd like to
>    construct the signatures with a functor-like thing, but from the
>    syntax in section 6.10 of the manual, I'm pretty sure that I can't.

You should make use of signatures in defining and constraining these modules as
well:
module type INTERVAL =
    sig
        type bound
        type t
        val new_t : bound -> bound -> t
        val hi : t -> bound
        val lo : t -> bound
    end

then build the functor like:

module F:
    functor (Order : TOTAL) ->
    sig
        include INTERVAL with type bound = Order.t
        (* you can constrain further here
    end

module Int : INTERVAL with type bound = int

module Float : INTERVAL with type bound = float
    (* there's a spurious fun "hi" here, but you could take that away as well *)

>  * I can't find a way to use the $F$ to define anything
>    in the top level namespace, e.g. $Int_confidence_interval$
>    or $My_custom_type_confidence_interval$, so I end up
>    with  $Confidence_interval.Int$ here and then, when I use $F$
>    later for other things, $My_custom_type.Confidence_interval$,
>    and the slightly-baroque and not-at-all-parallel names are annoying.

SUpposing:
module TotalInt = struct type t = int let compare = (-) end
module TotalFloat = struct type t = float let compare = (Pervasives.compare: float
-> float -> int)

exist then you shoul be able to make:

module IntInterval = Confidence_interval.F (TotalInt)
module FloatInterval = Confidence_interval.F (TotalFloat)

> It occurs to me that these annoyances could be avoided by keeping the
> functor-constructed modules anonymous, using explicit functor
> expressions (e.g. $Confidence_interval.F(Int_order)$ and
> $Confidence_interval.F(My_custom_type)$) in any code which uses the
> modules. Would that be a good way to do it? Or is there some other
> good way?

If you wnat to re-use any of these XXIntervals, then provide them in a library
module of their own like
interval_basics (this is where I create and export heavily used instantiations of
functors). Otherwise just
use, abuse and dispose of them in an application.

> If I did use explicit functor expressions everywhere, it'd be readable
> enough: if my intent is make the things exactly parallel, then using
> the explicit functor expressions everywhere would make that obvious,
> so I'd be happy. But because my previous closest approach to functors
> was using templates in g++, I'm predisposed to worry about the
> compiler emitting multiple copies of the functor expansion if I don't
> give the functor expansion a home in a particular file. Is that an
> issue in Ocaml?

Hum!! Functor application, I guess, is not to be used casually, as functions
applications. It incurs in heavy costs in my experience... Better instantiate
modules in libraries, and then reuse... You can make some nice initialisation of
objects by mixing module instantiation and object creation within them...

Regards,

            Francisco Valverde


-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr