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]

Reply via email to