From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id CAA24198; Sun, 4 Aug 2002 02:45:58 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id CAA23891 for ; Sun, 4 Aug 2002 02:45:57 +0200 (MET DST) Received: from laurelin.dementia.org ([208.167.88.73]) by nez-perce.inria.fr (8.11.1/8.11.1) with ESMTP id g740juf12205 for ; Sun, 4 Aug 2002 02:45:56 +0200 (MET DST) Received: by laurelin.dementia.org (Postfix, from userid 1001) id 97A7870CA; Sat, 3 Aug 2002 20:53:07 -0400 (EDT) To: ohl@physik.uni-wuerzburg.de Cc: caml-list@inria.fr Subject: Re: [Caml-list] Creating mutually dependent objects? References: <15690.48916.704957.774489@wptx47.physik.uni-wuerzburg.de> From: John Prevost Date: 03 Aug 2002 20:53:07 -0400 (3.689 UMT) In-Reply-To: <15690.48916.704957.774489@wptx47.physik.uni-wuerzburg.de> Message-ID: <86eldfa1ho.fsf@laurelin.dementia.org> User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk >>>>> "to" == Thorsten Ohl 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, John. ------------------- 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