Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:117944 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 30153 invoked from network); 14 Jun 2022 12:40:57 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 14 Jun 2022 12:40:57 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 02AFC1804AF for ; Tue, 14 Jun 2022 07:28:24 -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, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-qk1-f179.google.com (mail-qk1-f179.google.com [209.85.222.179]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 14 Jun 2022 07:28:23 -0700 (PDT) Received: by mail-qk1-f179.google.com with SMTP id 68so6460704qkk.9 for ; Tue, 14 Jun 2022 07:28:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20210112.gappssmtp.com; s=20210112; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=Tt+UAln3WZa+MIUXstLIUhK6y8WMJGkTtfxxvtHv/6E=; b=NlZkayyYY3DDrYcl+Vbw0xwkPb49SE96VZJ4s3zfcTB++bcM/0KwjDtpdIGTZfH2of TV/5DNKwaTKnMd8QxN1Ej1yoyYQ4PLUPfdcP9zTLa5lgdsDuBtSEiGSV6WLFVIbZ4CbG F22ZbHzYKhy5niyeggPJTXxBGvnXMdpzgWJV4U/O+7IqnqyO/9waurUCEGTn+shJqCEE gWSJDixCQe1UoT/onOiMBwynpAmvY8O7Wo9ix6wz8acquaP+y1w0b7jGo2hYrsDLnpur S3EJPXMijEUOQGkmH26eSAKfp7eT9A1/udbfjVha0SbdGAWhC0kexzriQ+OdrZwcP4ct pLaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=Tt+UAln3WZa+MIUXstLIUhK6y8WMJGkTtfxxvtHv/6E=; b=xuh2Sjm5AswvVEnoJOKanb+wOgCSSLDdf2CgfrYtmbGacbI117fVcDe1Zf9E00bEc5 gF2DqAzodyTiW5ZQUqAa3KUrgonngyfptMk8sFdq+4VDjHe1zBkdjTdvyg2kdGtSbyPy xh1B51f2evAJnASpXwgQZ+TI/7XhoqZKn8bspG7uPbINdTwN1ehenkAHdSPTATKahM+p Hb8GvzEQwSo+x7dhL8FkeEmWWFnDgP7XXPFUl3CUwqiHOwfydMwMnp9hDjEsqOYe07J/ P1Bu1FyxzqEnkT/HDrsaU/Ij8sx0TssTANgbY3zQ15pqZsoQjLj1qQbasQUWxrZ/8OIc KM9Q== X-Gm-Message-State: AOAM532CcL04KIAzbGm/YnjTLfOJMjfwcm/sRq6YF7/6BKb34a0jF1dC hN5jJsFOiSCSPh/tj7KYzRw96yPWPWYimg== X-Google-Smtp-Source: ABdhPJxVM/7/I6iDI/1SvfUjBg3zKR1bpqti2mh4s7luIrfwh2c4v0MddCUjA+Yo93+qY4WE171/Cw== X-Received: by 2002:a05:620a:404a:b0:6a7:7ee2:e6c2 with SMTP id i10-20020a05620a404a00b006a77ee2e6c2mr4063187qko.715.1655216902706; Tue, 14 Jun 2022 07:28:22 -0700 (PDT) Received: from [192.168.1.10] (c-24-98-254-8.hsd1.ga.comcast.net. [24.98.254.8]) by smtp.gmail.com with ESMTPSA id bp8-20020a05620a458800b006a6d20386f6sm9338692qkb.42.2022.06.14.07.28.21 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 Jun 2022 07:28:21 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.7\)) In-Reply-To: <42cdb2d9-485d-cf5c-4cce-b9c1f8c2084e@gmail.com> Date: Tue, 14 Jun 2022 10:28:21 -0400 Cc: internals@lists.php.net Content-Transfer-Encoding: quoted-printable Message-ID: <92190FB5-BB44-4621-A6FE-EB795CB90577@newclarity.net> References: <2b35605f-8da8-46b1-aec3-00bd1bfe47fd@www.fastmail.com> <8310f3fd-0011-970e-5379-b2b6e03942b2@gmail.com> <2347345.PIDvDuAF1L@arnaud-t490> <8422e11c-4a3f-9f99-56ce-884491dfe08e@gmail.com> <39470114-2c35-4c71-b8ef-c8d3ce3c3555@www.fastmail.com> <42cdb2d9-485d-cf5c-4cce-b9c1f8c2084e@gmail.com> To: Rowan Tommins X-Mailer: Apple Mail (2.3608.120.23.2.7) Subject: Re: [PHP-DEV] [RFC] Short Closures 2, aka auto-capture take 3 From: mike@newclarity.net (Mike Schinkel) > On Jun 13, 2022, at 1:39 PM, Rowan Tommins = wrote: >=20 > On 13/06/2022 14:52, Larry Garfield wrote: >>> That's one perspective. The other perspective is that the proposal = is to >>> extend closure syntax to support automatic capture. >> As noted before, this is a distinction without a difference. >=20 >=20 > It's a difference in focus which is very evident in some of the = comments on this thread. For instance, Arnaud assumed that adding = "use(*)" would require a change to arrow functions, whereas that never = even occurred to me, because we're looking at the feature through a = different lens. >=20 >=20 >>> By the way, the current RFC implies you could write this: >>>=20 >>> fn() use (&$myRef, $a) { $myRef =3D $a * $b; } >> The RFC already covers that. $b will be auto-captured by value from = scope if it exists. See the "Explicit capture" section and its example. >=20 >=20 > So it does. I find that extremely confusing; I think it would be = clearer to error for that case, changing the proposal to: >=20 > > Short Closures support explicit by-reference capture with the |use| = keyword. Combining a short closure with explicit by-value capture = produces an error. >=20 > And the example to: >=20 > $a =3D 1; > fn () use (&$b) { > return $a + $b; // $a is auto-captured by value > // $b is explicitly captured by reference > } >=20 >=20 > Clearer syntax for this has been cited previously as an advantage of = use(*) or use(...): >=20 > $a =3D 1; > function () use (&$b, ...) { // read as "use $b by reference, = everything else by value" > return $a + $b; > } >=20 >=20 >> 1. Auto-capture could still over-capture without people realizing it. = Whether this is actually an issue in practice (or would be) is hard to = say with certainty; I'm not sure if it's possible to make an educated = guess based on a top-1000 analysis, so we're all trying to predict the = future. >=20 >=20 > I tried to make very explicit what I was and was not disputing: >=20 > > Whether the risk of these side effects is a big problem is up for = debate, but it's wrong to suggest they don't exist. >=20 > The RFC seems to be implying that the implementation removes the side = effects, but it does not, it is users paying attention to their code = which will remove the side effects. >=20 >=20 >> Arguably it's less of an issue only because short-closures are, well, = short, so less likely to reuse variables unintentionally. >=20 >=20 > Our current short closures aren't just a single *statement*, they're a = single *expression*, and that's a really significant difference, because = it means to all intents and purposes *they have no local scope*. (You = can create and use a local variable within one expression, but it = requires the kind of twisted code that only happens in code golf.) >=20 > If there are no local variables, there is nothing to be accidentally = captured. That's why the current implementation doesn't bother = optimising which variables it captures - it's pretty safe to assume that = *all* variables in the expression are either parameters or captured. >=20 >=20 >> 2. The syntactic indicator that "auto capture will happen". The RFC = says "fn". You're recommending "use(*)". However, changing the = indicator syntax would do nothing to improve point 1. >=20 >=20 > The reason I think it would be better is because it is a more = *intentional* syntax: the author of the code is more likely to think = "I'm using an auto-capture closure, rather than an explicit-capture = closure, what effect will that have?" and readers of the code are more = likely to think "hm, this is using auto-capture, I wonder which = variables are local, and which are captured?" >=20 > Of course they can still guess wrong, but I don't think "fn" vs = "function" is a strong enough clue. "Strong enough" is an opinion, and it seems all who have commented have = differing ones of those. =20 But maybe a memory device would help address (some of?) your concerns: - fn() =E2=80=94 It is SHORT and implicit. Short is CONVENIENT. Thus = Short auto-captures variables because that is the most Convenient thing = to do. - function() =E2=80=94 It is LONG. Long is more EXPLICIT. Thus Long = requires Explicitly declaring variables, which is also more rigorous and = robust. Or for the TL;DR crowd: - fn() =3D> SHORT =3D> CONVENIENT =3D> Auto-captures - function() =3D> LONG =3D> EXPLICIT =3D> Requires declaration Hope this helps. #fwiw -Mike