Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:121821 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 99400 invoked from network); 28 Nov 2023 12:49:36 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Nov 2023 12:49:36 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 01F0418003E for ; Tue, 28 Nov 2023 04:49:43 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) 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, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (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 ; Tue, 28 Nov 2023 04:49:42 -0800 (PST) Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-9fcfd2a069aso746629366b.1 for ; Tue, 28 Nov 2023 04:49:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701175773; x=1701780573; darn=lists.php.net; h=in-reply-to:from:references:to:content-language:subject:user-agent :mime-version:date:message-id:from:to:cc:subject:date:message-id :reply-to; bh=nHR+SZPSOA2GE6rZmhm/k1ie4OB1Eyb9SjzyCzYyGi4=; b=OQODD6iCzjACXPMJqfjFIaar+P6Wq+NpVnIrmndsjXISUfsnVRRlqWyCmoe87Img+C MgNDEzCEl2JcIvrfd1FMiDbkm6z1YJ3JyZeaabHo/vH308piFzAWStW4IT3N4Q637geG n4+r+HsKpMuw559FNo6SfaHwtFD5VNY6aDY3IGrCeeh2/MtAnk+K2wXB06k3WrKRTRAW wv4jkLu7lvAUR3BGlWRetM85Wc7uER7cxZ1ySfr5wbGwLSViAIM9NMod75jsfOeB+Rle 1IOv/qlnm+fh2IfsZbnlKyPMwGzob1EhEC63EkQQXxIFgBMXTmU8ls2e2I79/6PFdU2l LxCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701175773; x=1701780573; h=in-reply-to:from:references:to:content-language:subject:user-agent :mime-version:date:message-id:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=nHR+SZPSOA2GE6rZmhm/k1ie4OB1Eyb9SjzyCzYyGi4=; b=fPPrSTAmitNHdjx1llEm7V0opj6xrqtyD7e9Lto1ecnaKx9ZaKNKZQbnK17BW8ZQXa UXMi/XgNaLpUZkjIPDOfrELRlCmVYyxPukouy7WlSrVaHqLiuG/FliioXVfvscT+cXtp uLPeIxllKN4JwGEYeCJaBC/Q0J0Pazai6MAnZTwtO02F1cb1sVEDvdd9C/t8cTVa96Kb OzBdx/BuFJtgBE2JF1JE+Vi1Y7wOHr/Zv2aOte5Mc2eAPtU7M/IYtFd2fS4oPrBexC/1 +X0hsl/SuZ9dL3W/YH7cm9bm89DEym4zVlvEqgsFOpxab/WopaWZWzUgjOpfBNNRn/jk xISw== X-Gm-Message-State: AOJu0Yx3Ba8HGSFg7pUlsnEijBSUtbCpSNJcn1HOLXdVwFIa+nJ9/xpM oHf3FzYhwoQ71UXyYmWDC4NSA7h4UC8= X-Google-Smtp-Source: AGHT+IHVi5vHcb4+G+ccVyfU0HWvnfglt7qDDAzSv2D6MSLB9ShD0qOMVhvcPPEryLcI0gN2FuCXHw== X-Received: by 2002:a17:906:d158:b0:a10:f087:ba43 with SMTP id br24-20020a170906d15800b00a10f087ba43mr3811161ejb.43.1701175773249; Tue, 28 Nov 2023 04:49:33 -0800 (PST) Received: from [192.168.0.22] (cpc83311-brig21-2-0-cust191.3-3.cable.virginm.net. [86.20.40.192]) by smtp.googlemail.com with ESMTPSA id x22-20020a1709060a5600b009c3827134e5sm6704915ejf.117.2023.11.28.04.49.32 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 28 Nov 2023 04:49:32 -0800 (PST) Content-Type: multipart/alternative; boundary="------------9qR7IrhQujc5B0Xaj2QzKJMF" Message-ID: Date: Tue, 28 Nov 2023 12:49:30 +0000 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-GB To: internals@lists.php.net References: In-Reply-To: Subject: Re: [PHP-DEV] Callable arguments cannot have default value From: rowan.collins@gmail.com (Rowan Tommins) --------------9qR7IrhQujc5B0Xaj2QzKJMF Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 28/11/2023 09:54, Claude Pache wrote: > The big problem with the `callable` type, is that it can be check only at runtime. For instance: > > ```php > function foo(callable $x) { } > > foo('strlen'); // ok > foo('i_dont_exist'); // throws a TypeError > ``` To expand on this example, and address the original question more explicitly, consider if we allowed this: function foo(callable $x = 'maybe_exists') { } To decide whether that's a valid definition, the compiler needs to know whether 'maybe_exists' can be resolved to the name of a global function; but it might be defined in a different file, which hasn't been included yet (or, more generally, which isn't being compiled right now). To allow the default, the engine would need to defer the validity check until the function is actually executed. This is how "new in initializers" works [https://wiki.php.net/rfc/new_in_initializers] and we can actually use that feature to implement a default for callable parameters: ```php class WrappedCallable {     // Note: can't declare callable as the property type, but can as an explicit constructor parameter     private $callable;     public function __construct(callable $callable) {         $this->callable = $callable;     }     public function __invoke(...$args) { return ($this->callable)(...$args); } } function test(callable $f = new WrappedCallable('strlen')) {     echo $f('hello'); } test(); ``` Using this wrapper, we can pass in any value which is itself valid in an initializer, including callables specified as 'funcname' or ['class', 'staticmethod']. The trick is that we're not actually evaluating that value as a callable until we invoke test(), at which point the constructor of WrappedCallable performs the assertion that it's actually callable. So this compiles: function test(callable $f = new WrappedCallable('i_dont_exist')) {     echo $f('hello'); } But will then error at run-time, *unless* a global function called i_dont_exist has been defined before that call. It seems like it would be feasible for the engine to do something similar natively, creating an equivalent of WrappedCallable('i_dont_exist') using the first-class callable syntax: function test(callable $f = i_dont_exist(...)) {     echo $f('hello'); } Regards, -- Rowan Tommins [IMSoP] --------------9qR7IrhQujc5B0Xaj2QzKJMF--