What to do if you “just don’t get” F#

by kiteason22. December 2013 08:11

You’ve heard a lot about F#, maybe watched a video, seen a presentation. Maybe even given it a spin.

And you just don’t get it.

But you’re a persistent kind of person and you don’t want to dismiss it out of hand. After all, the rapidly-growing F# community can’t all be wrong. (Can we?)

Here are a few actions you can take which might ‘unblock’ your appreciation of the language. If you give these things a try and you still think ‘meh’, well – good luck to you. Nothing is for everybody!

Unlearn OO

Many developers have grown up in an object-oriented environment. Sometimes they make the mistake of trying immediately to map simple F# syntax into an OO view of the world. (Where are my classes? Where are my encapsulation and data hiding? How do I do inheritance? Tell me now!) Don’t get me wrong: F# has a pretty complete OO story to tell, with interfaces, inheritance and all that good stuff. The trouble is that if you try and learn F# in an OO context from the get-go, you may be trying to do too much at once. Staying close to an OO (C#) view of the world will mean you’ll have the nagging feeling that ‘I could do this quicker in C# - with a single Resharper command’.

It’s better to make a clean break with OO initially. You can work back to a more class-based view of the world later (if you need to).

Action: Forget everything you know about OO to start with. Learn some basic syntax (let, |>, map). Only worry about OO features once you have that basic stuff down.

Forget the functional jargon

The F# world, and functional languages in general, are littered with terms like ‘monads’ and ‘algebraic data types’ – and of course ‘functional’ itself. These can be offputting. So forget them: you don’t need to understand them. How can I be sure? I’m a professional F# developer and I am proud to say I have only the dimmest understanding of both monads and algebraic data types – and many other terms. When you need to start understanding such things, they will come easily. But you can bash out a lot of great code before you get to that stage.

Action: Forget any terminology you might come across that isn’t directly linked to the task at hand.

Expect a Higher Code Density

F# developers tend to do a lot more per line of code than – for example – C# developers. Time after time I have sat in (or given) demos where people coming from other language traditions have clearly been thinking ‘Well that’s nice, but when is (s)he going to show me the real code’. Subconsciously at least, the audience skims over what they think is header information, when in fact they are looking at actual code. I sometimes think that people imagine we are actually ‘cheating’ in some way but nope – we are just doing a hell of a lot per line of code. Less filler, more thriller!

Action: Get used to really looking at every line of code. It’s probably doing more than you think.

Tools Support – Get Over It

Sometimes people get really scared when they learn that they aren’t going to be able to use Resharper in F# code. Relax! You are just moving one tick along the lengthy scale between ‘hipster who edits everything in Notepad’ and ‘corporate type who needs a 4GL to do anything’. Developers can succeed at many points along the scale. Sure we’d like certain basic refactorings (like ‘Rename’ – which is coming, slowly). But this is actually much less of an issue in practice than you might think. This is largely because F# codebases tend to be smaller and simpler, so need less ‘wrangling’. Maybe, just maybe, you’ll actually feel liberated without Resharper questioning your every keystroke.

Incidentally, this comment really only applies to those tools which examine and manipulate the syntax of your code (such as Resharper’s ‘convert to linq expression’). Other types of tool, notably NUnit and the magnificent NCrunch, tend to work just fine with F#.

And if there is a cherished tool which you just can’t let go of, consider requesting the authors to add F# support.  (Or pitch in yourself!)

Action: Be prepared to let go of a few cherished tools.

I hope some of these mental tricks help you get over that initial hump. If they do – welcome aboard!

Tags: ,

Calculating cumulative binomial distribution probability

by kiteason13. October 2013 08:15

On my current project, we recently came across the problem of calculating cumulative binomial distribution probability. The formula for this is relatively straightforward:

 binomial

Any decent programmer could code this up in short order.  In fact we used the function provided by Math.Net.

But there's a problem. Although the final results are modest numbers, some of the intermediate results are... well the term 'astronomical' is too small a word. Our failing case involved calculating 12798! (12798 factorial) - which in case you didn't know is 12798 * 12797 * 12796 ... * 2.  Yeah, that's a big number. According to Wolfram Alpha it works out at

factorial

Compare that to the estimated number of protons in the universe, which is a mere 10^80.

I had a think about this, and I wondered: how is Excel doing this?  Excel has a BINOM.DIST function which calculates for large inputs fine – and fairly quickly.  As luck would have it, Microsoft have actually published the logic they use, here: http://support.microsoft.com/kb/827459

Kudos to them for both developing this algorithm, and publishing it.

I was able to re-implement this in F# relatively easily, and our binomial statistical tests now work just fine.  I didn’t bother to switch to the special algorithm only for large inputs (as Excel does) as for our purposes the results don’t appear to be affected by the different approaches.

Since then I’ve refined the code a bit to make it less repetitive (and not proprietary!).  Here is the entire function.

(Full project with units tests here:  https://github.com/misterspeedy/Binomial)

If anyone fancies adding a more comprehensive set of tests, and incorporating the code into Math.Net, please feel free.

Tags: , ,

You're looking a little flushed

by kiteason8. October 2013 12:52

Recently someone raised the issue of how you might use active patterns to represent the various named Poker hands.  You can’t do it directly, as there are - depending on exactly how you count them - ten named hands.  You can only have 7 tags in a ‘complete’ active pattern.

I decided to experiment with partial active patterns to represent the hand types.  It didn’t end up as the snappy, fssnip-able example I was hoping for.  (Full code here.)  But it was very instructive.

The named poker hands are, in descending order of winning-power:

  • Royal Flush
  • Straight Flush
  • Four of a Kind
  • Full House
  • Flush
  • Straight
  • Three of a Kind
  • Two Pair
  • One Pair
  • High Card

The definitions I’ve used – and many of the test cases – are here: http://en.wikipedia.org/wiki/List_of_poker_hands

So – let the cards speak!  First, discriminated unions (DUs) to represent a suit:

…and a ‘rank’ (e.g. Ace, 10 of…):

(By the way I’ve been told off by @lu_a_jalla for using unicode characters.  Sorry, but they’re just so cute - I couldn’t resist it.)

Types to represent a card and a hand of cards:

And we’ll also need some utility functions which summarise the contents of a set of cards in various ways.  I won’t list them all but you’ll get the idea from these:

Now we can write some partial active patterns to work out the type of a hand.  Each partial active pattern either returns some specific tag (e.g. RoyalFlush), or 'None’. 

Here’s the one for Royal Flush:

…and for Straight Flush:

(Actually I suspect you could get away with not distinguishing between those two as ‘Royal’ is a special case of ‘Straight’.  But we’ll ignore that.)

Here’s the one for Four of a Kind:

You get the idea.  It’s worth saying that these partial active patterns need to be matched in order, because some of the higher hands would also be matched by lower hands’ active patterns.

Now we can get to the real business of Poker: deciding which of two hands wins.  Let’s have yet another DU to represent that:

You’ll see that this DU has a static member which can determine the outcome of comparing two card ranks.  (I initially started off by implementing IComparable, but that took me down the rabbit-hole of having to implement IEquatable and various operators.  So I backed out of that one!)  This member is used when we can determine a winner based on one card from each hands.  Hand-level comparisons are handled like this:

It’s a long gist, but worth it to see how this approach plays out.  You’ll see that I work down the named hands, in descending order of ‘power’.  For each hand I deal with the cases where a hand is pitted against a hand of same type (e.g. Flush with Flush), because for this case we need to go into detail about the cards within the hand.  Then I deal with the cases where we know a hand wins because it is pitted against an inferior hand.

One other subtlety: if you’re eagle eyed you might question why CompareHands takes arguments of Hand rather than arrays of cards.  The reason is because in lines like this:

…if we pass in Hand (whose constructor mandates there there are five cards in the hand) we know we are not going to hit an out of range index looking at the 0th card.

If you look at the source in GitHub you’ll see that I’ve also implemented a ‘showdown’ – in other words comparing a number of hands to determine an overall winner.  But that’s something for another post.

I was impressed by the ability of DUs and partial active patterns to model cards, hands, and the interactions between them.  But I’d be interested to hear if anyone has a more concise solution.

Tags: , , ,

About the author

F# bore

Month List

Page List