Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114245 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 79877 invoked from network); 28 Apr 2021 21:56:25 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Apr 2021 21:56:25 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B40CE1804E2 for ; Wed, 28 Apr 2021 15:01:01 -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-oi1-f177.google.com (mail-oi1-f177.google.com [209.85.167.177]) (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 15:00:58 -0700 (PDT) Received: by mail-oi1-f177.google.com with SMTP id l17so33222290oil.11 for ; Wed, 28 Apr 2021 15:00:58 -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=Wq71DwX4k0tHldn4GF9z2FzojOUaJuoMvfcqvsUnedg=; b=fCylznD2ccqF6MOPeHsotLHQn8JjWDRK1UXbZcue8mBY9YNgxuZEYRD3YyNaQNnEly Hz+EhwI4JQwB5L6U8XaFMzSJmfdmLoFuf+EEN7+KktxKZx6sjuEO9HcF7yhXWqH2Ch+M +CKULQHE1wxO3srAhoxXMGY2uiGenEM4hndodV33Lx7jJJGy+kUhEmXLLWZu1ppRjJoU mQC/zc5KwP2aLoPTrrs8iwSkR7wiGs8kegXzioJWX4u1SsquHHsasz9O99nD3c8gBnNc fOWK3TayCim2IPZGRcNRIt0TGQZMfe2FLSUElT1UHh9wtUqThvBC9AD9QB5BGxH9Hdcs gGfg== 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=Wq71DwX4k0tHldn4GF9z2FzojOUaJuoMvfcqvsUnedg=; b=mUsQuwzYUs5t7d9GjXDZnLz+AsWOoNPkGtmIUHWqbE0ngSIPEAxJ727wErh+HnGOTs 54LSSswUJdMsdLjZOh/jKs9rzlSTUh4Ns9FVRBgbMsprDeluQzmCk3vxahvxzQnQqFoY nuj3Qo5HS+WbGonhC8qrsS/ssYcSznL0aDGSaA2s/xvfF0KbmQ9IhrKZ+7OCeq3WbfeW JIBGYEcbC649gZYsSHKMeGOqFKNa1uMGyWcy/hU2QxRbbM5VP72VuWYmJjccPNkSZSv3 m7vq0m2oTNzpeNLl0e8Yc+EK1zkp2ywINyGOtFDB9MU7GjpJJyTfFWplZ3+/z4K8p+w3 kX/w== X-Gm-Message-State: AOAM530qxXdPPMefz1FLnWLaO+xlpt6JuXsA4PvOPWjpXEa3V6n9cX2g ahva5fPgnwE5Rt/vLyMPFEVh7mkCoXd81CP59VU= X-Google-Smtp-Source: ABdhPJxDJosWrwWxlR7wIPlBjembe5vI9G65J0mTPWo7DEoYz51Twy5q7TECURJ21FJXNpOll/AN+6Y++Ge54SCvf04= X-Received: by 2002:aca:af16:: with SMTP id y22mr7742526oie.18.1619647255860; Wed, 28 Apr 2021 15:00:55 -0700 (PDT) MIME-Version: 1.0 References: <88c9eb5f-f80c-4869-b7f8-1b58b9e2eaa3@www.fastmail.com> In-Reply-To: Date: Wed, 28 Apr 2021 23:00:44 +0100 Message-ID: To: Nikita Popov Cc: PHP Internals Content-Type: multipart/alternative; boundary="00000000000058d7bc05c10f8356" Subject: Re: [PHP-DEV] [RFC] Auto-capture multi-line closures and short functions take 2 From: enunomaduro@gmail.com (Nuno Maduro) --00000000000058d7bc05c10f8356 Content-Type: text/plain; charset="UTF-8" On Wed, 28 Apr 2021 at 15:31, Nikita Popov wrote: > 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 > Hey Nikita, Concerning point 1: Agreed. Going to update both the pull request and the RFC accordingly. Concerning point 2: Developing some sort of static analysis that can infer what needs to be captured may be problematic. First, that won't be consistent with the way auto-capture currently works in PHP (one-line short closures). Second, what needs to be captured may be determined at runtime (thinking about eval, variables names computed at runtime, etc). Of course, I am willing to hear more thoughts on this. Regards, Nuno. --00000000000058d7bc05c10f8356--