Adventures in F# - F# 101 Part 2

Update:  Added more topics
I know it's been a little bit too long since I began this series from when I continued, but plenty of distractions came up along the way.  I intend to go a little deeper today into what functional programming means and why you should care.  As always, check out my previous post on the matter here.

Getting Sidetracked

Last night at the DC ALT.NET meeting, Craig Andera and I discussed Lisp, F# and functional programming as a whole.  His language of the year was Lisp and I thought that was an interesting choice of the language to learn, but when you think about it, most good things in programming lead back to SmallTalk and Lisp...  I had been hearing a bit about IronScheme, the IronLisp rewrite,  so of course I had to check it out.  Maybe this will be one of my future languages to learn, but I had enough exposure during my college years to last a little bit, so it's on the plan anyways.

Basic Introduction

So, just in case you missed the idea of functional programming and what it means, I have a few posts on where you should start here:
But, if you really want the condensed version, Bart de Smet has a really nice introduction on functional programming in a series, although incomplete, which you can read here:
Now that I take it you have read that and caught up, let's continue onto today's part.

The Joys of Currying

Where we left off last time was just dealing with the basics of functions and the fact that they are treated as values much like any other "variable".  Now let's get into a popular topic among functional programming, a concept called Currying.  The term was invented back in the earlier days of functional programming after the early logician Haskell Curry.  He's so good in fact that he got not only a functional programming style named after him, but a language named after him with Haskell.  If you listen to the DotNetRocks Episode 310 with Simon Peyton-Jones, you can learn more about that.

Anyhow, the basic idea of Currying is to take a function with multiple arguments and transform it into a function that passes in only one argument, with the other arguments specified in the Currying function itself.  So you can think of it as a function that calls another function and returns a function.  You can think of it also as being a partial function.  So, let's actually get down to it and write some F# code to show how to do this:

#light

let n = 10

let multiply a b = a * b

let multiplyByFive = multiply 5

let result = multiplyByFive 4

printfn "result = %i" result

So, what I accomplished above is that I had a function called multiply that takes two arguments, a and b.  Then I created a currying function called multiplyByFive which curries the multiply function by supplying a five value.  Then I can call the multiplyByFive curried function with a 4 and sure enough the result is 20.

As always, I'm always curious on how it looks through .NET Reflector to see how F# does its magic.  So, let's crack that open and take a look.  First let's look at the tree of Reflector to see what it creates for us:



Now as you can see, it created the multiply function.  Then we also have a multiplyByFive FastFunc function.  The functions get stored in the namespace free area and yet the main function gets placed elsewhere.  Now, let's look at the function implementation itself.



From what you can see, it created a SampleFile class because I created a SampleFile.fs to create the curried functions.

For those of you who are C# buffs, well, you can also do the same in C# with the new anonymous function type, System.Func in .NET 3.5.  Mads Torgersen, the C# Program Manager, noted on his blog quite a while ago asking the question, "Is C# Becoming a Functional Language?".  This post was pretty great and it's unfortunate that he doesn't blog as much as he does.  Remember kids, this isn't as pretty as F# because it's not what C# is really good at, but slowly but surely, functional programming paradigms are slowly seeping into C#.

namespace CSharpCurriedFunctions
{
    public static class CurriedFunctionExtensions
    {
        public static Func<A, Func<B, R>> Curry<A, B, R>(this Func<A, B, R> f)
        {
            return a => b => f(a, b);
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> multiply = (a, b)=> a* b;
            Func<int, Func<int, int>> curriedMultiply = multiply.Curry();
            Func<int, int> multiplyByFive = curriedMultiply(5);
           
            Console.WriteLine("result = {0}", multiplyByFive(4));
        }
    }
}

If you're interested more in doing this with C#, I would suggest you head over to Dustin Campbell's blog and read the post about The Art of Currying.  For those who want to learn more, well, Dustin should be at ALT.NET Open Spaces, Seattle and hopefully will submit an F# topic for us to get our heads around. 

How useful is this in C#?  Well, time will tell, but you could imagine having some search criteria for your repository using curried functions to "overload" with values.  Anything is really possible, but as you can see, it's a lot cleaner in F# and that's where it really shines.

The Odd Tuple

When specifying arguments to any given function, you can specify them without parentheses much as you would in VB.NET should it be a subroutine.  This is really helpful if you want to enable currying and such.  But, you can also specify them as a tuple.  For the math illiterate among you, that simply means a sequence of objects of a specified type.  This you must put within parentheses.  This makes you supply all arguments at once.  A simple example of this would look like this:

#light

let add (a, b) = a + b

let result = add(3, 4)

printfn "result = %i" result

Pretty simple example and of course the result would be 7.

Where is the Returns Department?

As you may have noticed from the functions from above, I never really did specify any return type or return statement.  Implicitly behind the scenes, F# does that for you.  Basically when you define a function, you should indent with a tab and the last assignment becomes your return value.  The return is implicit right after the indenting is ended.  So, let's take a simplistic view of this:

#light

let addThings a b  =
  let c = a + b
  sprintf "result = %i" c

let result = addThings 3 7

print_string result

As you may notice, when using the light syntax (#light), you cannot indent, instead just use two spaces and that should suffice.  Anyhow, you may note, I was doing a simple addition and then my final assignment becomes my return value, which is using the sprintf function, which to you C buffs out there, should look familiar.

Conclusion

I've got a lot more on this topic quite frankly and still just covering the basics of your first F# program.  There is so much to learn on this, but these are the basic building blocks you need to make that leap into functional programming.  It's becoming more interesting year by year as our languages such as Ruby, C# and so on continue to drive towards functional programming, so it's important to grok the fundamentals.  Next time, I hope to cover some recursion stuff, functions, lists and even operators (the really fun stuff).  Until next time...

kick it on DotNetKicks.com

3 Comments

Comments have been disabled for this content.