Apologies, I pasted the wrong code, it should have read: " which makes the code:
> function foo( $i, $s ) > { > $i = (int) $i; > $s = (string) $s; > } Not be equivalent to: > function foo( (int) $i, (string) $s ) > { > } As the type-hint information is not available outside the function for the first one. " On 17 July 2014 19:29, Dan Ackroyd <dan...@basereality.com> wrote: > 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