Pages

Wednesday, January 25, 2012

Seattle F# User Group Meeting

Seattle F# user group's first meeting will be held on this Saturday. 

If you are in Seattle area, it is time to join.. :-)

http://www.meetup.com/FSharpSeattle/events/49365112/




Sunday, January 22, 2012

MethodInfo <--> Quotation

When I think about the meta programming with quotation, I realize both the reflection and quotation are all meta programming which can provide the program information. Reflection is nothing new and I learn quotation for a while. Now the problem becomes how to make these two systems work together.

thnaks to my colleagues: Keith and Vlad, the solution to this problem is:

From methodInfo to quotation:


    type T =
        []
        static member M(x) = 1 + x
    let methodInfo = typeof< T >.GetMethod("M")
    let e = Quotations.Expr.TryGetReflectedDefinition methodInfo

From quotation to methodInfo:

       match <@ T.M 1 @> with
    | Quotations.Patterns.Call(None, mi, args) -> mi
    | _ -> failwith "Expected Call"





Sunday, January 15, 2012

New Year Resolution: GPU and Cloud

Chinese New Year is the coming. My new year resolution is to get myself dive into the GPU and Cloud with F#. This post is to list some general information for somebody interested to get started. I will constantly update this page. Hopefully can save you a few seconds when doing google search. :)

As my background is mainly on GPU and my first application was using F# on graphics models five years ago, so GPU is my natural expansion. The following list are some interesting GPGPU sites.
Cloud is a new concept and is also new to me. I am more interested in MapReduce and its usage with F#. Also  I am always interested to learn some new programming model other than google's mapReduce model. 

More sample code is coming with powerful F#, stay tune.. :-)

Friday, January 13, 2012

Get active pattern names

When I studied active pattern in F#, I wanted to get the active pattern names. For example:

the function let (|A|B|) x = ()

has  |A|B| active pattern, what I want to do is to get "A" or "B". I have been digging into the reflection for days, but could not find anything. Thanks to Don, I can use the meta programming concept to get this job done. This sample is important not just it can get active pattern name, but also teaches me to use meta programming if reflection does not work.

    /// A generic routine to get the active pattern case name for the result of applying
    /// active pattern 'q' to a given input.
    let nameGetter (q: Quotations.Expr<'T -> 'U>) =
        let meth =
            match q with
            | Quotations.Patterns.Lambda (_,Quotations.Patterns.Call (_,m,_)) -> m
            | _ -> failwith "usage: nameGetter <@ (|A|B|) @>"
        let names = meth.Name.Split( [| '|' |], System.StringSplitOptions.RemoveEmptyEntries)
        let tagProperty = typeof<'U>.GetProperty "Tag"
        if tagProperty = null then failwith "usage: nameGetter <@ (|Total|Active|Pattern|) @>"
        fun (x:'T) ->
            let res = meth.Invoke(null,[| box x |])
            let tag = tagProperty.GetValue(res, null) :?> int
            if tag < 0 || tag >= names.Length then failwith "unexpected tag"
            names.[tag]
       
    let (|A|B|) x =
        match x with
        | 'a' -> A
        | 'b'-> B

    let getName = nameGetter <@ (|A|B|) @>
    getName 'a' // A
    getName 'b' // B


Thursday, January 5, 2012

F# ≥ C# (Active Pattern & Enum)

F# provides an interesting feature called "active pattern". It converts the input data to something different.  One of the interesting usages is to replace the enum. When I program the enum, I always find frustrated to link enum item to its definition. For example, the following enum define a number enum,
enum Numbers
{
     Odd,
     Even,
}
but it does not specify what is Odd or Even. I tried to use attribute or simple comments, but what I really want to get is to get the definition in F# when see the enum item. When I see the active pattern, my eyes lit up. It is true you can use a non-partial pattern to solve this problem, but you can't put more than 8 items, so I choose to use partial pattern so my system can be expanded easily in the future.

let ( | Even | _ | ) x = if x % 2 = 0 then Some() else None
let ( | Odd  | _ | ) x = if x % 2 <> 0 then Some() else None
let f x =
    match x with
    | Even -> "even"
    | Odd -> "odd"
let r = f 2  //r = "even"
the above sample only return Some() or None. If want to return something more interesting,



let f0 x = x % 2 = 0
let f1 x = x % 2 <> 0
let ( | Even | _ | ) (x:int) = if f0(x) then Some(sign x) else None
let ( | Odd  | _ | ) (x:int) = if f1(x) then Some(sign x) else None
let f (x:int) =
    match x with
    | Even sign -> sprintf "even sign=%d" sign
    | Odd sign -> sprintf "odd sign=%d" sign
let r = f 2

noticed the highlighted "sign" is to hold the return result Math.Sign(x).

One last thing I want to try is to pass the function with Even (or Odd) pattern. The new code is:


let f0 x = x % 2 = 0
let f1 x = x % 2 <> 0
let ( | Even | _ | ) f (x:int) = if f(x) then Some(sign x) else None
let ( | Odd  | _ | ) f (x:int) = if f(x) then Some(sign x) else None
let f (x:int) =
    match x with
    | Even f0 (* you can think x passed in here *) sign -> sprintf "even sign=%d" sign
    | Odd f1 (* you can think x passed in here *) sign -> sprintf "odd sign=%d" sign
let r = f 2

Please note if you define the pattern Even like the following which take the function f as the second parameter.
let ( | Even | _ | ) (x:int) f = if f(x) then Some(Math.Sign(x)) else None
There will be an error. So the parameter order really matters when you defined the pattern.






Sunday, January 1, 2012

Active Patterns to transform number



Today I read through the active pattern in F# and was inspired to use it somehow. The following is a very simple sample to convert number. I will continue improving this code and, in the meanwhile, improve my F# skill.

the following code convert int 1002 to string "One Thousand and Two".

let ( | Billion | Million | Thousand | Hundred | Less |) x =
    match x with
    | _ when x >=1000000000 -> Billion
    | _ when x >=1000000 -> Million
    | _ when x >=1000 -> Thousand
    | _ when x >=100 -> Hundred
    | _ -> Less

let rec getStr2 x =
    match x with
    | 0 -> ""
    | 1 -> "One"
    | 2 -> "Two"
    | 3 -> "Three"
    | 4 -> "Four"
    | 5 -> "Five"
    | 6 -> "Six"
    | 7 -> "Seven"
    | 8 -> "Eight"
    | 9 -> "Nine"
    | 10 -> "Ten"
    | 11 -> "Eleven"
    | 12 -> "Twelve"
    | 13 -> "Thirteen"
    | 14 -> "Fourteen"
    | 15 -> "Fifteen"
    | 16 -> "Sixteen"
    | 17 -> "Seventeen"
    | 18 -> "Eighteen"
    | 19 -> "Nineteen"
    | _ when x >= 20 && x < 30 -> "Twenty " + (getStr2 (x%20))
    | _ when x >= 30 && x < 40 -> "Thirty " + (getStr2 (x%30))
    | _ when x >= 40 && x < 50 -> "Forty " + (getStr2 (x%40))
    | _ when x >= 50 && x < 60 -> "Fifty " + (getStr2 (x%50))
    | _ when x >= 60 && x < 70 -> "Sixty " + (getStr2 (x%60))
    | _ when x >= 70 && x < 80 -> "Seventy " + (getStr2 (x%70))
    | _ when x >= 80 && x < 90 -> "Eighty " + (getStr2 (x%80))
    | _ when x >= 90 && x < 100 -> "Ninety " + (getStr2 (x%90))

let rec getStr x =
    let joinStr numberBase word =
        let a = getStr (x % numberBase)
        let b = getStr (x / numberBase)
        sprintf "%s %s %s" b word a
    match x with
    | Less -> getStr2 x
    | Hundred -> joinStr 100 "Hundred"      
    | Thousand -> joinStr 1000 "Thousand"
    | Million -> joinStr 1000000 "Million"
    | Billion -> joinStr 1000000000 "Billion"