From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id TAA20606 for caml-redist; Thu, 11 May 2000 19:54:35 +0200 (MET DST) 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 RAA21212 for ; Thu, 11 May 2000 17:59:40 +0200 (MET DST) Received: from isil.localdomain (isil.maya.com [192.70.254.5]) by nez-perce.inria.fr (8.10.0/8.10.0) with ESMTP id e4BFxYP29062 for ; Thu, 11 May 2000 17:59:38 +0200 (MET DST) Received: by isil.localdomain (Postfix, from userid 1000) id 8F842369B4; Thu, 11 May 2000 12:02:06 -0400 (EDT) Sender: weis To: Hongwei Xi Cc: caml-list@inria.fr Subject: Re: reference initialization References: From: John Prevost Date: 11 May 2000 12:02:06 -0400 In-Reply-To: Hongwei Xi's message of "Wed, 10 May 2000 00:50:10 -0400 (EDT)" Message-ID: <871z39m5xd.fsf@isil.localdomain> User-Agent: Gnus/5.0805 (Gnus v5.8.5) Emacs/20.5 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii >>>>> "hx" == Hongwei Xi writes: hx> I have given some thoughts on this one. hx> I find that it is really not a good design choice to hx> initialize every reference in all ML-like languages (yes, I hx> well realize the difficulty in not doing so). Here is my hx> argument. The contrary argument is twofold. First--if you want a reference which you may assign no initial value to, you can use an option. Certainly, this is yet another bit of overhead. (But the good thing is that unlike in Java, you have the choice to always receive a not-null value, and therefore you don't have to check all the time!) Second--as for uninitialized values and loops and the like: try to find a better way to do it. I don't remember the last time I had to use a reference in a loop to get what I wanted. I hardly remember the last time I used a reference. Another reason to prefer this second approach (especially in a loop) is that O'Caml's GC mechanism implies that destructive updates of heap values are slower than variable changes, so the tail-recursive loop: let test l = let rec loop n = function | [] -> n | _ :: t -> loop (n + 1) t in loop 0 l is more efficient than: let test l = let l' = ref l in let n = ref 0 in let n = ref 0 in while !l' <> [] do incr n; l' := List.tl l' done; !n even if you ignore the cost of repeatedly dereferencing--just because of the cost of updating. IMO, it's easier to read, too, though you need to be used to the idiom. Note that a loop like "for i = 1 to n" is as efficient (or more so, possibly, I don't remember) as the equivalent tail recursive loop. Why? Because like the tail recursive call, all updates are temporary storage in the stack, not values in the heap. I have not seen the message you are replying to, so I don't know if it addresses your specific concerns--but it might, I hope, clarify something about ML style type systems that I find very important: the ability to *choose* what features a variable has. (Optional value, mutable value) rather than always having to deal with optional mutable values. John.