Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:119393 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 79036 invoked from network); 22 Jan 2023 20:36:54 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 22 Jan 2023 20:36:54 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 88C7E180212 for ; Sun, 22 Jan 2023 12:36:53 -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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS19151 66.111.4.0/24 X-Spam-Virus: No X-Envelope-From: Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com [66.111.4.29]) (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 ; Sun, 22 Jan 2023 12:36:52 -0800 (PST) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 7DBF85C00D5 for ; Sun, 22 Jan 2023 15:36:52 -0500 (EST) Received: from imap50 ([10.202.2.100]) by compute4.internal (MEProxy); Sun, 22 Jan 2023 15:36:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm3; t=1674419812; x= 1674506212; bh=I1tyIMFm2M2oiE2Sd7Y+cUAHkhddK3yG6YlifwL4+Rs=; b=H TQTWLtmq3AM1BDFD0NhcTUTjUGg4EgsCELmeRl5Pw6wOXAqJFc3v8u0RBdEoNUTT KMhVQEUqT3rZc6toVpUTzNSqNUGj6cDKhjKw2PJ4kXVnwjmJis41EIxsFKN6XuzB x24jvjZR0RkSW+OB+kj8oOpfSbLzkXcGvA0Ltf3zRfuHSugxjdiJ+rywR8i2sVqS 5WAzsNcch4xttYzW3Iyly6+IJlzY3nRBoX99O99lHfRhgWye3yH/KOaegMg1Ik3p Tg8r/6nF/BvGIJgSGNQLXBzfHAAHFj0wrb+NQpEpkNNmM/zZBjYq/5kiksZkuchg J5bSJkBfLnNESDgEpQCQQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:date:feedback-id :feedback-id:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:sender:subject:subject:to:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; t=1674419812; x=1674506212; bh=I1tyIMFm2M2oiE2Sd7Y+cUAHkhdd K3yG6YlifwL4+Rs=; b=Fhbi+wAAI2NI7PV9D8vkBlUr10BJ+XiRlH9uvCJNfCoV K27hnpI1fZbkjs0aZnrXhljN4cIhwvVq2x+2O+tLZzo9AgyyyiGmjBjnsUsV7un6 t66WilHvEzr/MlEAq3Vt0cw/6XC2DH1wnQcCC4eWO0gApmerB+yAga9UuIYMn21T gVTzOIpqro2/q6iJEKBptAIU+4wf5JfEesxRV2PJKQMUHZ4MuK08qUffvo7c8CCG TqxIEj2fSsjnx72d0CUR+FgIsRUXxQZ9VDOkVYG/EbfMMHENaa+CSESYMjadQ2iY ktG66NEEpdESu/GeBZ47rPSlw+PY6oaGQW7ZyGjn1Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrudduiedgudegudcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefofgggkfgjfhffhffvufgtsehttdertderredtnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuggftrfgrthhtvghrnhepkeetleehffegfedvudefueejkefhvddtueeuvdev teeiveehledugeejudfhhfetnecuffhomhgrihhnpehgihhthhhusgdrtghomhenucevlh hushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehg rghrfhhivghlughtvggthhdrtghomh X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 331461700089; Sun, 22 Jan 2023 15:36:52 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.9.0-alpha0-85-gd6d859e0cf-fm-20230116.001-gd6d859e0 Mime-Version: 1.0 Message-ID: <88a59c46-9261-43f1-874d-ffc2f9caff32@app.fastmail.com> In-Reply-To: <8f530a4a-bf48-4259-877e-16ebf8082936@app.fastmail.com> References: <8f530a4a-bf48-4259-877e-16ebf8082936@app.fastmail.com> Date: Sun, 22 Jan 2023 14:36:30 -0600 To: "php internals" Content-Type: text/plain Subject: Re: [PHP-DEV] Introduce the abiltiy to use the first-call-callable syntax on non-static methods, statically From: larry@garfieldtech.com ("Larry Garfield") On Sun, Jan 22, 2023, at 11:45 AM, Ollie Read wrote: > Hello all, > > I've created a feature request issue on GitHub (here: > https://github.com/php/php-src/issues/10414), but I have been advised > that it's best to post here. > > What I would like to introduce/suggest, is the ability to create a > closure from a method using the first-class-callable syntax (eg: > MyClass::aMethod(...)), for a non-static method, statically. > > Currently, the following code causes an error. > > ``` > class Test { > public function test(): string { return 'test'; } > } > > $closure = Test::test(...); > ``` > > I understand why the error is thrown, but, and I'm unsure of the > specifics regarding this, I think we could delay the error until the > closure was called. The reason for this, is that closures can be bound, > so if you followed on from the code above, you could do the following: > > ``` > $closure->bindTo(new Test); > $closure(); > ``` > > The above would bind the closure in $closure to the scope of an object, > which in this case, is the class that the method belongs to. > > The best example I can think, for this, would be when filter a > collection of instances. If you were using a collection library, you > would currently have something like the following: > > ``` > $collection->filter(function (Str $string) { > return !$string->empty(); > }); > ``` > > Whereas it would be much nicer to have the following: > > ``` > $collection->filter(Str::empty(...)); > ``` > > In this situation, the collection library would be responsible for > binding the closure to the value it is iterating. So you'd implement this yourself elsewhere? class Str { public function empty(): bool { ... } } I don't see in this example how this is any better than what is already currently possible: class Str { public static function empty(Str $s): bool { ... } } $collection->filter(Str::empty(...)); > I have limited experience with PHPs source, and C in general, but my > understanding would be that if we were creating a closure, we would > skip the check for the static method. The code responsible for handling > the closure call would most require some additional functionality to > check if it was bound to a valid instance, returning an error if it > isn't, and then returning an error if it isn't bound at all and the > method isn't static. > > The more I think about it, the more I think this may require a new type > of Closure, or at least a runtime applied interface, to help developers > determine whether a closure was created using first-class-callable > syntax. This is, I think, the important part here, and would be a prerequisite. Right now there's no way (as far as I know) to differentiate a closure that is callable from one that would be callable if it were bound to an object. That's generally not a huge deal in practice as unbound closures are not often used, but what you're suggesting would make them much more likely. Also, a static closure cannot be bound, so you cannot just blindly bind whatever callable you're passed to $this, in your example. (Besides, blindly binding a closure to $this sounds like a great security hole.) So for some variant of this to work, I think you'd first need to think through how to (easily and without dipping into reflection) determine if a closure object is bindable (static or not) and if it's already bound. Once that's figured out, then we can see what, if any, short-hand way to make a not-yet-bound closure makes sense. (Which could be FCC syntax or not, I don't know.) --Larry Garfield