* 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 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
* 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
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