Browse thread
Another question about modules
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2008-07-16 (01:59) |
From: | Martin Jambon <martin.jambon@e...> |
Subject: | Re: [Caml-list] Another question about modules |
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/