Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:75673 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 7347 invoked from network); 17 Jul 2014 19:37:24 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Jul 2014 19:37:24 -0000 Authentication-Results: pb1.pair.com header.from=danack@basereality.com; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=danack@basereality.com; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain basereality.com from 209.85.212.181 cause and error) X-PHP-List-Original-Sender: danack@basereality.com X-Host-Fingerprint: 209.85.212.181 mail-wi0-f181.google.com Received: from [209.85.212.181] ([209.85.212.181:53295] helo=mail-wi0-f181.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0F/A2-18859-2F528C35 for ; Thu, 17 Jul 2014 15:37:23 -0400 Received: by mail-wi0-f181.google.com with SMTP id bs8so3338271wib.14 for ; Thu, 17 Jul 2014 12:37:18 -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=CQ0T/ZidpJi1LrDLwGeSGQTnysCQptPnycUyG/RmMX8=; b=C1sn9f3J+qv6MeKyJzMTcMsm2J7sccAI7GKLA1LwVBkapDfFxw3prt8tHuQtGANJ4F DzVl7q7YENFINTUktCgLf5ngA+EYxE2lKGj0zag4+0IJy8y7eBn8YePUSh2ZQMMcD3gt sH1jmSI2fsuzKizg3GTuni5KkAO5aHEnFNBY0aMEamilXYV4xxSYdizv00Y4FEDkHMgu akRtfe9Dd0QbVh8voCc4ZER/0JPeMosniCbRZU86tEPLxcXzGTHxHjKBUZJ+0vc2JdnM M5Tp5Q16thDnOr1M2srfMsjSEro57mIlKEKsSOPr2LBsAAwEsLvu2xUMMiaYzjXoB1J8 iseQ== X-Gm-Message-State: ALoCoQnZLTiRUacsrX8ydIVAjArvmUygLthAhZMu7r6q93Eow68nTVT1D2i+ELxI3ts2RpYIbaOU MIME-Version: 1.0 X-Received: by 10.180.13.208 with SMTP id j16mr540489wic.15.1405625838521; Thu, 17 Jul 2014 12:37:18 -0700 (PDT) Received: by 10.216.51.144 with HTTP; Thu, 17 Jul 2014 12:37:18 -0700 (PDT) X-Originating-IP: [78.148.159.41] In-Reply-To: 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 20:37:18 +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) Apologies, I pasted the wrong code, it should have read: " which makes the code: > function foo( $i, $s ) > { > $i =3D (int) $i; > $s =3D (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 wrote: > Hi Thomas, > >> Perhaps I miss your point. But what is the difference to current behavio= r 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 refle= ction 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 yo= ur >>>> 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 behavio= r 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 befor= e >> calling the function: This should only stress, that providing usable dat= a 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-num= eric >> 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 arou= nd. >>>>> >>>>> >>>>> >>>>> 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 t= hat >>>> I'm a big fan of strictly "defining types of parameters", because I se= e >>>> 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/histor= y >>>> 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 yo= ur >>>> 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 wh= o'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 t= hey >>>> 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 happ= y >>>> that >>>> my code works as PHP deals with casting. If your string does not conta= in >>>> a >>>> usable value you have to live with the good old PHP way when you use c= ode >>>> with wrong input data and my code treats it as an integer and you perh= aps >>>> 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 Symfon= y's >>>> debug mode: In debug mode all errors are converted to exceptions but t= hey >>>> are ignored in production mode. I guess you'd never say: My applicatio= n >>>> 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 i= t >>>> 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 "scala= r >>>> parameter casting" in contrast to the hints. But of course you can arg= ue >>>> 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