http://qs1969.pair.com?node_id=459926


in reply to Re^2: Is Perl a good career move?
in thread Is Perl a good career move?

Hi Juerd,

You make some excellent points about PHP, (and having spent much of the last 2 years as a PHP programmer, I agree with many of your points). In particular the namespace issue is a killer (although using OO techniques you can avoid the problem to a degree). You have also made some errors in your comments.

>>> Heck, it doesn't even have anonymous functions.

Yes it does.

>>> That's another thing: how will you be rewriting that hash of coderefs? A hash of strings that are evaled at runtime?

#!/usr/bin/php -q <?php error_reporting(E_ALL); $dispatch_table = array( # create some anonymous functions 'foo' => create_function('$a', 'return "foo got $a\n";'), 'bar' => create_function('$a', 'return "bar got $a\n";'), 'baz' => create_function('$a', 'return "baz got $a\n";') ); print $dispatch_table['foo']('hello'); print $dispatch_table['bar']('hi'); print $dispatch_table['baz']('yo'); ?> # outputs foo got hello bar got hi baz got yo

>>> Also, don't think $foo = bar() || $baz does the same in PHP. In PHP, you end up with true or false. So you must write it in two separate expressions.

$baz = "DEFAULT VALUE"; function bar(){return "Assigned value";} function quux(){return false;} $foo = bar() ? bar() : $baz; print "$foo\n"; $foo = quux() ? quux : $baz; print "$foo\n"; # outputs Assigned value DEFAULT VALUE

I'm not sure if you could consider that as two separate expressions, but it seems a concise enough idiom for me.

While PHP does not have closures, I have used static variables in functions to emulate some of the behaviours I have used closures for in Perl.

Perl remains, by far, my language of choice, but I thought it would only be fair to point these things out

cheers

thinker

Replies are listed 'Best First'.
Re^4: Is Perl a good career move?
by Juerd (Abbot) on May 24, 2005 at 14:58 UTC

    Heck, it doesn't even have anonymous functions.
    Yes it does. (...) create_function.

    Functions created by create_functions are NAMED, not anonymous. In fact, create_function RETURNS the name.

    I'm not sure if you could consider that as two separate expressions, but it seems a concise enough idiom for me.

    I sure do. If in "bar() ? bar() : $foo", the bar function does something impure, like increase a counter, it does so twice, while with Perl's "bar() || $foo", it is done only once. Also, if bar() takes 10 seconds to finish, then "bar() ? bar() : $foo" will take at least 20.

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      >> Functions created by create_functions are NAMED, not anonymous. In fact, create_function RETURNS the name.

      Create function does indeed return a string, but does that mean it is not an anonymous function. perhaps we are concentrating too much on semantics here

      The documentation for the function states " create_function -- Create an anonymous (lambda-style) function". Perhaps more semantics. Nevertheless, building a dispatch table from the result of create_function works for me.

      I take on board your point about ||= for a function which has side effects

      cheers

      thinker

        The functions created by create_functions are named, not anonymous. The value returned by create_function is the name of the newly created function. This name begins with a nullbyte, but it is a global name anyhow. $foo = create_function(...); $foo(); works because $foo here is a symbolic reference. create_function uses eval and has many caveats. From PHP's source:

        sprintf(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(%s){%s}", Z_STRV +AL_PP(z_function_args), Z_STRVAL_PP(z_function_code));
        The function has a name, and is thus not anonymous. PHP's documentation is outright false.

        Your dispatch table may work for you. But it is very inefficient and very ugly. You'd even be better off with a bunch of explicitly named functions and simple symbolic references. Back to square one of the programming mine field...

        Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      ($foo = bar()) || ($foo = $baz); $foo = (($bar = bar()) ? $bar : $baz); The key is that the || casts the right hand side as a boolean, and php does not have a magic variable that gets set while you aren't looking.
        That is incredibly ugly, and no "magic variable that gets set" is even RELEVANT in this discussion.