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]

Reply via email to