PHP 5.3 Part 2 - Lambda Functions & Closures

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Notes on slide 1

    Do Introduction

    2 Favorites

    PHP 5.3 Part 2 - Lambda Functions & Closures - Presentation Transcript

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

    + melechimelechi, 2 years ago

    custom

    2573 views, 2 favs, 0 embeds more stats

    This is Part 2 of the series about PHP 5.3. It goes more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 2573
      • 2573 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 2
    • Downloads 57
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories