Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: michael.le_barbier@laposte.net (Michaël Le Barbier)
To: caml-list@yquem.inria.fr
Subject: Strategy to avoid name collision in signatures
Date: Sat, 03 Nov 2007 23:20:16 +0100	[thread overview]
Message-ID: <86tzo3nf8f.fsf@Llea.celt.neu> (raw)

In some piece of code, I use functors combined with include as a kind
of macro facility. In this scheme, it can happen that an identifier is
exported multiple times from various include directives, this ``name
collision'' is an error, and I am looking for ways to avoid it
whithout much annoyance. (OK, this is very vague, details and example
are coming.)


Let's consider ordered types: one needs only a type and a compare
function to define an ordered type, but one may agree that the
signature

  module type OrderedType.PROTO =
  sig
    type t
    val compare: t -> t -> int
  end

is a bit spartiat and wish for handy shortcuts such as ge, le, gt, lt,
eq (ge means ``greater or equal'', and so on). As a tool to provide
these handy shortcuts in signatures, let's define a OrderedType.Make
functor that takes an OrderedType.PROTO and make an OrderedType.S:

  module type OderedType.S =
    type t
    val compare: t -> t -> int
    val ge: t -> t -> bool
    ...
  end

Now, if one writes a module with a ``compare'' function, he can start
with

  include OrderedType.Make(struct ... end)

to get all these handy shortcuts at hand. Now, let's replicate the
strategy, and define

  module type FunnyType.PROTO = sig type t = ... end
  module type FunnyType.S = sig type t = ... end
  module FunnyType.Make = ...


This is a poor design, as one soon realizes, because one cannot write
something like

  include OrderedType.Make(struct ... end)
  include FunnyType.Make(struct ... end)

By doing so, one gets two definition for type `t', which is an error:

  Multiple definition of the type name t.
  Names must be unique in a given structure or signature.


Of course, one can refrain to name every ``thingie'' type with ``t'',
but this might break other requirements, so one will end up having
duplicate content in module OrderedType. First part is the regular
content above described, second part is replicating the regular
content, with type t getting a new name (e.g. second part consists of
modules S_ALT, Make_alt looking like S and Make with type t renamed to
ordered_type_t; the input signature PROTO doed not need to be
replicated). Having code duplicated is not an agile way of doing
things (first kind of annoyance).

Just saying

  module PreOrderedType = OrderedTypeMake(struct ... end)
  let ge = PreOrderedType.ge
  ...

is totally inefficiant, since any change to OrderedType must be
reflected in every place you use it (second kind of annoyance). Sure,
one can generate appropriate lines automatically, but this is a far
from ideal solution ... let's forget this one!


It is also possible to rely on literate programming tool (such as
NOWEB) to introduce a kind of macro capability and bypass the need of
OrderedType.Make and FunnyType.Make. This is not an ideal solution as
well (third kind of annoyance, cousin of second kind).


I am looking for a way to handle this, that do not deviate too much
from the non-working

  include OrderedType.Make(struct ... end)
  include FunnyType.Make(struct ... end)

(solutions relying on camlp4/5 are an option, yet I cannot use this
tool for now, because of my ignorance.)

BTW, what's the purpose of ``include''? I did not remark any
mention of it in Chailloux et al., and I wonder if the way I try to
use it is weird or regular.

Thanks a lot for having read this long article and for any light you
could bring me up.
-- 
Cheers,
Michaël LB


             reply	other threads:[~2007-11-03 22:15 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-03 22:20 Michaël Le Barbier [this message]
2007-11-03 22:47 ` [Caml-list] " Andrej Bauer
2007-11-04  6:15   ` Michaël Le Barbier
2007-11-04  0:01 ` Julien Moutinho
2007-11-04  7:34   ` Michaël Le Barbier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86tzo3nf8f.fsf@Llea.celt.neu \
    --to=michael.le_barbier@laposte.net \
    --cc=caml-list@yquem.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox