Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126984 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 qa.php.net (Postfix) with ESMTPS id CBB541A00BC for ; Mon, 31 Mar 2025 20:38:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1743453391; bh=S03Wgv+uIRT/3m+d8+LCNYa+MkjY2WOneHTMkFxZgOI=; h=From:Date:Subject:To:From; b=chq1O8xLK4l/48URprIxDOraWWc/lCXMvxWJMAB3JH8Ez+Y58Ola2alQKLza4cYsK 68+JwtgZuFVZfHPzfkdRhaMoxqijQGiSPXZOhDcOYep0JoHVJYVpvA9J3zLgyNUmpp tPv2mHKqvmYs2i/wKlf1ZzLrJ8IE6myyrYv2MxCzkVTFo4jkhiCJisdgDF+FYqcMTR lRjoDjkBbRrN5RHzC8QVJSCe6B6jwyr+3dxj1GRmbhxluBkqIftQNAtG1v2NZD5Uo+ /maAxazaoTc90EcqapPWhTuxUjo+MkIv1laKTCXx8cTNu32qu/196HBJ0nb/oqkR1+ cLWpTbqAGE7mQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B17CA1804B3 for ; Mon, 31 Mar 2025 20:36:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,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.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-qt1-f171.google.com (mail-qt1-f171.google.com [209.85.160.171]) (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, 31 Mar 2025 20:36:27 +0000 (UTC) Received: by mail-qt1-f171.google.com with SMTP id d75a77b69052e-477296dce8dso48551951cf.3 for ; Mon, 31 Mar 2025 13:38:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743453534; x=1744058334; darn=lists.php.net; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=9PtJ4k9OflXXiRpDBIpkjXeFOJ2gxK78F4CLBfsDhOk=; b=Na6/m7gZahv/VPgJmYq6GSVhzRj9zp6Lfol3XLXAaMy31CSSpAlnlFzsFSji/glTEu iHqOKixTJI33L9AQcIBJKMqv4XN9ww0KGLd6x8T3S1+Fajb83eM/pxH1tv8n8sns7AEX vcvDvnub+vvl4nOFrPuBKLLPBA4o+glPTN94FTHTnWQkIk5i3F+DpMF8mdprEO3Zh6u9 lEuofY7sJE6bsZeNUCUXMtZpV/HbwgA3qjpPjrAlfhiMEyOloTLmz3zJ8dv+YK1Hye/4 OnzgkVySpO+aNEnnTAsKoow+O0VbAVLnuJpW7N1imD/9mVuOzNHB/zzdE1zdMmnPKgds etSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743453534; x=1744058334; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=9PtJ4k9OflXXiRpDBIpkjXeFOJ2gxK78F4CLBfsDhOk=; b=FiQxZLzVdBERm8e0QhHGhy6WxXWgISME0SCqozt/dBdt2vwF7/AexECh1WOQQXcF7k 9oSbzwsBRXES/hqwdMV+Z/KBB1v2mpQ8VVctvDlSsK8b49KOKd4DnN//QQmRhiFMtSTo G7LaxjvBtjcM70odupmdlkv/ZWtJVIP8Ie+TCPiru8w/AkM3KOEZ1ewdif3GcKkhb4m+ YmchIwFF19Qdh0AYP/8Li9+Kwru8y/iGRjWZx+xXDlnQx9/0AebN87dyEPXllC1LATxp PQBYaHbuyQLeDLbc+Teaw+4iYShNKLQ8NxXVXxGl2IYV+IxmnWv6KUdQjo+XLwjwJXDV 2diw== X-Gm-Message-State: AOJu0YzyZVI5cnl6J48UFen3btri/DmzhJReHPHAJj14nG1W3hDGI1Hj rmhSBcb97wuJbZcE8UuvI0WTOxITVOuDTcVXOUxI2AXSRbZci2Lt34Nc34IRwEbpposMmj0cSTj zWCXOvzR1N2C6JE/RNwGegdw6jrTWRYhY7pU= X-Gm-Gg: ASbGncv2RCg6tddnuQz7gtj11u4h2l7hF0X3xG3I9Ax5loptvdoRSt2ysMHLhSxfYSe jqFityRRUYHhCUxXhiD2ENdLhG9ShSFSfqc7UQ3xGkhl2zqaKeLKKPSg9/h0l7Au4BgqfQDAms0 a8nzcDBfPhkuwmUPGQ3ssm+EogJaSY9NNVQOsTiKHd5tjdRle/HFwGQpZL2w== X-Google-Smtp-Source: AGHT+IH0bdrSxHqhgUyDx9BY9eySZtXCvuchEGeSIUbRcCFKSbNJc5sZGhnsTy/wwfjoOmQTeKWhYec5rer6fPjNrgI= X-Received: by 2002:a05:6214:1311:b0:6e8:9bcd:bba6 with SMTP id 6a1803df08f44-6eef5d67c13mr8221106d6.7.1743453533925; Mon, 31 Mar 2025 13:38:53 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Mon, 31 Mar 2025 22:38:43 +0200 X-Gm-Features: AQ5f1JqubLF6FlBDYJo8G2dkJgIZUYufIgoip-mWSuDkTkQfBC-Rb63vMZ6RQks Message-ID: Subject: [PHP-DEV] Closure::getCurrent() for recursion To: PHP internals Content-Type: text/plain; charset="UTF-8" From: tovilo.ilija@gmail.com (Ilija Tovilo) Hi everyone A few years ago, an RFC was proposed to introduce special syntax for self-referencing closures, mainly used for implementing recursion. https://wiki.php.net/rfc/closure_self_reference The proposed solution allows specifying a variable that will be assigned the closure object on function entry. $fibonacci = function (int $n) as $fn { if ($n === 0) return 0; if ($n === 1) return 1; return $fn($n-1) + $fn($n-2); }; This is essentially already possible through a by-reference capture. $fibonacci = function (int $n) use (&$fibonacci) { ... }; This cannot be a by-value capture because by the time the closure is created and variables are bound, $fibonacci is not assigned yet. The downside of by-reference capturing is that if $fibonacci is accidentally reassigned, the reference within the closure is also changed. However, I consider a language change largely unnecessary. Instead, this may be solved with a very simple static function: Closure::getCurrent(). $fibonacci = function (int $n) { if ($n === 0) return 0; if ($n === 1) return 1; $self = Closure::getCurrent(); return $self($n-1) + $self($n-2); // Or return Closure::getCurrent()($n-1) + Closure::getCurrent()($n-2); }; Another suggestion was to introduce a magic constant __CLOSURE__. However, this would be misleading, given it can refer to different closure instances, thus not actually being constant. You can find the implementation here: https://github.com/php/php-src/pull/18167 I picked the name Closure::getCurrent() to be consistent with Fiber::getCurrent(). Contrary to fibers, calling Closure::getCurrent() from non-closures is nonsensical and thus disallowed, resulting in an Error exception. It will only succeed when called directly from closures. It will not recurse the call stack. Do you have thoughts or concerns with this solution? If not, I'm planning to merge it into master in a few weeks. Ilija