3 ms·
Hi nikic. Thanks for the feedback! (I'm the author of that article). The O'Reilly editors made a few changes to the wording without my review that make it more
by codeguy 13y ago
Hi nikic. Thanks for the feedback! (I'm the author of that article). The O'Reilly editors made a few changes to the wording without my review that make it more ambiguous as to what features were introduced in what version. I agree as is it can be confusing. But the point is that the latest version of PHP provides all of these features. The variadic function statement was an error on my part and it has since been corrected in the article.
- anaphor 13y agoDo you really think tacking on more badly designed features makes PHP better? PHP's "closures" require you to write down the free variables in an enclosed function and tell PHP that they exist, that is something a compiler should be doing. Google "closure conversion".
- Kiro 13y ago> PHP's "closures" require you to write down the free variables in an enclosed function and tell PHP that they exist Can you give an example? I googled "closure conversion" but didn't understand.
- dmiladinov 13y agoIn order to use variables from the scope that the anonymous function came from, you have to explicitly import them into the anonymous function with the use[1] block: public function getTotal($tax) { $total = 0.00; $callback = function ($quantity, $product) use ($tax, &$total) { $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($product)); $total += ($pricePerItem * $quantity) * ($tax + 1.0); }; array_walk($this->products, $callback); return round($total, 2); } In other languages that have true closures, the anonymous function "closes over" the lexical scope in which it was declared. [1]: http://www.php.net/manual/en/functions.anonymous.php http://www.php.net/manual/en/functions.anonymous.php
- coldtea 13y agoYeah, so? Sounds even better, as you can only declare what you'll actually use from the enclosing scope. Besides, doesn't Python work the same way?
- anaphor 13y agoWrong. You only need to use the free variables of the closure, you don't need to copy the entire environment from the function you're defining your closure in. By the definition of a free variable you actually use it, otherwise it wouldn't be a free variable of the function! Python definitely does not work the same way, but in Python "x = 3" can inadvertently shadow (make a local name) something defined in the outer scope, but that's a completely different problem.
- gdwatson 13y agoIn modern versions of Python you can declare "nonlocal x", but that's only necessary if you want to assign to x. Since assignment in Python creates a local variable by default, there needs to be a way to tell the byte compiler not to shadow the nonlocal variable. If you don't assign to x, the compiler will do the right thing without help.
- mercurial 13y agoI for one don't find it particularly shocking. While I agree it's not common, having things more explicit in PHP rather than less is not necessarily a bad thing. Of course, this being PHP, this is probably by accident. I've been bitten in the past in Perl and Javascript by thoughtless capture of variables from the outer scope.
- anaphor 13y agoIt is an algorithm used in compiling languages like Scheme where you calculate the set of free variables in a function and then create a closure (a function pointer and an environment, which is basically a way to lookup free variables). PHP requires you to do this by hand with the "use" keyword, e.g. use($a, $b, $c) where $a, $b, and $c are free variables (that is they are not bound in the current scope). I see no reason why PHP couldn't be doing this for you other than that the devs are lazy.
- blindhippo 13y agoLast I checked, PHP was open source. Why don't you go and do this for the "lazy devs" if it bugs you so much.
- fooyc 13y agoAFAIK, `use` were required because PHP has variable-variables: <?php $x = "b"; $b = 42; echo $$x; // equivalent to echo $b; // Here the compiler can't determine all the variables // used in the function. // Has a result, there were two choices: // - capture the whole environment // - capture explicitly named variables function () { return $$x; } Hopefully, nobody uses variable-variables these days, however this is the reason behind the introduction of `use` for closures.
- anaphor 13y agoYep that occurred to me after I posted this, but I believe it should be possible to exclude variable variables from this at the cost of a runtime error if you try to use them in a closure. Someone else pointed out to me that PHP has other ways of messing with variables as well and that it would require full evaluation to determine all of them, so maybe it "makes sense", but only because of the extremely dynamic nature of variables in PHP.
- tsm 13y agoExample 3 here: http://us1.php.net/manual/en/functions.anonymous.php http://us1.php.net/manual/en/functions.anonymous.php The necessity of `use` is, IMHO, ridiculous.
- deleted 13y ago[deleted]