caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] strange error with packed modules and module type of
@ 2012-05-30  0:25 Milan Stanojević
  2012-05-30  2:30 ` Markus Mottl
  0 siblings, 1 reply; 5+ messages in thread
From: Milan Stanojević @ 2012-05-30  0:25 UTC (permalink / raw)
  To: Caml List

[-- Attachment #1: Type: text/plain, Size: 1619 bytes --]

I'm playing with specifying interfaces for packed modules. Afaik, when
compiling library lib, if there is a file lib.mli, compiler will check
whether library obeys the interface in lib.cmi and then use that as
the interface for the library, otherwise the interface will be
inferred.

This is what I have.
foo.ml:
type t = int
let x = 5

foo.mli:
type t
val x : t

g.mli:
module Foo : sig include module type of Foo end


and I compile the library G like this:
ocamlopt.opt -for-pack G -c foo.mli foo.ml
ocamlopt.opt -c g.mli
ocamlopt.opt -pack -o g.cmx foo.cmx

No problems, everything works.

Now I want to get fancy and I add std.ml, and change g.mli (code
included as packed.tar.gz)

std.ml:
module Foo = Foo

g.mli:
module Std : sig include module type of Std end

and compile similarly like before
ocamlopt.opt -for-pack G -c foo.mli foo.ml
ocamlopt.opt -for-pack G -c foo.cmx std.ml
ocamlopt.opt -c g.mli
ocamlopt.opt -pack -o g.cmx foo.cmx std.cmx

But now I get this helpful error message
File "g.cmx", line 1, characters 0-1:
Error: The implementation (obtained by packing)
       does not match the interface g.mli:
       Modules do not match:
         sig module Foo : sig type t = Foo.t val x : t end end
       is not included in
         sig module Foo : sig type t = Foo.t val x : t end end
       Modules do not match:
         sig type t = Foo.t val x : t end
       is not included in
         sig type t = Foo.t val x : t end
       Type declarations do not match:
         type t = Foo.t
       is not included in
         type t = Foo.t


Does anyone know what is going on here?

Thanks,
   Milan

[-- Attachment #2: packed.tar.gz --]
[-- Type: application/x-gzip, Size: 383 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] strange error with packed modules and module type of
  2012-05-30  0:25 [Caml-list] strange error with packed modules and module type of Milan Stanojević
@ 2012-05-30  2:30 ` Markus Mottl
  2012-06-07 19:53   ` Milan Stanojević
  0 siblings, 1 reply; 5+ messages in thread
From: Markus Mottl @ 2012-05-30  2:30 UTC (permalink / raw)
  To: Milan Stanojević; +Cc: Caml List

On Tue, May 29, 2012 at 8:25 PM, Milan Stanojević <milanst@gmail.com> wrote:
> g.mli:
> module Std : sig include module type of Std end

Btw., this is equivalent and slightly shorter:

  module Std : module type of Std

> and compile similarly like before
> ocamlopt.opt -for-pack G -c foo.mli foo.ml
> ocamlopt.opt -for-pack G -c foo.cmx std.ml
> ocamlopt.opt -c g.mli
> ocamlopt.opt -pack -o g.cmx foo.cmx std.cmx
>
> But now I get this helpful error message
[snip]
> Does anyone know what is going on here?

This seemingly identical construction compiles:

g.mli:
module Std : sig module Foo : module type of Foo end

I guess this also points to what is going wrong.  If I understand this
correctly, the workaround basically says: "Std contains a submodule
Foo which just happens to have the same signature as the module
implemented by foo.ml".  But the broken version says: "Std contains a
submodule Foo which is equivalent to the module implemented by
foo.ml".  This equivalence is somehow lost with packing, hence the
unhelpful error message.  Not sure, but I guess this can be fixed in
the compiler?

Regards,
Markus

-- 
Markus Mottl        http://www.ocaml.info        markus.mottl@gmail.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] strange error with packed modules and module type of
  2012-05-30  2:30 ` Markus Mottl
@ 2012-06-07 19:53   ` Milan Stanojević
  2012-06-07 23:37     ` Jacques Garrigue
  0 siblings, 1 reply; 5+ messages in thread
From: Milan Stanojević @ 2012-06-07 19:53 UTC (permalink / raw)
  To: Markus Mottl; +Cc: Caml List

If I just do
ocamlopt.opt -for-pack G -c foo.mli foo.ml
ocamlopt.opt -pack -o g.cmx foo.cmx

that is, forget all the fancyness with std and specifying interface
for G, the resulting G module has the type
sig module Foo : sig type t = G.Foo.t val x : t end end

So somehow the resulting interface of G is defined in terms of itself?!

Should I just file this problem on ocaml mantis?

p.s the only way I was able to get interface for G is to make a helper
program that uses G with a wrong signature and get the compiler to
give me the type in the error message. Is there a better way?

main:ml
module F : sig type t end = G
let () = ()

$ ocamlopt.opt g.cmx main.ml
File "main.ml", line 1, characters 28-29:
Error: Signature mismatch:
       Modules do not match:
         sig module Foo : sig type t = G.Foo.t val x : t end end
       is not included in
         sig type t end
       The field `t' is required but not provided



On Tue, May 29, 2012 at 10:30 PM, Markus Mottl <markus.mottl@gmail.com> wrote:
> On Tue, May 29, 2012 at 8:25 PM, Milan Stanojević <milanst@gmail.com> wrote:
>> g.mli:
>> module Std : sig include module type of Std end
>
> Btw., this is equivalent and slightly shorter:
>
>  module Std : module type of Std
>
>> and compile similarly like before
>> ocamlopt.opt -for-pack G -c foo.mli foo.ml
>> ocamlopt.opt -for-pack G -c foo.cmx std.ml
>> ocamlopt.opt -c g.mli
>> ocamlopt.opt -pack -o g.cmx foo.cmx std.cmx
>>
>> But now I get this helpful error message
> [snip]
>> Does anyone know what is going on here?
>
> This seemingly identical construction compiles:
>
> g.mli:
> module Std : sig module Foo : module type of Foo end
>
> I guess this also points to what is going wrong.  If I understand this
> correctly, the workaround basically says: "Std contains a submodule
> Foo which just happens to have the same signature as the module
> implemented by foo.ml".  But the broken version says: "Std contains a
> submodule Foo which is equivalent to the module implemented by
> foo.ml".  This equivalence is somehow lost with packing, hence the
> unhelpful error message.  Not sure, but I guess this can be fixed in
> the compiler?
>
> Regards,
> Markus
>
> --
> Markus Mottl        http://www.ocaml.info        markus.mottl@gmail.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] strange error with packed modules and module type of
  2012-06-07 19:53   ` Milan Stanojević
@ 2012-06-07 23:37     ` Jacques Garrigue
  2012-06-08 20:36       ` Milan Stanojević
  0 siblings, 1 reply; 5+ messages in thread
From: Jacques Garrigue @ 2012-06-07 23:37 UTC (permalink / raw)
  To: Milan Stanojević; +Cc: Markus Mottl, Caml List

On 2012/06/08, at 4:53, Milan Stanojević wrote:

> If I just do
> ocamlopt.opt -for-pack G -c foo.mli foo.ml
> ocamlopt.opt -pack -o g.cmx foo.cmx
> 
> that is, forget all the fancyness with std and specifying interface
> for G, the resulting G module has the type
> sig module Foo : sig type t = G.Foo.t val x : t end end
> 
> So somehow the resulting interface of G is defined in terms of itself?!
> 
> Should I just file this problem on ocaml mantis?

This is the right behavior.
To understand it, you should distinguish between the interface (or abstract signature)
and the concrete type of a module (its strengthened signature).
The above type is not the interface of G (which of course should not refer to
itself by name) but its strengthened signature (its exact type).
Since an abstract signature has a meaning independently of the module you use it
for, it is strengthened so that the abstract components of the interface
refer explicitly to the module.

See this dialogue:

# module M : sig type t val x : int end = struct type t = int let x = 1 end;;
module M : sig type t val x : int end
# module N = M;;
module N : sig type t = M.t val x : int end

> p.s the only way I was able to get interface for G is to make a helper
> program that uses G with a wrong signature and get the compiler to
> give me the type in the error message. Is there a better way?

As shown above, you can define another module as an alias.
It will give you the strengthened signature for your original module.

You can also see its abstract signature, using "module type of".

# module type S = module type of M;;
module type S = sig type t val x : int end

Jacques Garrigue

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] strange error with packed modules and module type of
  2012-06-07 23:37     ` Jacques Garrigue
@ 2012-06-08 20:36       ` Milan Stanojević
  0 siblings, 0 replies; 5+ messages in thread
From: Milan Stanojević @ 2012-06-08 20:36 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: Markus Mottl, Caml List

>> Should I just file this problem on ocaml mantis?
>
> This is the right behavior.
> To understand it, you should distinguish between the interface (or abstract signature)
> and the concrete type of a module (its strengthened signature).

I was actually referring to my original problem.
Can you point out what I was doing wrong there?

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-06-08 20:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-30  0:25 [Caml-list] strange error with packed modules and module type of Milan Stanojević
2012-05-30  2:30 ` Markus Mottl
2012-06-07 19:53   ` Milan Stanojević
2012-06-07 23:37     ` Jacques Garrigue
2012-06-08 20:36       ` Milan Stanojević

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).