Showing posts from February, 2013

Do not use try..finally in recursive functions

Recently I stumbled upon a post in Moirae Software blog. It was about hunting a memory leak in a F# application. What was interesting about the leak that it was caused by non-tail recursive call, however the call seemed to be tail at first glance. It turned out that tail calls is full of rather subtle pitfalls. For further information on the topic I recommend this F# team blog post. As a real engineer, I must check everything myself :) This is the results:
In short, the F# team folks are absolutely right - recursive calls from try...with/try...finally block are not tail. In case of non-async (plane) functions it follows to quick stack overflow exception. In case of async functions things gets a bit more interesting due to continuations created by Async expression builder. Although the continuations have 'fixed' the stack overflow problem (effectively have hidden it), the result is even more dangerous - a memory leak. Conclusion is simple:
Never, ever do recursive calls f…

Crafting Code in F#

Howard Lewis wrote a nice post "Crafting Code in Clojure" about craftable code. He started with a rather ugly Java class and reached a lovely small Clojure solution. I was curious how it would be looked written in F#. Have a look at the result: It's odd that F# core library does not contain Map.keys/Map.values functions. Otherwise, the code would be a bit more shorter. However, maps aren't used in static languages like F# to represent domain types. Hence, the more idiomatic version: (the Fact attribute is from library, and =? operator is from wonderful Unquote one).