Sunday, September 22, 2013

STM: F# vs Haskell

STM is a very nice parallel programming model used intensively in Haskell and Clojure. There's a F# implementation which can be found in FSharpx library.

Today I'm going to test performance of both the Haskell and the F# STMs. The test is very simple - read a couple TVars, check their equality, then write them back incremented by 1, repeat a million times.

First, the Haskell code:

So, it took about 170 ms. OK, now F#: It took about 1,6 seconds which is an order of magnitude slower than the Haskell result. It's rather frustrating.

Sunday, September 1, 2013

Grouping consecutive integers in F# and Haskell

Let's look at what F# and Haskell can offer us while reimplementing grouping consecutive integers in C# algorithm.

F#:

Haskell:

For my current taste, the Haskell version is more readable due to the awesome separate type annotation and to the lovely Erlang-style pattern matching on function arguments.

Saturday, August 24, 2013

Haskell: performance

It turned out that it's not Haskell who was slow in my previous Fibonacci test. It was my lack of Haskell knowledge. Haskell has two integral types - Int, which has bounds -2147483648..2147483647 and Integer, which is unbounded. Both types implement Integral type class, so out fib function can be defined in terms of this type class:
OK, now we can test performance of the function parametrizing it with the two concrete types. Integer first:
We get our previous result ~15 seconds which is rather slow. Now test it with Int type:
Whoa! The Int type is ~6 times faster than Integer! And with result of 2.8 seconds Haskell's took the third position in our small rating :) Current list (in seconds):
  • C# - 1.26
  • F# - 1.38
  • Nemerle - 1.45
  • Haskell - 2.8
  • Clojure - 9
  • Erlang - 17
  • Ruby - 60
  • Python - 120





Saturday, August 17, 2013

Beginning Haskell

Okey, it passed about a year I started learn and use F# and it's now time to learn Haskell. As usual, I started from the naive Fibonacci function: The performance in this particular algorithm is not fantastic, it's actually ~4 times slower than F#. It's OK for now.

Sunday, June 16, 2013

The Either monad: we can finally get rid of exceptions

Jessica Kerr recently wrote on the very interesting topic: what the best way to get rid of exceptions and of the mess they introduce into the program flow.
Simply put, she's gently introduced the Either monad in Scala language.
Although I find Scala to be a very advanced OO language with reasonably good FP support, I don't think the code Jessica used in her post can force anybody to change the habitual exception handling flow in favor of the Data Flow. This's why: Scala is too verbose.
But this is not the case in a more advanced functional language like OCaml, Haskell or F#. Let's take a look what the latter can offer:

The code is much more clear because of using the monadic function composition (>=>) and the amazing type inference.
Conclusion: if you do use monands, use their full power.

Saturday, May 4, 2013

FSharpx: Validating with applicative functors

I've been recently interested in Functors, applicatives and monads, especially in context of complex validation. FSharpx has a validation module (among many other wonderful features). I've played with it a bit:

Applicatives can be combined using several operators and functions, for example all following functions are equivalent:

Sunday, February 17, 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 from try...with/try...finally blocks!
  • Never, ever use either 'use' nor 'use!' in recursive functions!


Saturday, February 2, 2013

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 xUnit.net library, and =? operator is from wonderful Unquote one).

Thursday, January 24, 2013

Joe Armstrong about learning

‎"Programming today hasn't improved much in the last 20 years - it was mess then and it's still a mess. IDE's and revision control systems have just made matters worse - now you have all the old versions of the mess as well as the mess itself, and the IDE means you can't even see the mess. The best IDE in the world is your BRAIN - it's a zillion times better than these clicky things. 

Notice there is no quick fix here - if you want a quick fix go buy "learn PHP in ten minutes" and spend the next twenty years googling for "how do I compute the length of a string"" -- Joe Armstrong, creator of Erlang

http://erlang.org/pipermail/erlang-questions/2013-January/071949.html

Sunday, January 6, 2013

Optimized Fibonacci in F#

Vlad Chistyakov suggested to use [Memoze] macro attribute to speed up the Nemerle version of Fibonacci function. I don't think it's a very good idea to use macros in situations where plane functions work just well. Look at an optimized F# Fibonacci:

The speed is fantastic, as expected: