Hi Matthew,

On 23 February 2015 at 16:01, Matthew Weier O'Phinney <matt...@zend.com> wrote:
> Today, without scalar type hints, we end up writing code that has to first
> validate that we have something we can use, and then cast it. This can often 
> be
> done with ext/filter, but it's horribly verbose:
>
>     $value = filter_var(
>         $value,
>         FILTER_VALIDATE_INT,
>         FILTER_FLAG_ALLOW_OCTAL | FILTER_FLAG_ALLOW_HEX
>     );
>     if (false === $value) {
>         // throw an exception?
>     }
>
> Many people skip the validation step entirely for the more succinct:
>
>     $value = (int) $value;
>
> And this is where problems occur, because this is when data loss occurs.

I would usually do:

is_int($value) or ctype_digit($value) and is_numeric($value) where
appropriate if I expect a later cast from a string. There are shorter
options that predate filter_var().

> What I've observed in my 15+ years of using PHP is that people _don't_ 
> validate;
> they either blindly accept data and assume it's of the correct type, or they
> blindly cast it without validation because writing that validation code is
> boring, verbose, and repetitive (I'm guilty of this myself!). Yes, you can
> offload that to libraries, but why introduce a new dependency in something as
> simple as a value object?

I think we should be very clear that lazy programming, of the bad
sort, should not in any way impede change.

> Now, you may argue that you won't need to cast the value in the first place,
> because STH! But what if the value you received is from a database? or from a
> web request you've made? Chances are, the data is in a string, but the _value_
> may be of another type. With weak/coercive mode, you just pass the data as-is,
> but with strict enabled, your choices are to either cast blindly, or to do the
> same validation/casting as before:
>
>     $value = filter_var(
>         $value,
>         FILTER_VALIDATE_INT,
>         FILTER_FLAG_ALLOW_OCTAL | FILTER_FLAG_ALLOW_HEX
>     );
>     if (false === $value) {
>         // throw an exception?
>     }
>
> Interestingly, this adds overhead to your application (more function calls), 
> and
> makes it harder to read and to maintain. Ironically, I foresee "strict" as 
> being
> a new "badge of honor" for many in the language ("my code works under strict
> mode!"), despite these factors.

Pretty much all other languages face the exact same issue. Not all of
them are dynamically typed. I really do not see the string->int issue
as an issue for either RFC. You will have a string. It may need to be
an integer. It will be casted to an int if needed.
string->intent->scan->cast||error. Will it add overhead to your
application? I can't really say. Will you be writing these bitesize
casting functions? Chances are there'll be a package or core PHP
functions for that (perhaps, maybe) or your preferred ORM will do it
behind the scenes - once everyone has time to digest whatever passes.
At present we're at the "lick it" taste-test stage.

> You can say, "But, Static Analysis!" all you want, but that doesn't lead to me
> writing less code to accomplish the same thing; it just gives me a tool to 
> check
> the correctness of my code. (Yes, this _is_ important. But we also have a ton 
> of
> tooling around those concerns already, even if they aren't proper static
> analyzers.)

We do? Not to put words in your mouth, this is all me, a lot of the
tools people associate with testing (like the obvious one) require a
Human touch. Humans are lazy. I just wrote V2 of a tool to test the
testers. Many of these tools are not substitutes for type checking,
etc. They are complementary. Adding more code correctness checking
would generally be to the good, though we can all debate to what
degree.

> From a developer experience factor, I find myself scratching my head: what are
> we gaining with STH if we have a strict mode? I'm still writing exactly the 
> same
> code I am today to validate and/or cast my scalars before passing them to
> functions and methods if I want to be strict.
>
> The new coercive RFC offers much more promise to me as a consumer/user of the
> language. The primary benefit I see is that it provides a path forward towards
> better casting logic in the language, which will ensure that — in the future —
> this:
>
>     $value = (int) $value;
>
> will operate properly, and raise errors when data loss may occur. It means 
> that
> immediately, if I start using STH, I can be assured that _if_ my code runs, I
> have values of the correct type, as they've been coerced safely. The lack of a
> strict mode means I can drop that defensive validation/casting code safely.

And the reply would be variations including "but was that the user's
intent?". Yes, you have the type you wanted. Was it the type the
caller intended you to have or did they do something in error that
just silently passed unnoticed?

> My point is: I'm sick of writing code like this:
>
<snip reason="the horror">
>
> and _not_ push the burden on consumers to validate/cast their values.

And again, we're going to have to consider that burden. We're all
still thinking in terms of PHP5 and not considering how to be user
friendly, and the good type of lazy, under a stricter regime. Where
did the user get the status code from? Why did THAT not return an
integer? Don't we have those return types ready to rock? If this were
a response of some sort, why didn't they simply use an integer? Why
are we writing multiline blocks of code (everywhere and anywhere) and
not doing "extract method" followed by filling out the annoying
Packagist webhook for a git repo?

> This is what I want from STH, no more no less: sane casting rules, and the
> ability to code to scalar types safely. While I can see some of the benefits 
> of
> strict mode, I'm concerned about the schism it may create in the PHP library
> ecosystem, and that many of the benefits of the coercive portion of that RFC
> will be lost when working with data from unknown data sources.
>
> If you've read thus far, thank you for your consideration. I'll stop bugging 
> you
> now.

But you responded later! :)

Paddy

--
Pádraic Brady

http://blog.astrumfutura.com
http://www.survivethedeepend.com

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to