Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:130028 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 64E891A00BC for ; Fri, 6 Feb 2026 15:12:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1770390736; bh=54qnZicVpee7c4lJasBrZl80n0qtHViOR9B/uRAxQTU=; h=Date:From:Subject:To:Cc:References:In-Reply-To:From; b=LH1j/fLXgyrxP1cU1eBJu1THEgJn1tgmHpBSBUk0Ue9tTB/YOip2bQ9IWI0BgHG2K K3EwYOKh5Mta0qGJ3kzgObmgHTiN35aDfNjAwZfdGaAQEVcWN2fhcVV5ucbohMEC4t qst1vNCvfzcL3Y2PYY7o96JRf3wTna3uRtvcwoS/pfEUEf+E3v9rrScjrqLonXQk+w heKft0p+xnwREjyTmegsSfIm/M9MWaFSyVzgTqtg9yNGbK4bXMyX1BOvVZnLxQMnm0 hnlETH5o7wagws8pOVfYOC1P/o7Cy/ZpI+uY9LcCGfUaJO3RqtYVSiQbe8RdnlqAV/ OsXeXeyYlm6jg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2A137180074 for ; Fri, 6 Feb 2026 15:12:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from chrono.xqk7.com (chrono.xqk7.com [176.9.45.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 6 Feb 2026 15:12:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bastelstu.be; s=mail20171119; t=1770390728; bh=ua8seFczEgUT68pwWsBHU+r2AX4lnc55n2zbXhWaKLs=; h=Message-ID:Date:MIME-Version:From:Subject:To:Cc:References: In-Reply-To:Content-Type:from:to:cc:subject:message-id; b=VnVkjCrGcmmRCR1Nc0aDQwFyC89VM+0vu/dbZ8aSasitO3E38Xd6rsfQGK5pjIkYy GauEWQeL/eppREmuEZzqgZqcjRt/h+DSYdtpKuPZpopJ0p84XmPUepHICl/mDbxDPU 43AdV1kEz04F12+HQbRPcidVAHjb6aXQMYvk5/BUzRG83dUzli8KylfFcSLi5Ag6EP 302WPinX2cnap2MD9J5NRXVMMXItbDKiOkqfiAQ3JlD8pCGD+lOq/iNj+oTVdCM5cJ 08RQiKpz/ANqFwi71ac0A7bJYHbxyMOHWmhW9yx65UXFCnHWQ2mB2+nyavTxnKMy8s /7eS3uqyg39Cg== Message-ID: <3038c7a5-416a-49d8-9322-5f323678cd9e@bastelstu.be> Date: Fri, 6 Feb 2026 16:12:05 +0100 Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 Subject: Re: [PHP-DEV] [RFC] Partial Function Application for instance of non-static methods ("$this") To: Bob Weinand Cc: php internals , Arnaud Le Blanc References: <64953ec741a4c6609519e1878ad37b54@bastelstu.be> <1c8827c1-a860-4e40-89fd-51698cbbe475@hotmail.com> Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: tim@bastelstu.be (=?UTF-8?Q?Tim_D=C3=BCsterhus?=) Hi Am 2026-01-31 05:25, schrieb Bob Weinand: > I see the rejected features section, but this is a non-argument to me, > like x(...['$this' => $obj]) is just allowed the same currently. > > I don't think that argument weighs strong enough. Thank you. We didn't consider unpacking and after checking with Arnaud, it would indeed be an option to use `x(this: ?)` within the call and still allow `x(...["this" => $x])` as an escape hatch to preserve compatibility. With regard to your comment on the PR and the “Open Issue” listed in the RFC about the name for the `$this` parameter in the resulting Closure we have two options to offer: 1. `ClassName::methodName(this: ?)` with the parameter being called `$__this`. 2. `ClassName::methodName($this: ?)` with the parameter being called `$this`. Notably `ClassName::methodName(this: ?)` with the parameter being called `$this` is not an option, because it would result in inconsistent behavior: `ClassName::methodName(this: ?)` semantically relies on `$this` never being a valid parameter name, such that `this: ?` can unambiguously refer to the “implicit `$this` value” for a method call. However when the parameter in the generated Closure would be called `$this`, there is some ambiguity for cases like: $c = DateTime::format(this: ?, format: ?); $c2 = $c(this: ?, format: 'c'); Is `this: ?` in the definition of `$c2` referring to the `$this` parameter of the generated Closure or is it an attempt to partially apply the `Closure` object for the `Closure::__invoke()` method that is referenced by `$c`? Similarly allowing `this: $object` with a concrete value is explicitly disallowed, because of possible ambiguity with regard to inheritance: class P { public function m() { echo "P"; } } class C extends P { public function m() { echo "C"; } } // is this calling P::m() or is this calling C::m()? P::m(this: new C()); This would however prevent calling a partially applied instance method with named arguments: $c = DateTime::format(this: ?, format: ?); // Disallowed, because this: must be partially applied. $c(this: new DateTime(), format: 'c'); If the syntax to define the PFA was using `C::m($this: ?)`, `$this` in the resulting Closure would just work like any other parameter. So this leaves `this: ?` + `$__this` and `$this: ?` + `$this`, for which Arnaud an I didn't come to a clear agreement and thus want to hold an informal poll. For you to make an educated decision, we prepared a comparison table: ($this: ?) (this: ?) (1) `this: $value` remains legal (with variadics): Yes No (2) Unpack ambiguity: Yes Yes (3) Uses existing syntax / no weird name: No Yes (4) PFA param name is $this, not $__this: Yes No To explain each of the points: (1) Is referring to: function dump(...$args) { var_dump($args); } dump(this: "foo"); remaining legal without using dump(...['this' => 'test']); as a workaround. (2) Is referring to: dump(...['this' => 'foo']); dump(...['$this' => 'foo']); behaving differently from: dump(this: "foo"); dump($this: "foo"); (3) Is referring to: dump($this: ?) introducing new syntax (the leading `$`) instead of just new semantics (a special parameter referring to an object instance). (4) Is referring to: $c = DateTime::format(this: ?, "c"); $c("foo"); emitting: Uncaught TypeError: DateTime::{closure:pfa:test.php:3}(): Argument #1 ($__this) must be of type DateTime, string given with the error message referring to `$__this` rather than `$this` and similarly: $c(__this: new DateTime()); being required when using named parameters to call the Closure is desired. ---------------- Long story short: Which of the two alternatives of 1. `ClassName::methodName(this: ?)` with the parameter being called `$__this`. 2. `ClassName::methodName($this: ?)` with the parameter being called `$this`. Do you prefer? Best regards Tim Düsterhus