How Can a PHP Functional Programming Library Be Used to Process Sequences of Actions in a Simpler Way - Either package blog

Recommend this page to a friend!
  All package blogs All package blogs   Either Either   Blog Either package blog   RSS 1.0 feed RSS 2.0 feed   Blog How Can a PHP Functio...  
  Post a comment Post a comment   See comments See comments (0)   Trackbacks (0)  

Author:

Updated on: 2021-04-23

Posted on: 2021-04-23

Package: Either

Often PHP developers need to write code that processes sequences of actions that may be executed or not depending on the success of prior actions.

Using the traditional if and else code structures may become confusing when there is a long sequence of actions that can be executed conditionally.

Read this article to learn how to use a functional programming approach with the Either package to avoid using the if and else statements to make the code less confusing.

Exception handling as a form of code micromanagement

We introduce a structure called Either. It's used on the functional world with programming languages like Haskell ad Scala. After I started using it, I appreciate the way it turns my PHP code more clear.




In this article you will learn:

Some Background on Functional Programming

How to Process Conditional Actions using Either

Practical Example of Processing Conditional Actions using Either

Conclusion

How to Download the Either Package or Install it With PHP Composer


Some Background on Functional Programming

I started coding more or less when I was 6 years old with a very primitive version of BASIC. Every line of code needed to be preceded by a line number. Just like this:

10 print "hello"
20 let a = 5
30 for ....

Notice the number increasing by 9. This is because I could add something between the lines, I would have done like this:

10 print "hello"
20 let a = 5
30 for ...
15 print "world"

Then it was enough to write renum to have again a distance of 9 between each line and reorder the line number 15 between the 10 and the 20.

To go to a different line we could just write goto and the line number.

After some years it arrived the wonderful Quick Basic. It had two main advantages: the possibility to save to EXE executable program file (I didn't called it compilation) and line numbers were not used.

From now on a goto statement could be referred not anymore to a line number, but to a label. To me it was a wonderful abstraction, instead of writing goto 10, I could just give more sense to my code by doing for example something like goto :error

A Better Way to Process Conditional Sequences of Actions

Nowadays, 50 years after the letter Go To Statement Considered Harmful Edsger Dijkstra's, we just stopped using GOTO or at least we think we did.

We found many alternatives to do that dirty job in a formally cleaner way. For example we introduced the concept of Exceptions.

It works wonderfully for operating systems, and should have remained on that lower level, handled by the OS in case of exceptional events not found during the compilation phase, like a division by zero.

We mixed that concept with high level concerns to micromanage the execution flow increasing the complexity of the code.

We are determining not just how a problem should be solved, but also trying to impose a temporal correlation of every module in the code. Every time it makes sense the order of execution of one or more instructions, we are talking about complexity caused by control.

How to Process Conditional Actions using Either

SOLID principles help us here. Design patterns also. Every pattern that group a set of instructions into something else can be considered as a way of reducing complexity caused by control. One pattern that come from the Functional world is the Either.

An "Either" is, as the name could suggest, a structure that can be something or something else. Lets consider an example to explain the problem:

We want to query a user by Id from a DB by calling a method getById.

$repository->getById(5)

What if 5 is not an existing record? Should this method throw an exception? or just return null? I find both cases a wrong way of describing the problem that lead to a higher complexity.

We could instead use a better functional way face up reality and determine that actually getById can return two possible types.

In case there is a user with id 5, it will return a User Object. Else it will return an Error Value object containing a textual description of the problem.

Such a structure that can be a User or an Error is an Either. An Either will be an Abstract that can be Left or Right. Left is by convention used to describe the kind of structure that represent an Error, Right, instead a correct value.

Practical Example of Processing Conditional Actions using Either

What follows is an actual piece of code that I am using on my prototype when implementing the code that will be used to handle the repositories.

private function queryFetch(PDOStatement $stm): \Utils\Either {
        try {
            $stm->execute();
            $result = $statement->fetch();
            $response = $result ?                
                new \Utils\Right($result) :
                new \Utils\Left("Empty result");
        } catch (Exception $ex) {
            $response = new \Utils\Left(
                "Query error - [{$request}] - {$ex->getMessage()})");
        }
        return $response;
    }

It becomes interesting when we introduce a common pattern used to reduce an Either. In the Scala language that is called fold and can be used also to react to something by executing a piece of code on case of Left, or another piece of code in case of Right.

Using the library in this repository, you will be able to lock down traditional if and else code structures or an equivalent structure in a more strict pattern, fold.

As an example of use, I will display actual code I used in a Scheduler I built to handle the execution of jobs.

$processExecutionResult->fold(
            function($processDescriptor) use ($gateway) {
                $gateway->setJobAndPidStatus($processDescriptor[1], TspScheduler::JOB_STATUS_SKIPPED, $processDescriptor[0]);
            },
            function($processDescriptor) use ($gateway) {
                $gateway->setJobAndPidStatus($processDescriptor[1], TspScheduler::JOB_STATUS_FINISHED, $processDescriptor[0]);
            }
        );

The result of the job, in the example above is assigned to a variable $processExecutionResult. Depending on this result, if it is an error the code will set the job value as Skipped. If it is successfully executed, I will set the state as Finished.

Conclusion

In my code I am using rarely if and else code structures. I have a piece of code for every case, and many of my methods return never two possible values. They only return one that is of type Either.

How to Download the Either Package or Install it With PHP Composer

The Either package is available for you to download as a ZIP archive by going to the download page or install it using the PHP Composer Tool by going to the installation instructions page.




You need to be a registered user or login to post a comment

Login Immediately with your account on:

FacebookGmail
HotmailStackOverflow
GitHubYahoo


Comments:

No comments were submitted yet.



  Post a comment Post a comment   See comments See comments (0)   Trackbacks (0)  
  All package blogs All package blogs   Either Either   Blog Either package blog   RSS 1.0 feed RSS 2.0 feed   Blog How Can a PHP Functio...  

For more information send a message to info at phpclasses dot org.