Friday, October 31, 2008

Mocking F#

The intent of this entry is to show how to do TDD (Test Driven Development) in F# with the help of a dynamic mock object framework such as RhinoMocks. Along the way, we will explore how to implement an object oriented design in F# with features including namespaces, classes, interfaces, properties, and members. This example includes several best practices, but is by no means production ready. Most specifically, it is missing error handling and validation. In addition, certain patterns and practices have been intentionally ignored in order to make the example a little easier to understand.

This is an implementation of a simplified customer service that might exist in any standard LOB (Line of Business) application. In the end, we have a service that allows the current balance of a customer to be returned with a specified discount applied.

As always, we write the tests first (Note: As is my usual style, the tests are in C# and the code is in F#):

C# Customer Entity Test:

[TestMethod]
public void CanCreateCustomer()
{
FSharpMockExample.Entities.ICustomer customer = new FSharpMockExample.Entities.Customer(1, "ABC, Corp.", 20);
Assert.AreEqual(customer.Id, 1);
Assert.AreEqual(customer.Name, "ABC, Corp.");
}

[TestMethod]
public void CanCalculateBalanceWith10PercentDiscount()
{
FSharpMockExample.Entities.ICustomer customer = new FSharpMockExample.Entities.Customer(1, "ABC, Corp.", 20);
decimal newBalance = customer.CalculateBalanceWithDiscount(.1M);
Assert.AreEqual(newBalance, 18);
}



F# Customer Entity:




Signature File:



#light
namespace
FSharpMockExample.Entities

type ICustomer = interface
abstract
Id: int with get
abstract Name: string with get
abstract CalculateBalanceWithDiscount: decimal -> decimal
end

type
Customer = class
new
: int*string*decimal -> Customer
interface ICustomer
end



Source File:



#light
namespace
FSharpMockExample.Entities

type ICustomer = interface
abstract
Id: int with get
abstract Name: string with get
abstract CalculateBalanceWithDiscount: decimal -> decimal
end

type
Customer = class
val
id: int
val name: string
val balance: decimal
new(id, name, balance) =
{id = id; name = name; balance = balance}
interface ICustomer with
member
this.Id
with get () = this.id
member this.Name
with get () = this.name
member this.CalculateBalanceWithDiscount discount =
this.balance - (discount * this.balance)
end
end



C# Customer Data Access Object Test:



[TestMethod]
public void CanGetCustomerById()
{
FSharpMockExample.Data.ICustomerDao customerDao = new FSharpMockExample.Data.CustomerDao();
FSharpMockExample.Entities.ICustomer customer = customerDao.GetById(1);
Assert.AreEqual(customer.Id, 1);
Assert.AreEqual(customer.Name, "ABC Company");
}



F# Customer Data Access Object:



Signature File:



#light
namespace
FSharpMockExample.Data
open FSharpMockExample.Entities

type ICustomerDao = interface
abstract
GetById: int -> ICustomer
end

type
CustomerDao = class
new
: unit -> CustomerDao
interface ICustomerDao
end



Source File:



#light
namespace
FSharpMockExample.Data
open FSharpMockExample.Entities

type ICustomerDao = interface
abstract
GetById: int -> ICustomer
end

type
CustomerDao = class
new
()={}
interface ICustomerDao with
member
this.GetById id =
new Customer(id, "ABC Company", 20.00M) :> ICustomer
end



C# Customer Service Test:



[TestMethod]
public void CanCalculateBalance()
{
var mocks = new MockRepository();
var customerDao = mocks.CreateMock<FSharpMockExample.Data.ICustomerDao>();
FSharpMockExample.Entities.ICustomer customer = new FSharpMockExample.Entities.Customer(1, "XYZ Company", 50);

using (mocks.Record())
{
Expect.Call(customerDao.GetById(1)).IgnoreArguments().Return(customer);
}

using (mocks.Playback())
{
int customerId = 1;
decimal discount = .1M;
FSharpMockExample.Services.ICustomerService customerService = new FSharpMockExample.Services.CustomerService(customerDao);
var balanceWithDiscount = customerService.CalculateBalaceWithDiscount(customerId, discount);

Assert.AreEqual(balanceWithDiscount, 45);
}
}



F# Customer Service:



Signature File:



#light
namespace
FSharpMockExample.Services
open FSharpMockExample.Data
open FSharpMockExample.Entities

type ICustomerService = interface
abstract
CalculateBalaceWithDiscount: int*decimal -> decimal
end

type
CustomerService = class
new
: unit -> CustomerService
new: ICustomerDao -> CustomerService
end



Source File:



#light
namespace
FSharpMockExample.Services
open FSharpMockExample.Data
open FSharpMockExample.Entities

type ICustomerService = interface
abstract
CalculateBalaceWithDiscount: int*decimal -> decimal
end

type
CustomerService = class
val
customerDao: ICustomerDao
new (customerDao) =
{customerDao = customerDao}
new () =
{customerDao = new CustomerDao()}
interface ICustomerService with
member
this.CalculateBalaceWithDiscount (customerId, discount) =
let customer =
this.customerDao.GetById(customerId)
customer.CalculateBalanceWithDiscount(discount)
end
end






Hopefully, this example will inspire you to go out an give this amazing language a try.

Saturday, October 25, 2008

F# Seq Module

Many of the features that make F# so powerful, are the modules that make up the FSLib library. One of my favorites is the Seq module which can be found in Microsoft.FSharp.Collections namespace.

This simple example demonstrates how to use the "sum" function of the Seq module. In this example, four integers are added together. The result is then squared.

Note: I have chosen to write these sample tests in C# to help emphasis the interoperability of the languages. These tests could have just as easily been written in F#. For examples of this, check out the book Expert F#.

Test:

[TestMethod]
public void CanCalculateSeqExample()
{
List<int> numbersToCalculate = new List<int>();
numbersToCalculate.Add(1);
numbersToCalculate.Add(2);
numbersToCalculate.Add(3);
numbersToCalculate.Add(4);
int result = FSharpSample.CalculateSeqExample(numbersToCalculate);

Assert.AreEqual(result, 100);
}


.fs File:

#light
let CalculateNumberSquared x = x*x

let CalculateSeqExample args =
Seq.sum args |> CalculateNumberSquared


.fsi File:

#light
val CalculateNumberSquared: int -> int

val CalculateSeqExample: seq -> int


Explanation:

While this example is very simple, it provides a brief view into the power that some of these modules provides. This example also shows how functions can be chained together. The astute observer will have noticed the "|>" operator in the
CalculateSeqExample function. This operator is known as the pipe-forward or forward operator. It allows the result of the preceding function to be forwarded on to the next function in the chain.


Saturday, October 18, 2008

Comparing MSIL of F# Versus C#

Comparing MSIL:

To get a good understanding of what is going on "under the covers" of our example from last week, a person can view the generated MSIL (Microsoft Intermediate Language). While there are several options for doing this, I chose to use Reflector.

Here's a review of the F# code as well as the C# equivalent:

F#:

Test:

[TestMethod]
public void CanCalculateNumberSquared()
{
int
result = FSharpSample.CalculateNumberSquared(2);
Assert
.AreEqual(result, 4)
}

Code:

#light
let
CalculateNumberSquared x = x*x;;

Here's the C# code.

Test:

[TestMethod]
public void
CanCalculateNumberSquaredInCSharp()
{
CSharpSample.CSharpSample cSharpSample = new CSharpSample.CSharpSample();
int
result = CSharpSample.CalculateNumberSquared(2);
Assert
.AreEqual(result, 4);
}

Code:

public class CSharpSample
{
public int
CalculateNumberSquared(int numberToSquare)
{
return
numberToSquare * numberToSquare;
}
}

Here is the managed code with comments explaining what is happening:


C#:

.method public hidebysig instance int32 CalculateNumberSquared(int32 numberToSquare) cil managed {     
.maxstack
2 // maximum number of elements that can be pushed to the valuation stack
.locals init (
[0] int32 CS$1$0000) // this is a local variable of type int32
L_0000: nop // do nothing -- indicates compiled in debug mode
L_0001: ldarg.1 // push argument 1 onto the stack
L_0002: ldarg.1 // push argument 1 onto the stack (multiplying a number by itself)
L_0003: mul // multiply values
L_0004: stloc.0 // pop a value from the stack into a local variable
L_0005: br.s L_0007 // go to labl L_0007
L_0007: ldloc.0 // push local variable at index 0 onto the stack
L_0008: ret // return the value from the stack (if there is one) and return from the method
}
F#:


.method public static int32 CalculateNumberSquared(int32 x) cil managed {     
.maxstack
4 // maximum number of elements that can be pushed to the valuation stack
L_0000: nop // do nothing -- indicates compiled in debug mode
L_0001: ldarg.0 // push argument 0 onto the stack
L_0002: ldarg.0 // push argument 0 onto the stack
L_0003: mul // multiply values
L_0004: ret // return the value from the stack (if there is one) and return from the method
}

This first thing that I noticed when comparing the managed code from each example, was that
the F# code is more succinct. Each is accomplishing the same goal, but the CIL generated from
F# is five lines less that that which was generated from the C# example.
The second thing I
noticed was that the F# method is static while the C# method is not. To ensure that we are
comparing apples to apples, a new static method was generated in the C# example.


Here's the code:


Test:


[TestMethod]

public void
CanStaticCalculateNumberSquaredInCSharp()

{
int
result = CSharpSample.StaticCSharpSample.CalculateNumberSquared(2);
Assert
.AreEqual(result, 4);

}


Code:

public static class StaticCSharpSample

{

public static int CalculateNumberSquared(int numberToSquare)
{
return
numberToSquare * numberToSquare;
}
}

MSIL:
.method public hidebysig static int32 CalculateNumberSquared(int32 numberToSquare) cil managed {     
.maxstack
2 // maximum number of elements that can be pushed to the valuation stack
.locals init (
[0] int32 CS$1$0000) // this is a local variable of type int32
L_0000: nop // do nothing -- indicates compiled in debug mode
L_0001: ldarg.1 // push argument 1 onto the stack
L_0002: ldarg.1 // push argument 1 onto the stack multiplying a number by itself)
L_0003: mul // multiply values
L_0004: stloc.0 // pop a value from the stack into a local variable
L_0005: br.s L_0007 // go to labl L_0007
L_0007: ldloc.0 // push local variable at index 0 onto the stack
L_0008: ret // return the value from the stack (if there is one) and return from the method
}
As you can see, the MSIL is very similar to that which was generated in our first example.
While we could probably find a way to make the C# example generate the same managed
code as the F# example, it is clear that the F# example requires less work and less lines of code
to generate the more succinct result.

Breaking Down The Code

Overview:

Last week we walked through creating our first F# application using TDD (Test Driven Development). Today we will break down that first example to identify what each of our commands are doing.

Here's a review of the extremely simple application that we wrote:

Test:
[TestMethod]
public void CanCalculateNumberSquared()
{
int result = FSharpSample.CalculateNumberSquared(2);
Assert.AreEqual(result, 4);
}

Code:

#light
let CalculateNumberSquared x = x*x;;

Breaking Down The Code:

So what does this all mean?

#light
The #light (pronounced "Hash" light) compiler directive provides various features that simplify the F# language. It also allows compatibility with the language OCaml. At the time of this writing, most experts recommend the use of this directive.

Identifiers:
The "let" keyword allows the programmer to associate any value or formulate to an "Identifier". Here's how Robert Pickering describes identifiers in his book "Foundations of F#". "To most people coming from an imperative programming background, this will look like a variable assignment. There are a lot of similarities, but there are key differences. In pure functional programming, once a value is assigned to an identifier, it never changes. This is why I will refer to them throughout this book as identifiers and not variables." If you have not read this book, I strongly recommend it.

In our example, we are setting up an identifier named "CalculateNumberSquared", specifying a parameter named "x", and finally providing instructions on what to do with that parameter. This identifier can then be passed around to other identifiers and/or functions.

This ability to pass around functions and identifiers is one of the great features in F#. While it may take some time to get use to this concept, you will soon wonder how you ever got along without it.

Monday, October 13, 2008

Getting Started With F#

First retrieve and install the latest release of F# (the Sept. 2008 CTP can be found here).

I'm a believer in TDD (Test Driven Development), so our first step after installation of the CTP is to create a test.

Step 1: Creating the Test Project:

1. Open Visual Studio and type Ctrl+Shift+N to create a new project.
2. Create a Test project by selecting a project type of Visual C#\Test\Test Project. ( Note: I'm using a C# test project in VS2008, but any other test project will do.)
3. Set the location to any desired path with a new destination folder of "FSharpGettingStarted".
4. Change the Name to "FSharpTests".
5. Ensure that "Create New Solution" is selected and that "Create Directory For Solution" is checked.
6. Click OK.

Step 2: Creating the First Test:

1. Delete the default class that was generated in the test project.
2. Right click the FSharpTests project and select "Add\New Test...".
3. Select the Unit Test template and set the Test Name to "FSharpSampleTests.cs" then click OK.
4. In the newly generated class, locate the method "TestMethod1" and rename it to CanCalculateNumberSquared.
5. Remove the text that was generated in the method and type:
int result = FSharpSample.CalculateNumberSquared(2);
Assert.AreEqual(result, 4);

Step 3: Creating the F# project:
1. Type Ctrl+Shift+N and select the project type of Visual F#\F# Library.
2. Change the name to "FSharpSample".
3. Change the Solution option to "Add to Solution" and click OK.

Step 4: Adding the F# Function From Our Test:
1. Delete the "Module1.fs" file that was generated.
2. Right click on the FSharpSample project and select Add\New Item\F# Signature File.
3. Name the file "FSharpSample.fsi".
4. Right click on the FSharpSample project and select Add\New Item\F# Source File.
5. Name the file "FSharpSample.fs". (Note: if you add the ".fs" file before the ".fsi" file you may see an error message that states "An implementation of file or module FSharpSample has already been given. Compilation order is significant in F# because of type inference. You may need to adjust the order of your files to place the signature file before the implementation.". If you see this error, simply delete the ".fs" file and recreate it or manually edit the ".fsproj" file so that the ".fsi" file reference is above the ".fs" file reference in the ItemGroups.)
6. Open the FSharpSample.fsi file and type "val CalculateNumberSquared: int -> int" in the line directly below the line that states "#light".
7. Open the FSharpSample.fs file and type "let CalculateNumberSquared x = x*x;;" in the line directly below the line that states "#light".
8. Add the FSharpSample project as a reference to your Test project.
7. Run your test and it should now pass.

That's all there is to setting up your first F# library created with TDD. Next we will start talking about what some of this all means.

Sunday, October 12, 2008

F# Versus C#, VB, and Other .NET Languages

Why F#? What does F# provide that C#, VB, etc. does not?

1. By default, F# uses immutable types, which means that once a type is created, it will not change. This behavior makes the language inherently safe for concurrent operations. With an ever increasing need for concurrency support in enterprise applications, this behavior is becoming more and more desirable. With F#, concurrency related errors such as race conditions, synchronization issues, lock convoys, and deadlocks will be greatly reduced.

2. F# is built on the concept of functions rather than objects. While objects are supported, functions are also first class citizens. Functions can be and passed around like objects in C#/VB. This makes the language extremely well suited for algorithmic computations and makes it easier to achieve efficient processing of lists of data. Since everything compiles to IL, similar performance on these operations could conceivably be achieved with any .NET language, but F# allows optimal performance for specific operations with much less code. Note: In addition to the new abilities, you still have all functionality available in the .NET framework.

3. One of the features of F#, that I have found extremely useful, is the interactive scripting functionality. This allows the developer to select a subset of code and run it like a script. Anyone with a background it SQL will find this functionality very easy to understand and extremely useful for learning/experimenting with the language.

4. Finally, anyone with experience in C# will be thrilled to learn that the immutable aspects of F# will greatly reduce or eliminate the dreaded "Object reference not set to an instance of an object" error.

Note: F# should be added as an addition to an engineer's arsenal, not a replacement for the existing language of choice. My philosophy has always been, use the tool that is best suited for the task. Use F# in places where it can accomplish the task better and/or easier than the other available options.

Many of the points listed here are based on comments/documentation from the following:

http://msdn.microsoft.com/en-us/fsharp/default.aspx

Ted Neward: (http://msdn.microsoft.com/en-us/magazine/cc164244.aspx,
http://www.dotnetrocks.com/default.aspx?showNum=377)

The book "Expert F#" (http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?isbn=1590598504)

Saturday, October 11, 2008

What is F#?

What is F#?

F# is a functional programming language written by Don Syme from Microsoft. In addition to F#, Don has done extensive work on the CLR (Common Language Runtime) and is the main reason that we have generics in C# and VB.NET. F# was built on top of the CLR, which means that it compiles down to IL (Intermediary Language) and is interoperable with all of the other CLR based languages. The Sept. CTP Release is available here.

What is functional programming?

The first functional programming languages--IPL and LISP (which stands for List Programming)--were created in the 1950s. These languages, and all functional programming languages including F#, were built on the foundation of Lambda Calculus. There are many functional programming languages such as OCaml, Erlang, Haskell, and Eiffel. In addition, other languages such as XSLT
are built on some of the concepts from functional languages (note: XSLT is not a functional programming language).

We have functional programming languages to thank for many of the features that have been released in the .NET Framework such as generics, iterators, and LINQ.

Friday, October 10, 2008

A New Direction

As you may have noticed, I have not created a new post in over a year. This is mostly due to more work than time and a lot of other excuses.

I hope to change that trend over the next several months.

Last night I attended the Nasvhille .Net User Group (UG) to see a presentation by Elijah Manor. If you were unable to attend, you missed a great crash course on MVC (Model View Controller), JQuery, Ajax, etc. I strongly recommend downloading and reviewing the sample code.

While at the UG I was asked to put together a presentation for the meeting in March 2009. Now for the task of figuring out a topic...

My recent interests have primarily been focused on improving the performance of enterprise applications. This has led to research on scaling techniques (such as implementing REST (Representational State Transfer) with ROA (Resource Oriented Architecture), parallelism, and languages that inherently promote thread safety such as F#. There are some great Dot Net Rocks episodes that give an overview of some of these topics (http://www.dotnetrocks.com/default.aspx?showNum=367, http://www.dotnetrocks.com/default.aspx?showNum=375, http://www.dotnetrocks.com/default.aspx?showNum=377).

While it is likely that one of these topics will be chosen for the presentation, there are several other patterns and/or practices that may end up winning out. Some of these include: DI (Dependency Injection), Data Persistance Layer (NHibernate), DTO (Data Transfer Object), TDD (Test Driven Development).

Over the new few months I will be posting about various points of interests related to these topics.