Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120399 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 1942 invoked from network); 25 May 2023 17:29:40 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 25 May 2023 17:29:40 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 9B6D71804BC for ; Thu, 25 May 2023 10:29:38 -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.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 ; Thu, 25 May 2023 10:29:37 -0700 (PDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id D29D05C0190 for ; Thu, 25 May 2023 13:29:36 -0400 (EDT) Received: from imap50 ([10.202.2.100]) by compute4.internal (MEProxy); Thu, 25 May 2023 13:29:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :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=fm1; t=1685035776; x=1685122176; bh=VWT/crBkS9 7wgtgxwW1eVCoW76LfIZrKRH4UQbK9l1Q=; b=eyVPJJafUiS+O9RqYyEHduxBWn 8a0Kbn9mHiAWR7mPmwxYzgUjmgjvpEcXiCIG6alI5B4FxgOaUL0ZuzBScTJGEUAD P2F2u4BQsQ4uhXyMhV5+pwyn2mgI7CbjG+zBwSH6aqI8ohEO2kEkVvODj/oSP0E+ s99z7TD3QalcELw4FY6frjQ1oG4MyPulWgb+7qVwJvhC0uMZjq+yXRoS4t3yYuza V5CJH+QvBjNU0XsjYqwa+YysDEENmEEh9BIK+gauGqWsXyyT0K3kUOimWgjl4soE AgGqdIJRjBGsw0PeToy3LuX9Rs7I4iyJdiGhWvQDUobEZIJfNx8pZUhumGTQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :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=fm1; t=1685035776; x= 1685122176; bh=VWT/crBkS97wgtgxwW1eVCoW76LfIZrKRH4UQbK9l1Q=; b=c 2Bqn8VXy4t84Chx/AWEmbAVeWytUUCi9sJG3gobPMmJAvy1HxAUbONwDIIlwJkk5 DT6ojT7zYKL4rKPg8hlaeINgVXSAVxtgSbZx9lt8/QWOUw9tRC6BjaD+C6QyAgPR 7Z+1BthgjRlvuNk8ewRBX9iu7Pn45pszAZiiAFsnhUru8RoLgxMAtNrCl/K6eyvc /WtT8CnoDMdewgr7ktN/ddRNE2YWt41mToYVOQJSVCRfsf+lCVcQfWWXCLcg0G1d je52IwIFpE2T0xYjUVVkS6Xcl/zf3f5b3fp19zru8N6bd/bAinOPkZaIP3jwyydf ziAAtjX1RhEqIGBQEzxyg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrfeejjedguddufecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefofgggkfgjfhffhffvufgtgfesthhqredtreerjeenucfhrhhomhepfdfn rghrrhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrd gtohhmqeenucggtffrrghtthgvrhhnpeeggeehgfetjeehgefggefhleeugefgtdejieev vdethfevgeeuudefleehvdetieenucffohhmrghinhepphhhphdrnhgvthenucevlhhush htvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghr fhhivghlughtvggthhdrtghomh X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id 94CCF1700089; Thu, 25 May 2023 13:29:36 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.9.0-alpha0-441-ga3ab13cd6d-fm-20230517.001-ga3ab13cd Mime-Version: 1.0 Message-ID: In-Reply-To: References: <5e35344e-e885-4b65-8f86-2cb43330af46@app.fastmail.com> Date: Thu, 25 May 2023 17:29:14 +0000 To: "php internals" Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] [Discussion] nameof From: larry@garfieldtech.com ("Larry Garfield") On Thu, May 25, 2023, at 3:21 PM, Robert Landers wrote: > On Tue, May 16, 2023 at 11:56=E2=80=AFPM Larry Garfield wrote: >> >> On Sat, May 13, 2023, at 7:27 AM, Robert Landers wrote: >> > Hello Internals, >> > >> > It is with much trepidation and excitement that I'd like to announce >> > the `nameof` RFC (https://wiki.php.net/rfc/nameof). It has changed >> > quite a bit in the last couple of days, so if you haven't seen the >> > latest draft, please check it out. >> > >> > Essentially, it allows using `nameof()` anywhere a string can be us= ed, >> > even in static contexts. From a developer's perspective, it is a >> > string and from the engine's perspective, it is also mostly a string >> > (depending on how deep we want to go on error checking -- see the >> > RFC). >> > >> > If anything is unclear or if I missed something, please let me know. >> > >> > Robert Landers >> > Software Engineer >> > Utrecht NL >> >> Some concrete use cases that I know I run into, and would thus be wha= t I'd hope an RFC like this would resolve: >> >> Router::addRoute('\my\space\my_action_function`); >> >> Right now that has to be a string with a full namespace. You cannot = use a FCC here, because you want to use this data to compile the router = somehow. So in this case we want the full namespace. (Ignore function = autoloading for now.) >> >> Router::addRoute(MyClass::actionMethod); >> >> Various frameworks have different custom syntaxes for this case. It'= s also not clear if this refers to a static method, or a "instantiate th= is out of the container first and then call this method" approach. In t= hese cases, we would want the full class name, and the method name on it= s own, as separate strings. >> >> In my FP library, I have code like this: >> >> function prop(string $prop): \Closure >> { >> return static fn (object $o): mixed =3D> $o->$prop; >> } >> >> function method(string $method, ...$args): \Closure >> { >> return static fn (object $o): mixed =3D> $o->$method(...$args); >> } >> >> Which you can then use in a pipe, like so: >> >> pipe($someObject, method('foo'), prop('bar')); >> >> Or, more realistically, you'd use method() and prop() in a map or fil= ter call within the pipe. >> >> In this case, you want just the method/property name on its own, with= out a namespace, because it will be used in the context of an object to = be named later. >> >> How would nameof() handle each of these cases? >> >> --Larry Garfield >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: https://www.php.net/unsub.php >> > > Hey Larry, > > I did not ignore you. I somehow missed your question while researching > something after reading the first half of your email last week -- I, > apparently, never made it to the second half until today. I'll get to > that in a sec. Not to worry. >> pipe($someObject, method('foo'), prop('bar')); >> >> Or, more realistically, you'd use method() and prop() in a map or fil= ter call within the pipe. >> >> In this case, you want just the method/property name on its own, with= out a namespace, because it will be used in the context of an object to = be named later. > > So, for example, you could replace your pipe with: > > pipe($someObject, method(nameof($someObject->foo(...))), > prop(nameof($someObject->bar))) > > It looks a bit wordy, but PHP differentiates between properties and > methods by using a parenthesis/bracket (hence if you want to call a > property that is actually a closure, you have to write ($this->prop)() > otherwise it will look for a method called prop and fail to find it). > > At runtime, you would receive a warning on this line if $someObject is > missing a method called foo or a property called bar (if the > error-detecting version is chosen). This would result likely result in > an actual error in your method() and prop() functions. However, it > should make debugging from logs a bit easier since you'll (hopefully) > notice the warning. I figured it would be something like that. I don't know how it would be= done better, but it also makes the code notably more verbose, and clums= y with the extra ()s. So, I'm not sure if it's a net-win or not. > Now, why I didn't answer you and only made it half way through your em= ail... > > Much of the earlier discussion was about functions/consts being > fully-qualified names. I was mostly against it, because I was offering > 'both' qualified and unqualified. However, your initial examples > really hit home for me and I did a bit of spelunking in various > popular PHP codebases for class::name (since that is really the only > similar thing) and for stringified names of things. I'm now convinced > that FQL's should be returned for functions, and constants (but not > methods and properties). Mission accomplished, then. :-) And yes, I agree with that conclusion. > Thus, your example: > > Router::addRoute('\my\space\my_action_function`); > Router::addRoute(MyClass::actionMethod); > > could be rewritten as > > use function \my\space\my_action_function; > Router::addRoute(nameof(my_action_function)); > Router::addRoute(nameof(MyClass::actionMethod(...))); > > I'll have to think about how to word this in RFC, but I'll do so as > soon as I figure it out. >> use function \my\space\my_action_function; >> Router::addRoute(nameof(my_action_function)); >> Router::addRoute(MyClass::name . '::' . nameof(MyClass::actionMethod(= ...))); // or something since the class name is not returned with nameof= (). The function one seems reasonable. The method version, though, looks su= per ugly and hard to implement. I'd be much more likely to just split i= t into two arguments and leave the second as a string, TBH. =20 Using a :: pseudo-constant suffix rather than a ()-based construct would= help with the syntax clumsiness in both cases, but wouldn't entirely el= iminate it. I don't have a really great answer here, unfortunately. I = think I'd marginally prefer a ::name suffix at this point just for synta= ctic convenience, but I'm still undecided if the overall tradeoff is wor= th it. (For ::name, probably, as that would be a much lighter syntax im= pact for those unusual cases that it's needed.) --Larry Garfield