caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* try and tail call
@ 2006-10-21 14:00 Christophe Raffalli
  2006-10-21 15:03 ` [Caml-list] " Chris King
  2006-10-22  2:44 ` ketty
  0 siblings, 2 replies; 5+ messages in thread
From: Christophe Raffalli @ 2006-10-21 14:00 UTC (permalink / raw)
  To: caml-list


consider this piece of code:

  (try
    let b = f a in
    (fun () -> g b)
  with
    (fun () -> h a)) ()


Is the call to "g" a tail call and is it omptimized as such ?

If not, how to encode a feature like this one:

  try
    ...
  end
    ... (* the exception raised here are not handles by with but 
propagated *)
  with
    ...

By the way I think this "try ... [end ...] with ..." syntax is usefull 
anyway because you have often a bug when
you write

try
  let b = f a in (* you know this may raise Not_found *)
  g b (* you assume wrongly that this can not raise Not_found *)
with
  Not_found -> h a

The unwanted capture of Not_found could be avoided with try ... end ... 
with ...

Christophe Raffalli

 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] try and tail call
  2006-10-21 14:00 try and tail call Christophe Raffalli
@ 2006-10-21 15:03 ` Chris King
  2006-10-22 17:16   ` Christophe Raffalli
  2006-10-22  2:44 ` ketty
  1 sibling, 1 reply; 5+ messages in thread
From: Chris King @ 2006-10-21 15:03 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: caml-list

On 10/21/06, Christophe Raffalli <raffalli@univ-savoie.fr> wrote:
>
> consider this piece of code:
>
>   (try
>     let b = f a in
>     (fun () -> g b)
>   with
>     (fun () -> h a)) ()
>
>
> Is the call to "g" a tail call and is it omptimized as such ?

Yes, it is, at least in the assembly code output by ocamlopt.  (Neat
trick, btw.)

> If not, how to encode a feature like this one:
>
>   try
>     ...
>   end
>     ... (* the exception raised here are not handles by with but
> propagated *)
>   with
>     ...

What's typically used is something along the lines of:

match (try Some (f a) with Not_found -> None) with
| Some b -> g b
| None -> h a

though I wouldn't be surprised if the method you used above is
slightly faster since it avoids creating unnecessary option objects
(the anonymous functions are statically allocated).

> By the way I think this "try ... [end ...] with ..." syntax is usefull
> anyway because you have often a bug when
> you write
>
> try
>   let b = f a in (* you know this may raise Not_found *)
>   g b (* you assume wrongly that this can not raise Not_found *)
> with
>   Not_found -> h a
>
> The unwanted capture of Not_found could be avoided with try ... end ...
> with ...

Many people agree with you... I find almost always that I want
something like the syntax you describe above, rather than what Caml
provides natively.  Martin Jambon provides an example syntax extension
in his Camlp4 tutorial[1] which allows the use of "let-try-in-with"
blocks:

let b = try f a in g b
with Not_found -> h a

Here, only exceptions raised by "f a" are caught by the try block, and
"g b" occurs in a recursive context.

Hope this helps,
Chris

[1] http://martin.jambon.free.fr/extend-ocaml-syntax.html#lettry


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] try and tail call
  2006-10-21 14:00 try and tail call Christophe Raffalli
  2006-10-21 15:03 ` [Caml-list] " Chris King
@ 2006-10-22  2:44 ` ketty
  2006-10-22 17:08   ` Christophe Raffalli
  1 sibling, 1 reply; 5+ messages in thread
From: ketty @ 2006-10-22  2:44 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 353 bytes --]

Hi,

On 10/21/06, Christophe Raffalli <raffalli@univ-savoie.fr> wrote:
>
>
>   try
>     ...
>   end
>     ... (* the exception raised here are not handles by with but
> propagated *)
>   with
>     ...


You could do it like this:

exception Propagate of exn

try
  ...
  try ...
  with x -> raise (Propagate x)
with
  | Propagate x -> raise x
  | ...

[-- Attachment #2: Type: text/html, Size: 804 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] try and tail call
  2006-10-22  2:44 ` ketty
@ 2006-10-22 17:08   ` Christophe Raffalli
  0 siblings, 0 replies; 5+ messages in thread
From: Christophe Raffalli @ 2006-10-22 17:08 UTC (permalink / raw)
  To: ketty; +Cc: Christophe Raffalli, caml-list


>
> You could do it like this:
>
> exception Propagate of exn
>
> try
>   ...
>   try ...
>   with x -> raise (Propagate x)
> with
>   | Propagate x -> raise x
>   | ...
>
does not work, calls in the second ... are not tail call. (no tail call 
in a try)

Christophe


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] try and tail call
  2006-10-21 15:03 ` [Caml-list] " Chris King
@ 2006-10-22 17:16   ` Christophe Raffalli
  0 siblings, 0 replies; 5+ messages in thread
From: Christophe Raffalli @ 2006-10-22 17:16 UTC (permalink / raw)
  To: Chris King; +Cc: Christophe Raffalli, caml-list

Chris King a écrit :
> On 10/21/06, Christophe Raffalli <raffalli@univ-savoie.fr> wrote:
>>
>> consider this piece of code:
>>
>>   (try
>>     let b = f a in
>>     (fun () -> g b)
>>   with
>>     (fun () -> h a)) ()
>>
>>
>> Is the call to "g" a tail call and is it omptimized as such ?
>
> Yes, it is, at least in the assembly code output by ocamlopt.  (Neat
> trick, btw.)
>
OK, but when g b is in fact a piece of code using a lot of values, it 
seems that the call is no more tail call and
the stack keeps far to much values ... anyway, I am rewriting my code in 
a completely different (and better) way to avoid the problem ...
but it would be nice to know exactly what call are tailcalls and what 
value are stored in closure in all cases.

Christophe


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-10-22 18:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-10-21 14:00 try and tail call Christophe Raffalli
2006-10-21 15:03 ` [Caml-list] " Chris King
2006-10-22 17:16   ` Christophe Raffalli
2006-10-22  2:44 ` ketty
2006-10-22 17:08   ` Christophe Raffalli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).