Hi Rowan,

Although I understand your concerns, I wouldn't consider them a roadblock
for this feature. My rationale is that `is_numeric` has been with PHP for
so long that I don't think we would ever be able to have a `numeric`
type-hint that doesn't align with it, which imho means we either have it or
we don't, a 3rd option where a possible type-hint that is inconsistent with
the function seems worse than not having it. I fully agree with your
concerns that it might not fully represent what the developer wants, but I
would make a judgement call when using it the same way developers have to
make a judgement call when using `is_numeric`. It might allow far more than
you want, but there seems to be enough use-case that it fits where the
downside is negligible or even insignificant.
My point is that I don't look at the language validation to protect my code
against unexpected values and I can setup validation to deal with that.
What complicates things is that I want to avoid having a force-cast which
is not safe for my usage because I want to preserve `null` while not having
to disable strict_types.


On Tue, Jun 2, 2020 at 5:47 PM Rowan Tommins <rowan.coll...@gmail.com>
wrote:

> Hi Marco,
>
> On Tue, 2 Jun 2020 at 16:10, Deleu <deleu...@gmail.com> wrote:
>
> >
> > The primary intent would be to safely pass around input that usually
> comes
> > from HTTP, CI or Database. Whenever interacting with these data
> providers,
> > string is a common format. `is_int` will not return true for integer
> values
> > that are string, instead we need to rely on `is_numeric`.
> >
>
>
> The problem with is_numeric() is that it uses an extremely broad definition
> of "numeric", which is not often what you actually want - for instance,
> is_numeric("-2.56E-90") returns true.
>
> The case I frequently see is much stricter: the variable should either be
> an integer, or a string representation of an integer. Whenever this comes
> up, I struggle for what the correct check actually is:
>
> * is_int($x) won't accept any strings
> * is_numeric($x) will accept far too much
> * an int type annotation with strict_types=0 is similar to is_numeric; in
> strict_types=1 it's the same as is_int
> * (int)$x will never give an error (meaning it's oddly easy to accidentally
> _suppress_ errors by trying to make code run under strict_types=1)
> * (int)$x != 0 is sometimes good enough, as long as zero is not a valid
> value (if you use this when accepting Unix timestamps, for instance, Jan
> 1st 1970 is going to be rejected!)
> * ctype_digit( (string)$x ) is confusing to read (the cast is required to
> accept actual integers, and the name is odd out of its intended context);
> it will also reject any negative numbers, which may or may not be desirable
>
> The only suitable built-in function I'm aware of is filter_var, which has a
> pretty horrible API:
>
> if ( filter_var($x, FILTER_VALIDATE_INT) !== false ) ...
>
> In the common case that you want to cast the variable to int on success (to
> pass to a strictly typed function), you would need to do something like
> this:
>
> $x = filter_var($x, FILTER_VALIDATE_INT);
> if ( $x === false ) {
>     throw new TypeError;
> }
>
> I would love to see the language have a built-in short-hand for that, in
> the form of some kind of "strict cast", e.g.:
>
> $x = (int!)$x;
>
> or:
>
> $x = (strict int)$x;
>
> Once converted in that way, you could safely pass to a parameter marked int
> in strict mode, so wouldn't need a new pseudo-type.
>
>
> Regards,
> --
> Rowan Tommins
> [IMSoP]
>


-- 
Marco Aurélio Deleu

Reply via email to