[Mono-list] Fwd: Tail calls
"Andrés G. Aragoneses"
knocte at gmail.com
Sat Sep 28 10:34:12 UTC 2013
I hope these two links are useful to you:
https://bugzilla.novell.com/show_bug.cgi?id=476785
http://www.mail-archive.com/mono-devel-list@lists.ximian.com/msg21820.html
On 28/09/13 03:37, mono user wrote:
> I replied to jmalcom about a week ago but forgot to cc the list. Seeing
> as no-one else replied to my original post, would it please be at all
> possible for someone to suggest somewhere else I might try asking? I
> just want to understand exactly what makes the difference between a
> tail-call that Mono can eliminate and one it cannot. Many thanks.
>
> ---------- Forwarded message ----------
> From: *mono user* <monouser22 at gmail.com <mailto:monouser22 at gmail.com>>
> Date: Sat, Sep 21, 2013 at 5:24 AM
> Subject: Re: [Mono-list] Tail calls
> To: jmalcolm <malcolm.justin at gmail.com <mailto:malcolm.justin at gmail.com>>
>
>
> Many thanks for replying. There are four tail calls. i) k [] on the
> first line of mapk, ii) mapk f ... on the second line of mapk, iii) the
> call to f passed to the second call to mapk, and iv) the nested call to
> k also on the second line of mapk.
>
> I take it you imply that the code is meant to run out of stack because
> it is broken. That would in many ways be by far the best outcome from my
> point of view. But here is a transcript that shows it works fine under
> .net and f# 3.0. I wonder if you turned tail calls on when compiling?
>
> $ "c:/Program Files (x86)/Microsoft SDKs/F#/3.0/Framework/v4.0/Fsc.exe"
> --tailcalls+ test.fs
> Microsoft (R) F# Compiler version 11.0.50727.1
> Copyright (c) Microsoft Corporation. All Rights Reserved.
>
> Administrator at lab ~
> $ ./test.exe
> Testing depth 1
> Testing depth 2
> Testing depth 4
> Testing depth 8
> Testing depth 16
> Testing depth 32
> Testing depth 64
> Testing depth 128
> Testing depth 256
> Testing depth 512
> Testing depth 1024
> Testing depth 2048
> Testing depth 4096
> Testing depth 8192
> Testing depth 16384
> Testing depth 32768
> Testing depth 65536
> Testing depth 131072
> Testing depth 262144
> Testing depth 524288
> Testing depth 1048576
> Testing depth 2097152
> Testing depth 4194304
> Testing depth 8388608
> Testing depth 16777216
> Testing depth 33554432
>
> Administrator at lab ~
> $
>
>
> On Fri, Sep 20, 2013 at 4:56 AM, jmalcolm <malcolm.justin at gmail.com
> <mailto:malcolm.justin at gmail.com>> wrote:
>
> mono user wrote
> > I wondered if it would be possible to have some advice on how tail
> > recursion elimination works in Mono. I would like to understand under
> > what circumstances Mono can do a tail recursive call without leaving
> > the caller on the stack, and when it cannot. I am afraid I could not
> > find this information anywhere, though I did not try reading the
> > sources. Many thanks in advance.
> >
> > I have a large F# project that I want to run under Mono, and was
> > pleased to see that all 1500+ unit tests passed the first time under
> > 3.2.1. However, my code runs out of stack once applied to non-trivial
> > input, even when I allocate a gigabyte of stack.
> >
> > Here is a cut-down example that started its life as a much larger
> fold
> > (which would be prohibitively expensive to rewrite in imperative
> > style). Under .net it runs to completion, whereas under Mono it dies
> > after i reaches 17. Is there a way of rewriting the map so that it
> > would not leave anything on the stack when evaluating f?
> >
> > [I cannot just use List.map because it stays on the stack while
> > applying f, and so would cause an overflow e.g. if given a function
> > that uses the same call to map again over and over as it descends
> down
> > a data structure.]
> >
> > fsharpc --tailcalls+ tailtest.fs
> > mono --optimize=tailc tailtest.exe
> >
> > let rec mapk f xs k =
> > match xs with
> > [] -> k []
> > | x::xs -> mapk f xs (fun xs' -> f x (fun x' -> (x' ::
> xs') |> k))
> >
> > let test_tail n =
> > printf "Testing depth %u\n" n
> > let xs = [1..n]
> > let expected = List.map (fun x -> x + 1) xs
> > let actual = mapk (fun x k -> k (x + 1)) xs id
> > if expected <> actual then
> > failwithf "Something went badly wrong"
> >
> > for i=0 to 25 do
> > test_tail (1<<<i)
> >
> > _______________________________________________
> > Mono-list maillist - <email>Mono-list at .ximian
>
> > http://lists.ximian.com/mailman/listinfo/mono-list
>
> I do not know F# so I must just be missing it but I do not even see
> the tail
> call in there.
>
> Regardless, I just wanted to throw out there that it fails for me
> under .NET
> as well. It only gets to 13 before I get a StackOverflow.
>
>
>
> --
> View this message in context:
> http://mono.1490590.n4.nabble.com/Tail-calls-tp4660875p4660934.html
> Sent from the Mono - General mailing list archive at Nabble.com.
> _______________________________________________
> Mono-list maillist - Mono-list at lists.ximian.com
> <mailto:Mono-list at lists.ximian.com>
> http://lists.ximian.com/mailman/listinfo/mono-list
>
>
>
>
>
> _______________________________________________
> Mono-list maillist - Mono-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
>
More information about the Mono-list
mailing list