Fun with PHPUnit Data Providers

Submitted by Larry on 24 August 2021 - 12:13pm

Most PHP developers are familiar with PHPUnit these days. It is the most widely used testing framework for PHP by a wide margin (although others do exist). One of its more under-utilized features, though is data providers.

Data providers are a PHPUnit feature (and many testing frameworks have an equivalent) that lets you run a single test method multiple times but with different data. Often it's presented as a way to save typing, but I find it is also a useful architectural tool, too. And there are ways to use them that are even nicer than what most people tend to do.

Continue reading this post on PeakD.

The case for partials and pipes in PHP

Submitted by Larry on 23 June 2021 - 3:07pm

The Partial Function Application RFC is currently in voting, and right now it's a close vote to the negative. I wanted to take this opportunity to try and make the broader case for partial application and for its related RFC, the pipe operator, in a way that is more appropriate for a blog post than the RFC body (which is, by design, more concerned with the finer details of "what").

The main pushback on the RFC so far is that the benefits don't outweigh the cost of yet-more-syntax in the language. Which is a fair position to hold, albeit one I hope to convince you is incorrect. That is, I believe the benefits vastly outweigh the syntax and implementation cost.

Continue reading this post on PeakD.

Good technical writing is hard

Submitted by Larry on 31 May 2021 - 8:07pm

A few days ago, I randomly tossed this out on Twitter without context:

Technical writing requires assuming the reader is simultaneously highly intelligent and utterly ignorant, without making them feel like you think they're utterly ignorant.

That shit is hard, yo.

Someone asked for ideas on how to achieve that goal, and it seemed like a topic worthy of discussion so here we are.

Technical writing is not for Dummies

I would expand the statement above a bit, actually. Good technical writing requires:

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.

First, Thinking Functionally in PHP is now available in Russian! The translation is by Alexey Pyltsyn, who is responsible for the Russian translation of the PHP documentation as well as numerous other tech book translations.

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.

Continue reading on PeakD.

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.

For this exercise, I chose to experiment with a junior version of the PSR-7 request object as a concrete example. The code below is not exactly PSR-7; it's a representative sample of portions of a naive, slightly reduced scope version of PSR-7 requests only, and using all PHP 8.0 features available. The goal is not a complete working object, but sufficient real-world representative examples of situations that an immutability plan would need to address.

Continue reading this post on PeakD.

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.

Continue reading on PeakD

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:

<?php
function A($in)
{
  
// ...
  
return B($out);
}

function

B($in)
{
  
// ...
  
return C($out);
}

function

C($in)
{
  
// ...
  
return $out;
}
?>

Structure it like this:

<?php
function A($in)
{
   
// ...
   
return $out;
}

function

B($in)
{
   
// ...
   
return $out;
}

function

C($in)
{
   
// ...
   
return $out;
}

function

doit($in) {
   
$out = A($in);
   
$out = B($out);
   
$out = C($out);
    return
$out;
}
?>

Now `A()`, `B()`, and `C()` are all easier to read, understand, and test, and we can more easily add a step B2 or D if we want. So powerful is this concept that many languages have a native operator for piping functions together like that. PHP doesn't, yet, but it's straightforward enough to do in user space anyway.


Want to know more about functional programming and PHP? Read the whole book on the topic: Thinking Functionally in PHP.


Thinking Functionally in PHP
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:

<?php
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.

<?php
$criteria
= fn(User $user): bool => $user->hasRole('moderator');

$filtered = array_filter($users, $criteria);
?>

Now we can work with the `$filtered` list, which has only the values we want. That could be a simple foreach<code> loop, or, better, it's now ideally suited for use with <code>array_map().


Want to know more about functional programming and PHP? Read the whole book on the topic: Thinking Functionally in PHP.


Thinking Functionally in PHP
Larry 3 August 2020 - 1:47pm