Lambda Functions & Closures A Sydney PHP Group Presentation 2 nd  October 2008 By Timothy Chandler
Lambda Functions – Lambda Calculus <ul><li>Lambda functions originate from lambda calculus  which was introduced by Alonzo...
Lambda Functions – Implementations <ul><li>Implementing the lambda calculus on a computer involves  treating &quot;functio...
Lambda Functions – Implementation Examples <ul><li>Python: </li></ul><ul><li>C++: </li></ul>s Python Lambda Function func ...
Lambda Functions – Implementation Examples <ul><li>C#: </li></ul><ul><li>C# v3.0: </li></ul>s C# v3.0 Lambda Function //Cr...
Lambda Functions – Implementation Examples <ul><li>JavaScript: </li></ul>s JavaScript Lambda Function <ul><li>var  lambdaF...
Lambda Functions – The PHP Way <ul><li>PHP 5.3: </li></ul><ul><li>Syntax: </li></ul>s PHP 5.3 Lambda Function <ul><li><?ph...
Lambda Functions – The PHP Way <ul><li>The goal of PHP’s Lambda function implementation is to allow for the creation of qu...
Closures
Closures – The Funarg Problem <ul><li>Lambda functions  MUST  be first-class objects. </li></ul><ul><li>Funarg, meaning “f...
Closures – The PHP Funarg Problem Solution <ul><li>PHP  5.3  introduces a new keyword ‘use’. </li></ul><ul><li>Use this ne...
Closures – The “use” Keyword <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Lambda Function Closure <ul><li>$confi...
Closures – The “use” Keyword <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Lambda Function Closure – As an Anonym...
Closures – “use” as reference or copy <ul><li>Variables passed into the “use” block are copied in by default – This is the...
Closures – “use” by reference <ul><li>Example: </li></ul><ul><li>Why? </li></ul><ul><ul><li>Able to directly affect the va...
Lifecycle <ul><li>A lambda function can be created at any point in your application,  except in class declarations . </li>...
<ul><li>Lambda functions can live longer than whatever created them. </li></ul><ul><li>Example: </li></ul><ul><li>Result: ...
<ul><li>Imported variables can also live longer. </li></ul><ul><li>Example: </li></ul><ul><li>Result: </li></ul>Lifecycle ...
<ul><li>Methods and properties used in a closure can live longer than the object. </li></ul><ul><li>Example: </li></ul><ul...
<ul><li>If a closure exists with a reference to an object’s method or property, that object is not completely destroyed wh...
<ul><li>Lambda Functions are Closures because they automatically get bound to the scope of the class that they are created...
Object Orientation <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Static Lambda Functions <ul><li>class  foo </li>...
<ul><li>PHP  5.3  introduces a new magic method. </li></ul><ul><li>Invokable objects are now possible through the use of t...
Object Orientation <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Invokable Objects <ul><li>class  foo </li></ul><...
Questions?
Thank you. <ul><li>References </li></ul><ul><li>http://en.wikipedia.org/wiki/Lambda_calculus </li></ul><ul><li>http://en.w...
Upcoming SlideShare
Loading in...5
×

PHP 5.3 Part 2 - Lambda Functions & Closures

9,904

Published on

This is Part 2 of the series about PHP 5.3. It goes into detail regarding Lambda Functions and Closures - a great new feature in PHP 5.3.

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
9,904
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
151
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide
  • Do Introduction
  • PHP 5.3 Part 2 - Lambda Functions & Closures

    1. 1. Lambda Functions & Closures A Sydney PHP Group Presentation 2 nd October 2008 By Timothy Chandler
    2. 2. Lambda Functions – Lambda Calculus <ul><li>Lambda functions originate from lambda calculus which was introduced by Alonzo Church and Stephen Cole Kleene in the 1930s. </li></ul><ul><li>The lambda calculus can be thought of as an idealized, minimalistic programming language. It is capable of expressing any algorithm , and it is this fact that makes the model of functional programming an important one. </li></ul><ul><li>The lambda calculus provides the model for functional programming. Modern functional languages can be viewed as embellishments to the lambda calculus. </li></ul>
    3. 3. Lambda Functions – Implementations <ul><li>Implementing the lambda calculus on a computer involves treating &quot;functions&quot; as “first-class objects” , which raises implementation issues for stack-based programming languages. This is known as the Funarg problem – More on this later. </li></ul><ul><li>Many languages implement lambda functions. These include: </li></ul><ul><ul><li>Python </li></ul></ul><ul><ul><li>C++ </li></ul></ul><ul><ul><li>C# (2 different implementations – Second one improved in C# v3.0) </li></ul></ul><ul><ul><li>JavaScript </li></ul></ul><ul><ul><li>...and many more... </li></ul></ul>
    4. 4. Lambda Functions – Implementation Examples <ul><li>Python: </li></ul><ul><li>C++: </li></ul>s Python Lambda Function func = lambda x : x ** 2 s C++ Lambda Function std :: for_each ( c . begin (), c . end (), std :: cout << _1 * _1 << std :: endl ) ;
    5. 5. Lambda Functions – Implementation Examples <ul><li>C#: </li></ul><ul><li>C# v3.0: </li></ul>s C# v3.0 Lambda Function //Create an delegate instance MathDelegate lambdaFunction = i => i * i ; Execute ( lambdaFunction ) ; s C# Lambda Function //Declare a delegate signature delegate double MathDelegate ( double i ) ; //Create a delegate instance MathDelegate lambdaFunction = delegate ( double i ) { return Math . Pow ( i , 2 ) ; }; /* Passing ' lambdaFunction ' function variable to another method, executing, and returning the result of the function */ double Execute ( MathDelegate lambdaFunction ) { return lambdaFunction ( 100 ) ; }
    6. 6. Lambda Functions – Implementation Examples <ul><li>JavaScript: </li></ul>s JavaScript Lambda Function <ul><li>var lambdaFunction = function ( x ) </li></ul><ul><li>{ </li></ul><ul><ul><li>return x * 10 ; </li></ul></ul><ul><li>} </li></ul><ul><li>document.write ( lambdaFunction ( 100 )) ; </li></ul>
    7. 7. Lambda Functions – The PHP Way <ul><li>PHP 5.3: </li></ul><ul><li>Syntax: </li></ul>s PHP 5.3 Lambda Function <ul><li><?php </li></ul><ul><li>$lambdaFunction = function ( $x ) </li></ul><ul><li>{ </li></ul><ul><ul><li>return $x * 10 ; </li></ul></ul><ul><li>}; </li></ul><ul><li>print $lambdaFunction ( 100 ) ; </li></ul><ul><li>?> </li></ul>s Lambda Function Syntax function & ( parameters ) use ( lexical vars ) { body };
    8. 8. Lambda Functions – The PHP Way <ul><li>The goal of PHP’s Lambda function implementation is to allow for the creation of quick throw-away functions. </li></ul><ul><li>Don’t confuse with “create_function()”. </li></ul><ul><ul><li>These functions compile at “run-time”. </li></ul></ul><ul><ul><li>These functions DO NOT compile at “compile-time”. </li></ul></ul><ul><ul><li>Optcode caches CANNOT cache them. </li></ul></ul><ul><ul><li>Bad practice. </li></ul></ul>
    9. 9. Closures
    10. 10. Closures – The Funarg Problem <ul><li>Lambda functions MUST be first-class objects. </li></ul><ul><li>Funarg, meaning “functional argument”, is a problem in computer science where a “stack-based programming language” has difficulty implementing functions as “first-class objects”. </li></ul><ul><li>The problem is when the body of a function refers to a variable from the environment that it was created but not the environment of the function call. </li></ul><ul><li>Standard Solutions: </li></ul><ul><ul><li>Forbid such references. </li></ul></ul><ul><ul><li>Create closures. </li></ul></ul>
    11. 11. Closures – The PHP Funarg Problem Solution <ul><li>PHP 5.3 introduces a new keyword ‘use’. </li></ul><ul><li>Use this new keyword when creating a lambda function to define what variables to import into the lambda functions scope – This creates a Closure . </li></ul>
    12. 12. Closures – The “use” Keyword <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Lambda Function Closure <ul><li>$config = array ( 'paths' => array ( 'examples' => 'c:/php/projects/examples/' )) ; </li></ul><ul><li>$fileArray = array ( 'example1.php' , 'example2.php' , 'exampleImage.jpg' ) ; </li></ul><ul><li>$setExamplesPath = function ( $file ) use ( $config ) </li></ul><ul><li>{ </li></ul><ul><ul><li>return $config [ 'paths' ][ 'examples' ]. $file ; </li></ul></ul><ul><li>}; </li></ul><ul><li>print_r ( array_map ( $setExamplesPath , $fileArray ) ) ; </li></ul><ul><li>Array </li></ul><ul><li>( </li></ul><ul><ul><li>[ 0 ] => c : / php / projects / examples / example1 . php [ 1 ] => c : / php / projects / examples / example2 . php </li></ul></ul><ul><ul><li>[ 2 ] => c : / php / projects / examples / exampleImage . jpg </li></ul></ul><ul><li>) </li></ul>
    13. 13. Closures – The “use” Keyword <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Lambda Function Closure – As an Anonymous Function <ul><li>$config = array ( 'paths' => array ( 'examples' => 'c:/php/projects/examples/' )) ; </li></ul><ul><li>$fileArray = array ( 'example1.php' , 'example2.php' , 'exampleImage.jpg' ) ; </li></ul><ul><li>print_r ( array_map </li></ul><ul><ul><li>( </li></ul></ul><ul><ul><li>function ( $file ) use ( $config ) </li></ul></ul><ul><ul><ul><li>{ </li></ul></ul></ul><ul><ul><ul><li>return $config [ 'paths' ][ 'examples' ]. $file ; </li></ul></ul></ul><ul><ul><ul><li>} , </li></ul></ul></ul><ul><ul><ul><li>$fileArray </li></ul></ul></ul><ul><ul><li>)) ; </li></ul></ul><ul><li>Array </li></ul><ul><li>( </li></ul><ul><ul><li>[ 0 ] => c : / php / projects / examples / example1 . php [ 1 ] => c : / php / projects / examples / example2 . php </li></ul></ul><ul><ul><li>[ 2 ] => c : / php / projects / examples / exampleImage . jpg </li></ul></ul><ul><li>) </li></ul>
    14. 14. Closures – “use” as reference or copy <ul><li>Variables passed into the “use” block are copied in by default – This is the expected PHP behaviour. </li></ul><ul><li>You can cause a variable to be imported by reference the same way you do when defining referenced parameters in function declarations. </li></ul><ul><li>The PHP 5 pass by reference for objects rule still applies. </li></ul>
    15. 15. Closures – “use” by reference <ul><li>Example: </li></ul><ul><li>Why? </li></ul><ul><ul><li>Able to directly affect the variable from within the lambda function. </li></ul></ul><ul><ul><li>If used with a large array, can prevent massive overheads. </li></ul></ul><ul><ul><li>Memory efficient. </li></ul></ul>s Referenced Variable Import
    16. 16. Lifecycle <ul><li>A lambda function can be created at any point in your application, except in class declarations . </li></ul><ul><li>Example: </li></ul><ul><li>Throws Error: </li></ul>s Lambda Function in Class Declaration <ul><li>class foo </li></ul><ul><li>{ </li></ul><ul><ul><li>public $lambda = function () </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><ul><li>return 'Hello World' ; </li></ul></ul></ul><ul><ul><li>}; </li></ul></ul><ul><ul><li>public function __construct () </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><ul><li>print $this -> lambda () ; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>new foo () ; </li></ul>Parse error : syntax error, unexpected T_FUNCTION in D:Developmentwwwphp5.3lambda5.php on line 4
    17. 17. <ul><li>Lambda functions can live longer than whatever created them. </li></ul><ul><li>Example: </li></ul><ul><li>Result: </li></ul>Lifecycle s Lifecycle Example 1 <ul><li>class foo </li></ul><ul><li>{ </li></ul><ul><ul><li>public $lambda = null ; </li></ul></ul><ul><ul><li>public function __construct () </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><ul><li>$ this -> lambda = function () { return 'Hello World' ;}; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>$foo = new foo () ; </li></ul><ul><li>var_dump ( $foo ) ; </li></ul><ul><li>$lambda = $foo -> lambda ; </li></ul><ul><li>unset ( $foo ) ; </li></ul><ul><li>var_dump ( $foo ) ; </li></ul><ul><li>print $lambda () ; </li></ul>object(foo)#1 (1) { [&quot;lambda&quot;]=> object(Closure)#2 (0) { } } NULL Hello World
    18. 18. <ul><li>Imported variables can also live longer. </li></ul><ul><li>Example: </li></ul><ul><li>Result: </li></ul>Lifecycle s Lifecycle Example 2 <ul><li>//Create prefix say function. </li></ul><ul><li>$say = function ( $prefix ) </li></ul><ul><li>{ </li></ul><ul><ul><li>return function ( $suffix ) use (& $prefix ) </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>print $prefix . $suffix ; </li></ul></ul><ul><ul><li>}; </li></ul></ul><ul><li>}; </li></ul><ul><li>//Create suffix say function - will loose $prefix right? </li></ul><ul><li>$say = $say ( 'Hello ' ) ; </li></ul><ul><li>//Wrong! - Execute new say concatenated function. </li></ul><ul><li>$say ( 'World!' ) ; //Outputs &quot;Hello World!&quot; <$prefix><$suffix> </li></ul>Hello World
    19. 19. <ul><li>Methods and properties used in a closure can live longer than the object. </li></ul><ul><li>Example: </li></ul><ul><li>Result: </li></ul>Lifecycle – Objects s Lifecycle Example 3 <ul><li>class foo </li></ul><ul><li>{ </li></ul><ul><ul><li>public $bar = &quot;Bar &quot; ; </li></ul></ul><ul><ul><li>public function __construct () { print &quot;__construct() “ ;} </li></ul></ul><ul><ul><li>public function __destruct () { print &quot;__destruct() “ ;} </li></ul></ul><ul><ul><li>public function getBarLambda () </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><ul><li>return function () { return $ this -> bar ;}; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>$foo = new foo () ; $bar = $foo -> getBarLambda () ; </li></ul><ul><li>print $bar () ; </li></ul><ul><li>unset ( $foo ) ; </li></ul><ul><li>var_dump ( $foo ) ; </li></ul><ul><li>print $bar () ; </li></ul><ul><li>unset ( $bar ) ; </li></ul><ul><li>print $bar () ; </li></ul>__construct() Bar NULL Bar __destruct() Fatal error Function name must be a string in D:Developmentwwwphp5.3lambda8.php on line 31
    20. 20. <ul><li>If a closure exists with a reference to an object’s method or property, that object is not completely destroyed when unset. </li></ul><ul><ul><li>__destruct() is NOT called until the closure is destroyed . </li></ul></ul><ul><ul><li>The unset object CANNOT be used in this situation as it will be considered a null value by anything trying to access it outside the closure environment. </li></ul></ul>Lifecycle – Objects
    21. 21. <ul><li>Lambda Functions are Closures because they automatically get bound to the scope of the class that they are created in. </li></ul><ul><li>$this is not always needed in the scope. </li></ul><ul><li>Removing $this can save on memory. </li></ul><ul><li>You can block this behaviour by declaring the Lambda Function as static. </li></ul>Object Orientation
    22. 22. Object Orientation <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Static Lambda Functions <ul><li>class foo </li></ul><ul><li>{ </li></ul><ul><ul><li>public function getLambda () </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>return function () { var_dump ( $ this ) ;}; } </li></ul></ul><ul><ul><li>public function getStaticLambda () </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><ul><li>return static function () { var_dump ( $ this ) ;}; </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>$foo = new foo () ; </li></ul><ul><li>$lambda = $foo -> getLambda () ; </li></ul><ul><li>$staticLambda = $foo -> getStaticLambda () ; </li></ul><ul><li>$lambda () ; </li></ul><ul><li>$staticLambda () ; </li></ul>object(foo)#1 (0) { } NULL
    23. 23. <ul><li>PHP 5.3 introduces a new magic method. </li></ul><ul><li>Invokable objects are now possible through the use of the __invoke() magic method. </li></ul><ul><li>Essentially makes the object a closure. </li></ul>Object Orientation
    24. 24. Object Orientation <ul><li>Example: </li></ul><ul><li>Result: </li></ul>s Invokable Objects <ul><li>class foo </li></ul><ul><li>{ </li></ul><ul><ul><li>public function __invoke () </li></ul></ul><ul><ul><li>{ </li></ul></ul><ul><ul><li>print 'Hello World' ; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul><ul><li>$foo = new foo ; </li></ul><ul><li>$foo () ; </li></ul>Hello World
    25. 25. Questions?
    26. 26. Thank you. <ul><li>References </li></ul><ul><li>http://en.wikipedia.org/wiki/Lambda_calculus </li></ul><ul><li>http://en.wikipedia.org/wiki/Closure_(computer_science) </li></ul><ul><li>http://en.wikipedia.org/wiki/Funarg_problem </li></ul><ul><li>http://wiki.php.net/rfc/closures </li></ul>
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×