Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113802 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 42523 invoked from network); 26 Mar 2021 16:15:27 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 26 Mar 2021 16:15:27 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BEF601804D3 for ; Fri, 26 Mar 2021 09:11:43 -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.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-qk1-f178.google.com (mail-qk1-f178.google.com [209.85.222.178]) (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 ; Fri, 26 Mar 2021 09:11:43 -0700 (PDT) Received: by mail-qk1-f178.google.com with SMTP id c3so5729604qkc.5 for ; Fri, 26 Mar 2021 09:11:43 -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=GoWZjCOfkb2a/SxdkHDC/zqL+VZyprqtbzVB8os7ODk=; b=V21W8l0WTDipOHt30/Iucw0F6P12iu0D2TpXQNBLBbwhvaG2jIWaZ79esHyqme0pV6 ODt28KQ2A93a297i+x4sDIeR8yrkxDVsJFS+5m82EoeeYpwzGr5AK7hDRnvBjkn0/Fdr 1TpSG1jxBsenkfmkM731k0zKWvNeJ2JuOdaI0UN7hq0SbWiZS2Ey3sgrch/jjT9M3OLY cr1MAOD6W9yq8piyLyrpKMoGBTYhkwlyf/C0nOpcG7bKPPZd7KCRnmwq/tK11Svua5BA 4swWf4CcSF8Q/65vBAQG1SgBOH1lZNxzfEYH/c92DAb/dRwK5W/XFGJpc748TNfbZ7SZ tVEQ== 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=GoWZjCOfkb2a/SxdkHDC/zqL+VZyprqtbzVB8os7ODk=; b=QKevAVKrMXweOkIGrOHLSXPz4QEpAfsM82kFUietjj93t1vRJb/a65R27jmQridCNo jnc3Z0Uavd1QRZ1BVDncduEvlDJKNk2XP+cJ5cSqAqk827W4RUzlE4T1Z3hpMRsO49G9 wVQuYZe91UnL5tMPGus5SKtnIwnvgjQqVhu7+wW3a1i14nK8CGxVavG2wclTzfZWUaIK pDrCQ0uIgHWZ9NJOCdAmO1mg/XMFq/5axhDOyrkELT33MY4jpJvxfupcxhj/DDpltWzS QLKrsxhGXzQoGarvLXfyBt3+o/m7VPu1dx+4mBu7Fotr6IwRmq8z7X0ExbG6omiXJrwW 5M8g== X-Gm-Message-State: AOAM532ZcALYIfvtW0PK9xixpRiO89fv953ZY4NhC6lq3g005bdUeBp+ 76FGHtrgXtkAESIFff6mz7lpDw== X-Google-Smtp-Source: ABdhPJwobQ7qKkRUIjMPSpJIUV1jM7qRfzQgc6t5dt6NcdLjfQOLeQh52qT2EcVEfnVq/A0JLC/BBg== X-Received: by 2002:a37:9b0e:: with SMTP id d14mr13782190qke.447.1616775099784; Fri, 26 Mar 2021 09:11:39 -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 h75sm6845139qke.80.2021.03.26.09.11.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Mar 2021 09:11:39 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.4\)) In-Reply-To: Date: Fri, 26 Mar 2021 12:11:38 -0400 Cc: PHP internals Content-Transfer-Encoding: quoted-printable Message-ID: <5501FE70-FBED-47EB-8010-173644BC064F@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> <635DD146-FC6F-4991-8D2C-5A6B492722D5@newclarity.net> <734f12de-da98-6b76-c2fe-8682f4d177aa@gmail.com> <36E45DD6-E2BD-4801-BAAE-4355C83D1AC3@newclarity.net> <15AE4315-A456-4ED8-990A-49EBD76C5B46@newclarity.net> To: =?utf-8?Q?Olle_H=C3=A4rstedt?= 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 26, 2021, at 8:12 AM, Olle H=C3=A4rstedt = wrote: >=20 > 2021-03-26 3:38 GMT+01:00, Mike Schinkel : >>=20 >>=20 >>> On Mar 25, 2021, at 4:09 PM, Olle H=C3=A4rstedt = >>> wrote: >>>=20 >>> 2021-03-25 17:49 GMT+01:00, Mike Schinkel : >>>>> On Mar 25, 2021, at 11:22 AM, Olle H=C3=A4rstedt = >>>>> wrote: >>>>>=20 >>>>> 2021-03-25 16:02 GMT+01:00, Mike Schinkel : >>>>>>=20 >>>>>>=20 >>>>>>> On Mar 25, 2021, at 10:41 AM, Rowan Tommins = >>>>>>> wrote: >>>>>>>=20 >>>>>>> On 25/03/2021 12:31, Nuno Maduro wrote: >>>>>>>=20 >>>>>>>> The reason why we believe the vast majority of PHP Developers = are >>>>>>>> going >>>>>>>> to >>>>>>>> appreciate this RFC is because multi-line short closures (aka >>>>>>>> Auto-capturing multi-statement closures) *are more simple, = shorter >>>>>>>> to >>>>>>>> write, and prettier to read *=E2=80=94 and the community love = these changes >>>>>>>> as >>>>>>>> proven on "property promotions", "one-line short closures", = etc. >>>>>>>=20 >>>>>>>=20 >>>>>>> My main point was that the RFC needs to spell out this argument, >>>>>>> rather >>>>>>> than taking it for granted that everyone agrees on "those = situations >>>>>>> where >>>>>>> that is warranted". >>>>>>>=20 >>>>>>> Most of the current text should be summarised in a "syntax = choices" >>>>>>> section somewhere near the end. I would like to see much more = space >>>>>>> devoted to: >>>>>>>=20 >>>>>>> * Why we need this feature. What has changed since it was left = out of >>>>>>> the >>>>>>> arrow functions RFC? What problems is it addressing? Why do you = think >>>>>>> it >>>>>>> is the best approach to those problems? >>>>>>> * The exact semantics proposed: How will the variables to be = captured >>>>>>> be >>>>>>> determined? Will it distinguish variables which are written = before >>>>>>> they're >>>>>>> read, and if so how is that defined? Can auto-capturing closures = be >>>>>>> nested, i.e. will "fn() { return fn() { echo $a; } }" capture $a = from >>>>>>> the >>>>>>> outermost scope? And so on... >>>>>>>=20 >>>>>>>=20 >>>>>>>> Besides, one advantage of this RFC is that it is consistent = with the >>>>>>>> current syntax of the language and with the short-functions = RFC[2]. >>>>>>>> For >>>>>>>> example, by proposing that "fn" keyword indicates a function = will >>>>>>>> auto-capture variables, by value. >>>>>>>=20 >>>>>>>=20 >>>>>>> While it's a cute rationalisation, there's no intuitive reason = why >>>>>>> "fn" >>>>>>> should have that meaning; we could pick any aspect of the = current >>>>>>> arrow >>>>>>> function syntax and say "the 'fn' keyword means that". >>>>>>>=20 >>>>>>>=20 >>>>>>>=20 >>>>>>>> On the other hand "use (*)" has no usages / or current meaning = in >>>>>>>> the >>>>>>>> language. >>>>>>>=20 >>>>>>>=20 >>>>>>> This is a straw man argument. I could equally say that "fn() { } = has >>>>>>> no >>>>>>> usages or current meaning in the language" - of course it = doesn't, we >>>>>>> haven't added it yet! >>>>>>>=20 >>>>>>> The "function use() {}" part of "function use(*) {}" has a >>>>>>> well-established meaning, and "*" to mean "everything" is a = notation >>>>>>> developers are likely to be very familiar with. >>>>>>>=20 >>>>>>> The two disadvantages I see with using "fn" as proposed are: >>>>>>>=20 >>>>>>> * Because it's shorter, people will decide it's the "better" = version, >>>>>>> when >>>>>>> they don't actually need any variable capture. An explicit = syntax >>>>>>> like >>>>>>> "use(*)" instead makes this a deliberate choice. >>>>>>=20 >>>>>> And yet adding " use (*)" makes the syntax longer, which goes = against >>>>>> one >>>>>> of >>>>>> the goals many people have for it: to be shorter. >>>>>=20 >>>>> I don't understand why this is a target in the first place. = Shorter >>>>> does not mean more readable, and readable is more important than >>>>> writable. >>>>=20 >>>> I agree that readable is more important than writable, but shorter = also >>>> does >>>> not necessarily mean it is *less* readable, either. >>>=20 >>> Sure. The brain removes noise and reads in "symbols" anyway (where >>> "fn" or "function" is a symbol of size 1). >>=20 >> That is actually not exactly true, at least not in all cases. >>=20 >> When "nction" combined with " use (.....)" adds to line length such = that a >> developer must scroll horizontally to see all the text then it is not = the >> same. >>=20 >> And this is not a hypothetical for those of us who frequently use = vertical >> split screen in our editors =E2=80=94 I am constantly battling with = lines that are >> too long. >>=20 >> Also when longer lines cause code to wrap on GitHub or in blog posts = or >> other places then it is not the same. >>=20 >>> A more important aspect of readability is the cognitive load on >>> short-term memory, or how many "chunks" the programmer has to keep = in >>> memory to understand a piece of code. In this case, I think >>> immutability and local scope helps a lot, of which PHP has neither. = Or >>> maybe predictability of the scope? All language quirks hurt >>> readability. I never had a problem with scope in JS, despite it >>> lacking immutability and only recently got proper block scope. >>=20 >> Given that the RFC prescribes by-value capture and not by-ref capture = how it >> is really even a problem? Or are you arguing that you fear people = will just >> write closures hundreds of lines long? >>=20 >> Maybe PHP should deprecate functions longer than 50 or 100 lines? >> >>=20 >>> Maybe more important than explicit/implicit capturing of scope is to >>> keep your functions short...? In our legacy code-base, we have = functions >>> thousands of lines long. I can see auto-capturing being a problem >>> there, but that's because of the technical debt and not the feature >>> itself, I guess. Will our juniors realize that, tho? >>=20 >> Now here is where I think the real problem is, the fact that other >> developers write functions thousands of lines long. >>=20 >> But realistically, legacy code won't be affected as people are rarely = if >> ever going to go back to your legacy code and convert a thousand line >> function into a closure with auto-capture. >=20 > No, I'm more concerned that someone will add a closer at the *bottom* > of a long-ass function, capturing all variables, and then not have a > properly defined lifetime, causing a memory leak or "spooky action at > a distance" with object references. In other words, could it be a > foot-gun? Maybe far-fetched, I don't know. Unless I misunderstand the RFC, the closure would only auto-capture the = variables that are specifically referenced inside the closure, so I = don't see it capturing *all* variables unless the developer intended it = to by referencing each one of them explicitly. And since the RFC captures the variables by-value I don't see how = auto-capture would be any different than using "use (...)," even with = objects. So if the developer intends to capture all variables and/or captures = objects and either of those actions result in a memory leak I don't see = how it could be the fault of auto-capture any more than with the current = "function (...) use (...) {...}" syntax? So it seems it would be on the = developer, not on the proposed syntax. Or am I missing something? -Mike