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