Function Purity in F#

In my last article about Functional domain modeling, I explored the expressiveness of F# in modeling a domain. I fell in love with the simplicity and expressiveness of the language. In this article I will attempt to explore function purity in F#. In F#, functions are first class citizens because it allows to pass function as an argument to other function, return a function or assign function to a variable. Initially I found it a bit hard to wrap my head around the concept of treating functions as first class citizens. In fact one of the biggest challenge for me was surprisingly not the weird syntax of F#, but to think in terms of functions.

Coming from an OO background and not very comfortable with F#, below was my first attempt to write a use case. I basically tried to mimic a use case in a typical ports and adapters project from one of the C# projects. This use case serves a basic purpose which is to update the dimensions of a product, if it exists, of course.

Pretty straight forward. The use case accepts a DataStore dependency using which the update method can query the Products table for existence of a product. If the product is found then the product is fetched from the data store and dimensions are updated. Finally, the product with updated dimensions is persisted in the database using the data store.

Though this use case works, there are several problems with this way of writing code. Lets take a look at the problems:

Testability

The code above is not easily testable. Why you ask? Lets look at how many ways things can go wrong with this code.

  1. What if the constructor arguments are null?
  2. What if the productExists data store method returns an exception.
  3. What if updateDimensions, which in turn calls getProduct and updateProduct methods on the data store returns exception?
  4. What if the product does not exist?
  5. What if product dimensions does not exist?
  6. what if ….

and the list will go on ..

So many scenarios to test with just one dependency. What if I add ExternalService as another dependency to this use case? Imagine the number of ways this third party service call can go wrong. The point is that whenever we deal with external systems, be it database or an external service, we are entering a world of uncertainty and we do not have much control over the behavior of those external systems. It would be nice if the use case and the domain model could completely avoid any type of IO operations or side affects. Sounds like a nice idea, but a use case which does not perform IO is next to useless. Stay with me and we will explore a way to minimize or avoid IO and side affects in the use case and domain model by the end of this article.

Hidden dependencies

One of the beautiful things about F# is its expressiveness. The update method in our example is all but expressive about its intent. It has a dependency on DataStore which is not evident when we look at the method signature. This is what I call as a hidden dependency. What if in future someone modifies the update method and calls a completely different method on the datastore? Since the update method is not expressive enough, developers can assume a lot of things. Is there a way to avoid these hidden dependencies? Can we make the update method a little more expressive to avoid mistakes by future developers? Again, by the end of this article, we will try to re-write the update method to make it a little bit more expressive.

Referential Transparency

Methods in our use case are not referentially transparent. Especially the update method is not by any means. What is referential transparency? A function is referentially transparent if the function can be replaced with its corresponding value without affecting the behavior of the system. For example,

if, x + y = 10

then, the expression x + y + z = 20 can be written as 10 + z = 20

In our use case the method update, depending on whether one of the data store methods return an exception, may or may not update the product dimensions. We can never assume that a call to update method always updates product dimensions. Due to this uncertainty, I will not be able to include update method in a method chain like this and assume that warehouse system will be always notified after the product dimensions update.

There are other smaller problems with this code. But for now, lets focus on fixing the problems that we identified above and making this use case a little bit better.

Here is an attempt to fix some of the problems we discussed above.

First thing worth noticing is that these functions are not inside a type because there is no common dependency between these two functions. These functions exists on its own (under a module) and only accepts parameters that they can work with. The function name and signature are self documenting and they clearly communicate the intent. There is no scope of nasty exceptions bubbling up because of an unstable dependency. These are pure functions.

Lets see how easy it is to test these functions.

Simple and straightforward. There is no need to setup mocks for different scenarios here. You can create test data to your hearts content and test this function out. I have used Autofixture, but Property based tests are better suited for testing these functions.

Coming back to the referential transparency. The find and update functions are referentially transparent. For instance, if the Product exists in the list of products then find will always return the Product. Otherwise, it always returns None, consistently.

So, we have seen how getting rid of impure operations tremendously simplifies the program. But wait, this new shiny pure functional program does nothing useful. The end goal of this program is to update dimensions in the database. How do we make sure that we stick to function purity but also be able to perform impure operations like persisting data in a database or calling a third party service etc? You need to do the following:

  1. Push IO (impure) functions at the boundary of your domain.
  2. Call pure functions from the impure functions and not the other way round.

As long as an impure function calls a Pure function you are good. When a pure function calls an impure function then the whole method chain becomes impure.

You would have guessed where we are going with this kind of separation between pure and impure functions. OK, no points for guessing, moving impure functions at the boundary and calling pure functions from there naturally leads you to clean architecture.

Let’s see how does the call to pure functions from an impure function looks like.


tryUpdateProductDimensionsis an impure function because it calls getAllProducts which in turn calls allProducts from the DB module. DB module performs a bunch of impure operations. We can call it as the core of impurity (pun intended). For the sake of completeness, here is how I have implemented the DB module.

Conclusion

For a developer who is not fully familiar with F# or the functional programming paradigm may quite easily fall into the pit of writing OO style code with F# just like me in the beginning of this article. In F#, separating impure functions from pure functions requires discipline. As I understand, F# has no in-built magic to prevent you from mixing pure and impure functions. Haskell in that respect is pretty strict because it forces you to wrap impure functions using an IO monadic system. In simple terms an IO monad is an abstract data structure which elevates a value. Once the value is elevated you can no longer access the original value. To access the original value, you must use one of the mapping functions of the monad. I can write a similar IO monad in F#, but is it really worth the effort? The F# compiler would not honor such an IO monad. Though I think that it may be a good idea to enforce it as a coding convention for your projects.

Let me know in the comments section below what you think about the IO system in Haskell. Should F# support something similar? If yes, why and if no why not?

Advertisements

Functional Domain Modeling

Lately, I’ve been reading about functional paradigm and related programming languages. More I read about it, more I feel that modeling domains in pure C# (or Java for that matter) is unnatural and does not communicate the intent of the domain clearly.

After so many years of writing C# code, that’s quite a statement to make. But, I am serious. Lets model a simple subdomain Order for a hypothetical e-commerce company using F# then later using C# and see which of the models looks more expressive.

Lets start with C# first. Below is a typical Order entity with some typical properties.

(For brevity, I have removed other properties & methods which add behavior to this model.)

At first glance, this model looks decent. Technically, it has all the properties required to represent an ​​Order. It uses ubiquitous language for modeling the domain, it uses strong types to represent attributes of an order (so, the smell of primitive obsession is also taken care of). The properties expose only public getters, so state change (if we choose to do so) is only possible via public methods. But, does this model document the design of Order subdomain? Can a developer look at this model and understand what are the business constraints in this sub-domain? The answer is No. Let’s examine this model closely to see why.

Lack of Choice

The PaymentMethod property is of type IPaymentMethod. Typically, this interface would be implemented by concrete payment method classes like ​CashOnDelivery, CreditCard Paypal etc. But, this property does not scream about all the supported payment methods of the order sub-domain.

Of course, I can always see what are the types implementing IPaymentMethod interface, but, its well.. ehm… unnatural …(you will see why when we examine the F# model). In short, the payments methods are not explicitly documented in the model. Another problem with having an interface is that it does not allow the domain modeler to make the property hold different types (or combination of types) of values depending on a particular payment method. For instance, in case of CreditCard, I would like the property to hold Card number and CardType information, if the payment method is PayPal then the property should hold the paypal Id etc.

Another problem, though minor, is that we do not know if we are dealing with a closed set of payment methods. What if an innocent developer makes an innocent mistake and adds MyAwesomePaymentMethod as another implementation of IPaymentMethod. So, now Order is secretly supporting a new payment method and no one (include the innocent developer) has a clue about it.

Here comes F# for the rescue. F# has discriminated unions. In other words a choice type, which, if used, unambiguously documents about the only three supported payment methods available. In other words, its a closed set of payment methods. Below is how the PaymentMethod type would be modeled in F#. Looking at this file, one can see the complete spec of PaymentMethod type.


If I want to print a payment method (Of course, I wouldn’t from a domain model, perhaps I would execute a function for each matched payment method), I can pattern match and print (or do something more useful) in here.

Notice how pattern matching allows us to return different information depending on  the choice of payment method. In case of Paypal, I can use the PaypalId. Similarly, in case of Card payment, I can use the card number and card type.

Coming back to C#, I can use pattern matching and try to mimic the F# choice type behavior. But its ugly and convoluted (IDK why I am even mentioning it here 😀 ).

Stuck without Option

Let’s take a good look at the C# domain model once again. Can you infer which properties are required and which are optional? Typically, an order may or may not have a discount code which makes the property DiscountCode optional. But, the C# model fails to document that constraint. You may argue that DiscountCode could be made nullable and then all is good. But, is null equivalent to not having a discount code?

In F#, we can use ​Option<'a> to denote an optional field as shown here:

This is a self documenting domain model. By looking at it I know that an order may or may not have DiscountCode.

Luckily, Language Ext package allows us to do this in C#. The Order model in C# (using Language Ext) now looks like this:

Much better!

As mentioned, an ​Option may or may not have a value. This is denoted with ​Some or​ None respectively. Below is how one can inspect / match an Option to see if it contains a Some or a None.


That’s a short one on why I feel that functional languages are naturally good for modeling domains as they make domain models expressive and self documenting. I am still experimenting with a couple of functional languages and so far I can see clear benefits of functional languages over imperative languages when it comes to developing a project with domain driven design.

I am not sure how easy or painful it is to access database or perform I/O with a functional language. I would probably run into it at some point. Do share your experiences (good and /or painful) with functional languages under comments and Thanks for reading!

Test Driven Development with TypeScript

In this article, I will demonstrate how to write testable code using TypeScript. I assume that the reader is familiar with JavaScript, heard about Typescript and has done or secretly desires to do test driven development.

There is an excellent quick start guide on Typescript that I recommend you to go through before moving ahead.

Continue reading Test Driven Development with TypeScript

A WCF Chat Service & Client

I attended a interview recently for which the pre-requisite was to develop a chat application using WCF as part of a code challenge. The requirement was quite simple, so instead of taking the usual route of creating a WCF service and adding its reference to a client application, I decided to hand code everything without any configuration or service references!

Of course the  assumption here is that the service and client applications are owned by a single company/team so that the contracts can be shared between the service and client.

Continue reading A WCF Chat Service & Client

Mobile Push Notification Service – Design Approach (Part 1)

Overview of Push Notifications

In this article, I am going to design the architecture for implementing push notifications for you mobile application. This part only has design and architecture information, code will be covered in Part 2.

If you are new to push notifications, please read wiki article about the technology and also about GCM and APN services.

Continue reading Mobile Push Notification Service – Design Approach (Part 1)

A Thread Safe Singleton Class in .NET

In this post I will demonstrate creating a singleton class in .Net that is thread safe. As usual the singleton class should have a private constructor as shown below so that any other class cannot “directly” create an instance of our singleton class.

Continue reading A Thread Safe Singleton Class in .NET