caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Another question about modules
@ 2008-07-15 20:41 Andre Nathan
  2008-07-15 22:51 ` [Caml-list] " Andre Nathan
  0 siblings, 1 reply; 8+ messages in thread
From: Andre Nathan @ 2008-07-15 20:41 UTC (permalink / raw)
  To: caml-list

Hello

I'm having an issue that is similar to the one reproduced in the code
below:

a.ml:

module SubA :
  sig
    type t
    val f : t -> unit
    val id : t -> int
  end =
  struct
    type t = { id: int }
    let f = B.f
    let id x = x.id
  end

a.mli:

module SubA :
  sig
    type t
    val f : t -> unit
    val id : t -> int
  end

b.ml:

open A
let f x = print_int (SubA.id x)

b.mli:

open A
val f : SubA.t -> unit


When I compile this, I get the following message:

File "a.ml", line 7, characters 2-75:
Signature mismatch:
Modules do not match:
  sig type t = { id : int; } val f : A.SubA.t -> unit val id : t -> int
end
is not included in
  sig type t val f : t -> unit val id : t -> int end
Values do not match:
  val f : A.SubA.t -> unit
is not included in
  val f : t -> unit


Shouldn't "t" (from A.SubA) and A.SubA.t be recognized as the same type
here? I don't understand why they aren't. Is there any workaround for
this issue or is this kind of thing (yet again) a sign that there's
something fishy in my design?

Thanks in advance,
Andre


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

* Re: [Caml-list] Another question about modules
  2008-07-15 20:41 Another question about modules Andre Nathan
@ 2008-07-15 22:51 ` Andre Nathan
  2008-07-16  0:18   ` Ashish Agarwal
  0 siblings, 1 reply; 8+ messages in thread
From: Andre Nathan @ 2008-07-15 22:51 UTC (permalink / raw)
  To: caml-list

I think this is similar to this simpler problem:

a.ml:

  type t = { id: int }
  let f x = print_int x.id; B.f x

a.mli:

  type t
  val f : t -> unit

b.ml:

  let f x = print_int 42

b.mli:

  val f : A.t -> unit


Which results in "This expression has type t but is here used with type
A.t" in a.ml, even though t and A.t are the same type. Is there a
general solution for this kind of situation?

Thanks,
Andre


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

* Re: [Caml-list] Another question about modules
  2008-07-15 22:51 ` [Caml-list] " Andre Nathan
@ 2008-07-16  0:18   ` Ashish Agarwal
  2008-07-16  0:44     ` Andre Nathan
  0 siblings, 1 reply; 8+ messages in thread
From: Ashish Agarwal @ 2008-07-16  0:18 UTC (permalink / raw)
  To: Andre Nathan; +Cc: caml-list

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

Firstly, you have a circular dependency. How are you compiling? That should
be the first error you get.

On Tue, Jul 15, 2008 at 6:51 PM, Andre Nathan <andre@digirati.com.br> wrote:

> I think this is similar to this simpler problem:
>
> a.ml:
>
>  type t = { id: int }
>  let f x = print_int x.id; B.f x
>
> a.mli:
>
>  type t
>  val f : t -> unit
>
> b.ml:
>
>  let f x = print_int 42
>
> b.mli:
>
>  val f : A.t -> unit
>
>
> Which results in "This expression has type t but is here used with type
> A.t" in a.ml, even though t and A.t are the same type. Is there a
> general solution for this kind of situation?
>
> Thanks,
> Andre
>
> _______________________________________________
> 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
>

[-- Attachment #2: Type: text/html, Size: 1845 bytes --]

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

* Re: [Caml-list] Another question about modules
  2008-07-16  0:18   ` Ashish Agarwal
@ 2008-07-16  0:44     ` Andre Nathan
  2008-07-16  1:05       ` Ashish Agarwal
  2008-07-16  1:54       ` Martin Jambon
  0 siblings, 2 replies; 8+ messages in thread
From: Andre Nathan @ 2008-07-16  0:44 UTC (permalink / raw)
  To: Ashish Agarwal; +Cc: caml-list

Hi

I've run this:

ocamlc -c a.mli
ocamlc -c b.mli
ocamlopt -c a.ml

The third command gives the error. I thought that the circular
dependency problem was related only to mutually-dependent types on
separate modules, but I guess I was wrong.

Searching the archives, it seems that the solution is to eliminate the
references to B in A by passing a function argument to A.f, as in

  type t = { id: int }
  let f bfun x = print_int x.id; bfun x

and then in b.ml something like

  let f x = print_endline (string_of_int 42)
  let _ = let a = { A.id = 1 } in A.f f a

That appears to solve the issue, although in my actual code it means
adding an extra parameter to many functions, since the call to what was
B.f here is somewhat deep in the call stack, so maybe there is a better
solution.

Thanks,
Andre

On Tue, 2008-07-15 at 20:18 -0400, Ashish Agarwal wrote:
> Firstly, you have a circular dependency. How are you compiling? That
> should be the first error you get.
> 
> 
> On Tue, Jul 15, 2008 at 6:51 PM, Andre Nathan <andre@digirati.com.br>
> wrote:
>         I think this is similar to this simpler problem:
>         
>         a.ml:
>         
>          type t = { id: int }
>          let f x = print_int x.id; B.f x
>         
>         a.mli:
>         
>          type t
>          val f : t -> unit
>         
>         
>         b.ml:
>         
>          let f x = print_int 42
>         
>         b.mli:
>         
>          val f : A.t -> unit
>         
>         
>         Which results in "This expression has type t but is here used
>         with type
>         A.t" in a.ml, even though t and A.t are the same type. Is
>         there a
>         general solution for this kind of situation?
>         
>         Thanks,
>         
>         Andre
>         
>         _______________________________________________
>         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
>         
> 
> 


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

* Re: [Caml-list] Another question about modules
  2008-07-16  0:44     ` Andre Nathan
@ 2008-07-16  1:05       ` Ashish Agarwal
  2008-07-16 14:05         ` Daniel Bünzli
  2008-07-16  1:54       ` Martin Jambon
  1 sibling, 1 reply; 8+ messages in thread
From: Ashish Agarwal @ 2008-07-16  1:05 UTC (permalink / raw)
  To: Andre Nathan; +Cc: caml-list

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

It seems the circular dependency error is given only when you do

ocamlbuild a.native

If you build byte code or use ocamlc directly as you did, then you get the
type mismatch error. Not sure why. In any case, you should consider
restructuring your code to eliminate the circularity. This is usually
possible and leads to cleaner designs.


On Tue, Jul 15, 2008 at 8:44 PM, Andre Nathan <andre@digirati.com.br> wrote:

> Hi
>
> I've run this:
>
> ocamlc -c a.mli
> ocamlc -c b.mli
> ocamlopt -c a.ml
>
> The third command gives the error. I thought that the circular
> dependency problem was related only to mutually-dependent types on
> separate modules, but I guess I was wrong.
>
> Searching the archives, it seems that the solution is to eliminate the
> references to B in A by passing a function argument to A.f, as in
>
>  type t = { id: int }
>  let f bfun x = print_int x.id; bfun x
>
> and then in b.ml something like
>
>  let f x = print_endline (string_of_int 42)
>  let _ = let a = { A.id = 1 } in A.f f a
>
> That appears to solve the issue, although in my actual code it means
> adding an extra parameter to many functions, since the call to what was
> B.f here is somewhat deep in the call stack, so maybe there is a better
> solution.
>
> Thanks,
> Andre
>
> On Tue, 2008-07-15 at 20:18 -0400, Ashish Agarwal wrote:
> > Firstly, you have a circular dependency. How are you compiling? That
> > should be the first error you get.
> >
> >
> > On Tue, Jul 15, 2008 at 6:51 PM, Andre Nathan <andre@digirati.com.br>
> > wrote:
> >         I think this is similar to this simpler problem:
> >
> >         a.ml:
> >
> >          type t = { id: int }
> >          let f x = print_int x.id; B.f x
> >
> >         a.mli:
> >
> >          type t
> >          val f : t -> unit
> >
> >
> >         b.ml:
> >
> >          let f x = print_int 42
> >
> >         b.mli:
> >
> >          val f : A.t -> unit
> >
> >
> >         Which results in "This expression has type t but is here used
> >         with type
> >         A.t" in a.ml, even though t and A.t are the same type. Is
> >         there a
> >         general solution for this kind of situation?
> >
> >         Thanks,
> >
> >         Andre
> >
> >         _______________________________________________
> >         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
> >
> >
> >
>
>

[-- Attachment #2: Type: text/html, Size: 4475 bytes --]

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

* Re: [Caml-list] Another question about modules
  2008-07-16  0:44     ` Andre Nathan
  2008-07-16  1:05       ` Ashish Agarwal
@ 2008-07-16  1:54       ` Martin Jambon
  2008-07-16 14:15         ` Andre Nathan
  1 sibling, 1 reply; 8+ messages in thread
From: Martin Jambon @ 2008-07-16  1:54 UTC (permalink / raw)
  To: Andre Nathan; +Cc: Ashish Agarwal, caml-list

On Tue, 15 Jul 2008, Andre Nathan wrote:

> Hi
>
> I've run this:
>
> ocamlc -c a.mli
> ocamlc -c b.mli
> ocamlopt -c a.ml
>
> The third command gives the error. I thought that the circular
> dependency problem was related only to mutually-dependent types on
> separate modules, but I guess I was wrong.
>
> Searching the archives, it seems that the solution is to eliminate the
> references to B in A by passing a function argument to A.f, as in
>
>  type t = { id: int }
>  let f bfun x = print_int x.id; bfun x
>
> and then in b.ml something like
>
>  let f x = print_endline (string_of_int 42)
>  let _ = let a = { A.id = 1 } in A.f f a
>
> That appears to solve the issue, although in my actual code it means
> adding an extra parameter to many functions, since the call to what was
> B.f here is somewhat deep in the call stack, so maybe there is a better
> solution.

If you have no other choice, you can do something like that:

--- a.ml ---

let b_fun_ref = ref (fun _ -> assert false)
let b_fun x = !b_fun_ref x

let a_fun x =
   ...
   b_fun
   ...

--- b.ml ---

let b_fun x =
  ...
  A.a_fun
  ...

let () =
   A.b_fun_ref := b_fun



For complex projects, the object system happens to be an excellent way of 
avoiding interdependency problems:

* You define class types early. Not a requirement, but highly recommended.
* You develop independent modules that would work with objects of these
   class types, without worrying about inter-dependencies.
* You just pass objects around, since they carry all the functions needed.
* You can have different implementations of the same class type.
* You can use inheritance.

In my opinion, using OCaml objects makes sense only in large 
projects. It's not theoretically or algorithmically exciting, but makes 
things manageable without magic skills.

I would say that objects are not well-suited to represent nodes 
of low-level data structures, because of performance but 
also because you may want to use pattern matching, circularity and other 
things that tuples, records and variants do better.


I hope you'll find this useful
:-)


Martin


> Thanks,
> Andre
>
> On Tue, 2008-07-15 at 20:18 -0400, Ashish Agarwal wrote:
>> Firstly, you have a circular dependency. How are you compiling? That
>> should be the first error you get.
>>
>>
>> On Tue, Jul 15, 2008 at 6:51 PM, Andre Nathan <andre@digirati.com.br>
>> wrote:
>>         I think this is similar to this simpler problem:
>>
>>         a.ml:
>>
>>          type t = { id: int }
>>          let f x = print_int x.id; B.f x
>>
>>         a.mli:
>>
>>          type t
>>          val f : t -> unit
>>
>>
>>         b.ml:
>>
>>          let f x = print_int 42
>>
>>         b.mli:
>>
>>          val f : A.t -> unit
>>
>>
>>         Which results in "This expression has type t but is here used
>>         with type
>>         A.t" in a.ml, even though t and A.t are the same type. Is
>>         there a
>>         general solution for this kind of situation?
>>
>>         Thanks,
>>
>>         Andre
>>
>>         _______________________________________________
>>         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
>>
>>
>>
>
> _______________________________________________
> 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
>

--
http://wink.com/profile/mjambon
http://mjambon.com/


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

* Re: [Caml-list] Another question about modules
  2008-07-16  1:05       ` Ashish Agarwal
@ 2008-07-16 14:05         ` Daniel Bünzli
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Bünzli @ 2008-07-16 14:05 UTC (permalink / raw)
  To: caml-list caml-list


Le 16 juil. 08 à 03:05, Ashish Agarwal a écrit :

> It seems the circular dependency error is given only when you do
>
> ocamlbuild a.native

Some errors are reported differently when you use ocamlbuild because  
of its automatic dependency analysis, I started a list here [1].

Daniel

[1] http://brion.inria.fr/gallium/index.php/New_kinds_of_build_errors

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

* Re: [Caml-list] Another question about modules
  2008-07-16  1:54       ` Martin Jambon
@ 2008-07-16 14:15         ` Andre Nathan
  0 siblings, 0 replies; 8+ messages in thread
From: Andre Nathan @ 2008-07-16 14:15 UTC (permalink / raw)
  To: Martin Jambon; +Cc: Ashish Agarwal, caml-list

On Wed, 2008-07-16 at 03:54 +0200, Martin Jambon wrote:
> I hope you'll find this useful
> :-)

It was, thanks :)

I am translating this code to ocaml, and the original version is written
in an object-oriented fashion, so there's naturally an impedance
mismatch on the translation... I'll wait a bit to decide if I should use
objects in ocaml or if it's better to try to redesign the code to make
it more... ocamly :p

Thanks again,
Andre


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

end of thread, other threads:[~2008-07-16 14:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-15 20:41 Another question about modules Andre Nathan
2008-07-15 22:51 ` [Caml-list] " Andre Nathan
2008-07-16  0:18   ` Ashish Agarwal
2008-07-16  0:44     ` Andre Nathan
2008-07-16  1:05       ` Ashish Agarwal
2008-07-16 14:05         ` Daniel Bünzli
2008-07-16  1:54       ` Martin Jambon
2008-07-16 14:15         ` Andre Nathan

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