Pages

Sunday, November 27, 2011

F# ≥ C# (Automatic Generalization)

In previous blog post, I use the Chain of Responsibility in a real world example. Five minutes later, I realize F# provides a very nice type generalization which makes my coding much easier than using C#.
let chainTemplate processFunction canContinue s =
    if canContinue s then
        processFunction s
    else s
the input parameter s is generalized so it is just a place holder. In my simple design pattern sample, the type is an integer.
// simple design pattern sample
let canContinueF _ = true
let processF x = x + 1
In the real world sample, s is actually a tuple type.

// real world problem 
let canContinueF (v,unitNameIndex) = v >= unit && unitNameIndex < unitNames.Length-1
let processF (x, unitNameIndex) = (x / unit, unitNameIndex+1)

F#'s automatic generalization feature almost makes my template pattern retired.

If you want to implement the same feature in C#, seems that you have to use generic function. It is true that C# can do the same thing, but readability and productivity will be much lower than the F# version. 

Sample in detail - Chain of Responsibility pattern

this post is to use the Chain of Responsibility pattern to implement a simple function to show the byte in KB, MB, or GB.

In this post, I use the Chain of Responsibility pattern to replace the while loop. The loop itself is done by the composite function defined below. There is another version to composite functions but I found it not easy to debug.

The process will stop when the canContinueF returns false. The result value won't be processed and just slip through other function. The F# provides a good generalization so I do not have to refactor any design pattern code.

let chainTemplate processFunction canContinue s =
    if canContinue s then
        processFunction s
    else s
let composite f a n =
    [1..n] |> Seq.map (fun _ -> f) |> Seq.fold (fun acc n -> acc |> n) a
let getReadableSize value =
    let unitNames = ["B"; "KB"; "MB"; "GB"; "TB"]
    let unit = 1000.
    let canContinueF (v,unitNameIndex) = v >= unit && unitNameIndex < unitNames.Length-1
    let processF (x, unitNameIndex) = (x / unit, unitNameIndex+1)
    let chainFunction = chainTemplate processF canContinueF   //combine two functions to get a chainFunction
    let (v,i) = composite chainFunction value unitNames.Length //value |> chainFunction |> chainFunction
 
    (v, unitNames.[i]) 
let (v,name) = getReadableSize (1001000000000000., 0)
printfn "%f %s" (System.Math.Round(v, 2)) name

Saturday, November 26, 2011

F# ≥ C# (Type extension and GI function)

At previous post, a way to expand class hierarchy and add base class. This post continues to explore the way to expand current system without touching existing code and shows how F# can do the same job with less effort. This post will show who to expand the current type by adding new methods. Also we present a special function can access type without a common base class or interface.

unlike C#'s extension methods, F#'s type extension methods just like the methods on the type. Combining the power from Generic Invoke (GI) function, we can expand current system much easier. The following is the code:
  • the feed function defined at first line is the GI function, it takes any time with a member Feed with signature unit->unit.
  • the original type does not have Feed function. The feed function is from type extension. 
Hopefully from this post and previous post, we have an end-to-end story about how to expand existing system with minimum effort and eventually shows how F# ≥ C#. Please note that CatType and DogType are something not changeable.

// the catType and dogType is from third party and can't change it. 
type CatType =
    | CatA of string
    | CatB of string
    | CatC of string * int
type DogType =
    | DogA of string
    | DogB of string
    | DogC of string * DogType
// code to extension 

let inline feed (x : ^T) = (^T : (member Feed : unit -> unit) (x))
type Animal =
    | Cat of CatType
    | Dog of DogType
// type extension to add a new method: Feed 
type DogType with
    member this.Feed() = printfn "feed dog"
type CatType with
    member this.Feed() = printfn "feed cat"
type Animal with
    member this.Feed() =
        match this with
        | Dog(m) -> feed m
        | Cat(m) -> feed m
 
let dogs = [ DogA("a"); DogB("a1") ] |> List.map Animal.Dog
let cats = [ CatA("b"); CatB("b1") ] |> List.map Animal.Cat
let zoo = dogs @ cats
zoo |> Seq.iter feed

From the previous post, we have the ability to unify two type into a single list structure, which provide the foundation to process them in a single run.

F# ≥ C# (Discriminated Unions)

It was a boring Black Friday with no interesting discount, so I decide to sit down and continue my blog serials about why F# is better than C#.

I came across my colleague's blog about discriminated union in F#. He proposed an interesting idea to use discriminated unions to do a class hierarchy. I really like this idea but the conclusion in his blog disappoints me a little bit.

Whereas a class hierarchy is "open", in that someone else can come along later and add a new subclass, discriminated unions are "closed", in that the author of the type specifies all the alternatives once-and-for-all (analogy: imagine a "sealed" class hierarchy).  This is often the main factor to consider when trying to decide between a class hierarchy and a discriminated union.

I like the elegant discriminated union. Combining with record, it should be more powerful and concise than C#'s class-based design. If the type hierarchy is closed, that will impose a big problem. Making two different types' data into a single list will be very difficult, this problem increases coding effort. For example, if we have CatType and DogType defined as below:


type CatType =
    | CatA of string
    | CatB of string
    | CatC of string * int
type DogType =
    | DogA of string
    | DogB of string
    | DogC of string * int 

let dogs = [ DogA("a"); DogB("a1") ]
let cats = [ CatA("b"); CatB("b1") ]

if we cannot make a new list which can hold dogs and cats, we have to explicitly access the "dogs" and "cats" to apply certain function. I have to make the discriminated union hierarchy "open" and shows how F# is better than C#.

So my problem becomes to find a way to combine these two list into a new list, something like:

let pets = dogs @ cats

in order to make this happen, I introduce a more general discriminated union type.

type Animal =
    | Cat of CatType
    | Dog of DogType
and convert the dogs and cats list to 



let dogs = [ DogA("a"); DogB("a1") ] |> List.map Animal.Doglet cats = [ CatA("b"); CatB("b1") ] |> List.map Animal.Cat


if you compile the code above, you can get a pets whose type is Animal. Good! Now I can show F# = C#. But how about the greater (>) part? 

In C#, in order to make two incompatible types be stored in list, we have to make them have a common base class or interface. If you can change two types' source code, that won't be a big problem. Adding some interfaces to CatType and DogType only makes your code several lines more. In a big team, you will have to ask around to get permission from code owner(s). 

If CatType and DogType is from a third party library, I believe it will be nightmare. F#'s implementation keeps the original implementation untouched and expands (generalizes) the system in a much cleaner way. Is that more productive?





Saturday, November 19, 2011

F# ≥ C# (Record)

Continue previous post, let us continue to explore how easily F# can reduce your coding effort compare to C#.

Until recently I started to notice the record type in F#. Originally I thought it was like C#'s struct or class, but it is not true.

type myPointRecord = { X : float; Y::float }
let pointA = { X = 0; Y= 0 }
let pointB = { X = 0; Y = 0 }

Two points are actually same. The way to prove they are same are very simple and intuitive:

let isEqual = pointA = pointB

The biggest advantage for a record is you can compare its content with "=" operator. I tried to compare two C# structs with "==", but it does not work. It is option to override C#'s equals and GetHashCode function to make a class to support non-reference comparison, but that is a lot of work especially when you are trying to make all your class to support this kind of content comparison.

F# ≥ C# (Tuple and Swap)

F#, as a new language, has something C# cannot easily do. That's what I really love F#, which makes the concise and less bug. Let me give some samples about how F# can do better than C#. Today is the first post for swap and tuple

swap is the simplest operation I could think of. Now I want a general swap function can handle any type. For C# version, object type or generic function can be used. But no matter what,  a temporary variable is needed. Now F# can do something simpler:

          let swap(a,b) = (b,a)
       
the passing parameter is (a,b) and the return value is (b,a). Is that simple?!

One thing always confused me is that (a,b) is a special type called tuple. So the function swap actually takes a single parameter whose type is tuple.

The tuple support more than 2 parameters, so you can do something like:

       let swap2(a,b,c,d,e) = (a,c,b,e,d)

to swap any element in a tuple in a way you prefer.



Friday, November 11, 2011

Reference DLL (mark-of-the-web)

Back from vacation which is always too short.. :-)


from F# Interactive, if there is an error like:

error FS0193: Could not load file or assembly XYZ or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)

The DLL has mark-of-the-web attribute set, the following link here is how to remove the attribute.