On Sat, Jun 22, 2024 at 8:34 PM Robert Landers <landers.rob...@gmail.com> wrote: > > On Sat, Jun 22, 2024 at 8:04 PM Rowan Tommins [IMSoP] > <imsop....@rwec.co.uk> wrote: > > > > 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 !? > > I've brought this up before, but I mostly see "as" being useful for > static analysis. That's what I've mostly used it for C#, anyway. > Logically, you know the type, but due to one-thing-or-another you > can't "prove" the type is that type (such as foreach-arrays or dealing > with results from user-code callbacks in library code). I want to be > able to say "this is an int or else." > > [snip] > > Now ... that being said, I'm def not a fan of this "~" thing. It makes > no sense to me. Semantically, what is the difference between "123", > 123, and 123.0 other than how the bits are arranged in memory? If it > can become an int -- regardless of how it is laid out in memory -- I > expect to end up with an int as long as it is an integer. I would find > it super annoying to have to fix that bug report with a single > character, just because someone returned 123.0 instead of 123 because > they rounded the number and I got the result from a callback.
In other words, I want what I currently get from mode 0, but instead of a warning, an error; but also not the sledgehammer of direct casting in mode 1. In mode 0, this is currently a warning (fn(int $x) => print($x))(123.1); and this is fine: (fn(int $x) => print($x))(123.0); But if you are used to working in mode 1, both are a fatal error: // strict_types=1 (fn(int $x) => print($x))((int)123.1); Which is probably much worse -- depending on your business -- because you don't get any notice that things are going wrong; it's completely silent. What I would find (and I think everyone would find, IMHO) is that you actually want to cast to int if it can be cast exactly to that type, otherwise fail. (fn(int $x) => print($x))(123.1 as int); // crash (fn(int $x) => print($x))(123.0 as int); // success! > > Further ~ means bitwise-not, so when you start mixing in literals ... > what does it mean? > > $y = $x as ~1|~float; > > What is the value of $y? Is it the literal negative two, casted to the > literal one (int), or casted a float?