Re: [Early Feedback] Pattern matching

From: Date: Sat, 22 Jun 2024 16:49:42 +0000
Subject: Re: [Early Feedback] Pattern matching
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
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]

Thread (79 messages)