On 21/06/2017 15:04, Rasmus Schultz wrote:
> > For me (and I am not alone), this feature is NOT a new syntax for
closures
>
> Regardless of why you want it, that's exactly what it is though -
another way to declare a closure.
>
> Even if it has different semantics, the resulting object is still an
instance of Closure, right?
>
> It should pass type-checks, it should support reflection, and so on -
otherwise, that's even more inconsistency,
> for no practical reason, and it will lead to an endless list of
problems which people will solve with even more ugly work-arounds,
> such as omitting type-hints, etc.
I am perfectly happy for the feature to support all those things.
> > If what you are looking for is a replacement syntax for existing
closures, you will have a completely different set of priorities
>
> I am not looking for a replacement syntax, but rather a replacement
feature.
Then you are looking for something different from me. Again, I don't say
you are wrong in this, I just don't share that desire, because I don't
see the need to replace - or supplement - a working feature with a
slightly different version.
> I think the priorities and requirements remain the same, but for
consistency, and to keep this feature generally useful,
> this feature should have parity with current Closures in terms of
capabilities - otherwise it will get in the way rather than help.
Again, this makes sense only given your starting point, which is not the
same as mine.
> Once people see the nicer, shorter syntax, and start to enjoy the
more natural scoping rules, it's going to be
> very frustrating to have to back-port to the old function-syntax and
add use-clauses etc every time the code
> changes and a single expression doesn't cut it.
I mentioned this in my last e-mail without going into details, because
it was discussed at length in the past, but perhaps you missed that, or
have forgotten. In PHP, automatic capture of variables is absolutely not
a natural scoping rule. Apart from the request super-globals - which
many modern frameworks deliberately hide away from the user - every
single variable has to be explicitly declared or imported into every
single scope, throughout the entire language.
The "use" clause on anonymous functions is not some weird wart for
implementation purposes, it is the natural companion to the "global" and
"static" keywords, and the natural consequence of not having a
declaration to force a variable to be local. In PHP, all variables are
local to a function by default, unless something explicitly says
otherwise; there are certainly languages, notably JS, where the opposite
is true, but that doesn't mean PHP is doing it wrong, or that mixing the
two conventions in one language would be a good idea.
I am willing to accept single-expression lambdas as an exception to this
rule only because they are constrained to be short and simple; they read
like an expression embedded in the outer scope, not a complete function
in their own right.
> A single-expression constraint on this feature would be a strange,
arbitrary, annoying, unnecessary limitation.
>
> We didn't get it right the first time.
I disagree with both of these statements. I don't consider this feature
an attempt to fix something that went wrong, I consider it a new,
complimentary, feature, for certain cases. Personally, I could live
without it, but I have been convinced that it would be a useful
short-hand for certain coding patterns.
If we were to allow multiple-statement automatic-capturing closures, we
would end up with 3 different ways to declare the same thing; using the
fn() variant as an example:
function($x) use($y) { return $x * $y; } // Long form; explicit return
and explicit capture
fn($x) => $x * $y; // Short form; implicit return and implicit capture
fn($x) => { return $x * $y; } // Hybrid; explicit return, but implicit
capture
The short form is still constrained to be a single expression, because
otherwise you can't omit the "return" statement; we would just have a
third form that looks a bit like the short form, but isn't. So whatever
syntax we choose, you won't be able to just add a semicolon and an extra
line to turn a lambda expression into a function body.
To me, the hybrid form is confusing and redundant; the fully shortened
form makes certain simple closures considerably more concise, and
remains reasonably readable. It is sugar for those use cases, just as
the closure itself could be considered sugar for constructing an
invokable object with private fields, and just as many other language
features are sugar for more basic operations.
Regards,
--
Rowan Collins
[IMSoP]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php