Thursday, May 22, 2008
One of the commonly used design pattern is the Observer Pattern because its just so easy to use and implement. The classic OO way of implementing it is to have a Subject class having the methods "Attach", "Detach" and "Notify". The Subject class usually stores the observers in an ArrayList and then when it needs to update the observers then iterates on the list and invokes the "Update" method of each observer. See diagram below.

In C#, a more elegant way of implementing this is with Events and Delegates. Here's a nice sample implementation. By using using events and delegates, the code became a lot shorter and straight-forward
In F#, implementation of the observer pattern became even more concise and elegant. How come? Take a look at the code below.
line 11 : A clean and simple (one-liner!) way of creating events and triggers. A call to IEvent.create is all it takes
lines 16 & 17 : calling "trigger" and passing the correct parameters notifies all listeners of the changeEvent. We don't even need to check if there are listeners attached. If this is in C# we need to make changeEvent != null otherwise a NullReferenceException will be raised.
lines 28 & 30. In F# Events are first-class values , that means we can pass it around and more importantly we can do all sorts of wonderful things with it using the IEvent module. For example, in line 28, we filtered the event, basically saying that we are only interested in events of the Remove operation. Now imagine if the Operation type (an enum actually, lines 5-7 ) contains more items such as Update, Delete, AddedThenRemoved, AddedThenUpdated, RemovedAddedAgainThenFinallyUpdated ... (you get what I mean). If we want to a handle only the Remove operation then we'd have no choice but to break it down using an if-elseif-else or switch-case construct. It would work but its not going to be pretty. And this is where IEvent.filter shines. With just a single line of code (line 28, please ignore the comment above it.), we were able to filter out the event that we are only interested in. Apart from filtering, IEvent also allows us to map, partition, fold, split etc. events.
lines 25 & 30 : 2 ways of attaching to an Event. I'm not very sure what's the difference between these 2. (TODO : Investigate)

Here's the output! Notice that the "observerForRemove" printed out only the message related to the Remove operation even though the Subject class raised 2 events (one for Add, another one for Remove) in the Notify() method at line 15. Sweet.

Saturday, May 10, 2008
To everyone who've either sent me an email or posted a comment asking whether
SoapBits can be made into an open source project, well here I am pleased to let you all know that finally it has happened!
SoapBits is now open source and is available at codeplex!
In line with this change, it have given it a new name,
STORM. (I meant "STORM" to be an acronym but I can only come up with
Soap
Testing for "ST" . The "ORM" part I have yet to figure out, so please do suggest if you think of a clever meaning. ;) ) Another major change is that the tool is now written
mostly in
F#, a language which I believe is a lot more expressive and powerful than C# because of the ease with which it has combined Object Oriented and Functional programming. The user interface part though is still written in C# mainly because F# is not yet fully integrated into Visual Studio.
STORM site :
http://codeplex.com/storm
As you all can see below, the UI has also changed a bit but the old functionalities are still there
Enjoy the tool everyone! And don't forget to give back and contribute to the project.
Tuesday, April 01, 2008
Here's a sample template that lets you have the String.Replace() functionality in XSLT 1.0. The template "string-replace-all" takes 3 parameters and recursively processes the input text string.
- text : main string
- replace : the string fragment to be replaced
- by : the replacement string

Here's how it is called:

The resulting value of $myVar after {ReplaceMe} is replaced is "This is a sample text : String.Replace() in XSLT and String.Replace() in XSLT"
For those who are not familiar with XSLT syntax and here's the C# equivalent. An excellent material for the thedailywtf! :)

(Note: I'm not so sure, but I think in XSL 2.0 there is already a built-in replace function on strings)
Tuesday, February 19, 2008
Problem:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?
Solution:
Finding the LCM can be done via factorization. Below is an excerpt from the wikipedia article.
The unique factorization theorem says that every positive integer number greater than 1 can be written in only one way as a product of prime numbers. The prime numbers can be considered as the atomic elements which, when combined together, make up a composite number.
For example:
Here we have the composite number 90 made up of one atom of the prime number 2, two atoms of the prime number 3 and one atom of the prime number 5.
This knowledge can be used to find the lcm of a set of numbers.
Example: Find the value of lcm(8,9,21).
First, factor out each number and express it as a product of prime number powers.
The lcm will be the product of multiplying the highest power in each prime factor category together. Out of the 4 prime factor categories 2, 3, 5, and 7, the highest powers from each are 23, 32, 50, and 71. Thus,
Code:
module Prob5 = begin
open System
open Microsoft.FSharp.Math
let primeFactors (num:float) =
//let num = 50.0
let divSeq = num |> Seq.unfold (fun x ->
let rec get num2 =
let sq = Math.Sqrt (num2)
let div = ref 2.0
while( (not(num2 % !div = 0.0)) && (!div < sq) ) do
if (!div = 2.0) then
div := !div + 1.0
else
div := !div + 2.0
div
let sq = Math.Sqrt (x)
let divisor = get x
if (x = 1.0) then
None
else if (sq < !divisor) then
Some (x, 1.0) // x is prime!
else
Some(!divisor, x/(!divisor))
)
divSeq
let pFactors = (2,20) |> Seq.unfold (fun (x,limit) ->
let y = float_of_int x
let s = (primeFactors y) |> Seq.map (fun x -> Convert.ToInt32(x))
if x <=limit then
Some ( (x,s), (x+1, limit))
else
None
)
let factorSort x y =
let (num1, _) = x
let (num2,_) = y
if (num1 < num2) then
-1
else if num1 > num2 then
1
else
0
let powSort x y =
let (_,num1) = x
let (_,num2) = y
if num1 < num2 then
1
else if num1 > num2 then -1
else
0
let all = pFactors |> Seq.map (fun (num,s) -> s |> Seq.countBy (fun x -> x ) ) |> Seq.concat
let allList = (Seq.to_list all) |> List.sort factorSort |> List.sort powSort
let a = ref 0
let b = ref 0
let filtered = allList |> List.filter (fun (x,y) ->
let (factor,pow) = allList |> List.find (fun (r,s) -> r=x )
if (factor = x ) && (pow = y) && ( (!a <> x) || (!b <> y) ) then
a := factor
b := pow
true
else
false
)
let main() =
let lcm = filtered |> List.fold_left (fun a (x,y) -> a * Math.Pow(float_of_int x, float_of_int y ) ) 1.0
printfn "\n\nLCM = %f" lcm
end
My solution for this one follows the steps outlined in the wikipedia excerpt above. It is a bit long but essentially it can be broken down into the following stages...
1 - Factor out the number 1 to 20.
This is done on function pFactors. pFactors outputs a sequenct of tuples wherein the first value is the number being factored while the second value is a sequence of its prime factors. For example, the output of this function when applied to the numbers 2 to 20
{ (2, {2}); (3, {3}; (4, {2;2}) ; (5, {5}) ...,<snip> .. (12, {2;2;3}) ...<snip> .. (20, {2;2;5}) }
type : seq< int * seq<int>>
2 - Count the number of occurrences of each prime factor and consolidate into just one sequence
This is done on line let all = pFactors |> Seq.map (fun (num,s) -> s |> Seq.countBy (fun x -> x ) ) |> Seq.concat
Seq.countBy counts the number of occurences of an item in a sequence. For example, if we apply to the sequence of prime factors of the number 20, the output will be
(20, {2;2;5} ) -> (2,2),(5,1) : where the 2nd value of the tuple is the number of occurences
So for the number 2 to 20 the output is
(2, 1)(3, 1)(2, 2)(5, 1)(2, 1)(3, 1)(7, 1)(2, 3)(3, 2)(2, 1)(5, 1)(11, 1)(2, 2)(3, 1)(13, 1)(2, 1)(7, 1)(3, 1)(5, 1)(2, 4)(17, 1)
(2, 1)(3, 2)(19, 1)(2, 2)(5, 1)
type : seq<int * int >
3 - Sort the output of stage 2.
The output of stage 2 obviously contains duplicates. Referring back to the wikipedia excerpt above, what we need only are those factors with the highest power (or most number of occurences). So in order for us to identify those factors, first we sort the sequence. This is done on line
let allList = (Seq.to_list all) |> List.sort factorSort |> List.sort powSort
The output (though a bit confusing) guarantees that the for any number, the one with the highest number of occurences comes out on top. For example (2,4) is on top of all the other tuple entries with first value of 2. And so is (3,2) for tuple values with first value of 3.
(2, 4)
(2, 3)
(2, 2)
(2, 2)
(2, 2)
(3, 2)
(3, 2)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(2, 1)
(3, 1)
(3, 1)
(3, 1)
(3, 1)
(5, 1)
(5, 1)
(5, 1)
(5, 1)
(7, 1)
(7, 1)
(11, 1)
(13, 1)
(17, 1)
(19, 1)
type : seq<int * int>
4. Filter the resulting sequence of stage 3 and take only those with the highest 2nd element. This is done on line
let filtered = allList |> List.filter (fun (x,y) -> ... <snip>...
output is : seq<int*int>
(2, 4)
(3, 2)
(5, 1)
(7, 1)
(11, 1)
(13, 1)
(17, 1)
(19, 1)
5. And finally we can compute the LCM. This is done on the line
let lcm = filtered |> List.fold_left (fun a (x,y) -> a * Math.Pow(float_of_int x, float_of_int y ) ) 1.0
Total execution time on my machine is 0.17 seconds which a great improvement from the 25 seconds using the brute force approach described here
Monday, February 18, 2008
These 2 problems have very short solutions so I'll put them together
Problem 3:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
Solution:
let prodOf3digit =
(100,100) |> Seq.unfold (fun (x,y) ->
match y with
| y when y < 0 -> None
| y when x <= 999->
if (y <= 999) then
Some(x*y, (x,y+1))
else if (x+1) <= 999 then
Some ( (x+1)*(x+1), (x+1, x+2) )
else
None
| y -> None )
let palindromes =
prodOf3digit
|> Seq.filter (fun x ->
let intStr = Int32.to_string x
let rev (s:string) =
let chunks =s.ToCharArray()
let reversed = Array.rev chunks
let r = new string(reversed)
r
let newNum = System.Convert.ToInt32 ( rev intStr )
newNum = x
)
let largest =
palindromes |> Seq.fold (fun a x -> if x > a then x else a) 0
The problem asked for the largest palindrome of 3-digit numbers, hence the magic number 100 and 999. The rest of the code is pretty much self-explanatory.
Problem 6:
The sum of the squares of the first ten natural numbers is,12 + 22 + ... + 102 = 385
The square of the sum of the first ten natural numbers is, (1 + 2 + ... + 10)2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.
Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
Solution:
let sumOfSq (n:bigint) =
let rec getSum (x:bigint) =
match x with
| x when x = 1I -> 1I
| x -> x*x + getSum (x - 1I)
getSum n
let sqOfSum n =
let s = [ 1I .. n ] |> Seq.fold (fun a x -> a+x) 0I
s*s
let main2() =
let diff = (sqOfSum 100I) - (sumOfSq 100I)
print_any diff
To compute the sum of squares, I've decided to use recursion, which apart from lists and sequences, is another workhorse of functional programming. One thing to remeber when using recursion is to always make sure you cover the base case in order to avoid looping indefinitely. In this case it is the line x when x = 1I -> 1I
Because of the large resulting values, the type used was BigInt.
Monday, February 11, 2008
Problem 1 :
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
Solution :
let mySeqP1 = [ 1 .. 999 ] |> Seq.filter (fun x -> ( (x % 5 = 0) || (x % 3 = 0)) ) |> Seq.fold(+) 0
printfn "sum = %i" mySeqP1
Problem 2:
Find the sum of all the even-valued terms in the Fibonacci sequence which do not exceed one million.
Solution :
let sumofEven = (1,1) |> Seq.unfold (fun (x,y) ->
match y with
| y when y < 0 -> None
| _ -> Some(y, (y, x+y)))
|> Seq.filter ( fun x -> x > 0 && x < 1000000 && (x % 2 = 0))
|> Seq.fold (+) 0
printfn "Sum of even = %i" sumofEven
For this solution I had to put the guard statement "when y < 0" so that negative numbers won't be included in the generated sequence. If that guard istatement s not there, negative numbers will be included when it goes over the maximum value of Int32.
Problem 3:
Find the largest prime factor of 317584931803.
Solution:
let primefactorsOf (num:float)=
let divSeq = num |> Seq.unfold (fun x ->
let rec get num2 =
let sq = Math.Sqrt (num2)
let div = ref 2.0
while( (not(num2 % !div = 0.0)) && (!div < sq) ) do
if (!div = 2.0) then
div := !div + 1.0
else
div := !div + 2.0
div
let sq = Math.Sqrt (x)
let divisor = get x
if (Int32.of_float(x) = 1) then
None
else if (Int32.of_float( sq ) < Int32.of_float( !divisor )) then
Some ( Int32.of_float( x ) , 1.0) // x is prime!
else
Some(Int32.of_float !divisor, x/(!divisor))
)
divSeq
let primefactors = (primefactorsOf 317584931803.0)
let mainp3() =
primefactors |> Seq.iter (fun x -> printfn "%i " x)
The function "primefactorsOf" takes a number and returns a sequence containing the prime factors of that number. The prime factors are determined using Trial Division. This of course is not very fast for ver large numbers but is sufficient enough for 317584931803.0 If it's not clear why the square root of the number being factored out was used instead of directly using the number itself, the wikipedia article explaining Trial Division is here.
If you want to output only the largest primefactor you can just pass the value primefactors to Seq.fold like so
let largestFactor = primefactors |> Seq.fold (fun a x -> if x > a then x else a ) 0
Next time I'll post my solution to problems 4-6.
Friday, January 18, 2008
The Problem : What is the first term in the Fibonacci sequence to contain 1000 digits?
The sweet solution :
#light
open System
let fib =
(1I,1I) |> Seq.unfold ( fun (sqEntry, acc) -> Some (acc, (acc, acc + sqEntry)) )
|> Seq.filter (fun x -> x.ToString().Length = 1000)
|> Seq.nth 0
print_any fib
Console.ReadLine()
ahh... such power and elegance....
Let me breakdown the solution
(1I,1I) |> Seq.unfold ( fun (sqEntry, acc) -> Some (acc, (acc, acc + sqEntry)) )
This line creates an inifinite list of fibonacci numbers using Seq.unfold. Let me say that again, it creates a in INFINITE list. How is that possible, you'd ask ? The reason is that F# performs Lazy Evaluation. By that, I mean the program will perform only the computation it needs to do. So in our case, the program will actually compute only the parts of the list that it will need. Here we used Seq.unfold to perform the computation. The unfold function creates a list and uses an accumulator to maintain the state between computations. The accumulator in this case is the tuple that contains the last 2 entries of the sequence
Seq.filter( fun x -> x.ToString().Length = 1000
This line applies the filter function to the sequence. This function returns a subset of the original list that matches the condition. In this case, the resulting list will contain only those numbers that is made up 1000 digits.
Seq.nth 0
This line retrieves the nth element in the sequence. Since the problem ask for the 1st term, naturally we retrieved the 0th element.
And finally the construct that ties everything together and makes the code such a wonder to look at is the
|> (the Pass-forward operator)
As its name implies, it passes forward the argument behind it to the function in front of it. So the solution in essence means
Pass the tuple (1I, 1I) to Seq.Unfold, then pass the resulting infinite list to Seq.filter, then pass the filtered list to Seq.nth which finally retrieves the 1st element!
Friday, November 09, 2007
When BizTalk compiles a project that contains a schema it generates a wrapper class for each schema. Take for example the typical Biztalk Project below. It contains a PropertySchema + 4 other schemas.

Compiling this project and opening it up with .NET Reflector, we'll get the following. The important stuff to note from this are
- A class was generated for each schema (including the Property schema)
- The generated classes inherit from "Microsoft.XLANGs.BaseTypes.SchemaBase"
- (See Figure 2) SchemaBase has a property called "XmlContent" which is overriden by the generated class. This property contains the raw schema string!

Figure 1. Reflector output

Figure 2. Properties Overriden by the Generated Class
So to get the raw schema, all we need to do is open up the dll in .NET Reflector and do some copy-paste magic. :) But what if you have a huge schema project? Extracting them all will be very painful (at least for me). So being the kind of programmer that hates repetitive work, and aside from the fact that I'm currently learning and loving F#, I hacked up this code to do everything automatically. Here's the tool in action. It creates the XSD files in the same folder where the tool was ran.

The tool can be downloaded here. (p.s. easy-share.com deletes the file if it has not been downloaded for within 30 days. Just drop me an email if you want me to send the file directly)
and here's the code (How it works will be topic in a future post )
#light
module BtXsd
open System
open System.Windows.Forms
open System.ComponentModel
open BtsXsdExtractorUI
open System.IO
open System.Reflection
open System.Text
open Microsoft.FSharp.Reflection
open Microsoft.FSharp.Core
open Microsoft.XLANGs.BaseTypes
let schemaPropertyName = "XmlContent"
let btsSchemas file =
if (not (String.IsNullOrEmpty(file))) then
let btsAssembly = Assembly.LoadFile(file)
let types = btsAssembly.GetTypes()
let schemabaseType = typeof
let btsSchemaTypes = types |> Array.filter (fun x -> schemabaseType.IsAssignableFrom(x))
btsSchemaTypes
else
[||]
let rec generateFileName rootDir name =
let ext = ".xsd"
let temp = Path.Combine(rootDir, name + ext)
if File.Exists(temp) then
let newName = name +"_("+ int_to_string (Directory.GetFiles(rootDir, name + "*", SearchOption.TopDirectoryOnly).Length) + ")"
generateFileName rootDir newName
else
temp
type Form1 =
inherit Form as base
val mutable components: System.ComponentModel.Container
override this.Dispose(disposing) =
if (disposing && (match this.components with null -> false | _ -> true)) then
this.components.Dispose()
base.Dispose(disposing)
val mutable tbDllFile: System.Windows.Forms.TextBox
val mutable btnBrowse: Button
val mutable btnExtract: Button
val mutable label1: Label
val mutable bgwExtract: BackgroundWorker
val mutable progressBar1: ProgressBar
val mutable openFileDialog1: OpenFileDialog
member this.InitializeComponent() =
this.tbDllFile <- new System.Windows.Forms.TextBox();
this.btnBrowse <- new System.Windows.Forms.Button();
this.btnExtract <- new System.Windows.Forms.Button();
this.label1 <- new System.Windows.Forms.Label();
this.bgwExtract <- new System.ComponentModel.BackgroundWorker();
this.progressBar1 <- new System.Windows.Forms.ProgressBar();
this.openFileDialog1 <- new System.Windows.Forms.OpenFileDialog();
this.SuspendLayout();
//
// tbDllFile
//
this.tbDllFile.Location <- new System.Drawing.Point(13, 33);
this.tbDllFile.Name <- "tbDllFile";
this.tbDllFile.Size <- new System.Drawing.Size(336, 20);
this.tbDllFile.TabIndex <- 0;
this.tbDllFile.Text <- "Erik:\\VS 2005 Projects\\FSharp\\FSoapBits\\ValidationSchemas.dll";
//
// btnBrowse
//
this.btnBrowse.Location <- new System.Drawing.Point(355, 30);
this.btnBrowse.Name <- "btnBrowse";
this.btnBrowse.Size <- new System.Drawing.Size(34, 23);
this.btnBrowse.TabIndex <- 1;
this.btnBrowse.Text <- "...";
this.btnBrowse.UseVisualStyleBackColor <- true;
this.btnBrowse.Click.Add(fun _ ->
if (DialogResult.OK == this.openFileDialog1.ShowDialog()) then
this.tbDllFile.Text <- this.openFileDialog1.FileName
else
this.tbDllFile.Text <- "")
//
// btnExtract
//
this.btnExtract.Location <- new System.Drawing.Point(314, 64);
this.btnExtract.Name <- "btnExtract";
this.btnExtract.Size <- new System.Drawing.Size(75, 23);
this.btnExtract.TabIndex <- 2;
this.btnExtract.Text <- "Extract";
this.btnExtract.UseVisualStyleBackColor <- true;
this.btnExtract.Click.Add(fun e ->
//let max = ref 0
let justTheFileName = Path.GetFileName(this.tbDllFile.Text);
if File.Exists(this.tbDllFile.Text) then
let temp = btsSchemas this.tbDllFile.Text
(*if not (temp.Length % 2 = 0) then
max := temp.Length + 1
else
max := temp.Length*)
this.progressBar1.Maximum <- temp.Length
this.progressBar1.Minimum <- 0
this.progressBar1.Step <- 1
this.progressBar1.Value <- 0
this.progressBar1.Refresh()
if temp.Length > 0 then
temp |> Array.iter (fun typ ->
let instance = Activator.CreateInstance(typ) :?> SchemaBase
let xsd = instance.XmlContent
let curAssm = Assembly.GetExecutingAssembly()
let curDir = Path.GetDirectoryName(curAssm.Location)
//let curDir = Directory.GetCurrentDirectory()
let fullFileName = generateFileName curDir typ.Name
//Path.Combine(curDir, typ.Name + ".xsd")
using(new StreamWriter(fullFileName, false, Encoding.Unicode)) (fun sw -> sw.Write(xsd))
this.progressBar1.Increment(1)
)
else
MessageBox.Show(justTheFileName + " does not contain BizTalk schemas") |> ignore
else
MessageBox.Show(justTheFileName + " file does not exist") |> ignore
)
//
// label1
//
this.label1.AutoSize <- true
this.label1.Location <- new System.Drawing.Point(10, 9)
this.label1.Name <- "label1"
this.label1.Size <- new System.Drawing.Size(85, 13);
this.label1.TabIndex <- 3;
this.label1.Text <- "Biztalk Assembly";
//
// progressBar1
//
this.progressBar1.Location <- new System.Drawing.Point(12, 64);
this.progressBar1.Name <- "progressBar1";
this.progressBar1.Size <- new System.Drawing.Size(296, 23);
this.progressBar1.TabIndex <- 4;
//
// openFileDialog1
//
this.openFileDialog1.FileName <- "openFileDialog1";
this.openFileDialog1.Filter <- "Dll files|*.dll"
//
// BtsXsdExtractorForm
//
this.AutoScaleDimensions <- new System.Drawing.SizeF(6.0F, 13.0F);
this.AutoScaleMode <- System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize <- new System.Drawing.Size(401, 113);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.label1);
this.Controls.Add(this.btnExtract);
this.Controls.Add(this.btnBrowse);
this.Controls.Add(this.tbDllFile);
this.Name <- "BtsXsdExtractorForm";
this.Text <- "BizTalk Assembly Schema Extractor";
this.ResumeLayout(false);
this.PerformLayout();
new () as this =
{
tbDllFile = null
btnBrowse = null
btnExtract = null
label1 = null
bgwExtract = null
progressBar1 = null
openFileDialog1 = null
components = null
}
then
this.InitializeComponent()
let main() =
Application.EnableVisualStyles() |> ignore
//Application.SetCompatibleTextRenderingDefault(false) |> ignore
let form1 = new Form1()
Application.Run(form1)// |> ignore
[]
do main ()
Tuesday, November 06, 2007
Funny (but true) article from TechRepublic. I gotta start looking for the Code Ninja in my team(!) but where do i start...
10 types of programmers you’ll encounter in the field
Monday, November 05, 2007
I don't remember exactly where, but some years ago I've come across a book that said something like -- A "complete" programmer must know the 3 main programming styles, 1. C-based (C#, Java C++ etc) 2. Scripting (Perl etc) and 3. Functional (Haskell, OCaml etc). Each style requires a different mind- set when writing code. I started out as a Perl programmer (i know it's weird that my first language was Perl... ), moved on to C++ and now I'm doing .NET (C# and BizTalk mainly). So, I've covered the first 2 "styles" and that leaves just functional programming.
I've always been interested with functional programming but I somehow I've always found an excuse not to try it. Add to that the facts that
- Going from OO to functional programming is hard. By that I mean the learning curve is very steep!!!
- I didn't want to throw away my existing knowledge on C#
- I didn't want to throw away the libraries I've compiled and written over the years.
- There are no F# jobs!! (at least there's none in Singapore)

A few weeks back Microsoft announced that it is productizing F#. It is now going to be a supported .NET language. That is really great because now my excuses #2 and #3 are no longer valid! Excuses #1 and #4 though it still has some weight, it is not enough anymore to keep me from learning functional programming with F#. Yes, there will always be a learning curve. And, the jobs...well, hopefully the bio-tech companies will soon adapt F# given that because of its functional nature, Microsoft is marketing it as a language for scientific reasearch and development.
F# is not a pure functional language like Haskell i.e. it allows side-effects. This is perfectly fine (I'm not a purist) because this is actually allows interoperability with other .NET libraries. Which means coding in F# will in no way greatly reduce my productivity.
For 2 weeks now, I've been reading up on F# while travelling to and from the office. Below is my first F# code. Check out how System.Windows.Forms controls are available from the code.

#light
open System
open System.Drawing
open System.Windows.Forms
open System.Windows.Forms.Design
let label =
let temp = new Label()
do temp.Name <- "label1"
do temp.Size <- new System.Drawing.Size(35, 13);
do temp.Text <- "Hello F#"
do temp.AutoSize <- true
do temp.Location <- new Drawing.Point(26,27)
temp
let form =
let temp = new Form()
do temp.Name <- "ErikForm"
do temp.Text <- "EriKForm"
do temp.ClientSize <- new System.Drawing.Size(292, 266);
do temp.Controls.Add(label)
temp
let ticker =
let temp = new Timer()
temp.Enabled <- true
temp.Interval <- 1000
temp.Tick.Add(fun _ -> label.Text <- DateTime.Now.ToLongTimeString())
do Application.Run(form)
Saturday, September 01, 2007
November 1 2007
It's been 2 months now since I've made SoapBits available on this blog. And I'm genuinely surprised that people had stumbled into it! Google you're the king!!
Here are some download stats from easy-share.com. On the average, the tool gets downloaded twice a day.
.jpg)
I've also received some emails regarding difficulties downloading from easy-share. This most probaly because of the layout of the easy-share web site. You need to scroll down a bit to get past the ads until you see the download part. I know, this s*cks a bit but its still better than hosting it at rapidshare where you have to wait for ages.
The latest version can be downloaded here : SoapBits v.1.1.1
October 13 2007 UPDATE - SoapBits v1.1.1 Released!
This release contains fixes to the following bugs
- Fails to process web services whose WSDL had included external schemas wherein the schemaLocation is in the URI format. Something like: <xs:include schemaLocation="http://MyCentralRepository/MyExternalTypes.xsd"/>
Fix: added to code to download the schema into the temp folder where all the other temporay files (wsdl, request and responses) are kept. This temp folder is deleted when the tool is closed.
2. Response Tab fails to display very large soap responses.
Fix: Modified the way the http response is read so that the entire response can be displayed.
3. Cannot send cookies.
Fix: Cookies are supported only via the "Send Raw Request" option. I've added code to make this easier . Please see the modified the documentation (part of the download) on how sending/receiving cookies can be done.
You can download SoapBits v.1.1.1 here.
Sept 25 2007/UPDATE
Just got back from vacation and is now working on fixing a bug relating to "included" schemas in the WSDL. I am also looking into implementing some feature requests.
I don't have specific date in mind yet for the new release but I promise I'll get to work on it whenever I'm free.
Guys thank you very much for reporting bugs and submitting feature requests. This will make SoapBits a much better app than I hoped it would be.
Sept 8 2007 /UPDATE - SoapBits v1.1.0 Released
As promised, here's the new release of SoapBits! This release contains the following changes
1. More robust exception handling. The reported bug(s) on unhandled exceptions are no more. Plus, I've added a feature that automatically unhides the Logging Pane whenever an exception is written to it.
2. The "Quick Edit" tab Response pane is now synchronized with the current selected method. Taking this synchronization fix further, I also synchonized the current selected web method with the" Test Data" tab Request and Response sub tabs. To illustrate, Say you are testing a web service that has 2 web methods, method1 and method 2. If you invoke method1 first, then method2 and then you selected method1 again from the "Web Methods" pane the data that will be shown in the "Test Data" tab will be for method1 even though the last method that was executed was method2.
3. "Quick Options" now includes a) Toggling the Logging Pane, b) Viewing the WSDL and c) Viewing the Soap Request Properties
4. The UI has a bit of an "MS Outlook" feel now.
5. I've also added a label to display the time! This is for my fellow devs who frequently forgets to have lunch or dinner!
6. "Help/About" now contains more info.
Check out the new look!
.JPG)
As always, for any bugs or enhancement requests please let me know. 
You can download SoapBits v1.1.0 here
Sept 4, 2007/ UPDATE
I have received the following comments regarding the tool and i'll be fixing these over the weekend. Let me know if there are more.
- Unhandled exception is generated when the URL passed is incorrect.
- The response output tree should refresh when another web method is selected
- Add to "Quick Options" a link to the Soap request properties.
Sept 1/ Initial Release
SoapBits is an application used to dynamically invoke any type of web service. The inspiration for this tool is the amazing .NET Web Service Studio tool written by Sowmys of Microsoft at GotDotNet. That tool has been a great help to me.
I have been using .NET Web Service Studio for a few years now and I have found that though it works great it needed a few enhancements. So basically what I did here is to take .NET Web Service Studio and add the enhancements I wanted.
Sowmys, if you object to me using your tool this way, just let me know. I’ll immediately discontinue distributing the tool.
OK so here we go...
Installation
Prerequisite : .NET Framework 2.0
Platforms supported : XP and Windows Server 2000. I haven't tried on Vista because I don't have one (...yet).
Instructions: Just extract the zip file into any directory
Tool Sections
* Quick Edit Tab

* Test Data Tab

QuickStart Guide.
* Invoking a web service using Quick Edit Option
1. Provide a wsdl in the address bar. Click Go. Select a web method
2. Provide values to the input parameters of the web method. Click Send Soap request button.
* Invoking a web service by using the "Raw Soap mesage" option
Another way to invoke a web service is to edit directly the raw soap message. Instructions on how to do this is in the document that is included in the download
You can download SoapBits here. Try it out and let me know how it goes!
Thursday, June 14, 2007
Every BizTalk developer knows that assemblies used by BizTalk must reside in the Global Assembly Cache and hence must be strong-named. As such, if you are using an assembly that reads a config section then in the BTSNTSvc.exe.config, you must specify the specific type of assembly in the GAC that will be used to read that section.
Taking SubSonic for example. the config section should read like:
<configSections>
<section name="SubSonicService" type="SubSonic.SubSonicSection, SubSonic, Version=2.0.0.1, Culture=neutral, PublicKeyToken=3db15eb857a3cee5" allowDefinition="MachineToApplication" restartOnExternalChanges="true" requirePermission="false"/>
</configSections>
And the SubSonicService section should be:
<SubSonicService defaultProvider="TestProvider">
<providers>
<add name="TestProvider" type="SubSonic.SqlDataProvider, SubSonic, Version=2.0.0.1, Culture=neutral, PublicKeyToken=3db15eb857a3cee5"
connectionStringName="ConnectionString"
generatedNamespace="Test.DataAccess"/>
</providers>
</SubSonicService>
The Version, Culture and PublicKeyToken must be specified. If not, BizTalk won’t be able to find the assembly and will report an error saying something like “it could not load assembly or file”.
To find out the version and PublicKeyToken of any assembly in the gac, simply go to C:\windows\assembly

You can download SubSonic here. Generate your own snk file, compile it, then off you go!
Thursday, December 14, 2006
Each one of us experience this at some point in our lives; a defining moment, a sudden unexpected event, a turning point - beyond which we are never the same again. I just had mine a few days back and I'm still reeling from its effects.
Tuesday, November 14, 2006
Last night a friend and I were at Changi international airport having coffee and just wiling away the time. And of all the topics that we could have talked about, we ended up talking about love. Hahaha! yeah, love. Well.. I suppose its not that surprising given that most of the people we know who came here to Singapore ended up with a messed-up love life. That of course includes me.
So how does moving to another country relate to breakups? Was it the distance? Was it the breakdown in communication caused by multitude of factors, primary of which is distance? Was it because both persons are now living "separate" lives? Or was it because they now are able to see the relationship from a different perspective now that their partner is no longer always around?
... *Sigh* ...
I wish I know the answer.
I wish my friend knew the answer.
But sadly, we were as just as clueless as everyone else. When love happens, when it hits you, you just know it. You just feel it. No matter how hard you try to find a logical reason as to why you have this feeling, you'll just never find it. It just happens. Ironically, the same argument can be applied as to why love disappears. One day you just realize that the feelings you had before is gone (or dying) without really knowing why. Again, you just feel it. The realization hits you just as hard as when you realized you were in love.
Love it seems is a creature of whim. It comes and goes as it pleases. And it doesn't even bother to explain.
Wednesday, May 03, 2006
Here's how you can remove parties programatically. It's quite easy.
I. First, you need a reference to the Microsoft.BizTalk.ExplorerOM assembly. You can find this assembly in the Biztalk install folder
II.. Create your code this way
try
{
BtsCatalogExplorer btsExp = new BtsCatalogExplorer();
1. PartyCollection pc = (PartyCollection)btsExp.GetCollection(CollectionType.Party);
2. for (int i=0; i<= pc.Count-1; i++)
{
3. if (bindingFileParties.Contains(pc[i].Name))
{
4. btsExp.RemoveParty(pc[i]);
5. i--;
}
6. btsExp.SaveChanges();
}
}
catch (Exception ex)
{
7. this.btsExp.DiscardChanges();
throw ex;
}
line 1 : Create an instance of the BtsCatalogExplorer and retrieve the partycollection deployed in the Mgmt database
line 2 : loop through all parties
line 3: Here I process only those parties which are declared in a binding file. The bindingFileParties variable here is an Arraylist which contains a list of all “party” values found in a binding file. This is just to make sure that I remove the parties which are mine.
line 4: This is the line where we actually remove the party.
line 5: Bring back the counter one step because we removed a party from the collection
line 6: Commit the changes to the database
line 7: Discard your changes if any exception occured.
You can also use this approach to remove ReceivePorts and Send ports. Just replace PartyCollection with ReceivePortCollection or SendPortCollection and CollectionType.Party with CollectionType.ReceivePort or CollectionType.SendPort