Designing a functional list API
The basics of functional pipelines.
This is part of a series on refactoring towards functional programming.
Introduction
Imperative versus declarative programming
Functional principles for better code
Designing a functional list API
Writing a filter function
Transforming with Map
Isolating side effects with ForEach
Functional composition
Functional composition through extension methods
Refactoring to point free
Functional refactoring conclusions
Let’s look at the example problem again.
foreach (var dish in menu)
{
var calories = dish.Calories;
if (calories < 400)
{
Console.WriteLine(dish.Name);
}
}
If we break it down, we’re doing four things inside the loop. We pick the calories, check if they are lower than the calorie limit (400), pick out the name and we write it out. It seems that there are three types of operations happening. Checking a condition, getting something and doing a side-effect. What we want to do is find suitable functional abstractions that work with these three operations. We also need them to be immutable, which means we need to create a new list after every operation since we cannot modify the original in any way.
When thinking of list-operations in a functional way, we often picture iteration as values flowing down a stream, changing along the way into a new form. This is often called a pipeline.
The first two steps in the pipeline are common operations in functional programming known as filtering and mapping. The third step is out of bounds of functional programming, but we’ll still implement it in the pipeline in a function, as a place to put side-effects. If we can’t rid ourselves of side-effects, we isolate them.
Here is the pipeline again with the three parts categorized.
Now it’s time to create a small class of higher-order functions to help us refactor the code towards functional thinking. We’ll stick to our principles - the functions should be pure, and they should be immutable. First, we’ll do the filtering.
Leave a Comment
Your email address will not be published. Required fields are marked *