caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: Hendrik Tews <tews@os.inf.tu-dresden.de>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] functor substitution gives error
Date: Tue, 7 Sep 2010 19:48:21 +0900	[thread overview]
Message-ID: <29A499AD-55AD-4A5A-84EE-7BE4D0A98B14@gmail.com> (raw)
In-Reply-To: <19588.45205.199003.965321@blau.inf.tu-dresden.de>

On 2010/09/06, at 18:12, Hendrik Tews wrote:

> Hi,
> 
> I have a strange compilation problem, which I suspect to be a
> compiler bug. Consider the following nested functor application
> 
> 
> module A(FreshGram : functor(Unit : sig end) -> Camlp4Syntax) : Camlp4Syntax =
>  FreshGram(struct end)
> 
> module B(FreshGram : functor(Unit : sig end) -> Camlp4Syntax) : Camlp4Syntax =
>  Printers_Ocaml_Make(A(FreshGram))
> 
> 
> This compiles fine, however, when I manually inline functor A:
> 
> 
> module C(FreshGram : functor(Unit : sig end) -> Camlp4Syntax) : Camlp4Syntax =
>  Printers_Ocaml_Make(FreshGram(struct end))
> 
> 
> I get a signature mismatch error in both 3.11.2 and 3.12. I would
> appreciate any explanation for this behaviour.

The reason is that the typing of modules is not closed under substitution.
More precisely, the use of anonymous modules (the "struct end" in your
code) is highly disruptive. It requires all modules around it to have
non-dependent signatures, whereas the ability to express dependency
is the great strength of  applicative functors...
Actually, all the theory was built assuming that there no anonymous modules.

The solution is easy enough: name all modules.

Here you just have to write:

  module Unit = struct end
  module C(FreshGram : functor(Unit : sig end) -> Camlp4Syntax) : Camlp4Syntax =
     Printers_Ocaml_Make(FreshGram(Unit))

Hope this helps.

Jacques Garrigue

> As the names suggest the problem came up with in some Camlp4
> code. Here is a striped down version, which reproduces the
> problem:
> 
> ==============================================================================
> module type Loc = sig               (* simplified version of Camlp4.Sig.Loc *)
>  type t
> end
> 
> module type Camlp4Ast = sig              (* simplified Camlp4.Sig.Camlp4Ast *)
>  module Loc : Loc
> end
> 
> module type Camlp4Syntax = sig        (* simplified Camlp4.Sig.Camlp4Syntax *)
>  module Loc : Loc
>  module Ast : Camlp4Ast with module Loc = Loc
> end
> 
> module type Printers_Ocaml_Make_Sig =      (* .mli of Camlp4/Printers/OCaml *)
>  functor(Syntax : Camlp4Syntax) -> 
> sig
>  include Camlp4Syntax
>    with module Loc = Syntax.Loc
>    and module Ast = Syntax.Ast
> end
> 
> module Printers_Ocaml_Make :                (* .ml of Camlp4/Printers/OCaml *)
>  Printers_Ocaml_Make_Sig = functor(Syntax : Camlp4Syntax) ->
> struct
>  include Syntax
> end
> 
> 
> module A(FreshGram : functor(Unit : sig end) -> Camlp4Syntax) : Camlp4Syntax =
>  FreshGram(struct end)
> 
> module B(FreshGram : functor(Unit : sig end) -> Camlp4Syntax) : Camlp4Syntax =
>  Printers_Ocaml_Make(A(FreshGram))
> 
> module C(FreshGram : functor(Unit : sig end) -> Camlp4Syntax) : Camlp4Syntax =
>  Printers_Ocaml_Make(FreshGram(struct end))
> ===============================================================================
> 
> The error occurs in the last line and says
> 
> Error: Signature mismatch:
>       Modules do not match:
>         sig
>           module Loc : sig type t end
>           module Ast : sig module Loc : sig type t end end
>         end
>       is not included in
>         Camlp4Syntax
>       Modules do not match:
>         sig module Loc : sig type t = Ast.Loc.t end end
>       is not included in
>         sig module Loc : sig type t = Loc.t end end
>       Modules do not match:
>         sig type t = Ast.Loc.t end
>       is not included in
>         sig type t = Loc.t end
>       Type declarations do not match:
>         type t = Ast.Loc.t
>       is not included in
>         type t = Loc.t
> 
> The error goes away with the following version of Printers_Ocaml_Make_Sig:
> 
> module type Printers_Ocaml_Make_Sig = functor(Syntax : Camlp4Syntax) -> 
> sig
>  module Loc : Loc 
>    with type t = Syntax.Loc.t
> 
>  module Ast : Camlp4Ast 
>    with type Loc.t = Syntax.Ast.Loc.t
>    and type Loc.t = Loc.t
> end
> 
> IMHO both Printers_Ocaml_Make_Sig versions should be equivalent:
> in the second version the include is spelled out and the module
> constraints are expanded into type constraints. 
> 
> The error comes back if one changes the order of the type
> constaints for module Ast.
> 
> 
> Bye,
> 
> Hendrik
> 
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


  parent reply	other threads:[~2010-09-07 10:48 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-06  9:12 Hendrik Tews
2010-09-06  9:39 ` [Caml-list] " Daniel Bünzli
2010-09-07 20:46   ` Jacques Garrigue
2010-09-07 10:48 ` Jacques Garrigue [this message]
2010-09-07 13:32   ` Hendrik Tews
2010-09-07 13:54   ` Daniel Bünzli

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=29A499AD-55AD-4A5A-84EE-7BE4D0A98B14@gmail.com \
    --to=garrigue@math.nagoya-u.ac.jp \
    --cc=caml-list@inria.fr \
    --cc=tews@os.inf.tu-dresden.de \
    /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).