Re: [RFC] Draft - Closure self reference
| From: | Rowan Tommins | Date: | Wed, 11 Nov 2020 19:07:34 +0000 |
| Subject: | Re: [RFC] Draft - Closure self reference | ||
| References: | 1 2 3 4 5 6 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-112227@lists.php.net to get a copy of this message | ||
On 11/11/2020 17:59, Christoph M. Becker wrote:
In JavaScript, a named function expression is different to a function declaration:I think the key difference is that in JS, functions and variables occupy the same namespace, so "function foo" and "var foo = function" mean roughly the same thing. For the same reason, *inside* a named function expression, it acts as though there is a local variable with the given name: var fn = function foo() {console.log(typeof foo)}; fn(); // outputs 'function' which actually makes it very similar to... On 11/11/2020 18:37, David Rodrigues wrote:var fn = function foo() {console.log('blah')} foo() => Uncaught ReferenceError: foo is not definedvs.function foo() {console.log('blah')} foo() => blahSo the named function expression is still an anonymous function; the label is only defined inside of the function body.
My suggestion is to reuse the keywordI like this idea; it avoids reserving a magic variable name, but gives all the flexibility of having the full Closure object available (having a "constant" whose value was a Closure object would be somewhat odd). To take Dan's example from the RFC, this would no longer have any surprises: $fibonacci = function (int $n) as $fibonacci {asto set a variable that will represent its own closure. It is more flexible once that we could choose any name and reuse in nested closures. It is pretty similar to how SQL works too. function fn1() as $lambda1 {return function() as $lambda2 use ($lambda1) { return [ gettype($lambda1), gettype($lambda2) ]; };}
if ($n === 0) return 0; if ($n === 1) return 1; return $fibonacci($n-1) + $fibonacci($n-2);}; $this_is_the_original_fibonacci = $fibonacci; $fibonacci = function (int $n) { return rand(0, $n); }; echo $this_is_the_original_fibonacci(10). "\n"; The $fibonacci inside the closure would be a normal local variable, which just happens to have the same name as the one outside, so assigning to one would have no effect on the other. Regards, -- Rowan Tommins (né Collins) [IMSoP]