Tuesday, February 16, 2010

F# Operators

F# Operators:

I've been studying F# and writing more and more code in it, and I'm intrigued by it's features. It has some very powerful and complex (to grasp) features but even combining the most simple features that language provides we can write code in very expressive way and also do some amazing things.

Let's look at F# operators:

In F# being a functional language everything is a function so operators are also functions, the interesting thing is that F# standard operators can be represented in different notations.

So for example the "+" operator can be represented as:

let x = 2 + 3         Infix Notation
let y = (+) 2 3      Postfix Notation

The nice thing about F# is that you can define your own operators that are both Infix and Postfix assignable
and being functions you can do all sorts of operations in them. Besides that F# functions can be curried that means their value can be accumulated and we can pass one parameter to the function.

Let's define our own operator that will measure time taken to execute our functions:

/// Measures time taken to execute a function
let (%%%) func p = 
    let time = new System.Diagnostics.Stopwatch();
    let result = func p;

So what's happening here?

We just created a function that takes 2 parameters (we don't need to tell the compiler what types those are, he will manage to figure that out by itself) that takes our function and the parameters that will be passed to the function, next we create a Stopwatch (this should be familiar from C#, VB.NET perhaps) and start it and call our function with p, what's important here that even if you don't want the function result you need to assign it to something (let result) the compiler will assume that the function result will be a unit (void) and will not let you to measure functions that return something, but after adding the "let result" the compiler will assume that your func will return some generic type (a generic type can be a unit).

Now we can use this operator in Infix and Postfix notation but Postfix just seams better for this kind of operation.

//a function that returns int.
let sum (a, b, c) = a + b + c 
printfn "%A" ((%%%) sum (2,3,4))  

//a function that returns unit (void)
let display text = printfn "Display:::%s" text 
printfn "%A" ((%%%) display "Hello There")

If you are interrested how the code is looking in C# here it is:

[CompilationArgumentCounts(new int[] { 1, 1 })]
public static long op_PercentPercentPercent<a, b>
(FSharpFunc<a, b> func, a p)
    Stopwatch time = new Stopwatch();
    b result = func.Invoke(p);
    return time.ElapsedMilliseconds;

So as you can see this is a standard function for the most part.

This was very brief introduction into F# operators and notations, if I will find time and ideas more will come in this topic, but probably in my next post I'm going to move on to something else regarding F# or C# (of course something great ;-) )

No comments: