Mam trochę kodu w F #, który działa dobrze pod .net, ale przepełnia stos pod Mono. Powiązanym problemem jest to, że wydaje się, że robi tak długo, zanim przestrzeń stosu, podobno do niego dostępna, się skończy (zaczyna się od System.Threading.Thread (ts, 1000000000)). O ile mogę powiedzieć, fałd, w którym umiera, jest rekursywny, a ślad stosu wygląda tak, jakby optymalizacja ogona nie była wykonywana. Używam wersji 3.2.1 z opcją --optimize = tailc.Ogony w Mono
Czy ktoś wie dokładnie, jakie rodzaje połączeń ogonowych usuwają stos wywołujący, a które nie? Lub alternatywnie, jak przydzielić więcej żetonów? Wielkie dzięki.
Jestem świadomy Tailcall elimination in Mono
EDIT: tu jest zarys kodu na żądanie w komentarzach. Jest to część fałdu na dużej strukturze danych, ale wadliwy stacktrace ma tylko mapk i myfold na nim.
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)
Na jakiej platformie działa się Mono? (FreeBSD? OS X? Linux?) –
Linux. 8-rdzeniowy procesor AMD z 64 Gb pamięci RAM, jeśli to robi różnicę. –
Jakiego rodzaju funkcji rekursywnej ogon masz? Czy nazywa się sama, czy też nazywa inną funkcją? (lub czy używają kontynuacji?) (próbuję po prostu dowiedzieć się, co może pójść źle - ponieważ niektóre wywołania ogona są zoptymalizowane przez kompilator F #.) –