SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Zealot
    Join Date
    Dec 2006
    Posts
    105
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP Functional programming

    I need to to a little functional programming, my question is in the code. Thanks.

    PHP Code:
    <?php
    function print1($arg1$arg2)
    {
      echo 
    'Print 1 function : ';
      
    var_dump($arg1);
      
    var_dump($arg2);
    }

    function 
    print2($arg1,$arg2)
    {
      echo 
    'Print 2 function : ';
      
    var_dump($arg1);
      
    var_dump($arg2);
    }

    function 
    applyOne($arg1,$funcName)
    {
      if(
    is_array($arg1)) $code "return $funcName(/*How should I write here for array ? Thanks*/ ,\$arg2)";
      else  
    $code "return $funcName(\"$arg1\", \$arg2);";

      return 
    create_function('$arg2'$code);
    }

    //this is working
    $printFunction applyOne('string 1''print1');
    $printFunction('arg2 string');

    //'This is not working, how to make it work for array ? But note that the array may contain other type of objects, not just string. Thanks.
    class obj {
       function 
    __construct(){}
    }
    $obj = new obj();
    $printFunction applyOne(array($obj), 'print2');
    $printFunction('arg2 string');

    ?>
    Can I have the array that has been passed to stay alive until passed to the print function ?

  2. #2
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could serialize the values to a string, and embed them in create_function. You would lose referential identity in the process, which is a problem, if you're passing objects. You might also run into some serious performance issues, if the object has references to other objects (Then the entire graph of objects will be serialized). If you want to do currying, you're much better off, using a global storage. Here's an implementation:
    PHP Code:
    <?php
    /** returns a partially applied function */
    function partial($fn) {
      
    $args func_get_args();
      
    array_shift($args);
      
    $id uniqid('_partial');
      
    $GLOBALS[$id] = array($fn$args);
      return 
    create_function(
        
    '',
        
    '
         $args = func_get_args();
         return call_user_func_array(
           $GLOBALS["'
    .$id.'"][0],
           array_merge(
             $GLOBALS["'
    .$id.'"][1],
             $args));
        '
    );
    }

    /** returns a partially applied function, with arguments applied to the right */
    function partialr($fn) {
      
    $args func_get_args();
      
    array_shift($args);
      
    $id uniqid('_partial');
      
    $GLOBALS[$id] = array($fn$args);
      return 
    create_function(
        
    '',
        
    '
         $args = func_get_args();
         return call_user_func_array(
           $GLOBALS["'
    .$id.'"][0],
           array_merge(
             $args,
             $GLOBALS["'
    .$id.'"][1]));
        '
    );
    }

    // tests
    assert_options(ASSERT_ACTIVEtrue);
    assert_options(ASSERT_WARNINGtrue);

    function 
    add($a$b) {
      return 
    $a $b;
    }
    $add "add";
    assert($add(28) === 10);
    $add2 partial($add2);
    assert($add2(8) === 10);

    function 
    test($a$b) {
      return array(
    'a' => $a'b' => $b);
    }
    $foo partial('test''foo');
    assert($foo('bar') === array('a' => 'foo''b' => 'bar'));

    $foo partialr('test''foo');
    assert($foo('bar') === array('a' => 'bar''b' => 'foo'));
    Note that there are still some memory management problems with this technique. Because PHP's memory management, is based on reference counting, values in the $GLOBALS array can not be reclaimed. This means that any value, you bind, using these functions, are never reclaimed. It may not be a big issue (The memory is still reclaimed at the end of the process), but you need to keep it in mind, before you bind very large variables.

  3. #3
    SitePoint Zealot
    Join Date
    Dec 2006
    Posts
    105
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Oh my GOD, that is so cool, you truly the programming God, Thank you Thank you. But I still don't get you about the $GLOBAL array reclaim ?

  4. #4
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by eagerlearner View Post
    But I still don't get you about the $GLOBAL array reclaim ?
    PHP manages memory through a technique, called reference counting. How it works is, that each time a value is assigned to a variable, it has an internal counter, which increases. Each time a variable is destroyed, or set to refer to something else, the counter diminishes. When the counter reaches zero (Eg. there are no variables, which refer the value), the value is destroyed and the memory reclaimed. When you put a variable in the global scope, it will stay alive and thus the value, it refers to, will never be reclaimed. It's an important note, that this memory leak is confined to the running process. When a script ends, all memory is reclaimed. So this is only a problem for long running scripts or scripts, which process a lot of data (And binds that data to callbacks). For most normal websites, this is a non-issue.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •