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?

Reply via email to