Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128821 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 B40B81A00BC for ; Mon, 13 Oct 2025 17:01:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1760374877; bh=zeGcStzmNC739BW98fpdph9Cg8YUOA9Lzt2NT+WSlys=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=U2LgUV5R2196ZvTAxKIx7JmN2qMRX1hxQz8yzwJHbhKTKdcIf0l+z3Mvx/N/IOjub q5S5QxtQiUS6LSu555KgNhLGvIyWCogdCpB4rE1t6tIZ/NF+KrLlrEFykkXpALme9Y GQYEnA1JPYyTFvztF1169p5j3oCvQBKxwUevHAUJLyOl1FeZxgrAI0iXiZ7uklhpPc aR9aEQGCS5Jx/0sLQZKxZ287ab2ScDdhozjVIBQlRodJKHJc+VMGsFhpKocJi1ikq/ s1GvDTcvC2DQAtPfdfKe6We+MxKGzFNDIQmh2kBiAPuo68DgLAVW6IllPX6GWssdqc iQaEQgJ7vE6OQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2B08D1801D5 for ; Mon, 13 Oct 2025 17:01:12 +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.7 required=5.0 tests=BAYES_05,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-ed1-f51.google.com (mail-ed1-f51.google.com [209.85.208.51]) (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 ; Mon, 13 Oct 2025 17:01:08 +0000 (UTC) Received: by mail-ed1-f51.google.com with SMTP id 4fb4d7f45d1cf-639e34ffa69so7002708a12.3 for ; Mon, 13 Oct 2025 10:01:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1760374862; x=1760979662; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=KDhRrAA3xq696ApWwsGzrrtYkBQuGUUTpFieC5481mk=; b=T2SN5HHW/LLAHIjgLp9fjW6OxCZucDZv3JIQsQL4uSau7LeWDWQaOTWXpDybT98lg7 i/qY/E4urVjv9rMOgb4uBi8cjc/r11sdXajU2L1LPWnHvUPFeyP36ZJMh/aHO9r/HVCA dy/O/HfxT+c1tMByX/dk0JunIo8xdf0QTNPORnx3W9DykKhAHW2444RK2oqFZMbCujMu QyWhoiR9hLzlob7UbjIw+4DsBaLnqLukygZ/5ord0h3zYTg17rhhqNoLlxbFLHGMqgxy IMoi+QKQg5jJsKCUtt/+hfN+Ufoshq8Expyk5Leubvv26OSJrVw8SjVcg7VYHX+uCBuj 9ayA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760374862; x=1760979662; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KDhRrAA3xq696ApWwsGzrrtYkBQuGUUTpFieC5481mk=; b=oDob813fv6GZ4sVrPwnfzQDMyc3xmKtKnoNm4RCBp9ww2Mpu2QdIzlbdfi7Zl4vxQN WUzOkC18pccumH78KwDSCUVs/kzmAxH54JENCGciaIhPMbABQu2pMTx7kIhRDc6yEqdP 8i4b/kbeRXrfBtPDCrE8CygzFvigIJyEH76e8ihtj1ralps+Gm5kPJguMLeVxpAd7gbW 4xHwC8EqKGYnEz5itttXbcaUj8qvhhSAxGCibpKNgJnCmFLV3nx+OSH7cbb7muIlW5HR rGIBNkwyVzGoMDYPuEftEXcGCIFfDpBPHfLB0Dzhupafd/VIVB3Q03dw9QftedD97DCh HfIA== X-Forwarded-Encrypted: i=1; AJvYcCXmZAWbVWh/+0gJPY8snz3EMwEm3UIgyaXXvWkSb7G0Y2q76Z80X1eRy1KJHu507eeTKempq1ynF3o=@lists.php.net X-Gm-Message-State: AOJu0YxHGMoqE4DEZvKPxZTVTipa7GsRfRsbDA7k6mdm9CKb979/4H48 7REhrBao2VywggAg0nzkkNNbeO8cglxNKGCvKQxSqJ+gPc25I705n8pqAhedGbjVDPn/gqkXaBB LjA8sp+lYy3ffZzN57rAWDL/j4Lwwh20= X-Gm-Gg: ASbGncukbjECPwVy0v/YO60r3qLW9DkgVehmaskgKQJXvmyh5TCK/KWwJTGEFr4Af9r wyO/i5sXiXYB38sGUf+fsdjwNA3QYAXlkM0FcsyFb44ea1wb+FuRHVRWdIxzyrzwL1pg4knjoJH oNkH4a4R+c8+4W6S3T32OeTpuzV5gydcvS1iN6US9lL100hyWDkOCJQ8wfC8cdZiBk1DegMgeKQ BjAPiKAmlqD1oNT2bgTth9bQw== X-Google-Smtp-Source: AGHT+IGfAd3UZurCBpvkaeBzaYQyfkC7AyY7nuKxc6BC9HfBqIuCtROAlj4saXxDUfB0OFNsxnHgbgGMkn2Yh6JJMSQ= X-Received: by 2002:a05:6402:90c:b0:639:e30c:2477 with SMTP id 4fb4d7f45d1cf-639e30c2c5cmr17673194a12.7.1760374862381; Mon, 13 Oct 2025 10:01:02 -0700 (PDT) Precedence: list list-help: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <13830641-0fb9-4de9-94ed-8873045ef820@app.fastmail.com> In-Reply-To: Date: Mon, 13 Oct 2025 19:00:50 +0200 X-Gm-Features: AS18NWBzYvojpCqyXJKnFo6lRrviqDdCA2pIOgj-oBEwR3gSDn4EDU7EfSSITQs Message-ID: Subject: Re: [PHP-DEV] [RFC] Partial Function Application v2 To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= Cc: Larry Garfield , php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: arnaud.lb@gmail.com (Arnaud Le Blanc) Hi Tim, On Sun, Oct 12, 2025 at 8:36=E2=80=AFPM Tim D=C3=BCsterhus wrote: > Relatedly to the stack trace example and also to the =E2=80=9CEvaluation = order=E2=80=9D > I'd be curious how pre-filled parameters are implemented technically. > For pre-filled variables, the regular variable capturing logic would > work, but it doesn't for function returns. Is it effectively creating a > temporary variable under the hood? Meaning is: > > $partial =3D speak(?, getArg()); > > desugared into: > > $pfa_tmp_2 =3D getArg(); > $partial =3D fn (string $who) =3D> speak($who, $pfa_tmp2); > > ? Pre-filled parameters are passed to the Closure via used vars, but there is no requirement for them to be in a CV slot so we don't need to create a temporary variable. We can bind used vars to any zval directly. The code $partial =3D speak(?, getArg()); Is compiled to INIT_FCALL speak SEND_PLACEHOLDER INIT_FCALL getArg T1 =3D DO_FCALL SEND T1 CALLABLE_CONVERT_PARTIAL The CALLABLE_CONVERT_PARTIAL opcode generates the AST for function (string $who) use ($msg) { return \speak($who, $msg); }; and compiles it (this is cached in SHM). It then instantiates the Closure, and binds $msg to ZEND_CALL_ARG(2). A few other values are passed via used vars, such as the object if it's an instance method call, or the underlying function if it's a closure. > - How does it interact with > `ReflectionFunctionAbstract::getClosureUsedVariables()`? > - Same question for other scope introspection functionality (e.g. Xdebug)= . getClosureUsedVariables() and other introspection functionality will report any used var as usual. Used vars are named after the parameter if there is no collision. But this should not be considered API as this may change. For instance, I want to optimize-out used vars for parameters that are pre-filled with a literal. It would be possible to hide used vars of a PFA in Reflection. Best Regards, Arnaud