Byte-sized functional programming: Mapping out your data

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.

With `array_map()`, you give it an array and a function. You get back the result of applying that function to every element in the array, individually. Like so:

<?php
$arr
= [1, 2, 3, 4, 5];
$fun = fn($x) => $x * 2;
$result = array_map($fn, $arr);
?>

The advantages of that over a `foreach` loop are:

* The function is a separate operation that can be as complex as you want.
* If it's more than a line or two, make it its own function or method somewhere and test it in isolation.
* If it's trivial, you can simply inline it.
* It's clear, visually, that every element's transformation is independent of every other's, because that's how `array_map()` works. A `foreach` loop may maintain state from one iteration to the next, but `array_map()` does not.


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 27 July 2020 - 3:42pm
Byte-sized functional programming: Immutable variables are easier to understand

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:

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

<?php
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): Point
  
{
      
$new = clone ($this);
      
$new->y += $by;
       return
$new;
   }
}
?>

In the second version, once a given `Point` object is created it will never change. We can safely pass it to another function or method and be guaranteed that its value won't change without us knowing. Instead, any attempt to change it results in a new object, with its own identity, representing the new point in space. (In practice there would be other methods here as well, but we're focusing on just the mutation part.)

Code that uses immutable variables is easier to think about, because we don't have to worry about "does passing this object to this function change it?" We know it doesn't. Once we know something about an object we can guarantee that fact doesn't change. That can make a lot of subtle bugs impossible, which means we don't have to spend time looking for or correcting them.


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 21 July 2020 - 7:30am

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. :-)

Continue reading this post on PeakD.

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.

If one of the parameters you pass in is itself complex, that may make the test complex. But if the parameter is complex, that can serve as an impetus to simplify it. Rather than passing in an object, for example, just pass in a single function. If that function in practice has more complexity behind it, fine, but it makes passing a mock function trivial. Just... make a new (anonymous) function for the one test.

When your code has fewer sneaky interactions, there's less effort involved in testing as well as fewer things to test.


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 14 July 2020 - 9:28am
Byte-sized functional programming: Pure functions encourage small code

One of the many pieces of advice for a long-term sustainable code base is to keep code small. The larger a code base is, the more effort it takes to understand all the moving parts. Your brain can only keep so much mental model of your code in it at once, and if the code you're looking at is too large then what you can fit in your own "active memory" at once then you will have an increasingly hard time understanding it.

Most useful applications tend to grow larger than what the typical human can fit in their active memory, however, so you need a way to break up your code so you can load a relevant piece into your brain at once to understand and debug it. Usually that takes the form of encapsulation, coupling, cohesion, and other common object-oriented vernacular.

But what about just a pure function?

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 has a number of advantages, such as being idempotent (calling it a second time with the same values is guaranteed to return the same result) and referential transparency (a function and its parameters is synonymous with its result, which can let you optimize the function away entirely in some cases). But perhaps the biggest advantage of pure functions doesn't have a fancy name: It's really easy to fit in your brain.

If you're trying to understand a given piece of code, a pure function will always be the easiest to understand because there is no need for context. There are some explicit inputs, which you can see; There is an explicit output, which you can see; And there's nothing else to care about. Reading the function (and the data definition of its parameters) is all you need to think about, because there's nothing else to think about. Every function becomes a natural "small enough to fit in your brain" unit.

A pure function will often call other pure functions, but that only creates slightly more overhead. Once you know a function is pure, it's easy to mentally "unload" as a black box that you can deal with separately. Go read that code first, then put it out of your brain and focus on the next function.

Moreover, functional programming-style code tends to favor function composition over direct function calls. That is, rather than function A calling function B which calls function C, you call function A and pass its return value to function B, then pass B's return value to C. That whole process can be wrapped up into another function if necessary. That makes it even easier to focus on only one function at a time, which is virtually guaranteed to fit in your brain at once.


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 6 July 2020 - 5:13pm
A Major Event in PHP ebook now available

In early 2019, the PHP Framework Interoperability Group (PHP-FIG) released PSR-14, the Event Dispatcher specification. At the time I posted a long series of blog posts detailing PSR-14 in all its glory.

After discussing with a few other FIG folks, I've decided to release that blog series as a small ebook. Mainly that is to provide an easy single-point-of-reference for those who want to really understand PSR-14. Also, it serves as a simple fundraiser.

The book itself is available completely free, as the original blog posts were. However, you can also purchase a copy if you want to help support my work on the Framework Interoperability Group and Open Sourcing Mental Illness. OSMI is a non-profit organization that works to raise awareness of and research information about mental health challenges in the tech community. 50% of all royalties for this book are automatically donated to OSMI to support their vital work.

If you just want to grab a copy for free, go for it. If you are able to, though, I would encourage you to pay what you're comfortable with to support both my Open Source efforts and OSMI.

(This announcement is a bit late due to a publishing goof on my blog. If you're seeing this for the second time, my apologies.)

Larry 6 July 2020 - 5:12pm

Type Matching in PHP

Submitted by Larry on 2 February 2020 - 1:46pm

One of the nice features of Rust is the match keyword. match is similar to `switch`, but with two key differences:

  1. It requires an exhaustive match, that is, every possible value must be accounted for or a default must be provided.
  2. match is an expression, meaning you can assign the return value of one of its branches to a variable.

That makes match extremely useful for ensuring you handle all possibilities of an enumerated type, say, if using an Optional or Either for error handling. Which... is something I've been experimenting with in PHP.

It's hard to make a PHP equivalent of match that forces an exhaustive match, as PHP lacks enumerated types. However, emulating an expression match turns out to be pretty easy in PHP 7.4, and kind of pretty, too.

Skipping PHP.CE this year

Submitted by Larry on 19 July 2019 - 7:01pm

Being a conference organizer is hard. Like, seriously. Aside from the obvious logistics, and the not-at-all-obvious logistics, you're in a position to create a social gathering, not just a technical one. That comes with a lot of baggage and challenges, many of them often competing and incompatible, that need to be balanced. One in particular is ensuring that the speakers are an eclectic lot that are representative both of the community as it is and as you want it to be. That can take a lot of work.

Earlier this year the organizers of the PHP Central Europe conference (PHP.CE) approached me and asked me to submit sessions for the PHP.CE conference in Dresden this October. I rather enjoy speaking at conferences so I of course did so, and this past week they announced their speaker selections, including me with 2 sessions.

Unfortunately, some fellow speakers pointed out that their speaker selections for this year included zero women. There were numerous speakers with 2 sessions (myself included) or a workshop and a session, but no women at all.

Continue reading this post on SteemIt.

On "10x developers"

Submitted by Larry on 14 July 2019 - 11:58am

Yesterday, a VC posted a Twitter thread about "10x engineers and how to spot them.'' It is a frankly terrible thread, and predictably, it became the latest Internet Pile On(tm), which we all know is Twitter's favorite pastime. I added my own thoughts in another thread, which I want to replicate here for posterity and then expand on a bit more now that I have a real keyboard and not just my phone.

First, here's my original thread, lightly edited for clarity, paragraphs, and links:

Continue reading this post on SteemIt.