> On Mar 24, 2021, at 6:45 PM, Rowan Tommins <rowan.coll...@gmail.com> wrote: > > On 24/03/2021 21:26, Mark Randall wrote: >> >> Automatic capture ceased to be a dramatic change from PHP the day after >> short closurers were introduced. So they've been a part of PHP for years >> now. > > > I strongly disagree. Short closures say "turn this expression into a > function". You would have to work really, really hard to introduce a > sufficient amount of complexity that scope was hard to follow.
Another perspective is that the short syntax reduces complexity by not needing to be as verbose. I just did a search through a few of my codebases and found that I almost never use more than one parameter, but I would still applaud this syntax. Why? 1.) Many of my use-cases for closure functions are within functions with only a few lines that simply return the closure, i.e these functions are names wrappers for the closure to simplify their reuse across the codebase. Anyway, having to declare the variable twice, once as a function parameter and again in the use() on the next line is just tedious overkill, IMO. Then there are a use-cases with array_filter() and similar functions where the use() just adds visual complexity to what could otherwise be visually easier to reason about at a glance. Probably the only use-case I can envision where auto-capture would be problematic would be when you do have really long functions. But if you have really long functions, don't you actually have a different problem that probably needs to be addressed first? 2.) This is subjective, but my workflow frequently has me splitting the screen vertically so I can view two related files side-by-side such as the calling code on one side and the code it calls on the other. For this use-case, I almost always find myself having to scroll horizontally whenever using a closure has a use() so I can see the use() variables. That is tedious and tiring. So syntax that results in longer lines is problematic for my workflow. I know not everybody can relate but I have to believe that I am not the only one this affects. 3.) This is also subjective, but because of the requirement for use() I often find myself *not* using a closure because of its visual noise, and the use() is the main contributor to the visual noise. Instead of using array_filter() with a side-effect free closure, I use a for loop because it is easier to reason about visually. If the short syntax existed I think I would more often use a closure. Maybe I am unique in this, but I am probably not. > Full-bodied auto-capture means you can introduce a variable on line 1, and > find it's never freed, because it was silently captured by a function on line > 200. Since there's no way to declare a local variable, you couldn't even opt > *out* of the capture, as "let" or "var" do in JavaScript. Actually, there is a way to declare a local variable. Use the long function syntax instead as there is no proposal to deprecate it. Different syntaxes for different use-cases. > I hit long lists of use() repeatedly, almost always because I need to perform > a series of operations within a callback, prime examples are database > transactions and using throw-aware buffering handlers. > > I think a lot of those use cases are using anonymous functions because > they're available, not because they're the best tool for the job. For some of these use-cases, the auto-capture would be the best tool. But if we don't get variable auto-capture then for those use-cases we'd have no choice but to use the tool that is *not* the best tool for the job because it would be the only tool we'd have. > A transaction wrapper, for instance, doesn't actually need to pass control to > the transaction and back to a callback, it just needs some before and after > boilerplate. > > > Python has a "with" syntax for this, which calls __enter__ and __exit__ > methods on a "Context Manager" object: > https://www.python.org/dev/peps/pep-0343/ > > Translating the syntax to look more PHP-ish, you'd write something like this: > > with ( new Transaction($db) as $transaction ) { > doSomething($to, $library, $thread); > andThenSomethingElse($author, $title, $library_name, $top_post); > } So "with" is a statement, not an expression? Not sure how that helps since I thought one of the benefits of the short function syntax (with variable auto-capture) was to move away from procedural statements and toward more functional expressions? > The compiler would then insert an appropriate try ... catch ... finally, with > no need for a callback, and therefore no need to capture lots of variables. > The full internal expansion is quite long, so I've posted it as a gist here: > https://gist.github.com/IMSoP/a4e316684415413dca8ec5debf51a812 > > This is simpler for the programmer (my example Transaction class is a total > of 20 lines long), more efficient at run-time (no extra stack frame for the > callback), and possibly even simpler to compile (no analysis needed to work > out what variables to capture). > > Obviously, this doesn't cover all cases where automatic capture would be > useful, but nor is it just a one-trick pony; the Python spec has lots of > example use cases. It is not clear to me from reading the PEP how a "with" statement obviates the benefit of variable auto-capture? Maybe because I don't "think" in Python, so from reading their examples I cannot see how this relates? Maybe prepare an RFC proposing a PHP version of the "with" statement and explain in the RFC how it would better address the use-cases of variable auto-capture for closure so we can compare and contrast the potential language additions? Include examples with variable auto-capture and contrast with your proposed "with" statement? -Mike -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php