Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113754 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 57410 invoked from network); 25 Mar 2021 04:16:37 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 25 Mar 2021 04:16:37 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 8ACE81804C0 for ; Wed, 24 Mar 2021 21:12:29 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-qt1-f195.google.com (mail-qt1-f195.google.com [209.85.160.195]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 24 Mar 2021 21:12:28 -0700 (PDT) Received: by mail-qt1-f195.google.com with SMTP id i19so788169qtv.7 for ; Wed, 24 Mar 2021 21:12:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20150623.gappssmtp.com; s=20150623; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=QR+p5b4PENOvb1zZUQADaqUUogblz2kfUY7KhDoKukU=; b=cvu3datVdYjKQePCydelc5ZRbpJ9WmzH9ssOA/a8L4ZpRDcOhLleupF0HrXcvArMFS n4sK2cNn3I0Ccw8tVMfBj1SOCVlOXZMG9FWDm/KwSSuV0RWOVJCpM4+f4fq5lKg9Gt8r fIXMrrEUoA4JJTxEEujY6vYA3rRFC/lLWvo9z7MWDIE719/5kT9k7sbw0kysGSJ70TDT LzZChHzB7B4VbxBT4pg6vsyJTQbSq9XN+wJY4dRsnmo5b4fWafR1UfoUDsOx3siWbkKy R4sZ+QX7FXDSkKks0GQUyl+OFkA3Qh8oqb1eWWa5uFsv0DTY/fc+7IDln0dt/sIrFqDh PEyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=QR+p5b4PENOvb1zZUQADaqUUogblz2kfUY7KhDoKukU=; b=qm5IDUfTI6vnZC8ouSMCBTaEpDl2A+pqpVkugdidFfK6rG2kQGxsKSqYMDD8qgsZj2 h5JnCmdKqRiBPPMOOWkZfii3YN72hoSVG3YgKiAPE81UC9dCLN0/xkRQ3RPuBSw02O4S U5dspX/e5W76ZFSV1kkMTnfny8Cr/UGExyFbekmo6nEWsQxxhVCHDC1+KlGkwC555jbI /1S9NP2b7JcFxwoo7hYzkjd4pTkPJHoQBzbiPT0ZZ+kmqzBzBMsTWO9GiB5G/4IYuuKm iS5qMqE9vnX1PUAqK/RrXRRFy7UN//9NT9dGw9YpFkRQQS/UIXqS8qM7NkYHRgQDyxG5 2cYg== X-Gm-Message-State: AOAM533jjtiUGPaBJGAzpXodjE8PXYakiwNcQ5Vx/dnb9RxVYBceTCoe lWy9PAI+AGG/c9BTrn6JeW3GsQ== X-Google-Smtp-Source: ABdhPJydQOyv5WYSQak4/J1W8jYQ+T1NGzaL6goXTpvu45+ADkO0kMoq0wAcu8Vn5L216w89B7dtcw== X-Received: by 2002:ac8:6e9c:: with SMTP id c28mr6054253qtv.117.1616645547163; Wed, 24 Mar 2021 21:12:27 -0700 (PDT) Received: from [192.168.1.239] (c-24-98-254-8.hsd1.ga.comcast.net. [24.98.254.8]) by smtp.gmail.com with ESMTPSA id j30sm2906587qtv.90.2021.03.24.21.12.24 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Mar 2021 21:12:24 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.4\)) In-Reply-To: <919e30e7-3e5e-d955-7bb4-1e1b5825cdd1@gmail.com> Date: Thu, 25 Mar 2021 00:12:22 -0400 Cc: internals@lists.php.net Content-Transfer-Encoding: quoted-printable Message-ID: <635DD146-FC6F-4991-8D2C-5A6B492722D5@newclarity.net> References: <88c9eb5f-f80c-4869-b7f8-1b58b9e2eaa3@www.fastmail.com> <4DC3B66E-A91A-4AA9-8872-8EE9DE92C2D4@cschneid.com> <8c72c162-83c0-7c7f-2fa7-4fbe3fb30a4a@gmail.com> <605bae82.1c69fb81.f49f7.d11eSMTPIN_ADDED_MISSING@mx.google.com> <919e30e7-3e5e-d955-7bb4-1e1b5825cdd1@gmail.com> To: Rowan Tommins X-Mailer: Apple Mail (2.3608.120.23.2.4) Subject: Re: [PHP-DEV] [RFC] Auto-capture multi-line closures and shortfunctions take 2 From: mike@newclarity.net (Mike Schinkel) > On Mar 24, 2021, at 6:45 PM, Rowan Tommins = wrote: >=20 > On 24/03/2021 21:26, Mark Randall wrote: >>=20 >> 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.=20 >=20 >=20 > 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.=20 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. =20 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.=20 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.=20 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.=20 > 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.=20 >=20 > 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.=20 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.=20 > 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. >=20 >=20 > 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/ >=20 > Translating the syntax to look more PHP-ish, you'd write something = like this: >=20 > 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? =20 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 >=20 > 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). >=20 > 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=