# /usr/portage

## Functional programming in PHP16

PHP has traditionally been a simple, procedural language that took a lot of inspiration from C and Perl. Both syntax wise and making sure function signatures are as convoluted as possible. PHP 5.0 introduced a proper object model but you know all of that already. PHP 5.3 introduced closures and PHP 5.4 improved closures very much (hint: $this is available per default). ### What is functional programming anyway? After a few years introducing more and more functional elements to my source code, it is not that straight forward to answer. I still do not have a coherent definition, but “I know it when I see it”. Let me put it that way: functional programs generally do not alter state, but use pure functions. Pure functions take a value and return another value without altering its input argument. The opposite example is a typical setter in an object oriented context. Typical functional programming languages support higher order functions, that is, functions that take or return other functions. A lot of them support a concept that is called currying or partial function application (PFA). Additional characteristics found in functional programming languages are elaborated type systems that e.g. use option types to prevent null pointer issues typical for imperative or object oriented programming languages. Functional programming has a lot of desirable attributes: not fumbling with state makes parallelism easier (not easy, it’s never easy), focusing on the smallest unit of reusable code, a function, can lead to really interesting effects with regards to reusability, requiring functions to be deterministic is generally a good idea for stable software. ### What does PHP has to offer? PHP is not a “real” or “pure” functional language. Far from it. We don’t have a proper type system, the cool kids make fun of our exotic syntax for closures and we have array_walk() that looks functional but allows altering state. Nevertheless, there are a few interesting building blocks for functional programming. Let’s start with call_user_func, call_user_func_array and $callable(). call_user_func takes a callback and a list of arguments and invokes the given callback with the given arguments. call_user_func_array does something similar, except, it takes an array of arguments. That’s pretty much the same as fn.call() and fn.apply() in JavaScript (without passing a scope). A less well known shiny new thing in PHP 5.4 is the ability to call functions directly on callables. callable is a meta type in PHP (as in: it consists of various underlying types): a callable can be a string to call simple functions, an array of <string,string> to call static methods, and array of <object,string> to call object methods, an instance of Closure or anything implementing the __invoke() magic method, also known as a Functor. This will look like that:

$print = 'printf';$print("Hello %s\n", 'World');


Additionally, PHP 5.4 introduces a new type hint “callable” that provides a simple contract for the callable meta type.

PHP also supports anonymous functions. As I said before, the Haskell community made fun us but hey, we finally have it. The jokes are somewhat expected, because the syntax is somewhat verbose. Let’s see a simple Python example.

map(lambda v: v * 2, [1, 2, 3])


Nice. Let’s see a little Ruby example:

[1, 2, 3].map{|x| x * 2}


Also pretty, nevertheless we use a block here and not strictly a lambda expression. Ruby has lambda as well, but List.map happens to take a block, not a function. Next example is Scala:

List(1, 2, 3).map((x: Int) => x * 2)


For a strictly typed language that is pretty compact. Now look at PHP:

array_map(function ($x) {return$x * 2;}, [1, 2, 3]);


A function keyword and no implicit return is what makes it look quite cumbersome. But anyway, it works. Another building block for functional programming.

array_map is a good start, there is also array_reduce. Another two important functions.

### A real world functional example

Let’s start with a simple program to calculate totals in a shopping cart:

$cart = [ [ 'name' => 'Item 1', 'quantity' => 10, 'price' => 9.99, ], [ 'name' => 'Item 2', 'quantity' => 3, 'price' => 5.99, ] ]; function calculate_totals(array$cart, $vatPercentage) {$totals = [
'gross' => 0,
'tax'   => 0,
'net'   => 0,
];

foreach ($cart as$position) {
$sum =$position['price'] * $position['quantity'];$tax = $sum / (100 +$vatPercentage) * $vatPercentage;$totals['gross'] += $sum$totals['tax'] += $tax$totals['net'] += $sum -$tax;
}

return $totals; } calculate_totals($cart, 19);


Yes it is a simple example that will only work for a single market but it’s a halfway complicated calculation and we can easily refactor into a more functional style.

Let’s use higher order functions first:

$cart = [ [ 'name' => 'Item 1', 'quantity' => 10, 'price' => 9.99, ], [ 'name' => 'Item 2', 'quantity' => 3, 'price' => 5.99, ] ]; function calculate_totals(array$cart, $vatPercentage) {$cartWithAmounts = array_map(
function (array $position) use ($vatPercentage) {
$sum =$position['price'] * $position['quantity'];$position['gross'] = $sum;$position['tax'] = $sum / (100 +$vatPercentage) * $vatPercentage;$position['net'] = $sum -$position['tax'];
return $position; },$cart
);

return array_reduce(
$cartWithAmounts, function ($totals, $position) {$totals['gross'] += $position['gross'];$totals['net'] += $position['net'];$totals['tax'] += $position['tax']; return$totals;
},
[
'gross' => 0,
'tax'   => 0,
'net'   => 0,
]
);
}

calculate_totals($cart, 19);  Now we no longer alter state, not even in the function itself. array_map() returns a new array of cart positions with gross, tax, net amounts and array reduce puts together the totals array. But can we go further? Can we make it much simpler? What if we destructure the program further and abstract it to what it really does: * Sum an element of an array multiplied it by another element * Take away a percentage of that sum * Calculate the difference between the percentage and the sum Now we need a little helper. This little helper is functional-php, a small library of functional primitives I’ve been developing for a few years now. First, there is Functional\pluck() that does the same as _.pluck() from underscore.js. Another helpful function is Functional\zip(). It “zips” together two lists, optionally using a callback. Functional\sum() sums the elements of a list. use Functional as F;$cart = [
[
'name'     => 'Item 1',
'quantity' => 10,
'price'    => 9.99,
],
[
'name'     => 'Item 2',
'quantity' => 3,
'price'    => 5.99,
]
];

function calculate_totals(array $cart,$vatPercentage)
{
$gross = F\sum( F\zip( F\pluck($cart, 'price'),
F\pluck($cart, 'quantity'), function($price, $quantity) { return$price * $quantity; } ) );$tax = $gross / (100 +$vatPercentage) * $vatPercentage; return [ 'gross' =>$gross,
'tax'   => $tax, 'net' =>$gross - $tax, ]; } calculate_totals($cart, 19);


A good counter argument is: is that really easier to read. At first: no, at a second look: you’ll get used to it. It took me while to get used to the syntax of Scala, it took a while to learn object oriented programming and it takes a while to grasp functional programs. Is this the perfect solution? No. But it shows what you can do by thinking more in terms of applying functions to data structures instead of using expressions like foreach to handle work on data structures.

### What else can we do?

Ever had issues with null pointer exceptions? There is php-option that provides an implementation of a polymorphic “maybe type” using a PHP object.

Than there is partial application: it transforms a function that takes n parameters to a function that takes <n parameters. Why is that helpful? Think about extracting the first character from a list of strings.

The boring way:

$list = ['foo', 'bar', 'baz'];$firstChars = [];
foreach ($list as$str)  {
$firstChars[] = substr($str, 0, 1);
}


The functional’ish way without PFA (partial function application):

array_map(function ($str) {return substr($str, 0, 1);}, ['foo', 'bar', 'baz']);


The way with PFA using reactphp/curry (my favorite currying implementation for PHP):

use React\Curry;
array_map(Curry\bind('substr', Curry\…(), 0, 1), ['foo', 'bar', 'baz']);


Yes. … (HORIZONTAL ELLIPSIS, U+2026) is a valid function name in PHP. But if you do not like that, use Curry\placeholder() instead.

### The end

Functional programming is a fascinating topic and I needed to name a single thing that I learned the most from in the
last years, it was looking into functional paradigms. It’s so different it will make you brain hurt. But in a good way.
Ah, one last thing: read Real World Functional Programming. It’s full of good advice and real world examples.

#### Update

Thank you Christopher Jones for fixing the higher order function example (the second step).

#### Update II

Thank you Anthony Ferrara for pointing out that the array_map example was wrong. Gotta love parameter ordering.

#### Update III

There is a russian translation.

#### Update IV

Thanks for the serbo-croation translation

Filed on 17-01-2013, 02:02 under , , , , , , , & 16 comments & no trackbacks

Trackback specific URI for this entry

1. ##### Martin Jansen means:
published on January 17th 2013, 12:12:05 pm

Regarding the lack of a coherent definition of functional programming. One of the most concise explanations I have seen so far is this one here:

http://pragprog.com/magazines/2013-01/functional-programming-basics

Basically it boils down to referencial transparency, i.e. what you’ve mentioned as "not altering state".

2. ##### Lars Strojny opines:
published on January 17th 2013, 07:34:15 pm

Cool, appreciated!

published on January 17th 2013, 11:49:24 pm

Good Piece. I always had thinked that a functional approach would bring many benefits to imperative languages too.
I have written a small php library of common functionals for php, currying included, you can find it in github (https://github.com/nicmart/Functionals).

4. ##### Lars Strojny supposes:
published on January 17th 2013, 11:53:11 pm

Cool, Functionals look nice. If you are interested, the whole compose, combine look very interesting. If you are interested you could contribute them to Functional PHP.

5. ##### Nicolò Martini reckons:
published on January 18th 2013, 09:41:14 am

I’m already a "starrer" of the library, and if the my free time will allow it, I’ll certainly give my contribute.

6. ##### Anthony Ferrara responses:
published on January 18th 2013, 06:02:18 pm

FYI: your array_map example is wrong. The parameters for array_map are $callback,$array. You’ve reversed them.

Yay! Yet another reason to love PHP’s confusing and illogical function parameter ordering…

7. ##### Lars Strojny means:
published on January 18th 2013, 06:05:36 pm

Thanks, fixed.

8. ##### Hero Glass reckons:
published on January 26th 2013, 03:36:25 pm

Very good read! I hope you won’t mind that I did a translation of it to Russian.
By the way, a little typo: in the first real world PHP example, isn’t "foreach ($carts as$position) {" should be "foreach ($cart as$position) {"?

9. ##### Lars Strojny returns:
published on January 27th 2013, 11:07:24 am

Thanks, fixed.

published on January 26th 2013, 11:23:14 pm

2) Why strpos?
> array_map(Curry\bind(‘strpos’, Curry\…(), 0, 1), [‘foo’, ‘bar’, ‘baz’]);

example from reactphp/curry call substr too:

$firstChar = Curry\bind(‘substr’, Curry\…(), 0, 1);$mapped = array_map($firstChar, array(‘foo’, ‘bar’, ‘baz’)); Reply 11. ##### Lars Strojny says: published on January 27th 2013, 11:08:36 am Thanks, fixed as well. Reply 12. ##### Lars Strojny answers: published on January 27th 2013, 11:13:59 am Very cool of you to translate the article to russian. Where can I find it to link to it? Reply 13. ##### hshhhhh states: published on January 27th 2013, 05:12:17 pm you can find url to russian version in twitter, i can’t post here because you have got a very strong antispam :D also you should create rss here. Reply 14. ##### hshhhhh responses: published on January 30th 2013, 01:05:35 pm Can you explain me why curring so good? I don’t understand. For example this code: use React\Curry; array_map(Curry\bind('substr', Curry\…(), 0, 1), ['foo', 'bar', 'baz']);  I can write as: $func =
array_map(function($string) { return substr($string, 0, 1); }, ['foo', 'bar', 'baz']);


Yes, it’s not clean as your code, but it works and in your code it works the same way by with syntax sugar.

And I saw much articles where author said that ‘curring is a very usefull’, but I don’t understand for what.

It I will write something like it:

foreach (['foo', 'bar', 'baz'] as &amp;$value) {$value = substr(\$value, 0, 1);
}


it will works faster then code with anonymous functions. May be in another languages it will no difference, but for what this curring?

15. ##### Lars Strojny supposes:
published on January 30th 2013, 01:30:23 pm

Yep, sure. You can always wrap the closure. Having an expression or function for partial function application (which is more exact than currying as term) is just more condense.