From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 796CDBC0A for ; Mon, 21 May 2007 14:57:39 +0200 (CEST) Received: from smtp.janestcapital.com (www.janestcapital.com [66.155.124.107]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l4LCvb9a018744 for ; Mon, 21 May 2007 14:57:39 +0200 Received: from [172.25.129.161] [38.96.172.125] by janestcapital.com with ESMTP (SMTPD-9.10) id A74A0248; Mon, 21 May 2007 08:57:46 -0400 Message-ID: <4651973F.9010503@janestcapital.com> Date: Mon, 21 May 2007 08:57:35 -0400 From: Brian Hurt User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.2) Gecko/20040804 Netscape/7.2 (ax) X-Accept-Language: en-us, en MIME-Version: 1.0 To: skaller Cc: caml-list@inria.fr Subject: Re: [Caml-list] tail rec References: <1179543365.26755.33.camel@rosella.wigram> In-Reply-To: <1179543365.26755.33.camel@rosella.wigram> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Miltered: at concorde with ID 46519741.004 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; compiler:01 ocaml:01 ocaml:01 non-trivial:01 recursive:01 tailcall:01 tailcall:01 wrote:01 rec:01 rec:01 caml-list:01 tail:01 tail:01 loops:02 attribute:03 skaller wrote: >I have a silly idea. Introduce a new construction: > >let tailrec f .. > >This is the same as let rec except it checks every direct call to f >is in tail position (and bombs out the compiler if not). > > > I dislike this idea, even for it's stated purpose (to make it easier for people to learn Ocaml). Wether a particular call is a tail call or not is not an attribute of the function, but an attribute of the call. The same function can be called as both a tail call and a non-tail call. If we're going to teach Ocaml, let's at least teach it right. And this is a non-trivial complaint. It's very common for me to write recursive loops where the call inside the function is a tail call, but the original call to the function is not a tail call. So I couldn't write: let tailrec loop i s = if i > 0 then loop (i-1) (s+i) (* proper tail call- it's a loop *) else s in let t = 2 * (loop n 0) in ... (* this is not a tail call *) A better proposal would be one where the call itself is marked as a tailcall, and bombs out if that call isn't. Maybe something like: let rec loop i s = if i > 0 then tailcall loop (i-1) (s+i) (* force this to be a tailcall *) else s in let t = 2 * (loop n 0) in ... (* not a tail call, and that's OK *) At which point I'm neutral on the idea. The rules for what is or isn't a tail call are not complicated. On the other hand, it's a little bit of extra correctness for not much cost. Brian