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 <[EMAIL PROTECTED]>
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/

_______________________________________________
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

Reply via email to