Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: skaller <skaller@users.sourceforge.net>
To: Basile STARYNKEVITCH <basile@starynkevitch.net>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] tail rec
Date: Sat, 19 May 2007 22:58:32 +1000	[thread overview]
Message-ID: <1179579512.18119.36.camel@rosella.wigram> (raw)
In-Reply-To: <464E8B1B.7080800@starynkevitch.net>

On Sat, 2007-05-19 at 07:28 +0200, Basile STARYNKEVITCH wrote:
> 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).
> 
> 
> While I also want a similar construct or help, I believe your proposal 
> is wrong. What would be needed is a tailrec operator keyword that makes 
> the compiler check that a given call is in tail position. It is not a 
> function which is tail recursive, it is a call which is.
> 
> In that way, the classical factorial does not have any tail call, so
> 
>    let rec fact n = if n <= 0 then 1 else n * tailrec fact (n - 1)

Felix actually implements this for procedure calls: instead of

	f x;

or

	call f x;

you can write:

	jump f x;

In that context, it is not a compiler *check* but sugar for

	call f x;
	return;

which forces the call to be tail. This is only for procedure
calls though, not function applications.

For Ocaml, it would seem your suggestion should use the
keyword 'return':

let rec fact n = if n <= 0 then 1 else n * return fact (n-1)

is pretty obviously an error, and a C/C++ programmer would
understand this.

The problem with your idea is that it doesn't allow the
programmer to do this:

let rec fact n = ....

Hum. Is this tail rec? I'm a GOOD programmer => I'm LAZY.
With my suggestion I could just write:

let tailrec fact n = ..

to check a claim that 'fact' isn't gratuitously non-tail rec.

The point is, I'm trying to establish a property of the function
implementation: ALL direct recursion is tailed.

In a longer chain of let rec .. and .. and this is only a single
keyword change.

Your suggestion would require writing 'tailrec' or 'return'
in advance for every call .. and no GOOD programmer would
do that because good programmers are lazy.

It would be the other way. First you write 

	let tailrec  ....

and now you get an error because there is a real and essential
non-tail call .. so you annotated that call:

	else x::(f y)

is an error because f isn't tailed but this is right so:

	else x::(rec f y)

has to be written to disable the check on that f.

In fact, I could go a step further and suggest ALL let rec
should be forced to be tailrec, so the ONLY way to do
a non tail call is write

	rec f y

The compiler then issues a warning when 'rec' is used
but the call actually is in tail position.

Unfortunately this breaks existing code so it would have
to be enabled by a compiler switch.

In summary then: what you (Basile) suggest is technically
sound, and could ALSO be implemented!

However the two features address the same issue from
opposite angles. My proposal assures a whole function
or list of function is directly tail rec, whereas
yours is extremely local and checks individual explicitly
annotated calls.

So from a software engineering/development viewpoint
they have quite different utility .. and they're not
exclusive!

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


  reply	other threads:[~2007-05-19 12:58 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-19  2:56 skaller
2007-05-19  5:00 ` [Caml-list] " Erik de Castro Lopo
2007-05-19  5:28 ` Basile STARYNKEVITCH
2007-05-19 12:58   ` skaller [this message]
2007-05-19 20:19     ` Jonathan Bryant
2007-05-19 21:55       ` Erik de Castro Lopo
2007-05-19 22:13       ` skaller
2007-05-19 14:28 ` Oliver Bandel
2007-05-19 14:46   ` Oliver Bandel
2007-05-19 16:06     ` skaller
2007-05-21 12:57 ` Brian Hurt
2007-05-21 13:04   ` Robert Fischer
2007-05-21 13:21     ` Basile STARYNKEVITCH
2007-05-21 13:30       ` Robert Fischer
2007-05-21 14:00         ` Brian Hurt
2007-05-21 13:47       ` Daniel Bünzli
2007-05-21 14:24         ` Christopher L Conway
2007-05-21 14:36           ` Jon Harrop
2007-05-21 14:49             ` Richard Jones
2007-05-21 14:42           ` ocaml faq (was [Caml-list] tail rec) Daniel Bünzli
2007-05-21 15:09             ` Christopher L Conway
2007-05-21 15:17               ` Robert Fischer
2007-05-21 15:27                 ` Daniel Bünzli
2007-05-21 16:23                   ` Richard Jones
2007-05-21 16:59                     ` Robert Fischer
2007-05-21 16:26                   ` Richard Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1179579512.18119.36.camel@rosella.wigram \
    --to=skaller@users.sourceforge.net \
    --cc=basile@starynkevitch.net \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox