Partial Application Technique in PHP

26 08 2011

Now that we have lambdas and closures in PHP5.3, we can use a functional programming technique known as partial application. The following code example is replete with comments so I think you’ll get the idea fast.

sample_code.php

<?php
error_reporting(E_ALL);
/**
  *  Demo of partial application technique in PHP5
  *  by Sharon Lee Levy, ZCE
  *  August 26, 2011
  *
  *
  *  Take function with multiple params
  *  as basis to create function requiring one argument
  *
**/
$f = function ( $a, $b ) {
 	     return( array("new" => $a + ( $a * $b )) );
		 
};
$curry = function( $f, $percent) {
      return function( $items ) use( $f, $percent ) {
	       if (is_array($items) ) {
                         inflateSomeItems( $items );
		         $callback = function ( $e ) use( $f, $percent ) {
 	                             return $f($e, $percent);
                             };
				return array_map( $callback, $items );
  		   }
	  }; 
};

/**
  * inflateSomeItems() 
  * @param array
  * makes any necessary cost adjustments before raising prices
  * returns array
**/
function inflateSomeItems( &$a )
{
    $inflateables = array('eggs' => 3.55, 'milk' => 3.99, 'chicken' => 1.58, 'steak' => 1.92); 
	foreach ($inflateables as $key => $value) {
	        if( isset( $a[$key] ) ) {
			    $a[ $key ] += $value;
			}
	}
}

/**
  * getResults()
  * @param array
  * format results in US currency
**/
function getResults($res)
{
  setlocale(LC_MONETARY, 'en_US');
  $callback = function ($e) {
    $usd =  '$' . number_format($e, 2, '.', ',');
	return $usd;
  };
  $nu = null;
  foreach ($res as $key => $value) {
       $temp = array_shift( $value );
	   $value = $callback( $temp );
	   $nu[$key] = $value;      
  }
  return $nu;
}

$percent = 0.25;
$RaisePrice = $curry( $f, $percent );

// now raise prices ...
$arrData = array("candy"=>1.00, "eggs"=>2.00, "milk"=>3.00, "bread"=>4.00, "chicken"=>5.00, "steak"=>6.00 );
$results = getResults(  $RaisePrice( $arrData ) );

Note how before raising prices across the board by 25 percent, the partial application technique allows me to first inflate the prices of certain items. I include the above code in a template file to display the results as follows:

font_end_code.php

<!DOCTYPE html>
<html>
<head><title>Sample Code by Sharon Levy</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<style>

#content {
    background:white;
	font-size:30px;
	font-weight:bold;
    font-family:"Comic Sans MS", Arial, Helvetica, sans-serif;
	height:21em;
	width:21em;
	margin-left:auto;
	margin-right:auto;
    margin-top:50px; 
	color:#888;
	text-shadow: 2px 2px 8px #ccc;
}
#newprices {
	margin-top:6em;margin-left:2em;width:20em;color:#000; 
}
.left {
	float:left;padding-left:4em;
}

.right {
	float:right;padding-right:8em;
}

.row {
   width:20em;
   color:#000;
}
.row:hover {
   color:#00f;
   cursor:default;
}

</style>
</head>

<body>
<div id="content">
<div id="newprices">
<?php
/**
  *  The "frontend" for demoing
  *  partial application technique in PHP5
  *  
  *  by Sharon Lee Levy, ZCE
  *  August 26, 2011
  *
**/
require("sample_code.php");
foreach( $results as $item => $price)
{
         echo '<div class="row"><div class="left"> - ' . ucfirst($item) . '</div><div class="right">' . $price . '</div></div>' . "\n";
}   
?>
</div>
</div>
</body>
</html>

You may also wish to read http://en.wikipedia.org/wiki/Currying which discusses the difference between partial application and currying.

This work is licensed under a Creative Commons License

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: