Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108727 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 26284 invoked from network); 23 Feb 2020 11:30:45 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 23 Feb 2020 11:30:45 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id EC1D61801FD for ; Sun, 23 Feb 2020 01:47:37 -0800 (PST) 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-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lj1-f180.google.com (mail-lj1-f180.google.com [209.85.208.180]) (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 ; Sun, 23 Feb 2020 01:47:37 -0800 (PST) Received: by mail-lj1-f180.google.com with SMTP id a13so6716822ljm.10 for ; Sun, 23 Feb 2020 01:47:37 -0800 (PST) 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=dYZqpR+YCiHC+njnsmg9jo1rzL1b5t891jn6QX8WZa4=; b=IogQzxBjKl3c7DxsSHfD8x8WNftfwW/bdMGUNFmqVDWpb8Yu5euDH+0qu+AAkP51j4 9wfQMYUSxSb2UXcGrT91kXdimOhr4GLNmUVt1yGJydM2Zo4BF8+Ks6mMeSkQyLP+fV79 0thCBj4keOpoLpghTNixhjlwf+4f87OKRzxx8wxxvIPbTvcU9qrt2vck61vEbTRHnaZ/ yLchC2H+PEXd1+kIl1Gx6nDKm4pRDswWcj6VWlygWF/pKTpjHbfKJ18fHvVnKcY0kkUP p6m5wn9hKX2VeahlsvPPUD3aJ3ZoNMiTpTfjxh4vGFx6ioEIam7pN3N+xccRkdEOsYbV hThg== 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=dYZqpR+YCiHC+njnsmg9jo1rzL1b5t891jn6QX8WZa4=; b=OzhkczEH8KNnq12HDB0LH1GHfsPie2gUYcehpylcKZd9Slq/yn+7M+mzbX9TNlmf++ 5aZf/e9AOk7alzLC1u0gaNdYbX3HHtwaEdPForpgJM8vZDaYqH16aZYWjAV66zDyAfXG 4FUOLzFGHmHDj6YjU3AH65Sae6fJHN5nB9fTLzMb5nshGGKSCOYT9LfD2XkoXz8NoUcx cNbWzU18hhb4NtBDGtXXY5KltXkpHpq+eSJtRapTMOWftYoUrtKqN17BHP6dysj506qS 0BJG8Ej/Ak6O01K/5mHtfsC0o/+L1f0IpznIf/y58OJyqpNtfrMKCs7dphv2Aj3HRTN9 yofw== X-Gm-Message-State: APjAAAWwPJdbhmOob6q8478N9ddujXTpX6vRTS4t4OKSwaVPUXKgrUwJ A3kMn+/hGFoH2eW2lpwFtLMeNJAGsiXgMzYypMs= X-Google-Smtp-Source: APXvYqyHwbACvi8cTcQcX6fE+EpnQ+ioMdCOlVQlUAGn63eSJQxO+qsuZcceiy+TGuRB19HTA2bb2Ylun8nqsIU5Z2M= X-Received: by 2002:a2e:a408:: with SMTP id p8mr27963742ljn.145.1582451253312; Sun, 23 Feb 2020 01:47:33 -0800 (PST) MIME-Version: 1.0 References: <8B2AFC37-9425-440C-B89D-61CBAAB0CDDD@gmail.com> In-Reply-To: <8B2AFC37-9425-440C-B89D-61CBAAB0CDDD@gmail.com> Date: Sun, 23 Feb 2020 10:47:17 +0100 Message-ID: To: Rowan Tommins Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000d402ce059f3b24dd" Subject: Re: [PHP-DEV] [RFC] Explicit call-site pass-by-reference (again) From: nikita.ppv@gmail.com (Nikita Popov) --000000000000d402ce059f3b24dd Content-Type: text/plain; charset="UTF-8" On Fri, Feb 21, 2020 at 11:20 PM Rowan Tommins wrote: > On 20 February 2020 14:13:58 GMT+00:00, Nikita Popov > wrote: > >Hi internals, > > > >I'd like to start the discussion on the "explicit call-site > >pass-by-reference" RFC again: > >https://wiki.php.net/rfc/explicit_send_by_ref > > > Hi Nikita, > > Thanks for putting the case for this so clearly. My instinctive reaction > is still one of frustration that the pain of removing call-site ampersands > was in vain, and I will now be asked to put most of them back in. It's also > relevant that users already find where & should and should not be used very > confusing. There is a potential "PR" cost of this change that should be > weighed against the advantages. > > I'm also not very keen on internal functions being able to do things that > can't be replicated on userland, and this RFC adds two: additional > behaviour for existing "prefer-ref" arguments, and new "prefer-value" > arguments. > I should say that this is a non-essential part of the RFC. I noticed that this RFC provides a way to solve this problem, but if we don't think it the problem is worth solving, then we don't have to solve it. The prefer-ref/prefer-val thing is indeed a bit peculiar. It's an artifact of the current way of implicit by-reference passing, where the decision of whether to pass by-value or by-reference has to be made based on an "educated guess" at the call-site. That leaves us with always-val, always-ref, prefer-val and prefer-ref as the possible passing modes. In the explicit by-ref passing regime, the latter two consolidate, and we have by-val, by-ref and "either" as the options, which is a lot more obvious. But again, I can't say I'm fully convinced myself that this is really a problem we need to solve. I don't really care about call_user_func() at all (it is entirely obsoleted by $fn()), and now that I think about it, __call() isn't really the right primitive to expose anyway. If you will allow me a little digression... Instead of having __call(), what we really should have is __get_method(). For a simple forwarding proxy, the implementation would look something like this: public function __get_method(string $name): Closure { if (method_exists($this->proxy, $name)) { return Closure::fromCallable([$this->proxy, $name]); } return null; } This solves multiple problems with one stone: First, it preserves the signature of the method we're proxying to: This is better than the solution in this RFC, because it preserves both by-ref argument passing and by-ref returns, and can validate that properly (i.e. passing a non-ref to by-ref will diagnose). Second, it makes is_callable() work precisely, because we no longer have to assume that with __call() any method is callable. Third, it makes Reflection work on the proxied method. It's possible to recover normal __call() semantics from this approach by writing something like this: public function __get_method(string $name): Closure { return function(...$args) use($name) { // Normal __call() implementation in here. }; } My current opinion is that I'd rather wait for the details of out and inout > parameters to be worked out, and reap higher gains for the same cost. For > instance, if preg_match could mark $matches as "out", I'd be more happy to > run in a mode where I needed to add a call-site keyword. > I believe we talked about this in some detail in the previous discussion on this topic. My basic stance on in/out is that it's *probably* not worth the complexity, unless it is part of an effort to eliminate references from PHP entirely (which would be hugely beneficial). Unfortunately I don't really see a clear pathway towards that. "out" parameters can remove one use-case of references, and I can see how that would work both in terms of semantics and implementation. The case of "inout" parameters is much more problematic. While these can nominally work without references, I don't see how they could do so efficiently (we would have to "move out" the value from the original location to avoid COW). Similarly, I don't have any answer to how &__get() and &offsetGet() would work without references. Regards, Nikita --000000000000d402ce059f3b24dd--