Hi Thomas, > Perhaps I miss your point. But what is the difference to current behavior if > you do not know about the types?
Not to the current behaviour, to the behaviour that would be possible with scalar type-hinting. >Or is your point about inspection of parameter type? Why shouldn't reflection >be able to provide information about scalar parameter casting? Yes, reflection should provide that information which makes the code: > function foo( $i, $s ) > { > $i = (int) $i; > $s = (string) $s; > } Not be equivalent to: > function foo( $i, $s ) > { > $i = (int) $i; > $s = (string) $s; > } My point is the reflection then allows the calling code to explicitly cast the parameters to the type the function expects, _with_ data loss if required, without triggering any warning on information loss. For example: function foo(bool $enabled) {...} $enabledValue = $request->getParam('enabled'); $dic->execute('foo', ['enabled' => $enabledValue ] ) The DIC should be able to know that the function expects a bool and so if the value of $enabledValue is the string 'true', that it should convert it to the boolean true, and so make the function happy. So that allows no E_CAST being generated, as there has been no implicit cast, only an explicit conversion somewhere in the DIC. cheers Dan On 17 July 2014 13:43, Thomas Nunninger <tho...@nunninger.info> wrote: > Hi Dan, > > > On 07/17/2014 02:12 PM, Dan Ackroyd wrote: >> >> Thomas Nunninger wrote: >>> >>> - "scalar parameter casting" should just be a convenience for coding: >>> >>> function foo( (int) $i, (string) $s ) >>> { >>> } >>> >>> is the same as: >>> >>> function foo( $i, $s ) >>> { >>> $i = (int) $i; >>> $s = (string) $s; >>> } >>> >>> or perhaps better:: >>> >>> $i = (int) $i; >>> $s = (string) $s; >>> >>> foo( $i, $s ); >>> >>> >>> That way you decide if you want to be very strict about the data in your >>> variables or not, and both parties (strict vs. non-strict) can share >>> code: >> >> >> I agree generally with your mail apart from this bit - people don't >> always just call code directly and so can't tell what types parameters >> should be. >> >> When you're calling code dynamically, e.g. through a dependency >> injection container, you need to be able to inspect what types are >> expected from outside the function. >> >> e.g. >> >> $dic->execute( >> 'foo', >> [ >> 'i' => $request->getParam('i'), >> 's' => $request->getParam('s') >> ] >> ); >> >> Without having the type-hinting/casting information available in the >> function, it's not possible for the calling code to know what type the >> function is expecting, and so it isn't able to cast it to what the >> function is expecting. > > > Perhaps I miss your point. But what is the difference to current behavior if > you do not know about the types? > > With casting the calling code does not need to know how to cast as the > called code accepts the parameter if the value can be used without data > loss. (If the example was misleading because the cast is happening before > calling the function: This should only stress, that providing usable data is > not a responsibility of the called function but the calling code.) > > If the called function is strict it checks the input parameters in the > function and raises some kind of error if information is lost on casting > (not if the type is wrong). If information is lost, E_CAST is raised and PHP > would use type juggling with expected or unexpected result (e.g. non-numeric > strings casted to int). The difference to current behavior is that the > product owner can decide if he wants strict behavior or not. > > > Or is your point about inspection of parameter type? Why shouldn't > reflection be able to provide information about scalar parameter casting? > > Regards > > Thomas > > >> On 17 July 2014 10:22, Thomas Nunninger <tho...@nunninger.info> wrote: >>> >>> Hi, >>> >>> On 07/16/2014 10:45 PM, Andrea Faulds wrote: >>>> >>>> >>>> >>>> On 16 Jul 2014, at 21:43, Zeev Suraski <z...@zend.com> wrote: >>>> >>>>>> anything this RFC permits will >>>>>> be permitted by zpp, it's the reverse that isn't necessarily true. >>>>> >>>>> >>>>> >>>>> Right, so it needs to be fixed. It makes no sense to force a new >>>>> agenda >>>>> on the language that's inconsistent with the rest of the language. >>>>> Align >>>>> your new feature to the rest of the language, not the other way around. >>>> >>>> >>>> >>>> But to do so would be to make the feature less useful, nor satisfy >>>> people >>>> who want stricter hinting. >>> >>> >>> >>> tl;dr: >>> >>> - I'd like to have E_CAST on all castings/type jugglings even if we do >>> not >>> get scalar type hinting. >>> >>> - I propose to say/implement "scalar parameter casting" instead of >>> "scalar >>> type hinting" with a casting syntax: >>> >>> function foo( (int) $i, ...) >>> >>> That way we lower expectations, explain the different syntax/semantics in >>> contrast to hints, give a hint what scalar parameter casting does, and I >>> see >>> the use-cases of both parties fulfilled. >>> >>> ------- >>> >>> I didn't follow the complete thread in detail. And I have to confess that >>> I'm a big fan of strictly "defining types of parameters", because I see >>> how >>> it could help me in my work. >>> >>> BUT: As I see it, E_CAST (with the existing type juggling rules/casts) >>> plus >>> "scalar parameter casting" is the best compromise in the spirit/history >>> of >>> PHP without BC breaks and I think all use-cases are satisfied: >>> >>> >>> - E_CAST notifies me about data loss on type juggling. >>> >>> - "scalar parameter casting" should just be a convenience for coding: >>> >>> function foo( (int) $i, (string) $s ) >>> { >>> } >>> >>> is the same as: >>> >>> function foo( $i, $s ) >>> { >>> $i = (int) $i; >>> $s = (string) $s; >>> } >>> >>> or perhaps better:: >>> >>> $i = (int) $i; >>> $s = (string) $s; >>> >>> foo( $i, $s ); >>> >>> >>> That way you decide if you want to be very strict about the data in your >>> variables or not, and both parties (strict vs. non-strict) can share >>> code: >>> >>> >>> - With E_CAST you get additional information on data loss on type >>> juggling >>> and casting in your complete code base. That's a plus for everybody who's >>> a >>> little bit scary about type juggling in those cases. >>> >>> - As a fan of strict mode I can develop my applications and libraries in >>> E_CAST mode via an error handler that throws exceptions on E_CAST. (We >>> even >>> run our code with E_ALL in production to find edge cases.) >>> >>> - I see the severity of E_CAST on a level like E_NOTICE and E_STRICT: >>> Best >>> practice - if others do not understand/care it's their "problem" but they >>> can use my code like each other code. >>> >>> - As a fan of non-strict behavior, you can provide a string for a >>> parameter >>> that is defined to be an integer. If it contains a number you are happy >>> that >>> my code works as PHP deals with casting. If your string does not contain >>> a >>> usable value you have to live with the good old PHP way when you use code >>> with wrong input data and my code treats it as an integer and you perhaps >>> have some data loss. But that's not the responsibility of my code - >>> especially if I interpret the casting syntax as casting the parameters >>> before hitting my method/function. (BTW: I don't think that casting >>> should >>> be used as sanitizing of user input like it was proposed/said to be >>> widely >>> used. I prefer validation over sanitizing.) >>> >>> - Depending where and how I define my error handler, I do not see that my >>> code needs to behave differently if E_CAST is enabled or not. I think you >>> should implement your error_handler for E_CAST in the spirit of Symfony's >>> debug mode: In debug mode all errors are converted to exceptions but they >>> are ignored in production mode. I guess you'd never say: My application >>> behaves differently. Otherwise you probably use exceptions for control >>> flow. >>> (I do not say that you have to disable E_CAST for your production mode. >>> But >>> if your code passes all tests in E_CAST, there is a good chance that it >>> works without E_CAST as well. Then it's your decision as product owner if >>> you have to break on errors in edge cases or not.) >>> >>> - Regarding consistency to array and object hints: Using the casting >>> syntax/semantics you could even provide (array) and (object) as "scalar >>> parameter casting" in contrast to the hints. But of course you can argue >>> that users are confused about "(array)" vs. "array". I could live with >>> that >>> confusion as people have to learn about "parameter casting" and that >>> should >>> be explicitly mentioned in the docs/tutorials/blog posts/... >>> >>> - I don't know if there is a downside for static code analysis. But >>> probably >>> you even need defined return types for that. >>> >>> >>> Regards >>> >>> Thomas >>> >>> >>> -- >>> PHP Internals - PHP Runtime Development Mailing List >>> To unsubscribe, visit: http://www.php.net/unsub.php >>> >> > > -- > Dipl.-Inf. Thomas Nunninger > Kartäuserstraße 3 > D-79102 Freiburg i. Br. > > Tel: +49 761 2171508-0 > Mobil: +49 163 7115153 > http://nunninger.info > > USt-IdNr: DE259832548 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php