English version
Accueil     À propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis à jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml à l'adresse ocaml.org.

Browse thread
[Caml-list] Creating mutually dependent objects?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2002-08-04 (00:45)
From: John Prevost <j.prevost@c...>
Subject: Re: [Caml-list] Creating mutually dependent objects?
>>>>> "to" == Thorsten Ohl <ohl@physik.uni-wuerzburg.de> writes:

    to> I need to create tuples of mutually dependent objects.  A
    to> working implementation adds a mutable instance variable that
    to> is updated after all objects in a tuple have been created.
    to> With a little bit of work, this variable can then be hidden.
    to> However, this is a bit tedious.  Why is the much more elegant
    to> approach using `let rec' forbidden?

Think of it in terms of "if a variable holds a value of type t, the
value *must* be a legal value of that type."  In your example, you'd
like to be able to say:

    to> let rec o1 = new o 1 o2 and o2 = new o 2 o1;;

But this can't be done, because the compiler can't know what you mean
to do with the two "new o" calls.  Consider that instantiating an
object is essentially a function call, and can run arbitrary code.
It's like wanting to be able to say:

let fun test x y = (x,y)

let rec o1 = test 1 o2 and o2 = test 2 o1

You can convert this definition to:

let rec o1 = (1,o2) and o2 = (2,o1)

This statement is indeed legal, if you have -rectypes turned on.  And
class types always hae rectypes turned on.

So what's the problem?  Why doesn't the compiler allow the version
with function calls even though it can be converted to an expression
that's allowed?  Well, this function has the same type as test, but
can't be converted to anything good:

let fun test2 (a,b) y = (a+1,y)

In this case, the two "objects" would have to be constructed by
sharing values.  You can't construct either o1 or o2 first because it
requires a valid, fully constructed copy of the other value before it
can be constructed itself.

So that's what's going on.  Since object constructors are like
functions and can use their arguments in code, the arguments must be
well-typed values.  Value constructors (record {..} expressions, sum
type constructors, and the like) are not allowed to run code--they
just plop the value down in the appropriate place.  And even then, if
they're hidden behind functions, they can't be used this way, since
it's *syntactic analysis* of the code that allows these constructions
to be used in a let rec.

Hope this was helpful,


To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners