Composition is a technique often used to build software by creating cohesive units that interact with each other to form the overall system. At the code level these units mainly consist of functions and objects. A system can be built by composing objects with abstractions that define the rules for communication with other objects. An alternative way of building the system is by composing functions and defining the rules of communication through functional contracts (i.e. passing functions into functions). Coming from an object oriented background I feel this second approach is worth exploring further.

Using the C# GildedRose kata as an example, an object oriented way of expressing the quality adjustment in a product looks like this

public class GildedRose
{
private static readonly Dictionary<string, IProduct> Products =
new Dictionary<string, IProduct>
{
{"Aged Brie", new Product(new QualityAdjuster(+1))},
{"Backstage passes to a TAFKAL80ETC concert",
new Product(new BackstageQualityAdjuster(1))},
{"Sulfuras, Hand of Ragnaros", new SulfurasProduct()},
{"NORMAL ITEM", new Product(new QualityAdjuster(-1))},
{"Conjured Mana Cake", new Product(new QualityAdjuster(0))}
};
public static void UpdateQuality(List<Item> items)
{
foreach (Item item in items)
Products[item.Name].Update(item);
}
}
public interface IProduct
{
void Update(Item item);
}
public class Product : IProduct
{
private readonly IAdjustQuality _qualityAdjuster;
public Product(IAdjustQuality qualityAdjuster)
{
_qualityAdjuster = qualityAdjuster;
}
public void Update(Item item)
{
item.SellIn = item.SellIn - 1;
item.Quality = item.Quality + (_qualityAdjuster.Adjust(item));
item.Quality = Math.Min(50, item.Quality);
item.Quality = Math.Max(0, item.Quality);
}
}
public class SulfurasProduct : IProduct
{
public void Update(Item item)
{
}
}
public interface IAdjustQuality
{
int Adjust(Item item);
}
public class QualityAdjuster : IAdjustQuality
{
private readonly int _defaultQuality;
public QualityAdjuster(int defaultQuality)
{
_defaultQuality = defaultQuality;
}
public int Adjust(Item item)
{
return item.SellIn < 0 ? 2 * _defaultQuality : _defaultQuality;
}
}
public class BackstageQualityAdjuster : IAdjustQuality
{
private readonly int _defaultQuality;
public BackstageQualityAdjuster(int defaultQuality)
{
_defaultQuality = defaultQuality;
}
public int Adjust(Item item)
{
if (item.SellIn < 0)
return -item.Quality;
if (item.SellIn < 5)
return +3;
if (item.SellIn < 10)
return +2;
return _defaultQuality;
}
}
Now I have a couple of issues with the code above. First there is some repetition and unnecessary noise in the code that declares constructors for various IAdjustQuality implementations. Secondly IAdjustQuality and IProduct are single-method interfaces and I am suspicious of interfaces with single methods. Interfaces are generally created for a bunch of related methods.

An alternative way to express the quality adjustment in a Product in the GildedRose example would be to compose functions rather than objects. Although C# traditionally has been perceived to be an object oriented language but with lambda expressions it is very much possible to write functional code in C#. Single-method interfaces are easy to replace with the usage of closures and "function pointers" as long as the function has a compatible signature to the method declared in the single-method interface. Lets see how we can replace IAdjustQuality with its functional equivalent.

public class GildedRose
{
private static readonly Func<int, Func<Item, int>> AdjustQuality =
quality => item => item.SellIn < 0 ? 2*quality : quality;
private static readonly Func<Item, int> AdjustBackstageQuality =
item =>
{
if (item.SellIn < 0)
return -item.Quality;
if (item.SellIn < 5)
return +3;
if (item.SellIn < 10)
return +2;
return 1;
};
private static readonly Dictionary<string, IProduct> Products =
new Dictionary<string, IProduct>
{
{"Aged Brie", new Product(AdjustQuality(1))},
{"Backstage passes to a TAFKAL80ETC concert",
new Product(AdjustBackstageQuality)},
{"Sulfuras, Hand of Ragnaros", new SulfurasProduct()},
{"NORMAL ITEM", new Product(AdjustQuality(-1))},
{"Conjured Mana Cake", new Product(AdjustQuality(0))}
};
public static void UpdateQuality(List<Item> items)
{
foreach (Item item in items)
Products[item.Name].Update(item);
}
}

Creating the AdjustQuality and AdjustBackstageQuality functions results in the removal of  2 classes and the interface declaration itself. Notice AdjustQuality function uses partial application i.e. it is a function that returns another function. The first function is applied partially to return the actual function. This should be more clear after looking at the Product class now.
public class Product : IProduct
{
private readonly Func<Item, int> _adjustQuality;
public Product(Func<Item, int> adjustQuality)
{
_adjustQuality = adjustQuality;
}
public void Update(Item item)
{
item.SellIn = item.SellIn - 1;
item.Quality = item.Quality + (_adjustQuality(item));
item.Quality = Math.Min(50, item.Quality);
item.Quality = Math.Max(0, item.Quality);
}
}

Applying the same technique of replacing an interface with its equivalent function pointer the IProduct interface can also be removed and the resulting code looks like this. 

public class GildedRose
{
private static readonly Func<int, Func<Item, int>> AdjustQuality =
quality => item => item.SellIn < 0 ? 2 * quality : quality;
private static readonly Func<Func<Item, int>, Action<Item>> UpdateProduct =
adjustQuality => (item =>
{
item.SellIn = item.SellIn - 1;
item.Quality = item.Quality + (adjustQuality(item));
item.Quality = Math.Min(50, item.Quality);
item.Quality = Math.Max(0, item.Quality);
});
private static readonly Func<Item, int> AdjustBackstageQuality = item =>
{
if (item.SellIn < 0)
return -item.Quality;
if (item.SellIn < 5)
return +3;
if (item.SellIn < 10)
return +2;
return 1;
};
private static readonly Dictionary<string, Action<Item>> Products =
new Dictionary<string, Action<Item>>
{
{"Aged Brie", UpdateProduct(AdjustQuality(1))},
{"Backstage passes to a TAFKAL80ETC concert",
UpdateProduct(AdjustBackstageQuality)},
{"Sulfuras, Hand of Ragnaros", item => { }},
{"NORMAL ITEM", UpdateProduct(AdjustQuality(-1))},
{"Conjured Mana Cake", UpdateProduct(AdjustQuality(0))}
};
public static void UpdateQuality(List<Item> items)
{
foreach (Item item in items)
Products[item.Name](item);
}
}
So why compose functions rather than objects. One of the benefits as you may have noticed straight away is that functional code is pretty succinct and has less lines of code (less than half of the original object oriented approach). The noise around declaring single-method interfaces and their implementations is no more present. However the functional approach might seem confusing and less readable especially the excessive use of lambda expressions and partial application. But I guess depending on whether you come from the object oriented background or the functional one you could sway either way. There is no right or wrong here. The basic idea is how objects and functions can be used to split your overall system into manageable chunks. The flexibility of achieving that in more than one way is a powerful tool to have.