Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123750 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 149491A009C for ; Sat, 22 Jun 2024 16:49:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719075062; bh=6Qd7yYXGTiE+5yqm3xy4jSI58qpC0Sa5KGWclqtzy3E=; h=Date:Subject:To:References:From:In-Reply-To:From; b=XcGnomzF/gwrFlT6PLbFSYBxT5ko8Wa42oh+oP34O/ogFVnWKrql8rDLEUmyOJFj4 CKl9QzWvo6PqJz9edn6h4gxcppiHsmVN8Xx5zPDMbro58safjD7lrGHXWaCvQQFdLO ZWXCJy7TA/SJXLoE4fq+38RBEtun4JZXEHr6llPuSlwuO2fLuZTJlPck2FCdVJchfO iEWOmltn8Xvh/FFq+cwYmffzMzUsQ8tgGW5u1e2/v5VzrN06DOZl369MDz7z1ohToC 0kyCz2GNpaEp/zlY95eTNNvDlKtShuAl0mP2kKpT8ltMFkzHDCS4H2tW9kY0XMekx9 pQ5wHeHAi467w== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 99F6918003F for ; Sat, 22 Jun 2024 16:51:01 +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=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from fhigh4-smtp.messagingengine.com (fhigh4-smtp.messagingengine.com [103.168.172.155]) (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 ; Sat, 22 Jun 2024 16:51:00 +0000 (UTC) Received: from compute7.internal (compute7.nyi.internal [10.202.2.48]) by mailfhigh.nyi.internal (Postfix) with ESMTP id 2661711400D8 for ; Sat, 22 Jun 2024 12:49:45 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Sat, 22 Jun 2024 12:49:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; h=cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm2; t=1719074985; x=1719161385; bh=xlVgOGb0qJ H4jHQvOWGbinzkBAWl4vJyZKNOVmLbGq0=; b=faeMEKEzVyuO7eGhospNPodzaq lizgNr+r6DfuhSmTZnIft7nZWFZqeHKrgKdorHzvEHgyrRBqanXzcw7VcdrUzc7i g5MoqIqau2XCx2dbV3RWWYh1iqZsALfqEW1U/vPBEddLfTaOe4wbiIdSRrziNLFy mxwcYjZ/JFeeocJJ1/NRYV4UDsw4774sb7FeREBLZpGnIgBOB1cxWMXdCh9JYjZB Uwysjyj4k6y6sAwFFtOVb1So/3drJ6kcT7urnKyNj6v7OVbbD05XWok7G6hFCccF PETcMp4v730shZVrRl+q1+U0x0mO8prmrB3+pTqZtGkDU/vZlNe9c22rJkbw== 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:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; t=1719074985; x=1719161385; bh=xlVgOGb0qJH4jHQvOWGbinzkBAWl 4vJyZKNOVmLbGq0=; b=PQ8bm7NtRwJbVFacb0zKeafzQf/kfvlZFkd3LUtDfGYl oBh7gnVBQwRiOaFXoLlvxiOMvwlF5tNPiH3dmFLm7QEqky84zPwCdKODrOoXltwP HTVUR/xQWJyApe1fAMtjiH8Ah5oYE6JuMUshb+64KiA37TUrtYlA+wYBdelVT6KD e0Db2zfDE+LkFbWL485PveS4X6GlHx9HCtpzOOou9Gy5Yd9hqP9l0b6QVeXs8Fyq KZj+tICSeXDZNtuF5qIFb3I7Agc+laZwU/fyOStt6f2uqM+SvEZdisIW83f4nd9Q o+aqY7N+3EGCIPWhOtiFChx3XKlfNzPKzjqW66pDmw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfeefiedguddtkecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecunecujfgurheptgfkffggfgfuvfhfhfgjsegrtd erredtvdejnecuhfhrohhmpedftfhofigrnhcuvfhomhhmihhnshculgfkoffuohfrngdf uceoihhmshhophdrphhhphesrhifvggtrdgtohdruhhkqeenucggtffrrghtthgvrhhnpe ehteelieeigfeuudeiueeiffdvveehudeufeekjeeugffffedtiedtgeettdelteenucev lhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehimhhsohhprd hphhhpsehrfigvtgdrtghordhukh X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Sat, 22 Jun 2024 12:49:44 -0400 (EDT) Content-Type: multipart/alternative; boundary="------------NF6z0xENH0vREv27zG2v0D0n" Message-ID: Date: Sat, 22 Jun 2024 17:49:42 +0100 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] [Early Feedback] Pattern matching To: internals@lists.php.net References: <2a6b92eb-d5e9-4a1a-9548-a068ac42ebd2@app.fastmail.com> <978b7177-8a22-41c0-94ce-d5539a2468c5@app.fastmail.com> Content-Language: en-GB In-Reply-To: From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") This is a multi-part message in MIME format. --------------NF6z0xENH0vREv27zG2v0D0n Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 21/06/2024 19:29, Larry Garfield wrote: > Valid points. The line between validation and casting is a bit squishy, > as some casts can be forced (eg, string to int gives 0 sometimes), and > others just cannot (casting to an object). So would $a as > array<~int> be casting, validating, or both? I think my concern is that both "x is T" and "x as T" read naturally as *expressions*, where their main purpose is to evaluate to a result, and side-effects are exceptional. From that point of view, we can give intuitive meaning to the following: - $foo is int => boolean; is $foo of type int? - $foo is ~int => boolean; can $foo be "safely" cast to int? - $foo as ~int => int; cast $foo to int (unless unsafe) But then what does this mean? - $foo as int => int; cast $foo to int if it's already an int !? Similarly for a lot of other patterns: - $foo as [int, int, int] => ?? - $foo as 3|5|null => ?? It seems like what's actually wanted here is something with an active verb, like "assert"; or a closed statement like "must be": - $foo mustbe int; statement - if $foo is not an int, throw an error - $foo mustbe ~int; statement - if $foo cannot be "safely" cast to int, throw an error - $foo mustbe [int, int, int]; - $foo mustbe 3|5|null; Then the "validate-and-cast" case is a completely separate feature, whose argument is a type, not a pattern (straw-man syntax): - safe_cast($foo as int); cast $foo to int, unless unsafe - safe_cast($foo as int|string); cast $foo to either int or string, using the same rules as parameters in mode 0 - safe_cast($foo as [int, int, int]); error, no such type to cast as I think the uneasiness around binding vs matching against variables is related: if "$x is $y" is an expression, $y reads naturally as an input to that expression: $arr = [ 123 ]; $fortyTwo = 42; $arr is [ int ]; // true $arr is [ 42 ]; // false $arr is [ $fortyTwo ]; // false ? As currently proposed, it's actually an *output*, and means something like this: $arr is [ mixed{bind $fortyTwo} ] // true, with $fortyTwo set to 123 ! How about using "=" to mark that a variable name is being assigned to: $arr is [ $fortyTwo ]; // false $arr is [ $id=int ]; // true, and $id set to 123 $arr is [ $id= ]; // equivalent to [ $id=mixed ], i.e. bind $id without further constraining its value So taking an example from the RFC: $result = match ($p) is { Point{x: 3, y: 9, $z=} => "x is 3, y is 9, z is $z", Point{$z=, $x=, y: 4} => "x is $x, y is 4, z is $z", Point{x: 5, $y=} => "x is 5, y is $y, and z doesn't matter", Point{$x=, $y=, $z=} => "x is $x, y is $y, z is $z", }; -- Rowan Tommins [IMSoP] --------------NF6z0xENH0vREv27zG2v0D0n Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit
On 21/06/2024 19:29, Larry Garfield wrote:
Valid points.  The line between validation and casting is a bit squishy,
 as some casts can be forced (eg, string to int gives 0 sometimes), and 
others just cannot (casting to an object).  So would $a as 
array<~int> be casting, validating, or both? 


I think my concern is that both "x is T" and "x as T" read naturally as *expressions*, where their main purpose is to evaluate to a result, and side-effects are exceptional.

From that point of view, we can give intuitive meaning to the following:

- $foo is int => boolean; is $foo of type int?
- $foo is ~int => boolean; can $foo be "safely" cast to int?
- $foo as ~int => int; cast $foo to int (unless unsafe)

But then what does this mean?

- $foo as int => int; cast $foo to int if it's already an int !?

Similarly for a lot of other patterns:

- $foo as [int, int, int] => ??
- $foo as 3|5|null => ??


It seems like what's actually wanted here is something with an active verb, like "assert"; or a closed statement like "must be":

- $foo mustbe int; statement - if $foo is not an int, throw an error
- $foo mustbe ~int; statement - if $foo cannot be "safely" cast to int, throw an error
- $foo mustbe [int, int, int];
- $foo mustbe 3|5|null;


Then the "validate-and-cast" case is a completely separate feature, whose argument is a type, not a pattern (straw-man syntax):

- safe_cast($foo as int); cast $foo to int, unless unsafe
- safe_cast($foo as int|string); cast $foo to either int or string, using the same rules as parameters in mode 0
- safe_cast($foo as [int, int, int]); error, no such type to cast as


I think the uneasiness around binding vs matching against variables is related: if "$x is $y" is an expression, $y reads naturally as an input to that expression:

$arr = [ 123 ];
$fortyTwo = 42;

$arr is [ int ]; // true
$arr is [ 42 ]; // false
$arr is [ $fortyTwo ]; // false ?

As currently proposed, it's actually an *output*, and means something like this:

$arr is [ mixed{bind $fortyTwo} ] // true, with $fortyTwo set to 123 !


How about using "=" to mark that a variable name is being assigned to:

$arr is [ $fortyTwo ]; // false
$arr is [ $id=int ]; // true, and $id set to 123
$arr is [ $id= ]; // equivalent to [ $id=mixed ], i.e. bind $id without further constraining its value


So taking an example from the RFC:

$result = match ($p) is {
  Point{x: 3, y: 9, $z=} => "x is 3, y is 9, z is $z",
  Point{$z=, $x=, y: 4} => "x is $x, y is 4, z is $z",
  Point{x: 5, $y=} => "x is 5, y is $y, and z doesn't matter",
  Point{$x=, $y=, $z=} => "x is $x, y is $y, z is $z",
};


-- 
Rowan Tommins
[IMSoP]
--------------NF6z0xENH0vREv27zG2v0D0n--