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 CAA19028; Wed, 28 Jul 2004 02:38:51 +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 CAA18260 for ; Wed, 28 Jul 2004 02:38:50 +0200 (MET DST) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.203]) by nez-perce.inria.fr (8.12.10/8.12.10) with ESMTP id i6S0cnEV026671 for ; Wed, 28 Jul 2004 02:38:49 +0200 Received: by mproxy.gmail.com with SMTP id 75so119054rnl for ; Tue, 27 Jul 2004 17:38:48 -0700 (PDT) Received: by 10.38.9.76 with SMTP id 76mr29356rni; Tue, 27 Jul 2004 17:38:48 -0700 (PDT) Message-ID: Date: Tue, 27 Jul 2004 20:38:48 -0400 From: John Prevost To: Ocaml Mailing List Subject: Re: [Caml-list] looping recursion In-Reply-To: Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit References: <16646.59534.101085.662305@soggy.deldotd.com> X-Miltered: at nez-perce with ID 4106F599.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Loop: caml-list@inria.fr X-Spam: no; 0.00; prevost:01 prevost:01 caml-list:01 recursion:01 implemented:01 admittedly:01 figuring:01 faq:01 compiler:01 int:01 rec:01 continuation:02 inner:02 exception:02 exception:02 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk Oops. Hit the send button before I meant to... Anyway, that little loop with Boom example should show why the try prevents the inner call from being in tail position: because the try block's expressions can refer to variables in the scope of the original function call, there's a possible continuation (you raise an exception) that brings those variables back into scope. The compiler *could*, I suppose, do some magic and notice when there are no locally bound variables in the exception code path, but even just thinking about how that might be implemented, I think it could get messy. What if it's not always the same try block that's around the call that would otherwise be a tail call? What if the fact that there are multiple exception handlers is important, like: exception Boom2 of int let rec loop2 x = try if x < 100 then loop2 (x + x) else raise (Boom2 0) with Boom2 y -> raise (Boom2 (y + 1)) let use_loop2 x = try loop2 x with Boom2 y -> y In this second example, use_loop2 is using the exceptions in loop2 to calculate the result. (Admittedly, this is a bizarre little setup.) So figuring out if it's "safe" to make it a tail call is hard--not to mention it would probably end up confusing the user even more if it did work only part of the time. (How do I change this so it's recongnized as tail recursive again?) Hope this helps. :) I tried to find an FAQ entry on this, because I thought there was one, but was unable to find anything. 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