Skip to content

Instantly share code, notes, and snippets.

@i-am-tom
Created November 11, 2016 15:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save i-am-tom/6c2ca614dbc7b366c3815107b6207e59 to your computer and use it in GitHub Desktop.
Save i-am-tom/6c2ca614dbc7b366c3815107b6207e59 to your computer and use it in GitHub Desktop.
A little tale to help the arrow syntax RFC along.
<?php
// == Arrow functions - A Love Story ==
// Arrow functions are wonderful for a variety of reasons, and below are some
// of my favourites. Hopefully, these will provide some sort of support for
// the RFC. Note that none of these have been tested, though...
// First up: arrow functions for clear and succinct code. The ability to
// create lambdas with relatively little boilerplate will most obviously
// and primarily benefit users of callback-accepting functions.
// We can write tidy ways to do traversals:
$tree = ['a' => ['b' => ['YAY']]];
$result = array_reduce(['a', 'b', 0], ($t, $k) => $t[$k], $tree);
// This computes a dynamic average:
array_reduce(range(0, 10), ($x, $y) => (3 * $x + $y) / 4, 0);
// And this one converts 0 - 25 to A - Z:
array_map($x => chr($x + 65), range(0, 25));
// Reverse sort with fancy PHP7:
usort($dictionary, ($a, $b) => strlen($b) <=> strlen($a));
// Secondly: lexical scope access. It's a common pitfall when introducing
// PHP to developers from other languages, as the "use" mechanism for copying
// variables into a closure scope is quite unique to PHP.
// LOADS of utility functions:
function pluck($k, $xs) {
return array_map($x => $x[$k], $xs);
}
function omit($k, $xs) {
return array_filter($xs, $i => $k == $i, ARRAY_FILTER_USE_KEY);
}
function every($p, $xs) {
return empty(array_filter($x => !$p($x), $xs));
}
// Thirdly: partial application. https://wiki.php.net/rfc/pipe-operator would
// propose a "$$" operator to act as a placeholder in function calls, which is
// actually partial application with some syntactic sugar. Specifically, the
// RFC can be mimicked with some simple combinators:
// Function composition (a reversed "lazy chain").
$compose = $f => $g => $x => $f($g($x));
$map = $f => $xs => array_map($f, $xs);
$capitaliseEach = $map('ucfirst');
// Now, we can compose these to make complex operations.
$process = $compose($map('ucfirst'))($map('strrev'));
// We can now use some functor laws to optimise this....
$process = $map($compose('ucfirst')('strrev'));
// There are an awful lot of optimisations that can be made when functions can
// be partially applied. Note that this is already possible in PHP, but it's
// rather ugly:
$compose = function ($f) {
return function ($g) use ($f) {
return function ($x) use ($f, $g) {
return $f($g($x));
};
};
}
// Having short array syntax has made this sort of code very popular within the
// JS community. Even if you don't go "fully functional", these are still usable:
$pow = $x => $y => pow($x, $y);
array_map($pow(2), range(0, 10));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment