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

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

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

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

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:

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"

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. :)

- GPGPU: http://gpgpu.org/
- GPGPU from nVidia: http://www.nvidia.com/object/GPU_Computing.html
- OpenCL from nVidia: http://developer.nvidia.com/opencl
- GPGPU tutorial I like: http://www.mathematik.uni-dortmund.de/~goeddeke/gpgpu/tutorial.html

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.

- Hadoop and F#: http://blogs.msdn.com/b/carlnol/archive/2011/12/16/hadoop-streaming-and-f-mapreduce.aspx
- MapReduce and F#: http://msdn.microsoft.com/en-us/magazine/gg983490.aspx and http://weblogs.asp.net/podwysocki/archive/2009/03/03/exploring-mapreduce-with-f.aspx

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

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

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,

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:

Please note if you define the pattern Even like the following which take the function f as the second parameter.

enum Numbersbut 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.

{

Odd,

Even,

}

let ( | Even | _ | ) x = if x % 2 = 0 then Some() else Nonethe above sample only return Some() or None. If want to return something more interesting,

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"

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 NoneThere will be an error. So the parameter order really matters when you defined the pattern.

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"

Subscribe to:
Posts (Atom)