Jul 8, 2011

f# essential - part 14 - object oriented without class

JavaScript is duck type language, if you expect a object has a method, you just call object.method. It supports Polymorphism very well, but you don't need implementation inheritance, and you don't need prototype, constructor at all. F#'s record type has similar concept. It is not a class, but it is strongly type, and it is super easy to create, it is like javascript object in strongly type. I think it is the one of best features in F#. Its syntax is as following

type YourRecordType = 
    { member1: type1;
      member2: type2 }

   with 
      member x.function1() = 
         /...

Why it is so interested to me. So first, the definition of record type is similar a interface. So it is strongly type. However, the implementation is not defined. More importantly, it is very easy to create an object, which is the implementation. For example

let yourObject = {
      member1: m1;
      member2: m2;
    }

Woo, that is so simple, if you make a member mutable, you can even switch implementation on the fly.

f# essential - part 13 - pattern matching over .net type

f# use unique syntax to match type like the following,

let divide1 x y =
   try
      Some (x / y)
   with
      | :? System.DivideByZeroException -> printfn "Division by zero!"; None

let result1 = divide1 100 0

let recognizeType (item : obj) = 
    match item with 
    | :? System.Int32 -> printfn "An integer" 
    | :? System.Double -> printfn "A double" 
    | :? System.String -> printfn "A string" 
    | _ -> printfn "Unknown type" 

f# essential - part 12 - function is not method, is not delegate, what is it anyway

As previous post discussed, f# function is not a method, because it support closure, it curry and so on, and .net method does not support these. It looks very much like a delegate (aka lambda, anonymous method) in .net. For example, the following looks like it is a delegate.

open System
open System.Linq

let l = [ 1; 2; 3 ]
let conditionFunction i = i > 1
let c = l.Where(conditionFunction).Count()

But it is not, the case compiler is actually something similar like the following.

let l = [ 1; 2; 3 ]
let conditionFunction i = i > 1
let conditionDelegate = new System.Func<_, _>(conditionFunction)
let c1 = l.Where(conditionDelegate).Count()

So let's use reflector again.

[CompilationMapping(SourceConstructFlags.Module)]
public static class Program
{
    // Methods
    public static bool conditionFunction(int i)
    {
        return (i > 1);
    }

    // Properties
    [CompilationMapping(SourceConstructFlags.Value)]
    public static int c
    {
        get
        {
            return $Program.c@36;
        }
    }

    [CompilationMapping(SourceConstructFlags.Value)]
    public static Func<int, bool> conditionDelegate
    {
        get
        {
            return $Program.conditionDelegate@34;
        }
    }

    [CompilationMapping(SourceConstructFlags.Value)]
    public static FSharpList<int> l
    {
        get
        {
            return $Program.l@32;
        }
    }

    // Nested Types
    [Serializable, CompilationMapping(SourceConstructFlags.Closure)]
    internal sealed class conditionDelegate@34
    {
        // Methods
        internal bool Invoke(int arg)
        {
            return Program.conditionFunction(arg);
        }
    }
 
 public static void main@()
    {
        FSharpList<int> l = l@32 = FSharpList<int>.Cons(1, FSharpList<int>.Cons(2, FSharpList<int>.Cons(3, FSharpList<int>.get_Empty())));
        Func<int, bool> conditionDelegate = conditionDelegate@34 = new Func<int, bool>(new Program.conditionDelegate@34().Invoke);
        int c = c@36 = Program.l.Where<int>(Program.conditionDelegate).Count<int>();
        Program.conditionFunction(1);
    }
}

f# essential - part 11 - ignore function

If you call a function which does not return unit type, you can not call it like the following.

let f1() = 
    //do some side effect stuff
    "f1"
f1()

You have to do the following

f1() |> ignore
//or 
let _ = f1()

f# essential - part 10 - why and when f# does not need null value,

I am surprise when I don't see a need to use null in f#. It use a generic record type "option", which is a very elegant solution to express nullness. In c#, we have reference type and value type, in .net 1/1.1, we express nullness for reference type using "null", in .net 2 above, we can use Nullable type of value type. However, f# unify this using option.

The null keyword is a valid keyword in the F# language, and you have to use it when you are working with .NET Framework APIs or other APIs that are written in another .NET language. The two situations in which you might need a null value are when you call a .NET API and pass a null value as an argument, and when you interpret the return value or an output parameter from a .NET method call. For more please refer to MSDN

f# essential - part 9 - no need to use ref record type in class

As I discussed it in post f# essential - part 5 - mutable, ref, ref record is used for closure. And mutable is similar concept of variable in c#. So that you can not use mutable defined outside of a function. So the following it is wrong

let build_t() = 
    let mutable x = 0
    let t() =
        x <- 1 + x
        printfn "you call me %i time(s)" x
    t

let t =  build_t()
t()

You have to convert it ref record type like the following.

let build_t() = 
    let x = ref 0
    let t() =
        x := 1 + !x
        printfn "you call me %i time(s)" !x

    t

If we define method in a class using F#, and we want to update the member field in a method, should we also use mutable or ref record. It turns out, both of them are supported.

type Foo() = 

    let mutable callT1Count = 0
    let callT2Count = ref 0

    member x.t1() = 
        callT1Count <- callT1Count + 1
        printfn "you call t1 %i time(s)" callT1Count

    member x.t2() = 
        callT2Count := !callT2Count + 1
        printfn "you call t2 %i time(s)" !callT2Count

let f = new Foo()

f.t1()
f.t2()

I used reflector to decompile it to c# code as follow to know that that is implemented in .net

[Serializable, CompilationMapping(SourceConstructFlags.ObjectType)]
public class Foo
{
    // Fields
    internal int callT1Count = 0;
    internal FSharpRef<int> callT2Count = Operators.Ref<int>(0);

    // Methods
    public void t1()
    {
        this.callT1Count++;
        FSharpFunc<int, Unit> func = ExtraTopLevelOperators.PrintFormatLine<FSharpFunc<int, Unit>>(new PrintfFormat<FSharpFunc<int, Unit>, TextWriter, Unit, Unit, int>("you call t1 %i time(s)"));
        int num = this.callT1Count;
        func.Invoke(num);
    }

    public void t2()
    {
        Operators.op_ColonEquals<int>(this.callT2Count, Operators.op_Dereference<int>(this.callT2Count) + 1);
        FSharpFunc<int, Unit> func = ExtraTopLevelOperators.PrintFormatLine<FSharpFunc<int, Unit>>(new PrintfFormat<FSharpFunc<int, Unit>, TextWriter, Unit, Unit, int>("you call t2 %i time(s)"));
        int num = Operators.op_Dereference<int>(this.callT2Count);
        func.Invoke(num);
    }
}

Why mutable is not supported in closure? I think the reason is that when you create an instance of Class, the variable (mutable) is already closed in an instance. Of course, ref type is still supported, but but I think it is double closed. We only need to use variable(mutable) in class.

f# essential - part 8 - talking to c# library

When I found that syntax in f# to support curry, I am very excited. May be we can do the same thing with .net library written in c#. For example, maybe I can use Console.WriteLine as a function to write the following code.

let greet = Console.WriteLine "hello, {0}"
greet "fred"
Console.WriteLine "hello, {0}" "fred"

The compiler give me an error "The value is not a function and can not be applied". So F# function is different from c# method. To call this method, you have to use a tuple syntax. But you can wrap a method easily into a f# function, then you can do curry

Console.WriteLine ("hello, {0}", "fred")

//wrap to a f# function
let writeline message (name: string) = 
    Console.WriteLine(message, name)

let greet = writeline "hello, {0}"
greet "fred"

Jul 5, 2011

f# essential - part 7 Curry

Function application, also sometimes referred to as function composition or composing functions is a big thing in functional programming. One style of composition is called Curry. Curry is feature of lots functional language. When you have a function with two parameter, you can pass one argument to the function, that create an new partial function, which accept one parameter. This partial function is also called curried function. F# support this in a very elegant syntax.

let print x y = 
     printfn "%i" x 
     printfn "%s" y 
let print100y = print 100 //create a curried function 
print100y "hello" //call the curried function 

If you want to fill in the second argument to create a new function, this is also support, like below.

let printx_hello x = dosomething x "hello" 
printx_hello 100

Jul 4, 2011

f# essential - part 6 - tuple

In other language, a method can not return more than one parameter. There are two way to get around this, use passed-by-reference parameter, or use composite type to encapsulate two or more fields in to one object. Both of them are not elegant. However, f# can express this using a very simple syntax to solve this problem, "tuple", which is a strongly typed structure. Here is an example.

let (x, y, z) = (1, 2, 3)
//or
let x, y, z = 1, 2, 3

f# essential - part 5 - mutable, ref

As mentioned in previous post, the "let" syntax define a identifier binding, which is immutable. So it is not variable in the sense of traditional programming. But we can not programming in pure functional language environment. We need to create state, and side effect. F# is pragmatic and play nice with .net framework, so it has to be support variable. To use variable, you just need to add a "mutable" in front identifier, then the identifier became variable in the sense of traditional programming.

let totalArray2 () =
    let array = [|1; 2; 3|]
    let mutable total = 0
    
    for x in array do
        total <- total + x

    printfn "total: %i" total

totalArray2()

However, mutable does not support closure. So if you write the following code, you will get a compiler error.

let totalArray2 () =
    let array = [|1; 2; 3|]
    let mutable total = 0
    
    let sum() = 
        for x in array do
            total <- total + x

    sum()
    printfn "total: %i" total

//The mutable variable 'total' is used in an invalid way. Mutable variables cannot be captured
//by closures. Consider eliminating this use of mutation or using a heap-allocated mutable 
//reference cell via 'ref' and '!'. 

The reason is that closure is bound to identifier but not variable. This identifier need to be immutable. To get around this, we can use immutable record identifier, but a member is mutable.

type MyRefRec<'a> = { mutable myref: 'a }
let totalArray1 () =
    let array = [|1; 2; 3|]
    let total = { myref = 0 }

    let sum() =
        for x in array do
            //now total is not a mutable type, so it can 
            //be captured by closure
            total.myref <- total.myref + x

    sum()

    printfn "total: %i" total.myref

You can see, MyRefRec is generic record. It has only one field. F# provide a shortcut and operator to simplified the above steps. This is "ref". So the above code can not be simplified as below.

let totalArray4 () =
    let array = [|1; 2; 3|]
    let total = ref 0

    let sum() =
        for x in array do
            //now total is ref type 
            total := !total + x

    sum()

    printfn "total: %i" !total

f# essential part 4 - closure

f# support closure. Here is the definition of closure

In computer science, a closure (also lexical closure, function closure or function value) is a function together with a referencing environment for the nonlocal names (free variables) of that function.

In f#, you can define functions within other functions. The inner function can use any identifier in scope, including identifiers defined in outer function. When the inner identifier return as result of the outer function, identifiers defined in outer function is still being captured by the inner function, the inner is called closure.

let buildGreet greeting  = 
    let prefix = Printf.sprintf "%s ," greeting
    let greet name = 
        Printf.sprintf "%s%s" prefix name
    greet //greet is a closure, even the it is return it can still access,


let getHelloMessage = buildGreet "hello"
let message = getHelloMessage "fred"
printfn "%s" message