Boilerplate is any seemingly repetitive code that shows up again and again, like getting and setting instance variables, but seems like it ought to be much simpler.
Jon Harrop recently commented on an MSDN article on Functional Programming in C++:
(from Figure 8) 60 lines of "functional" C++ in 1 line of F#: type Immutable = {d: float; s: string} http://msdn.microsoft.com/en-us/magazine/…
60 lines is a lot of boilerplate! Here Jon defines a 1 line record type to express a simple immutable type.
C#
Java and C# reduced the repetition of header files in C++. However C# code is still full of boilerplate, to the point where third party Visual Studio plugins like Resharper have become the de-facto standard for C# developers as a band-aid over the repetitive strain.
F# on the other hand is quite terse, which not only reduces the chances of RSI. it can also make the code easier to read and maintain.
Here’s 3 short examples of how F# avoids some of the boilerplate pitfalls of C#.
1. Constructors
It is common to inject dependencies into a class via the constructor. In C# these dependencies are then typically captured as fields for use by member methods:
public class VerySimpleStockTraderImpl : IAutomatedStockTrader
{
private readonly IStockAnalysisService analysisService;
private readonly IOnlineBrokerageService brokerageService;
public VerySimpleStockTraderImpl(
IStockAnalysisService analysisService,
IOnlineBrokerageService brokerageService)
{
this.analysisService = analysisService;
this.brokerageService = brokerageService;
}
public void ExecuteTrades()
{
// ...
}
}
Notice how both the analysisService and brokerageService names are referenced 3 times. I call this the local government pattern™ as everything needs to be filled out in triplicate.
F# classes specify the primary constructor as a closure over the class members so the arguments are captured in one hit:
type VerySimpleStockTraderImpl
(analysisService:IStockAnalysisService,
brokerageService:IOnlineBrokerageService) =
member this.ExecuteTrades() = () // ...
2. Properties
Other parameters to constructors may specify initial values for properties. C# 3 introduced auto-implemented properties to help reduce the boilerplate, but it is still quite verbose:
public class OrderLine
{
public OrderLine(decimal price, int quantity)
{
this.Price = price;
this.Quantity = quantity;
}
public decimal Price { get; private set; }
public int Quantity { get; set; }
}
F# lets you specify the initial value for a property at the property definition:
type OrderLine(price:decimal, quantity:int) =
member val Price = price
member val Quantity = quantity with get, set
The sample above uses the new F# 3 auto-property syntax.
3. Out parameters
In C# if you want to return more than one value from a function you must resort to out parameters:
string value = "";
if (openWith.TryGetValue("tif", out value))
{
Console.WriteLine("For key = \"tif\", value = {0}.", value);
}
else
{
Console.WriteLine("Key = \"tif\" is not found.");
}
F# lets you return any number of values. C# methods using out parameters can be called from F# as if they returned multiple parameters:
match openWith.TryGetValue("tif") with
| true, value -> printfn "For key = \"tif\", value = %A." value
| false, _ -> printfn "Key = \"tif\" is not found."
Summary
F# class and property syntax dramatically reduce the boilerplate over C# class definitions. Returning multiple values is easy in F# and there’s even support for methods using C#’s out parameters. Here I’ve presented just 3 examples that help scrap the boilerplate, but this is only the tip of the iceberg.
Interested? Try F#