Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:121819 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 89282 invoked from network); 28 Nov 2023 09:45:57 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Nov 2023 09:45:57 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E4706180048 for ; Tue, 28 Nov 2023 01:46:03 -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=-2.1 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_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-oo1-f45.google.com (mail-oo1-f45.google.com [209.85.161.45]) (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 01:46:03 -0800 (PST) Received: by mail-oo1-f45.google.com with SMTP id 006d021491bc7-58d439e3e15so1639199eaf.1 for ; Tue, 28 Nov 2023 01:45:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701164754; x=1701769554; 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=VnRgImHv2y0sWCGv37GdJPOU8C4mS4sjpps59IKLcHA=; b=jDw4Gt+dZzm6v7FC0kayMHdo1KBWapsFRQrAwdLAHYsiijDWPpOtqHfKJ7fszdXJEq rfYOYNtuj02RMagMD41gD6+uZFJuGEjK9fvz3OFTacpD1CwX27q0rEk4Rk453BiW5jZZ gSVNRKw2i/eXNqINFc5mAKOEXKsNNkTSYgVlIfK4BS6vqOXzaINcRjPR+W25DIvVA8L8 napPaCTbrXE64wqNIHXSjRK1oFlBvASWNMX3oa38UEjGKo/WfHIqlGc7pUwntGddBjUH hJKFXA+H6QtZAiuUew3YYcvOkiGX+YxHuBHhjB1u5dfc8pMtI0/1qDKjiGaCwBl9HUAA FR3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701164754; x=1701769554; 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=VnRgImHv2y0sWCGv37GdJPOU8C4mS4sjpps59IKLcHA=; b=dl/ncjyqIZ7FaEMZC5VQQZP1Kt1e1EzmV5Q+yyANVdIGuDVKiydA4YfMQV4hbTqgsd 7lh12uajDEN3K/pY1uZLcyyqxAQW+Ew2FdQgpoFMnPe3/ZJqatephrhIj5LIzIiaFwNk igILBqpjOcYIUv/bKpbqaw6vmN0Pn3Kp512AMvhLUztHZ3u1p5Ym96Ug312EmRH9zfQL WOW00pCOeIZuwGXecVabX83E+D3R0Ctj77U9FqYkL/Ja2o67rdvxd1ljqktTX6klYNtM 97zYJpQLGPpvczHm0JmdzK+HpKEOGtmWffXRnCVaAbEyGU803Xuvp6vQHvIWSSFcSc7m RwSA== X-Gm-Message-State: AOJu0YyST1XTW4rmRe58FcB3bnbjN3X1zNu+xfxkmbXW28JTi/5cRmxA eFA41SSuLlVoMRp6mx1mm+15SyRuMs+CHm8Uz+x4K+ISVBEB0g== X-Google-Smtp-Source: AGHT+IHHz4eD+F9g+TYanTI5YBpIyyGz0kxry18gDsd7Q52KYsDwAKq7jhq3B79BDofQik9YwTG1hVZsdtJovwqVEy4= X-Received: by 2002:a05:6870:40c8:b0:1fa:3df6:29fb with SMTP id l8-20020a05687040c800b001fa3df629fbmr4245036oal.2.1701164754401; Tue, 28 Nov 2023 01:45:54 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 28 Nov 2023 10:45:43 +0100 Message-ID: To: Sergii Shymko Cc: internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Callable arguments cannot have default value From: landers.robert@gmail.com (Robert Landers) On Tue, Nov 28, 2023 at 12:59=E2=80=AFAM Sergii Shymko = wrote: > > Hi, > > Wanted to bring up an inconsistent behavior of callable arguments compare= d to arguments of other types. > Callable argument cannot have a default value (tested string or array typ= es - both are not permitted). > The same exact value works perfectly fine when passed dynamically, it jus= t cannot be specified as a default. > The workaround is to remove the type annotation which is obviously undesi= rable. > > Here=E2=80=99s an example: > declare(strict_types=3D1); > function test(callable $idGenerator =3D 'session_create_id') { > $id =3D $idGenerator(); > // ... > } > > The function/method declaration above produces the following error on all= PHP versions: > Fatal error: Cannot use string as default value for parameter $idGenerato= r of type callable in /tmp/preview on line 4 > > Note that the exact same string argument can be passed without any issue: > function test(callable $idGenerator) {=E2=80=A6} > test('session_create_id=E2=80=99); > > Is there a specific architectural limitation causing this that's hard/imp= ossible to overcome? > > I=E2=80=99m aware that class properties cannot be annotated with callable= - another unfortunate limitation. > Callable is not a real type like other primitive types which causes all t= hese inconsistencies, correct? > Callable properties (separate topic) may be a challenge, but can at least= argument defaults be supported? > > Regards, > Sergii Shymko I stopped using "callable" a long time ago. These days I use \Closure and it works in all the same places (including properties). If you want to accept a callable string, you need to change the type to \Closure|string and verify it with `is_callable()`. > Is there a specific architectural limitation causing this that's hard/imp= ossible to overcome? IIRC, default arguments must be compile-time constant, and this isn't, apparently: session_create_id(...) You can also do something like this: function hello() { echo "hi\n"; } class wrapper { public function __construct(public \Closure|string $closure) { is_callable($closure) ?: throw new InvalidArgumentException('closure must be callable'); } public function __invoke() { return ($this->closure)(); } } function test(wrapper|Closure $closure =3D new wrapper('hello')) { ($closure)(); } test();