Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:75672 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 2738 invoked from network); 17 Jul 2014 18:29:10 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Jul 2014 18:29:10 -0000 Authentication-Results: pb1.pair.com smtp.mail=danack@basereality.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=danack@basereality.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain basereality.com from 209.85.212.176 cause and error) X-PHP-List-Original-Sender: danack@basereality.com X-Host-Fingerprint: 209.85.212.176 mail-wi0-f176.google.com Received: from [209.85.212.176] ([209.85.212.176:55928] helo=mail-wi0-f176.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A9/12-18859-4F518C35 for ; Thu, 17 Jul 2014 14:29:09 -0400 Received: by mail-wi0-f176.google.com with SMTP id bs8so8256801wib.9 for ; Thu, 17 Jul 2014 11:29:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=cC8AF4SN6xGcGofVrJ6RRGo0Bvp7uG9PdFLE6Z1rC3I=; b=YEf4+eZh43Fb8qQYz2HBsflJSxP8Q+YLcxu68b/nu3RrX8+AzPi3iPqqjWpTR5U2P3 9zx3FqMg5Gmq+lIYfw7ZfTb4vHS/2nWMxjht50m55Vf6MCWEUfufBvXTcB+Mvum+PeWd dQxHMvzsr1XcmA+VVNwz8t2NVx7VUYzKDUnpm+1RaPScyWyXHu2SQn81Xt1T8o0A7Bp3 czUU5EXkCfY1VYJFQj6aNFpaByXMypNFMhjxSpSS1JarCtUGa28aJylH4hpUZj7NIQsQ F79NnzWwuoWVb4CigolmM7GLvcFxzaE5Sd4x4CvcDXtU84+eMmmJAqDRimzDQQI2zLdb Evmw== X-Gm-Message-State: ALoCoQlzOXfvPxQzK83kYmOaG6KQxBiS9VnZSB+jtITSWKCHXasTl6NZaKyNRJkDqKGyG7oK5lcg MIME-Version: 1.0 X-Received: by 10.180.19.1 with SMTP id a1mr25114094wie.16.1405621745233; Thu, 17 Jul 2014 11:29:05 -0700 (PDT) Received: by 10.216.51.144 with HTTP; Thu, 17 Jul 2014 11:29:05 -0700 (PDT) X-Originating-IP: [78.149.0.73] In-Reply-To: <53C7C50A.6030601@nunninger.info> References: <08503591-EFC8-48E6-984E-FFC292C5EA5F@ajf.me> <16D48604-0C0A-4613-91A4-21392E3A2636@ajf.me> <05CE2216-C5D9-4937-9F2E-AA1407284D9F@ajf.me> <53C460DF.5040304@sugarcrm.com> <53C53A96.2040303@gmail.com> <53C55342.1010207@sugarcrm.com> <53C563B3.6060905@gmail.com> <54536191-1B92-4933-973F-0C8289D13A4C@ajf.me> <00d12255efc53466245b21a83ff7d474@mail.gmail.com> <1CE2ACC0-D6CA-407B-99C7-4914311B733E@ajf.me> <53C6CFB7.8090908@sugarcrm.com> <118BB3D7-BE52-44AB-BD0E-942830D44A2A@ajf.me> <9B7B8559-61FE-493D-BAEE-53E8C84D5E91@ajf.me> <53C795EA.1070303@nunninger.info> <53C7C50A.6030601@nunninger.info> Date: Thu, 17 Jul 2014 19:29:05 +0100 Message-ID: To: Thomas Nunninger Cc: Andrea Faulds , Zeev Suraski , Stas Malyshev , Andrey Andreev , Rowan Collins , "internals@lists.php.net" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] Scalar Type Hinting With Casts (re-opening) From: danack@basereality.com (Dan Ackroyd) 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 reflec= tion be able to provide information about scalar parameter casting? Yes, reflection should provide that information which makes the code: > function foo( $i, $s ) > { > $i =3D (int) $i; > $s =3D (string) $s; > } Not be equivalent to: > function foo( $i, $s ) > { > $i =3D (int) $i; > $s =3D (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 =3D $request->getParam('enabled'); $dic->execute('foo', ['enabled' =3D> $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 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 =3D (int) $i; >>> $s =3D (string) $s; >>> } >>> >>> or perhaps better:: >>> >>> $i =3D (int) $i; >>> $s =3D (string) $s; >>> >>> foo( $i, $s ); >>> >>> >>> That way you decide if you want to be very strict about the data in you= r >>> 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' =3D> $request->getParam('i'), >> 's' =3D> $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-nume= ric > 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 wrote: >>> >>> Hi, >>> >>> On 07/16/2014 10:45 PM, Andrea Faulds wrote: >>>> >>>> >>>> >>>> On 16 Jul 2014, at 21:43, Zeev Suraski 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 aroun= d. >>>> >>>> >>>> >>>> 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 th= at >>> 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 =3D (int) $i; >>> $s =3D (string) $s; >>> } >>> >>> or perhaps better:: >>> >>> $i =3D (int) $i; >>> $s =3D (string) $s; >>> >>> foo( $i, $s ); >>> >>> >>> That way you decide if you want to be very strict about the data in you= r >>> 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 i= n >>> 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 th= ey >>> 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 contai= n >>> a >>> usable value you have to live with the good old PHP way when you use co= de >>> with wrong input data and my code treats it as an integer and you perha= ps >>> 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 y= ou >>> 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 th= ey >>> 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 argu= e >>> 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=C3=A4userstra=C3=9Fe 3 > D-79102 Freiburg i. Br. > > Tel: +49 761 2171508-0 > Mobil: +49 163 7115153 > http://nunninger.info > > USt-IdNr: DE259832548