Functional Programming (Oct. 2020)
Let’s face it, functional programming languages are a bit of a flop.
That is a very controversial statement. People who love functional languages would swear by them. And they are a very interesting set of languages. They can do amazing things, and come along with a very interesting set of guarantees. But they just don’t have the commercial, production code influence as their procedural cousins. The only functional language I have ever seen in production was a domain specific language used to define the corporate model at an insurance company. Oh yeh, and the developers were the actuaries of the company (Thumbs up to anyone who actually knows what I am talking about).
Language aside, how can we apply functional concepts to our own code in order to make more interesting and useful products.
Pure functions are memory safe. An obvious statement to anyone familiar with functional languages, but has some very interesting side effects. Assuming that we set our data up properly to be consumed by a pure function, we can apply multithreading/multiprocessing to our problem set. We can do this without much overhead as well. A proper setup allows us to basically set these pure functions loose on a dataset and let the OS and processor do all of the work. This sort of approach allows us to much more easily take full advantage of a modern processor, and gives our user a much more responsive experience. It also allows for much more efficient data processing for data engineers/scientists.
Pure functions return the same value over the same inputs. This allows us to do result caching over inputs. For particularly expensive functions, this can save a massive amount of time in processing. This could be everything from a lookup in a database to a particularly complex numerical calculation. If it is an operation that is done a lot, and has to opportunity to have a lot of the same inputs, this strategy can save a lot of processing time. Care must be taken here not to store every value. The memory usage of a program can really spike if the domain of a function is too large, leading to worse performance overall. But again, taken with proper care, this can be a great way to improve the performance of your programs.
They can also help to minimize state. Not everything has to be wrapped around a class. Pure functions allow us to have consistent access to resources without the risking of bunging up state. If you are familiar with backend development, this actually sounds a lot like REST. One of the cornerstones of REST is that it is stateless. We can take that further and enforce a no side effect policy. This means that when we access resources, we avoid mucking with state. This means that when we access a resource, we will get the same result no matter how many times we touch it. This gives our resources much more defined, consistent behavior. Leading to a much more stable, less error prone app.
This was by no means an exhaustive list of the lessons we can learn from functional programming. These are just the ones that I find myself using most often in my day to day work.