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]