Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:121415 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 8041 invoked from network); 18 Oct 2023 17:42:53 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 18 Oct 2023 17:42:53 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A0189180504 for ; Wed, 18 Oct 2023 10:42:52 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS29838 64.147.123.0/24 X-Spam-Virus: No X-Envelope-From: Received: from wout4-smtp.messagingengine.com (wout4-smtp.messagingengine.com [64.147.123.20]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 18 Oct 2023 10:42:52 -0700 (PDT) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id DD0A93200A32 for ; Wed, 18 Oct 2023 13:42:50 -0400 (EDT) Received: from imap50 ([10.202.2.100]) by compute1.internal (MEProxy); Wed, 18 Oct 2023 13:42:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-type:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm3; t=1697650970; x= 1697737370; bh=1UYsCHPXbwqlgmAWBjfpPtoNSdVjIpXYRADMspNkysQ=; b=l R5CvNzgao71eBM+jsX0qC1Ew9YO68pDx1Q0i+SBH1Y7GGXLCaWYzBcR2XL52c5+t z/yGB4W3lWm3HlYcNrNrACANdNS2wnr2MKfUucPMp15vvzddCYSSJssSaKXq4qo8 BPUIwabqV8anXwW8DCQoy5DVBzFBa/ryPHRgzUGfquFPMml8mdjCJhpJ3N7noPcx gyDR0f9keQTtYNioHu6LSC6ywQFMyvy8tIMV8EGoPCXPlSv8bffWpFgiNwgjJcTx HGsGZ7DylS/cM51jCRiWo+iKuUgqx14hwbSTg832PaZn2RzyZrHD7xuRSUMQYu5X MxNzm8WVxtrWGcUFeiA/w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1697650970; x=1697737370; bh=1UYsCHPXbwqlg mAWBjfpPtoNSdVjIpXYRADMspNkysQ=; b=KZ5Tv81jW3HUT5jFgpgjrBPwnzP26 +RiQWXmiKqSeA3K2JwsLP7b+8wtarZSxigLAOHSA6zSO5xrlATwvRBQWCjlTlpL4 kodzziO/rY7H1ZvWEPPe8+oVg6mS8L8fiOkOuNVGSWNZfd5Ezji9SMsi6OxVHrpM YBmqDDoaJL2J8i/sv1RrKoY7+ApfjNpQ4vddG6Q+0JqSgy5gQ9jyydFf4GK2kfBZ Qn7+ZM+qRRmbAqn7UH3Se2b9/eNt/7BEr98B8Qc6sWMHUF6VaXjRIIbZ8XzKLTfS l0L9iIndzRm3I7+Jp61X+mVnvih8PKAi034MWleRztGrGKKhoklSTb++w== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrjeeggdduudegucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgesthdtredtreertdenucfhrhhomhepfdfnrghr rhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtoh hmqeenucggtffrrghtthgvrhhnpeetjeektefftdevleejjefhhffhjeeugfekvdelieeu teetuedvfefffeeutdefueenucffohhmrghinhepphgvrghkugdrtghomhdpphhhphdrnh gvthenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehl rghrrhihsehgrghrfhhivghlughtvggthhdrtghomh X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id E9E4A1700089; Wed, 18 Oct 2023 13:42:49 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.9.0-alpha0-1019-ged83ad8595-fm-20231002.001-ged83ad85 MIME-Version: 1.0 Message-ID: <96ea86c9-ea40-4d53-b074-89b82b4c7858@app.fastmail.com> In-Reply-To: References: <173ca550-71a0-4bd4-96f2-b64b6155115a@app.fastmail.com> Date: Wed, 18 Oct 2023 17:42:13 +0000 To: "php internals" Content-Type: text/plain Subject: Re: [PHP-DEV] Two new functions array_first() and array_last() From: larry@garfieldtech.com ("Larry Garfield") On Wed, Oct 18, 2023, at 3:37 PM, Deleu wrote: > I believe my reservations have been registered, I would not like to have > `array_first()` behave in a non-obvious way (i.e. involving array $key) > because it's useful for Fibers users. I believe that writing your own > wrapper that always returns key and value simultaneously is easy and > straight-forward and may even make it into the core in the future. Rather > than trying to solve deep convoluted issues on version 1, I believe PHP > could introduce the simplest version of the function first and later on add > an array_first_key_value() in the future if needed. I think there's a fundamental misunderstanding here. Fibers are not threads. They do not do preemptive multitasking. If a give function call stack does not explicitly suspend itself, then a fiber WILL NOT change the current context. If we assume that array_first(), being an internal function, does not explicitly suspend a fiber internally (which I think is a pretty safe assumption), then this code cannot possibly have a race condition in it: $key = array_key_first($arr); $value = array[$key]; The concerns about this having some kind of race condition around fibers are, as far as I am aware, entirely unfounded, and we should not consider them, as they do not exist. (Obviously if those two lines are separated by some other call, and that other call suspends a fiber, then it's possible there would be a race condition. But in that case the operation is not atomic anyway so all bets are completely off. Which is why you shouldn't be using shared mutable state arrays at all in the first place, fibers are not, but that's another story.) As far as the not-found error case goes, I cite my previous article on the subject here: https://peakd.com/hive-168588/@crell/much-ado-about-null More to the point, PHP arrays are untyped. That means there is absolutely no possible sentinel value that we can guarantee will never be an array value, because even if we defined some one-off enum to serve as a sentinel, that could be put into an array quite easily, even if it's dumb to do. `null` is the default sentinel value, but runs into various problems because its meaning in different contexts may be different. The question is whether null being a legit value in an array being accessed with array_first/array_last is a common *enough* case that we need to worry about it. I highly doubt it, frankly. I cannot think of a non-contrived case where that would be true. (An array with random null values in it that you don't want to filter out entirely seems like an edge case to me.) That means for the vast majority of use cases, this is completely fine: $v = array_first($arr) ?? $default; Because the cases where you care to differentiate between "there is no first value" and "there is a first value but it is a non-value" are small. And, as others have noted, in those cases count() isn't hard to use. So no, we don't need to do anything fancier than that. To the other points raised: Absolutely not to an in/out by-ref parameter. That is an abomination and I will vote against any API that does that, without hesitation. Let's not even discuss it. As far as the naming, most array functions that have a value version and key version don't specify "value", only the key. The unspecified version is the value version. (array_diff vs array_diff_key, array_intersect vs array_intersect_key, sort vs ksort, etc.) Pretty much nowhere do we specify "_value" in the function name. https://www.php.net/manual/en/ref.array.php That means array_first/array_last is consistent with the current API, and array_first_value would be the confusing oddball. For that reason, no, we should not do that and just use array_first/array_last. With all that said, I do support simple array_first/array_last functions, with just a null-for-not-found return. --Larry Garfield