Coming Soon – Application Redesign in F#

We have a reporting application at {Redacted}, one I’ve spent more than a few hours maintaining. A colleague of mine and I (the junior developer I spoke of in a prior post) met up with the business owner of the reporting application, to talk about rebuilding the application in more functional way.

This application is not a terribly complicated one. In short, it takes data from multiple data sources, and re-aggregates it into a series of reports. It has however, had multiple developers come and “peek in”, drop code into it, and leave.  In the current C# implementation, it’s 5 distinct assemblies. There are 8 test assemblies to go with it.  It has a lot of business value riding on it being robust and correct, so the tests do seem warranted.

A word to the wise though… simple things that are more complicated than they should be AND that have a ton of tests are REFACTORING GOLD. Nothing feels better than taking something complex and unwinding it to it’s core essentials, and nothing feels better than doing it in F#!

We took a page out of For Fun and Profit’s DDD page and focused for nearly an hour on the objects and processes involved in this report. Naturally, the process seemed extremely solvable in a functional way.

Unfortunately, due to time constraints on the rest of the day we were only able to start with some very high level type definitions, but those type definitions described our problem in such a way that the business owner was able to see and understand.

We did the whole thing with an instance of VS Code and Ionide, and had types describing the objects and functions involved, all with just a simple “domain” setup in the process. Did we implement anything particularly? Well, kinda yeah, this is perfectly compile-able F# code, which as opposed to Gherkin or some other spec-based “code”, does not need a secondary interpreter.


type Name = string
type Percentage = decimal
type Return = decimal
type TargetReturn = decimal
type Model = Name
type Allocation = ( Model * Percentage ) list
type MarketValue = decimal
type AccountReturn = Return
type Account = {
TAllocations : Allocation * MarketValue;
TMinusOneAllocations: Allocation * MarketValue;
Return: AccountReturn
}
type ModelReturn = decimal * Model
type RealizedTrackingError = AccountReturn -> TargetReturn
type SleeveReturn = ModelReturn -> RealizedTrackingError
type SleevedMarketValue = Allocation -> MarketValue
// no tracking error return
type SleeveLevelPerformance = Account -> ModelReturn list -> TargetReturn

That’s the crux of this application and function. I think we may be able to get this down to a few pages of code… as opposed to the novella you’d call it now. #FeelingHopeful

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s