caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Lauri Alanko <la@iki.fi>
To: caml-list@inria.fr
Subject: [Caml-list] Generative functors how?
Date: Thu, 20 Jan 2011 00:02:27 +0200	[thread overview]
Message-ID: <20110119220226.GM323@melkinpaasi.cs.helsinki.fi> (raw)
In-Reply-To: <20110119123335.GL323@melkinpaasi.cs.helsinki.fi>

On Wed, Jan 19, 2011 at 02:33:35PM +0200, Lauri Alanko wrote:
> Also, the limitations of package type constraints were also somewhat
> surprising. The limitation about unpacking first-class modules in
> functors was thankfully explained in the documentation, and it made
> sense after a moment's reflection. No such rationale was included for
> the rest of the design, so I'd be interested in hearing what's behind
> it.

Regarding the functor restriction, I found this explained in

<http://caml.inria.fr/pub/papers/xleroy-applicative_functors-popl95.pdf>,

section 2.7. It would be nice to have these sorts of background
references mentioned in the manual.

This brings me to a related issue. Functors in O'Caml are applicative,
as described in the above paper. However, I have a bit of
side-effectful magic code whose type-safety depends on functors being
generative (details at the end). What should I do?

One option is using the brand new -no-app-funct compiler option, which
I haven't seen advertised very much. However, this is a global change
(or can -no-app-funct be used consistently with only some modules?),
and although I don't currently see any need for applicative functors,
I dislike the idea of disabling them completely just for the
occasional need for generativity.

The other option is to use first-class modules. Instead of

module F(M : S1) : S2

one would use

val f : (module S1) -> (module S2)

This is arguably a more faithful interface, since the result module
initialization does have side effects, and I think the usual custom is
that functor applications are not really supposed to be observably
effectful. (But is type generation an "effect"?)

The problem with this is firstly that the expressible constraints are
limited. One can do stuff like:

val f : (module S1 with type t = 'a) -> (module S2 with type u = 'a)

but nothing more complex. The second problem is simply that because of
the above functor limitation with first class module unpacking, no
functor can directly use a generative module function like this, so I
have to cascade the change into all my functors that even indirectly
depend on generativity. Again, this is arguably a good thing since
then the generativity is directly expressed in the interfaces, but
it's just much nicer to write:


module F(M : S1) : S2 = struct
  ...
  module MA : SA = ...
  module MB : SB = G(MB)
  ...
end

rather than

let f m =
  let module M = (val m : S1) in
  let module FM = struct
    ...
    module MA : SA = ...
    module MB : SB = (val g (module MA : SA) : SB)
    ...
  end in
  (module FM : S2)

The extra level of indentation is almost a deal-breaker. :)

So, any recommendations for the best approach?


Lauri

P.S. Oh yes, here's a rough sketch of the magic:

module TypeId(Unit : sig end) : sig
  type 'a t
  val gen : unit -> 'a t
  val cast : 'a t -> 'b t -> 'a -> 'b option
end = struct
  type 'a t = int
  let next = ref 0
  let gen () = incr next; !next
  let cast ka kb a =
    if ka = kb then
      Some (Obj.magic a)
    else
      None
end

In this particular case, obviously a single module would be
sufficient, but I want to be able to have generatively multiple
distinct type constructors 'a t, so that typeids used in one context
cannot accidentally be confused by those used in another.

  reply	other threads:[~2011-01-19 22:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-19 12:33 [Caml-list] Limitations of first-class modules Lauri Alanko
2011-01-19 22:02 ` Lauri Alanko [this message]
2011-01-20  1:43 ` Jacques Garrigue
2011-01-20 18:04 ` Alain Frisch
2011-01-21 12:30   ` Jamie Brandon

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=20110119220226.GM323@melkinpaasi.cs.helsinki.fi \
    --to=la@iki.fi \
    --cc=caml-list@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;
as well as URLs for NNTP newsgroup(s).