Pages

Thursday, December 29, 2011

F# ≥ C# (Units of Measure II)


During the Christmas party, I heard a story about my friend got a ticket in Canada. The reason is simple: he drove 100 miles/hour in Ontario Canada where the speed limit is 100 km/hour. :-(

The fine for his case could be $10,000. Fortunately he did not get that scary number on his ticket, but still cost him a fortune.

When I was listening to his story, I realize how important the unit is and how nice F# provide such a feature. Other than the sample in the previous post, the following code snippet shows how a point class can have a unit with it, so that I can define a point class with "cm" unit, I believe this is very useful when doing scientific computation.

[ < Measure > ] type cm
type Point< [ < Measure > ] 't>(x:int< 't >,y:int< 't >) =
    member val X = x with get,set
    member val Y = y with get,set
    static member ( * ) (a:Point<_>,b:int) = Point(b*a.X,b*a.Y) 
let a = Point< cm >(1< cm >, 1< cm >)
a.X <- 3 < cm > 
printfn "%A" a.X
let c = a * 4


Tuesday, December 20, 2011

Use F# to Implement INotifiyCollectionChanged Interface

Today I find the INotifyCollectionChange interface on C# portable library. Because it is the core part of data binding to collection, I decide to implement this interface.

This implementation covers the following concepts, please also scroll down to see the full list.. :-)

  • declare an F# type (see color)
  • declare event (see color)
  • constructor: invoke base method (see color)
  • implement interface (see color)
  • mutable variable (see highlight comment)
  • inheritance (see highlight comment)
The other features are list at end of the page.



type ObservableList < 'T > () = 
    inherit List<'T>()     //inherit List
        
    let collectionChanged = Event< _ , _ > ( )


    let mutable isTriggerEvent = false   //mutable varaible


    new(items) = ObservableList<'T>() then base.AddRange(items)


    interface INotifyCollectionChanged with
        [ <  CLIEvent  > ]
        member this.CollectionChanged = collectionChanged.Publish


    member this.IsTriggerEvent
        with get() = isTriggerEvent
        and set(v) = isTriggerEvent <- v


    member this.Add(n:'T) = 
        base.Add(n)
        this.TriggerAdd(n, base.Count)


    member this.Remove(n:'T) = 
        let index = this.IndexOf(n)
        if index <> -1 then
            let r = base.Remove(n)
            this.TriggerRemove(n, index)
            r
        else 
            false


    member this.Remove(n:'T seq) =
        n |> Seq.iter (this.Remove >> ignore)
    member this.RemoveAt(index) = 
        if this.Count > 0 then 
            if index >=0 && index < this.Count then
                let item = base.[index]
                base.RemoveAt(index)
                this.TriggerRemove(item, index)
    member this.RemoveRange(index, count) = 
        [0..count-1] |> Seq.iter (fun i -> this.RemoveAt(index))


    member this.Sort()= 
        base.Sort()
        this.TriggerReset()
    member this.Sort(comparer) = 
        base.Sort(comparer)
        this.TriggerReset()
    member this.Sort(index, count, comparer) = 
        base.Sort(index, count, comparer)
        this.TriggerReset()


    member this.Reverse() = 
        base.Reverse()
        this.TriggerReset()
    member this.Reverse(index, count) = 
        base.Reverse(index, count)
        this.TriggerReset()


    member this.AddRange(items) = 
        items |> Seq.iter this.Add


    member this.Clear() = 
        base.Clear()
        this.TriggerReset()


    member this.Insert(index, item) = 
        base.Insert(index, item)
        this.TriggerAdd(item, index)
    member this.InsertRange(index, items) = 
       items |> Seq.iteri (fun i item -> this.Insert(index+i, item))


    member this.Item
        with get(i) = base.[i]
        and set i v = 
            let old = base.[i]
            base.[i] <- v
            this.TriggerReplace(v, old, i)


    member private this.TriggerAdd(item, index) =
        if this.IsTriggerEvent then
            collectionChanged.Trigger(this, NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index))
    member private this.TriggerRemove(item, index) =
        if this.IsTriggerEvent then
            collectionChanged.Trigger(this, NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index))
    member private this.TriggerReplace(item, oldItem, index) =
        if this.IsTriggerEvent then
            collectionChanged.Trigger(this, NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem, index))
    member public this.TriggerReset() =
        if this.IsTriggerEvent then
            collectionChanged.Trigger(this, NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset, null, -1))


    static member FromList(items) = ObservableList(items)


(continue)
  • indexed property (see color)
  • trigger event (see color)
  • static method (see color)
  • public and private member (see color)


Monday, December 19, 2011

F# ≥ C# (Meta Programming)

When C# first introduced the reflection, I was amazed by the idea writing or manipulating other programs. I can even read my own program to decide what to do next. This is something called meta programming. F# not only has reflection support but also provides more advanced meta programming technique: Quotations and ReflectedDefinition.

[ < ReflectedDefinition > ]
let myFunction a b c =
...

let myQuotation = < @@ myFunction @@ > 

the myQuotation quotation can be viewed as a parsing tree, from which C++ or SQL code can be generated.

The following code is a skeleton to traverse the quotation tree. You can insert your code in each active pattern. As for the debugging, quotation visualizer can be a good choice.

let rec iterate exp
match exp with
        | DerivedPatterns.Applications (e, ell) ->
            ()
        | DerivedPatterns.AndAlso (e0, e1) ->
            ()
        | DerivedPatterns.Bool e ->
            ()
        | DerivedPatterns.Byte e ->
            ()
        | DerivedPatterns.Char e ->
            ()
        | DerivedPatterns.Double e ->
            ()
        | DerivedPatterns.Int16 e->
            ()
        | DerivedPatterns.Int32 e->
            ()
        | DerivedPatterns.Int64 e ->
            ()
        | DerivedPatterns.OrElse (e0, e1)->
            ()
        | DerivedPatterns.SByte e ->
            ()
        | DerivedPatterns.Single e ->
            ()
        | DerivedPatterns.String e ->
            ()
        | DerivedPatterns.UInt16 e ->
            ()
        | DerivedPatterns.UInt32 e ->
            ()
        | DerivedPatterns.UInt64 e ->
            ()
        | DerivedPatterns.Unit e ->
            ()
        | Patterns.AddressOf address ->
            ()
        | Patterns.AddressSet (exp0, exp1) ->
            ()
        | Patterns.Application (exp0, exp1) ->
            ()
        | Patterns.Call (expOption, mi, expList)  ->
            ()
        | Patterns.Coerce (exp, t)->
            ()
        | Patterns.DefaultValue exp ->
            ()
        | Patterns.FieldGet (expOption, fi) ->
            ()
        | Patterns.FieldSet (expOption, fi, e) ->
            ()
        | Patterns.ForIntegerRangeLoop (v, e0, e1, e2) ->
            ()
        | Patterns.IfThenElse (con, exp0, exp1) ->
            ()
        | Patterns.Lambda (var,body) ->
            ()        
        | Patterns.Let (var, exp0, exp1) ->
            ()
        | Patterns.LetRecursive (tupList, exp) ->
            ()
        | Patterns.NewArray (t, expList) ->
            ()
        | Patterns.NewDelegate (t, varList, exp) ->
            ()
        | Patterns.NewObject (t, expList) ->
            ()
        | Patterns.NewRecord (t, expList) ->
            ()
        | Patterns.NewObject (t, expList) ->
            ()
        | Patterns.NewRecord (t, expList) ->
            ()
        | Patterns.NewTuple expList ->
            ()
        | Patterns.NewUnionCase (t, expList) ->
            ()
        | Patterns.PropertyGet (expOption, pi, expList) ->
            ()
        | Patterns.PropertySet (expOption, pi, expList, e) ->
            ()
        | Patterns.Quote e ->
            ()
        | Patterns.Sequential (e0, e1) ->
            ()
        | Patterns.TryFinally (e0, e1) ->
            ()
        | Patterns.TryWith (e0, v0, e1, v1, e2) ->
            ()
        | Patterns.TupleGet (e, i) ->
            ()
        | Patterns.TypeTest (e, t) ->
            ()
        | Patterns.UnionCaseTest (e, ui) ->
            ()
        | Patterns.Value (obj, t) ->
            ()
        | Patterns.Var v ->
            ()
        | Patterns.VarSet (v, e) ->
            ()
        | Patterns.WhileLoop (e0, e1) ->
            ()
        | _ -> failwith "not supported pattern"
Please note that the parsing tree needs some recursive function, so the iterate function is decorated "rec".


Saturday, December 17, 2011

F# ≥ C# (Concise Syntax)

Constant customer feedback shows F#'s code is more concise, which improves their productivity, but did not give any detailed information. I was always wondering what could make F# concise.


  • Implicit constructor and parameter


Today I declare a class and suddenly realize there is no constructor defined. The constructor is defined between two brackets as shown below:

type Account(name, socialNumber) = ...

the nice part is not just saving some typing, but also the value can be referenced from the code inside type definition. I would say this design is very considerate because those constructor parameters are mostly needed in other parts of the type definition. So instead declaring a class field and expose the field as a property, F# can expose property in one shoot.

type Account(name, socialNumber) =
    member me.Name with get() = name               //expose parameter
    member me.SSN with get() = socialNumber
    member me.Print() = printfn "%s - %d" name socialNumber   // access parameter from constructor


  • this keyword

If you take a closer look at the code above, you might scratch your head wondering what "me" is. Is this VB? No. In F#, you can use any identifier as "this" pointer. In the code above, I use "me", I saw some code use "x". For people from other background, such as VB, class definition is more friendly.

Do forget the "Automatic Generalization" feature, it can save many type definition code or even no need for "var".

Facing a long list of tasks when you open your computer in the morning, are you thinking about improve your productivity and can go home earlier?  :-)




Friday, December 16, 2011

C# type and F# representation


Today I got a question about how to map the following structure to F#. Nothing fancy, but it might help somebody transfer C# skill to F#.

namespace OuterNamespace
{    public sealed class PublicSealedClass { }
     internal sealed class FriendSealedClass { }
     public abstract class PublicAbstractClass { }
     internal abstract class FriendAbstractClass { }
     public class PublicClass { }
     internal class FriendClass { }
     public interface PublicInterface { }
     internal interface FriendInterface { }
     public struct PublicStructure { }
     internal struct FriendStructure { }
     public enum PublicEnum { }
     internal enum FriendEnum { }
}


F# code:



namespace OuterNamespace

[ < Sealed > ]
type PublicSealedClass() = class end

[ < Sealed > ]
type internal FriendSealedClass() = class end

[ < Sealed > ]
type PublicAbstractClass () = class end

[ < AbstractClass > ]
type internal FriendAbstractClass  () = class end

type PublicClass () = class end
type internal FriendClass () = class end

type PublicInterface = interface end
type internal FriendInterface = interface end

[ < StructAttribute > ]
type PublicStructure = struct end

[ < StructAttribute > ]
type internal FriendStructure  = struct end

//we do not support empty enum, so must have something inside.
type PublicEnum =
    Element = 0

type internal FriendEnum  =
    Element = 0


Monday, December 12, 2011

Set break point in a F# function

Not quite sure if this is a big deal, but I always frustrated about how to set a break point in a F# or C# LINQ expression. The mouse click does not always work, but today, but today the keyboard saved me. So


  1. move mouse to the function definition
  2. press "F9"

put a smile on my face..  :-)

Sunday, December 11, 2011

F# ≥ C# (Object Expression)

It has been a long week working on various F# libraries. This blog shows how to use Object Expression to make your code more concise.

I was working on a UI project which involves WPF/Metro command binding. The ICommand interface requires two functions: CanExecute and Execute. Because I already have some functions implemented in the F# project, I'd image implement ICommand in F# project is much easier.

In the WPF converter code snippets, I defined a new type to represent the converter. The code is like:


type StringToVisiblityConverter() =
    inherit ConverterBase(stringToInt>>intToBool>>boolToVisibility |> convert, nullFunction)


This technique is very familiar to C# developer. But I do not like the way the code, especially the inherit ConverterBase. What I really want to say is: create a command with two functions. I ended up with the code like the following:

let createCommand action canExecute=
            let event1 = Event<_, _>()
            {
                new ICommand with
                    member this.CanExecute(obj) = canExecute(obj)
                    member this.Execute(obj) = action(obj)
                    member this.add_CanExecuteChanged(handler) = event1.Publish.AddHandler(handler)
                    member this.remove_CanExecuteChanged(handler) = event1.Publish.AddHandler(handler)
            }

     let myCommand = createCommand
                        (fun _ -> ())
                        (fun _ -> true)
createCommand is a template function which takes two functions as input parameter. This function returns a ICommand object. The myCommand takes two dummy functions and generate a concrete object. I can reference this myCommand object from C# without any problem and the code is more readable than C# version.

As a professional developer, I am interested any technique can make my code more readable. How about you?  :-)

Thursday, December 8, 2011

F# Seattle Group created!


An F# Meetup Group in Seattle has now been launched by Tao Liu on the F# team. (It's only just been created, so get in early!)

Description: Description: http://photos1.meetupstatic.com/photos/event/1/5/b/a/global_78005562.jpeg

If you're in the Seattle or King County area and are interested in F#, then please join, and help get the group off to a great start.
A good meetup group absolutely depends on people participating by giving good presentations, and also on getting F# presenters who are coming through town to come by and give a talk. So start considering what talks you'd like to give, and what other activities you'd like to see the group doing. The meetup group site is a great place to propose new activities, topics and speakers.

There are also other F# meetup groups in New YorkLondon as well as other related F# or functional or .NET meetup groups


Saturday, December 3, 2011

Null character in F#

Unlike C#, null character can be represent as '\0'. in F#, you have to type more zero's.. :)

follow the spec: http://msdn.microsoft.com/en-us/library/dd323829.aspx

let a = '\0' won't compile, but
let a = '\000' will.

Friday, December 2, 2011

F# ≥ C# (Units of Measure)


If you involves in any real world application, the number most likely has a special unit. Adding this unit not only make sure the code is more readable, but also decrease the chance to introduce a bug.

The unit is a compile time feature, so there is no performance hit by using unit.

The simple unit sample will be:
[ < Measure >  ]type litre
[ < Measure > ]type pint
let MeasureSample1() =
   let v1 = 2.
   let v2 = 1.
   let ratio =  1.0 / 1.76056338
   let pintToLitre pints =
       pints * ratio
the v1 and v2 are no longer simple float in the eyes of F# compiler. It is a special value with a unit. More complex samples will be something like the following code snippet.

The unit can not only decorate the simple type like float or int, but also decorate the complex type. The unit in the following code snippet is serving as a parameter to create new types: one is USD bank account and the other is CAD account. Can you easily find something like this in C#?

type AccountState =
   | Overdrawn
   | Silver
   | Gold
[ < Measure >  ] type USD
[ < Measure >  ] type CND
type Account <  [ < Measure > ]  'u > ( ) =
   let mutable balance = 0.0<_>
   member this.State
       with get() =
           match balance with
           | _ when balance <= 0.0<_> -> Overdrawn
           | _ when balance > 0.0<_> && balance < 10000.0<_> -> Silver
           | _ -> Gold
   member this.PayInterest() =
       let interest =
           match this.State with
               | Overdrawn -> 0.
               | Silver -> 0.01
               | Gold -> 0.02
       interest * balance
   member this.Deposit(x:float<_>) =  balance <- balance + x
   member this.Withdraw(x:float<_>) = balance <- balance - x
let MeasureSample4() =
   let account = Account < USD >()
   account.Deposit(LanguagePrimitives.FloatWithMeasure 10000.)
   printfn "us interest = %A" (account.PayInterest())
   account.Withdraw(LanguagePrimitives.FloatWithMeasure 20000.)
   printfn "us interest = %A" (account.PayInterest())
   let canadaAccount = Account < CND >()
   canadaAccount.Deposit(LanguagePrimitives.FloatWithMeasure 10000.)
   canadaAccount.Withdraw(LanguagePrimitives.FloatWithMeasure 500.)
   printfn "canadian interest = %A" (canadaAccount.PayInterest())

Thursday, December 1, 2011

Type infer in LINQ


If you really want to use LINQ in F#, sometimes you have to specify the type:

counts is a Dictionary
counts
        .OrderByDescending(fun x -> x.Value)
        .Take(8)
        .Select(fun x -> x.Key)   //change this line to the line below will make you compile
        .ToList()


.Select(fun (x:KeyValuePair<_,_>) -> x.Key).  


F# ≥ C# (Extend type by properties)

In previous post, the type extension give me a lead to today's blog. C# programmer has been asking for "extension property" since introducing "extension method". Do not wait for C# any more, F# already got the feature:

type SomeClass1(x: int, y: float) =
   new() = SomeClass1(0, 0.)
type SomeClass1 with
    member this.PropertyA
        with get() = "aa"
        and set (v) = ....

this feature is not just for F#. You can invoke this PropertyA from C# as well. Is F# more convenient? :)