When thinking about functional programming, PHP is not the first thing that comes to our mind. However, it does offer some ways which allow us to implement functional approach to our code.
As such, functional programming in PHP should be thought of more as an additional asset you can use to make your code more readable and modular.
Eventually, this leads to an application which is easier to maintain and has less bugs.
So, what are Functional programming building blocks in PHP?
In this series of articles, we will explore the basic tools for implementing functional approach in PHP. For the first one let’s talk about concept of:
- Pure functions:
Pure functions are functions that have deterministic behaviour – they always produce the same output for the same input.
They follow the concept of referential transparency which means that a function call can always be replaced by its result without changing the behaviour of a program which ensures greater modularity and testability
To achieve such behaviour, we should follow several rules:
1.1. Pure functions do not use globals or variables outside of its scope
If a function uses a global variable, we cannot guarantee that its result will always be the same for the given input. A global variable may change its value during the lifetime of a program which can alter the output result in unpredictable ways. Let’s look at some different scenarios:
Example 1:
In the following example the variable $taxRate can be changed by some other part of code in the same class which can potentially create hard to trace bugs and we cannot reliably say that this function will always return the same result for same input.
It would be much better to write this function so that the variable $taxRate can be passed to function. This way we can ensure that it will always return the same result for given input.
Example 2:
In this next example, our function depends on a built-in PHP function getDate() which will return different result each time our function is called. This way it is hard to predict and test the result of our function for given input.
Let’s say we want to test this function by feeding it some specific dates. This is impossible since we depend on getDate() which is used inside of function body.
We can make this function pure by passing the $todayDate as variable to the function. This way we can easily feed test data to our function and check its behaviour.
1.2. Pure function should always return the same data type
Pure function should return only one data type. Let’s look at the function that for example returns duplicate values between 2 arrays.
The problem here is that the function can return an array when duplicates are found and null value if no duplicates are found. This means that the code that calls this function must implement a mechanism to handle both type of return values, increasing code complexity.
A better solution would be a function that just returns an empty array if no duplicate values are found. This way the calling code does not need to implement any additional handling of the function return value which avoids a potential break point in our code.
1.3. Pure functions do not create any side effects
A pure function should only return value and not modify external state, variables and data outside its own scope. By side effects we mean actions that affect the global state of application.
Examples of a side effect would be:
- functions that output text to screen
- functions that write to database
- functions that change the application global state. e.g.: writing to session data etc.
Now, creating an application that doesn’t output anything to screen or write anything to the database wouldn’t make much sense. The main idea here is to keep the “pure” parts which handle application logic separated from the “dirty” parts which deal with the database, screen output etc…
- To conclude
So, what can we conclude about Functional programming building blocks in PHP? Even when writing a traditional OOP oriented application in PHP, using pure functions in codebase leads to an application that is more robust and bug-free. Pure functions are much easier to maintain and test since they have no hidden dependencies and states.
Now that you’ve read this, are you maybe interested in Materialized View Refresh Strategies? Click to learn more!