php

Accumulator passing

Intent
Use of an accumulator variable to allow the finer control over the assembly of the final result of an algorithm
Motivation
We want to use method-chaining, but we need to return values from some of the methods
Implementation
Use an accumulator variable
Example
a simple IFS( iterative function system )
x(t+1) = x(t) + f[random(1..i)]( 1/(t+1) )
note: the implementation is quite naive and not foolproof at all.
<php
class example {
  private $ifs = array( 'sin', 'cos' );  

  function x( &$acc ) {
    $acc['t'] += 1;
    $acc['x'] = $acc['x'] + $this->ifs[ rand(0,1) ]( 1/ $acc['t'] );
    return $this;
  }
}

$ex = new example();

$something = array('t'=>0, 'x' => 0 );
$ex->x($something) -> x($something) -> x($something);
print 't: ' . $something['t'] . ' x: ' . $something['x'] . "\n";
?>
and when you run it:
vlado@cow:~/php design patterns$ php  php accumulator_passing.php
t: 3 x:1.34692254127
vlado@cow:~/php design patterns$ php accumulator_passing.php
t: 3 x: 1.64809122021
vlado@cow:~/php design patterns$ php accumulator_passing.php
t: 3 x: 2.66401049301

Fluent Interfaces/ Method chaining

Intent
return the next context of computation, enable simple and flexible sequencing of computation
Motivation
We want to provide a small domain specific language to improve the readability of the code
Implementation
return the next expected object (state)
Examples

class fluent_class {
  var $state_var;
  function self_next( $arg ) {
    ....
    return $this;
  }
  function other_next( $arg ) {
    ....
    return $this->another;
  }
}

$obj = new fluent_class();
$obj->self_next(1)
    ->self_next(2)
    ->other_next(3)
    ->something_else(4);

Note
This is an awkward idea to explain in words. Essentially you are delegating the desision what is the next object in the chain to the executable methods. It probably should be combined with weaving the values, which we would otherwise return, using accumulator style passing, or some other store method.
Have a look at Jonnay's post for better and more sensible code examples and the Fluenter class.
I sometimes look at this as the imperative "version" of continuation passing, but let's not even get there.

Poor man's macro programming in php

Jonnay's post I mentioned before started me thinking - what do you need to have macros in php. What is the closest we can get to that without actually changing anything in php (poor man's version? What minimal sugar does php need to make it comfy? What is the natural syntax for macros in php? I definitely don't know the answers to these questions but let's try: macro delay() { match { delay( $func, ... ) } : { $varname = $func . random(); $$varname = array(new promise( $func, ... ), 'evaluate'); return $varname; } match { $func( ... ) } : { return call_user_func($$varname, ... }; } }

This looks kind of allright, phpish. It has problems, but the above dream code demonstrates the idea enough - match the left-hand-side code and substitute it with the right hand side. The difference from C macros is that this macro is a program fragment/function/..., the result of which is substituted in the AST, as opposed to simple string pattern matching + substitution

Googles Summer of yawn.

Googles Summer of yawn. - Google's "Summer of Code" has started and they have announced a few PHP projects. Some of them look interesting and useful. However, I am going to pick apart one in particular, that to be honest, looks neither interesting or useful: The PHP Macro Preprocessor.
....

Why does the PHP Preprocessor need to be stuck in a world of #ifdefs and #includes? Instead of blindly copying what the C preprocessor does, why not focus on the languages strengths and deficiencies? The object system of PHP needs to be looked at, and see if it can be improved upon through a method of code transformation.

[sacrificial rabbit]

I sooo totally agree with Jonnay on this. In fact it is simply like reading my own thoughts, just put it better english, , ok, nearly. But what to do about it? I don't really know, I'm afraid I chicken out from digging into the guts of php. When I last looked there it was really scary.

Updated design pattern collection

I guess I'm on the down form my design pattern tantrum hit. I updated the collection so it now has about 20 of them, not all can be considered "officially" design patterns, but to be honest I don't really care. I'm very well aware that I ignore the existance of boundaries between design patterns, idioms, techniques, ... That is intentional. I like my rainbow coloured world and I want to keep it that way. If you disagree - just read the small script. My tanrum energy is over and I need to do work work. So the combing over the php design pattern collection will come later. For now enjoy, and have anger fits of your own.

Oh yes. I'm using a particular case of wishful thinking - using any php callable in $callable(...) expressions. The reality is a bit uglier. We need to use either call_user_func($callable,...); call_user_func_array($callable,...) How I wish php could do that out of the box, especially when it actually does it, just not in the short syntax. Anyone happy to hold my hand to do a php patch for that feature? I'm very unfamiliar with the internals, sorry.

Coroutines (generator based)

Intent
Abstract out naturally parrallel evaluation
Motivation
Merge two functional streams
Implementation
The coroutines can be implemented using generators. The example shows an example application
Examples
//if gen and gen2 are generators
function merge_data() {
  try {
    do {
      $data[] = 10*gen() + 5 + 4*gen2();
      ...
    } while( some_condition( ... ) );
  } catch ( $e ) { .... }
  return $data;
}

Generator (iterator protocol based)

Intent
Define a (stream like) value producer
Motivation
We want to be able do define functional streams
Implementation
Any object implementing an iteration protocol (interface) can be a base for a generator.
Examples

//a generator implemented with iterators
function generator($it=null, $cb=null) {
  static $itor;
  static $callback;

  if(!isset($itor)) ($itor = $it; $callback=$cb; }

  if($valid()) { $out = $callback($current); $next(); return $out; }

  //or if you are not sure about the type of the above callables ($valid, $next,..)
  if( call_user_func($valid) ) { 
    $out = call_user_func( $callback, $current); 
    call_user_func( $next ); 
    return $out; 
  }

  else throw( new some_exception );
}

Iterator (based on protocol method)

Intent
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
Motivation
We want to be able to postpone the effects of a computation, for example delay printing from a function to webserver output until whole web-page is assembled
Implementation
This is an alternative implementation based on protocol method, rather than interfaces
Examples

class alt_iterator {
  private $st = array();

  function next() { ... }
  function current() { ... }
  function valid() { ... }
  //... put the rest here

  function protocol() {
    return array(
             array($this,'next'),
             array($this,'current'),
             array($this,'valid'),
	     .....
	     );
  }
  
}

//an example use
function do_them($itor, $callback ) {
  list($next, $current, $valid, ...) = $itor->protocol();
  while($valid) {
    $callback( $current );
    $next();
  }
}

Dynamic dispatch

Intent
dispatch the control based on the environment, but delay enumerating the cases
Motivation
we don't know at the time of writing the code what are the different cases to dispatch on
Implementation
(nearly) invisible in php
Examples
$case($arg);
$object->$method($arg);
call_user_func($calleable, $arg1, $arg2);
Note
A more elaborate form of dynamic dispatch is Method Chaining

Lazy evaluation

Intent
A function/method call results in a promise for future computation
Motivation
We want to be able to postpone the effects of a computation, for example delay printing from a function to webserver output until whole web-page is assembled
Implementation
Instead of evaluating a function, we deliver a promise - a callable with no arguments, which when forced is executed
Examples

//for simplicity handle only functions with one argument 
class promise { 
  private $args = null;
  private $func = null;
  function __construct($func, $args) { 
    $this->func = $func; 
    $this->args = $args;
  } 
  function evaluate() { 
    call_user_func($this->func,$this->args);
  } 
} 

function delay( $func, $arg ) {
  return array(new promise($func, $arg), 'evaluate'); 
}

//example use
...
$chunks[] = delay('a_printer',$a_variable);
...
foreach($chunks as $chunk ) {
  if(is_callable($chunk)) {
    $chunk(); //force - this does it's own printing in this example
  } else {
    print $chunk;
  }
}
Powered by Drupal, an open source content management system