PHP

One year of functional PHP; now in Russian!

Submitted by Larry on 11 May 2021 - 8:14pm

A year ago, I published my first solo book, Thinking Functionally in PHP. The reception has been extremely positive; almost everyone that's read it (that has bothered to talk to me about it) has found it clear, helpful, and enlightening. Mission accomplished!

To celebrate the one year anniversary of the book's publication, I am happy to make two announcements.

I made a TYPO

Submitted by Larry on 5 May 2021 - 4:55pm

I am a firm believer in "anything worth doing is worth doing right." So when given the opportunity to get paid to do that, it's hard for me to say no. Which is why I didn't.

I am happy to report that this is my first week in my new role as Staff Engineer on the TYPO3 core contributors team.

TYPO3 is one of the oldest Content Management Systems on the market, dating back to 1998 in one form or another. In that time it's built up a very loyal following and a robust, active community of users, developers, and contributors. It has also, like any system of its pedigree, built up a lot of code over the years that hasn't kept up with modern practices.

Fortunately, I have some experience in helping to modernize large Free Software projects.

Object properties, part 2: Examples

Submitted by Larry on 9 January 2021 - 6:33pm

In my last post, I went over some of the pros and cons of various proposals for making PHP objects more immutable-ish, and the contexts in which they would be useful. I also posted the link to the PHP Internals list, where it generated some interesting if meandering discussion (as is par for the course on Internals).

One of the requests was for sample code to demonstrate why I felt particular feature proposals were better than others. Fair enough! This post is in response to that request, and I think it will help illuminate the challenges better.

Object properties and immutability

Submitted by Larry on 28 December 2020 - 5:30pm

There has been much discussion in recent weeks in PHP circles about how to make objects more immutable. There have been a number of proposals made either formally or informally that relate to object property access, all aimed at making objects safer through restricting write access in some way.

Since my last mega post on PHP object ergonomics was so well-received and successful (it resulted in both constructor promotion and named arguments being added to PHP 8.0, thanks Nikita!), I figure I'll offer another summary of the problem space in the hopes of a deeper analysis suggesting a unified way forward.

Byte-sized functional programming: Composition over inheritance for functions, too

A popular refrain in object-oriented code is to favor object composition over inheritance. It offers more flexibility, less overhead, and ends up being easier to reason about. The same concept applies to functions, too!

A common pattern is to have a function that does some work and then calls another function, which does some work and calls another function, and so on. The problem is that the first function then cannot be used or tested without the entire chain of other functions it calls. This is the function equivalent of "inheritance."

Instead, we can compose functions, that is, pipe them together. Instead, take the output of the first function and pass it to the second, then take the second's output and pass it to the third, etc. That way, each of the functions can be reused, tested, and understood in isolation, then we can stick them together like LEGO blocks to build whatever series of steps we want.

That is, instead of this:

Larry 15 August 2020 - 10:07am
Byte-sized functional programming: Filter first

Often when working with a list, we only want to work with a subset of a list that meets some criteria. All non-zero values, for example, or all users that have a given role. The procedural way to do that is to stick an if statement inside a foreach loop:

foreach ($list as $value) {
    If (!meets_criteria($value)) {
        continue;
    }
    // ...
}

That mixes up the filtering with the iteration, though. It also doesn't work if we're using array_map().

Instead, we can make stripping down the list a separate operation called "filter." PHP offers the array_filter() function for that purpose.

Larry 3 August 2020 - 1:47pm

Byte-sized functional programming: Mapping out your data

Submitted by Larry on 27 July 2020 - 3:42pm

Procedural code tends to think in terms of writing out steps, and so the usual way to work with a list is to iterate it using a `for` or `foreach` loop.

Functional code tends to think in terms of the relationships and transformations between data, where those relationships and transformations are defined as functions. That means the natural way to work with a list is to define a function that is the relationship between one list and another. The most common way of doing that is with a "map," which in PHP usually means the `array_map()` function.

Byte-sized functional programming: Immutable variables are easier to understand

Submitted by Larry on 21 July 2020 - 7:30am

An immutable variable is one whose value doesn't change after it has been first set. PHP doesn't natively support that, but we can write our classes in such a way to simulate it. For example, rather than this:

class Point
{
   private int $x;
   private int $y;
  
   public function __construct(int $x, int $y)
   {
       $this->x = $x;
       $this->y = $y;
   }
  
   public function moveUp(int $by): void
   {
       $this->y += $by;
   }
}

We can write this:

Advice for new speakers

Submitted by Larry on 18 July 2020 - 5:18pm

Someone messaged me recently to say he had just been selected for his first-ever conference talk, and since the talks of mine he'd seen in the past were so inspiring he wanted to know if I had any advice for new speakers. Since flattery will often get you somewhere, I offered the following advice. I figure it's generic enough that I should share it more widely. :-)

Byte-sized functional programming: Pure functions make testing easy

When testing stateful code, you have to first set up all of the explicit and implicit state that a given piece of code depends on. If the object you're testing has many dependencies that could be complex, or references global variables, or calls many other routines with their own dependencies, you may be looking at a lot of complex setup that makes testing hard to do effectively.

Pure functions greatly reduce that problem.

A pure function is a function that:

  • has no inputs other than those explicitly specified;
  • has no effect on any value other than the value it returns.

That means there is, by definition, only one place to inject dependencies: the call itself. And there's only one effect to validate: the return value of the function. No need to call a function and check what the effect was on some other value or piece of code: by definition, the only effect is the return value.

Larry 14 July 2020 - 9:28am