• Prev
  • Stop
  • Play
  • Next
  • Aquarium
  • Fine Day
  • Bright Green Lights
  • For Your Smile
  • Pull You Through
  • In Your System
  • subscribe
  • follow me on twitter
    • 2010-03-06T23:08 is it true O2 are launching a daily tethering option for the iPhone?
    • 2010-03-06T22:52 result of today's hacking: http://bit.ly/bYEq0w
    • 2010-03-05T22:40 these days my brain just filters out all of these three-point product intros. "tag. share. discover." meh.
    • 2010-03-05T22:24 def collatz(x); puts x; return if x == 1; if x % 2 == 1; collatz((3 * x) + 1) else collatz(x / 2); end end #xkcd
    • 2010-03-03T23:21 @nathanstaines no probs. someone else emailed me with the same issue and then the penny dropped :) qcd site looks awesome btw.
  • elsewhere
    • github github
    • linkedin linkedin
    • delicious delicious
    • flickr flickr
    • email email

  • Home
  • Logfile
  • Open Sawrce
  • Labs
  • About
  • Sitemap

Archive for May 2009

23.05.2009

Finding the arity of a closure in PHP 5.3

As part of the php-helpers project I’ve been working on a small library of functional programming primitives for PHP 5.3, including all the usual suspects like map(), every() and inject(). As we know, PHP arrays are really ordered maps, and when iterating with foreach we’re sometimes interested in both the key and value and other times it’s only the value we’re after. Preferably, code written in a functional style would be consistent with this pattern, each operation employing a single function capable of intelligently passing either $key, $value or `$value` based on what the user-specified lambda expected. So is this possible in PHP?

Arity to the rescue

From Wikipedia: “the arity of a function or operation is the number of arguments or operands that the function takes.”. Bingo. If we could somehow find the arity of a given closure, we could use this to decide whether to pass $key, $value or simply $value to our anonymous function. A language like Ruby makes finding a lambda’s arity as simple as foo.arity, but PHP isn’t quite so elegant, instead requiring us to whip out a bit of reflection:

Using reflection to find the arity of a closure
  1. <?php
  2. $c0 = function() {};
  3. $c1 = function($a) {};
  4. $c2 = function($a, $b) {};
  5. $c3 = function($a, $b, $c) {};
  6.  
  7. foreach (array($c0, $c1, $c2, $c3) as $c) {
  8.   $r = new ReflectionObject($c);
  9.   $m = $r->getMethod('__invoke');
  10.   echo $m->getNumberOfParameters() . "\n";
  11. }
  12. ?>

I’ll refrain from any puns alluding to vulgarity. Anyway, this yields the desired result:

  1. jason@ratchet Desktop  $ /usr/local/bin/php closure.php
  2. 0
  3. 1
  4. 2
  5. 3

Here’s the arity() function, and the resulting implementation of every(), taken directly from functional.php:

Implementation of arity() and every()
  1. // returns the arity of the given closure
  2. function arity($lambda) {
  3.     $r = new ReflectionObject($lambda);
  4.     $m = $r->getMethod('__invoke');
  5.     return $m->getNumberOfParameters();
  6. }
  7.  
  8. function every($iterable, $lambda) {
  9.     if (arity($lambda) < 2) {
  10.         foreach ($iterable as $i) $lambda($i);
  11.     } else {
  12.         foreach ($iterable as $k => $v) $lambda($k, $v);
  13.     }
  14. }

The lack of closures in PHP has long been one of the language’s most frustrating shortcomings when compared to its rivals, and their addition is – at least for me – the most exciting change in 5.3. While PHP will probably never be regarded as a “beautiful” language, closures allow us to write code which is both more flexible and concise by making it possible to define behaviour directly in the context it is being used, rather than having to implement it elsewhere in auxiliary classes or functions. Get on the bandwagon!

read more >

Archives

  • December 2009 (2)
  • May 2009 (1)
  • March 2009 (1)
  • January 2009 (1)
  • October 2008 (1)
  • September 2008 (2)
  • August 2008 (2)
  • June 2008 (2)

Friends

  • Magic Lamp
  • Garage Duo
  • Atom
  • Drew not Weird
  • Enthusiastik
  • Fusible Front
  • Jam Hot
  • John Disco
onehackoranother.com © 2008 - 2010 Jason Frame. All rights reserved.