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