Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114239 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 44195 invoked from network); 28 Apr 2021 14:26:51 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Apr 2021 14:26:51 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 43FDC1804DD for ; Wed, 28 Apr 2021 07:31: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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.41]) (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, 28 Apr 2021 07:31:23 -0700 (PDT) Received: by mail-lf1-f41.google.com with SMTP id b23so17014121lfv.8 for ; Wed, 28 Apr 2021 07:31:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=XBp7svvK+uzDFSTB7GATgFo4sGABNjicHCFx2R+mz+Q=; b=CCiTGPK3TE59fSnvgsAg6j5UnBlHxsD3hv3lyBQpWYdWWicaibGZg6wXzZkiWOv7N/ 0qr8roZl4nf5vu/428ZqgXMQTYIHTuSK+tmiFqZNQkChfy8OPZKYbxKFqYh1TZ40Mhj8 ilRqj6whWVVQ9QJ4ny4MiWTHSv2xL9+9+Wrv+3XF8G1ErrrLY+pHE9JYPcQLI+8Mtyka JwiWFOPDBEEEwXK61B3indmcOjuYP0vQaOEyLOupOsWriH/08gowRQwWteJYV3EH3d87 dkRVFuqoNmfhBsn9bOqb7TxOjTwgOV31jsNGIeuz4/8hOXYHdCpsGG+fsuxzpp2FeYPv c1nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=XBp7svvK+uzDFSTB7GATgFo4sGABNjicHCFx2R+mz+Q=; b=Y49h/NFO8qRgyQsRGQhlAAb42WCwys6ldM4+PqsvIFA09SWVRH8qKM49534V0fTFt0 0nCsa+Lqkwdk3PZOhuMxpKrgiFM9CuTRQioygOcWE1oJaxdp3KMSBPfqfwzlOtvTiTxH 9w1vkiCswWImDAk26PouXVR4LvEgYUt3VMPC0AW9Y0+y7aIwBSvr4dkbd/9SR3/egYg3 StBOQQgRdNavn2duW05f1SpWshrr6NMSe2I6JTTq6XfZ+GIMd0cLS+8tPnFJf+J16zQf NS2m5MyZw5pM2fB4vsBgtLSZQ0YvLE9Ie41sWiSiDSM8J5SaxJErSrDikv9nmcJPj1nk GNNw== X-Gm-Message-State: AOAM533oo5PAz4Gn9+dFJzmPcgod9xTIMltFoOutO9Qt+MxDG5Bm/Sd2 19gHCkSyzkqk4D+8JdLquTFVIZgulwsDy/M3m/E= X-Google-Smtp-Source: ABdhPJw9+AwgggKBw9runA+YqL0oO6YInbSCqem35tYFj76AFrpwz71HbfyE0J6NsjSX19dOM7usoX4bxprQ1qPbDJU= X-Received: by 2002:a05:6512:108e:: with SMTP id j14mr573804lfg.315.1619620282063; Wed, 28 Apr 2021 07:31:22 -0700 (PDT) MIME-Version: 1.0 References: <88c9eb5f-f80c-4869-b7f8-1b58b9e2eaa3@www.fastmail.com> In-Reply-To: <88c9eb5f-f80c-4869-b7f8-1b58b9e2eaa3@www.fastmail.com> Date: Wed, 28 Apr 2021 16:31:05 +0200 Message-ID: To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="00000000000095611105c1093b88" Subject: Re: [PHP-DEV] [RFC] Auto-capture multi-line closures and short functions take 2 From: nikita.ppv@gmail.com (Nikita Popov) --00000000000095611105c1093b88 Content-Type: text/plain; charset="UTF-8" On Wed, Mar 24, 2021 at 5:20 PM Larry Garfield wrote: > Greetings, Internalians. > > Some months back I proposed an RFC for short functions. > > https://wiki.php.net/rfc/short-functions > > After some discussion, I put it on hold to ensure that it was compatible > with the other discussion floating about around an alternate syntax for > multi-line closures that did auto-capture. It's important that the syntax > of both proposals is consistent. > > Nuno Maduro and i have talked recently and worked out the syntax that is > consistent between both proposals. That takes 'fn' off the table for > short-functions, for reasons discussed in both RFCs. > > To that end, I offer: > > 1) The updated short-functions RFC: > https://wiki.php.net/rfc/short-functions > > 2) A new RFC, code by Nuno, for auto-capturing multi-statement closures: > https://wiki.php.net/rfc/auto-capture-closure > > These are separate RFCs and at this time we plan to send them to separate > votes, but I list them together to demonstrate that they have been > developed in a mutually-compatible way. > > Further details in the auto-capture-closure RFC. > Hey Larry, I'm generally in favor of supporting auto-capture for multi-line closures. I think that extensive experience in other programming languages has shown that auto-capture does not hinder readability of code, and I don't see any particular reason why the effects in PHP would be different. I also think there is value in having a consistent syntax for closures -- currently, you have two options, and may need to switch between them as you add or remove code. There are some caveats though, which this RFC should address: 1. Auto-capture in arrow functions works by-value. This is sufficient for the purpose of single-line arrow functions, where you would be hard-pressed to perform any meaningful state mutation. For multi-line closures, it becomes much more likely that you want to modify a value from the outer scope. It should be possible to do this without switching to the function() notation. I do believe that by-value capture is the correct default, and should remain as such, but there should be an opt-in for by-reference capture. My suggestion would be to allow use(&$count) on fn(), which allows capturing certain variables by reference rather than by value. An alternative that has previously been discussed is to allow changing the default capture mode using something like use(&), but I believe it would be better if variables captured by reference had to be spelled out explicitly. 2. For much the same reason, capture analysis for arrow functions is very primitive. It basically finds all variables that are used inside the closure body and tries to import them, silently failing if they are not available in the outer scope. For multi-line closures, this would commonly end up importing too many variables. For example: fn() { $tmp = foo(); bar($tmp); return $tmp; } Here, there is no need to import $tmp from the outer scope, but a naive implementation (which I assume you're using) will still try to capture it. Now, this has two effects: a) Performance, as we're trying to capture unnecessary variables. This may be negligible, but it would be good to at least quantify. I would rather there not be recommendations along the line of "you should use function() for performance-critical code, because it's faster than fn()". b) Subtle side-effects, visible in debugging functionality, or through destructor effects (the fact that a variable is captured may be observable). I think it nothing else, the RFC should at least make clear that this behavior is explicitly unspecified, and a future implementation may no longer capture variables where any path from entry to read passes a write. Regards, Nikita --00000000000095611105c1093b88--