F# tail call optimization issues on Mono - f#

I have an issues concerning the F# on mono. Im doing this course in functional programming at my university. In the course we are using F#, and I uses Xamarin as my editor.
The thing is that we had a lesson on tail recursion, as a tool for getting efficiency. But when you are not able to write your function tail recursive, we had to use continuous, such that we using the heap and not the stack.
This seems not to work on mono 3.10.0 with F# 3.1, I get an System.StackOverflowException. This should be impossible to get, due the continuous should use the heap.
let rec fibC n c =
match n with
|0 -> c 0
|1 -> c 1
|n -> fibC (n-1) (fun v1 -> fibC (n-2) (fun v2 -> c(v1+v2)))

I tested a Fibonacci implementation passing an accumulator instead of a function (continuation) like this:
let fib n =
let rec _fib i (a,b) =
match i with
| 0 -> a
| _ -> _fib (i-1) (b, a+b)
_fib n (0,1)
which worked fine on Mono, i.e. no stack overflow.
So I guess it's only an issue with TCO when using continuations. There's a Xamarin ticket from June 2013 addressing this.

Related

Matching Patterns of Objects in F#

I have zero experience with F#. I started reading F# for C# Developers this weekend.
I had a problem recently (C# Code) where I had to search a list of .NET objects for subsets of objects that matched a certain pattern.
I described it as "regex style matching for objects" in the question. And I did get a great solution that I was happy with, and which seems to perform quite well.
But my recent interest in F# lead me to wonder whether functional programming might have an even better solution.
How would you solve this problem in F#?
Regex Style Pattern Matching in .NET Object Lists
One interesting functional concept that might be useful here is parser combinators. The idea is that you use composable functions that describe how to read some input and then compose parsers for complex patterns from a couple of primitives.
Parsers normally work over strings, but there is no reason why you couldn't use the same method to read a sequence of chromosomes.
With parser combinators, you would rewrite the "regex" as a composition of F# functions. Something like:
sequence [
zeroOrMore (chromosomeType R)
repeat 3 (chromosomeType B)
zeroOrMore (chromosomeType D) ]
This would give you a function that takes a list of chromosome objects and returns the parsed result - the subset of the list. The idea is that functions like zeroOrMore build parsers that detect certain patterns and you compose functions to build a parser - you get a function that you can just run on the input to parse it.
Explaining parser combinators is a bit too long for a SO answer, but it would probably be the most idiomatic F# approach to solving the problem.
This is a comment posted as an answer because it is to long for a comment.
Since it seems that Regular Expressions are working for your problem and that you might suspect that F# pattern matching or active patterns might be a better solution I will add some understanding.
The input R+B{3}D+ as I see it is a formal grammar, and as such will require a parser and evaluation engine, or the creation of something like a finite state machine. Since you know already that .Net Regex can solve this problem, why go through all of the trouble to recreate this with F#. Even using F# pattern matching and active patterns will not be easier than using RegEx.
Thus the problem is basically to convert the C# code to F# code and make use of RegEx. So you are asking us to translate your C# to F# and that is not a valid SO question.
EDIT
As Mark Seemann noted in a comment the only input we have is R+B{3}D+. So if your actual grammar is more complicated than what RegEx can handle then there might be a better solution in F#.
Hopefully this helps you understand what you are asking.
Building on the other answers: Start by implementing a parser combinator allowing composition of the type Parser<'a list>. Add parsers for the minimal grammar required by R+B{3}D+.
type Result<'T> = Success of 'T | Failure
type Parser<'T> = Parser of ('T -> Result<'T * 'T>)
module ListParser =
let (.>>.) (Parser f1) (Parser f2) =
Parser <| fun input ->
match f1 input with
| Failure -> Failure
| Success(value1, rest1) ->
match f2 rest1 with
| Failure -> Failure
| Success(value2, rest2) ->
Success(value1 # value2, rest2)
let oneOrMore what =
let rec aux gotOne acc = function
| x::xs when what = x -> aux true (x::acc) xs
| xss when gotOne -> Success(List.rev acc, xss)
| _ -> Failure
Parser <| aux false []
let exactly what n =
let rec aux i acc = function
| xss when i = 0 -> Success(List.rev acc, xss)
| x::xs when what = x -> aux (i - 1) (x::acc) xs
| _ -> Failure
Parser <| aux n []
Finally create a function which will run the parser repeatedly until the input list is exhausted.
open ListParser
let runForall (Parser f) xss =
let rec aux n acc xss =
match xss, f xss with
| [], _ -> List.rev acc
| _::xs, Failure -> aux (n + 1) acc xs
| _, Success(value, rest) ->
aux (n + List.length value) ((n + 1, value)::acc) rest
aux 0 [] xss
type ChromosomeType = R | B | D
[D;R;R;B;B;B;D;D;B;R;R;B;B;B;D;D;R;R;B;B;B;D;D]
|> runForall (oneOrMore R .>>. exactly B 3 .>>. oneOrMore D)
// val it : (int * ChromosomeType list) list =
// [(2, [R; R; B; B; B; D; D]); (10, [R; R; B; B; B; D; D]);
// (17, [R; R; B; B; B; D; D])]

Why does printing 5000 numbers in F# Interactive cause a StackOverflowException?

Tested on F# 3.1 on windows 7
fsi.PrintLength <- 5000;;
[1..5000];;
Process is terminated due to StackOverflowException.
Session termination detected. Press Enter to restart.
on Mono (F# 4.0), there doesn't seem to be such a limitation.
I think this is a bug in the formatting module that takes care of pretty printing to F# Interactive.
There are some non-tail recursive functions that uses PrintLength e.g. boundedUnfoldL in this line. Implementation of boundedUnfoldL is indeed not tail-recursive:
let boundedUnfoldL
(itemL : 'a -> layout)
(project : 'z -> ('a * 'z) option)
(stopShort : 'z -> bool)
(z : 'z)
maxLength =
let rec consume n z =
if stopShort z then [wordL "..."] else
match project z with
| None -> [] // exhaused input
| Some (x,z) -> if n<=0 then [wordL "..."] // hit print_length limit
else itemL x :: consume (n-1) z // cons recursive...
consume maxLength z
I don't know why it doesn't blow up on Mono. It would be surprising if F# Interactive on Mono can handle length > 5000 successfully.
You can report this as a bug to https://visualfsharp.codeplex.com/workitem/list/basic.

Tailcalls in Mono

I have some code in F# that works fine under .net but overflows the stack under Mono. A related issue is that it seems to do so long before the stack space supposedly available to it runs out (it is started with System.Threading.Thread (ts, 1000000000)). As far as I can tell, the fold it dies in is tail-recursive and the stack trace looks as if tail-optimization is not being done. I am running 3.2.1 with --optimize=tailc.
Does somebody please know exactly what kinds of tail calls remove the calling stack and which do not? Or alternatively how to allocate more stack? Many thanks.
I am aware of Tailcall elimination in Mono
EDIT: here is an outline of the code as requested in the comments. It is a part of a fold over a large data structure, but the failing stacktrace has just mapk and myfold on it.
let rec myfold f x k =
let rec mapk xs k =
match xs with
[] -> k []
| x::xs -> mapk xs (fun xs' -> myfold f x (fun x' -> (x' :: xs') |> k))
...
mapk (...) ( ... >> k)
As far as I know, --optimize=tailc isn't a supported F# compiler flag.
I don't think there's a way to enable/disable tailcall-optimization support in Mono (from the command-line, anyway); the F# compiler flag to enable tail-call optimizations is --tailcalls+, but according to Compiler Options (F#) that's on by default.
I think your best choices to get this resolved are:
File a bug report with Xamarin
Go on the #monodev IRC channel (on irc.gnome.org) and see if one of the developers/contributors there can help you out.

why do continuations avoid stackoverflow?

I've been trying to understand continuations / CPS and from what I can gather it builds up a delayed computation, once we get to the end of the list we invoke the final computation.
What I don't understand is why CPS prevents stackoverflow when it seems analogous to building up a nested function as per the naive approach in Example 1. Sorry for the long post but tried to show the idea (and possibly where it goes wrong) from basics:
So:
let list1 = [1;2;3]
Example 1: "Naive approach"
let rec sumList = function
|[] -> 0
|h::t -> h + sumList t
So when this runs, iteratively it results in:
1 + sumList [2;3]
1 + (2 + sumList [3])
1 + (2 + (3 + 0))
So the nesting (and overflow issues) can be overcome by Tail Recursion - running an accumulator i.e.
"Example 2: Tail Recursion"
let sumListACC lst =
let rec loop l acc =
match l with
|[] -> acc
|h::t -> loop t (h + acc)
loop lst 0
i.e,
sumList[2;3] (1+0)
sumList[3] (2+1)
sumList[] (3+3)
So because the accumulator is evaluated at each step, there is no nesting and we avoid bursting the stack. Clear!
Next comes CPS, I understand this is required when we already have an accumulator but the function is not tail recursive e.g. with Foldback. Although not required in the above example, applying CPS to this problem gives:
"Example 3: CPS"
let sumListCPS lst =
let rec loop l cont =
match l with
|[] -> cont 0
|h::t -> loop t (fun x -> cont( h + x))
loop lst (fun x -> x)
To my understanding, iteratively this could be written as:
loop[2;3] (fun x -> cont (1+x))
loop[3] (fun x ->cont (1+x) -> cont(2+x))
loop[] (fun x -> cont (1+x) -> cont(2+x) -> cont (3+x)
which then reduces sequentially from the right with the final x = 0 i.e:
cont(1+x)-> cont(2+x) -> cont (3+0)
cont(1+x)-> cont(2+x) -> 3
cont(1+x) -> cont (2+3)
...
cont (1+5) -> 6
which I suppose is analogous to:
cont(1+cont(2+cont(3+0)))
(1+(2+(3+0)))
correction to original post - realised that it is evaluated from the right, as for example replacing cont(h +x) with cont(h+2*x) yields 17 for the above example consistent with: (1+2*(2+2*(3+2*0)))
i.e. exactly where we started in example 1, based on this since we still need to keep track of where we came from why does using it prevent the overflow issue that example 1 suffers from?
As I know it doesn't, where have I gone wrong?
I've read the following posts (multiple times) but the above confusion remains.
http://www.markhneedham.com/blog/2009/06/22/f-continuation-passing-style/
http://codebetter.com/matthewpodwysocki/2008/08/13/recursing-on-recursion-continuation-passing/
http://lorgonblog.wordpress.com/2008/04/05/catamorphisms-part-one/
What happens is quite simple.
.NET (and other platforms, but we're discussing F# right now) stores information in two locations: the stack (for value types, for pointer to objects, and for keeping track of function calls) and the heap (for objects).
In regular non-tail recursion, you keep track of your progress in the stack (quite obviously). In CPS, you keep track of your progress in lambda functions (which are on the heap!), and tail recursion optimization makes sure that the stack stays clear of any tracking.
As the heap is significantly larger than the stack, it is (in some cases) better to move the tracking from the stack to the heap - via CPS.

Return item at position x in a list

I was reading this post While or Tail Recursion in F#, what to use when? were several people say that the 'functional way' of doing things is by using maps/folds and higher order functions instead of recursing and looping.
I have this function that returns the item at position x in a list:
let rec getPos l c = if c = 0 then List.head l else getPos (List.tail l) (c - 1)
how can it be converted to be more functional?
This is a primitive list function (also known as List.nth).
It is okay to use recursion, especially when creating the basic building blocks. Although it would be nicer with pattern matching instead of if-else, like this:
let rec getPos l c =
match l with
| h::_ when c = 0 -> h
| _::t -> getPos t (c-1)
| [] -> failwith "list too short"
It is possible to express this function with List.fold, however the result is less clear than the recursive version.
I'm not sure what you mean by more functional.
Are you rolling this yourself as a learning exercise?
If not, you could just try this:
> let mylist = [1;2;3;4];;
> let n = 2;;
> mylist.[n];;
Your definition is already pretty functional since it uses a tail-recursive function instead of an imperative loop construct. However, it also looks like something a Scheme programmer might have written because you're using head and tail.
I suspect you're really asking how to write it in a more idiomatic ML style. The answer is to use pattern matching:
let rec getPos list n =
match list with
| hd::tl ->
if n = 0 then hd
else getPos tl (n - 1)
| [] -> failWith "Index out of range."
The recursion on the structure of the list is now revealed in the code. You also get a warning if the pattern matching is non-exhaustive so you're forced to deal with the index too big error.
You're right that functional programming also encourages the use of combinators like map or fold (so called points-free style). But too much of it just leads to unreadable code. I don't think it's warranted in this case.
Of course, Benjol is right, in practice you would just write mylist.[n].
If you'd like to use high-order functions for this, you could do:
let nth n = Seq.take (n+1) >> Seq.fold (fun _ x -> Some x) None
let nth n = Seq.take (n+1) >> Seq.reduce (fun _ x -> x)
But the idea is really to have basic constructions and combine them build whatever you want. Getting the nth element of a sequence is clearly a basic block that you should use. If you want the nth item, as Benjol mentioned, do myList.[n].
For building basic constructions, there's nothing wrong to use recursion or mutable loops (and often, you have to do it this way).
Not as a practical solution, but as an exercise, here is one of the ways to express nth via foldr or, in F# terms, List.foldBack:
let myNth n xs =
let step e f = function |0 -> e |n -> f (n-1)
let error _ = failwith "List is too short"
List.foldBack step xs error n

Resources