Improve functional programming section

- Change criteria for filter
- Extend the first example to show anonymous function without assignment
- Add paragraph on recursion
- Wrap to 120 chars
This commit is contained in:
Goran Rakic
2012-07-13 18:00:37 +02:00
parent be9ff04411
commit 9f40674396

View File

@@ -5,8 +5,8 @@ isChild: true
## Programming Paradigms ## Programming Paradigms
PHP is a flexible, dynamic language that supports a variety of programming techniques. It has evolved dramatically over PHP is a flexible, dynamic language that supports a variety of programming techniques. It has evolved dramatically over
the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anonymous functions and namespaces in PHP the years, notably adding a solid object-oriented model in PHP 5.0 (2004), anonymous functions and namespaces in PHP 5.3
5.3 (2009), and traits in PHP 5.4 (2012). (2009), and traits in PHP 5.4 (2012).
### Object-oriented Programming ### Object-oriented Programming
@@ -18,41 +18,52 @@ interfaces, inheritence, constructors, cloning, exceptions, and more.
### Functional Programming ### Functional Programming
PHP supports first-class function, meaning that a function itself can be assigned to a variable, both user-defined and built-in. Those PHP supports first-class function, meaning that a function can be assigned to a variable. Both user defined and built-in
functions referenced by a variable can be invoked dynamically. Functions can be passed as arguments to other functions (feature called functions can be referenced by a variable and invoked dynamically. Functions can be passed as arguments to other
Higher-order functions) and function can return other functions. functions (feature called Higher-order functions) and function can return other functions.
Recursion, a feature that allows a function to call itself is supported by the language, but most of the PHP code focus
on iteration.
New anonymous functions (with support for closures) are present since PHP 5.3 (2009). New anonymous functions (with support for closures) are present since PHP 5.3 (2009).
The most common usage of higher-order functions is when implementing a strategy pattern. Built-in `array_filter` function asks both The most common usage of higher-order functions is when implementing a strategy pattern. Built-in `array_filter`
for the input array (data) and a function (strategy, callback) used as a filter criteria on each array item. function asks both for the input array (data) and a function (a strategy or a callback) used as a filter function on
each array item.
{% highlight php %} {% highlight php %}
<?php <?php
$input = array(1, 2, 3, 4, 5, 6); $input = array(1, 2, 3, 4, 5, 6);
// Creates new anonymous function and assigns it to a variable // Creates a new anonymous function and assigns it to a variable
$criteria_even = function($item) { $filter_even = function($item) {
return ($item % 2) == 0; return ($item % 2) == 0;
}; };
// Built-in array_filter accepts both the data and the function // Built-in array_filter accepts both the data and the function
$output = array_filter($input, $criteria_even); $output = array_filter($input, $filter_even);
// The function doesn't need to be assigned to a variable. This is valid too:
$output = array_filter($input, function($item) {
return ($item % 2) == 0;
});
print_r($output); print_r($output);
{% endhighlight %} {% endhighlight %}
Closure is an anonymous function that can access selected variables imported from the outside scope without using any global variables. Closure is an anonymous function that can access variables imported from the outside scope without using any global
Theoretically, a closure is a function that has some arguments closed (like fixed) by the environment when the function is defined. This variables. Theoretically, a closure is a function with some arguments closed (e.g. fixed) by the environment when it is
can be used to cross the variable scope restrictions in a very clean way. defined. This is used to cross variable scope restrictions in a very clean way.
In the next example we use closures to define a function returning a single criteria function for `array_filter`, out of a family of In the next example we use closures to define a function returning a single filter function for `array_filter`, out of
criteria functions. a family of filter functions.
{% highlight php %} {% highlight php %}
<?php <?php
/** /**
* Creates an anonymous criteria function accepting items > $min * Creates an anonymous filter function accepting items > $min
*
* Returns a single filter out of a family of "greater than n" filters
*/ */
function criteria_greater_than($min) function criteria_greater_than($min)
{ {
@@ -63,18 +74,19 @@ function criteria_greater_than($min)
$input = array(1, 2, 3, 4, 5, 6); $input = array(1, 2, 3, 4, 5, 6);
// Use array_filter on a input with a selected criteria function // Use array_filter on a input with a selected filter function
$output = array_filter($input, criteria_greater_than(3)); $output = array_filter($input, criteria_greater_than(3));
print_r($output); // items > 3 print_r($output); // items > 3
{% endhighlight %} {% endhighlight %}
Each criteria function in the family accepts only elements greater than some minimum value. Single criteria returned by `criteria_greater_than` Each filter function in the family accepts only elements greater than some minimum value. Single filter returned by
is a closure whith `$min` argument closed by the value existing in the scope (given as argument when `criteria_greater_than` is called). `criteria_greater_than` is a closure whith `$min` argument closed by the value in the scope (given as an argument when
`criteria_greater_than` is called).
Early binding is used by default for importing `$min` variable into the created function. For true closures with late binding one should use Early binding is used by default for importing `$min` variable into the created function. For true closures with late
a reference when importing. This can be used with some templating or input validation libraries, where anonymous function is defined to capture binding one should use a reference when importing. Imagine a templating or input validation libraries, where closure is
out-of-scope variables and access them later when the anonymous function is evaluated. defined to capture variables in scope and access them later when the anonymous function is evaluated.
PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they PHP 5.4 added the ability to bind closures to an object's scope and also improved support for callables such that they
can be used interchangeably with anonymous functions in almost all cases. can be used interchangeably with anonymous functions in almost all cases.