[RFC] Scalar Type Hints v0.2

php.internals

Andrew Faulds

11 years ago
Good evening, I’ve made some quite significant changes to my Scalar Type Hints RFC, and bumped its version to 0.2. Here: https://wiki.php.net/rfc/scalar_type_hints This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the updated RFC from the v0.1 RFC. Please tell me your thoughts. Thanks!
-- Andrea Faulds http://ajf.me/

Robert Stoll

11 years ago
Hi Andrea
> -----Ursprüngliche Nachricht----- > Von: Andrea Faulds [mailto:ajf@ajf.me] > Gesendet: Mittwoch, 14. Januar 2015 01:17 > An: PHP Internals List > Betreff: [PHP-DEV] [RFC] Scalar Type Hints v0.2 > > Good evening, > > I’ve made some quite significant changes to my Scalar Type Hints RFC, and bumped its version to 0.2. > > Here: https://wiki.php.net/rfc/scalar_type_hints > > This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the > updated RFC from the v0.1 RFC. > > Please tell me your thoughts. > > Thanks! > -- > Andrea Faulds > http://ajf.me/ > > -- > PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
I had a few thoughts on the new proposed declare(strict_typehints=TRUE); construct and I must say I do not really like that we would have different behaviour just based on a directive. This is quite ugly from a readability point of view since I as user cannot easily see whether somewhere (above) in the code the directive was set (I have changed my mind a little bit below - left it here for traceability purposes). Which brings me to the question what happens with the following code: function foo(int $a){} //is weak right? declare(strict_typehinting=TRUE); I guess it is weak since you wrote: "If this boolean value is TRUE, strict type-checking mode is used for function calls in the remainder of the file" Maybe it is a good idea to add such an example to the examples as well. Now, having rethought my own email, I think we should enforce some code style to avoid a huge mess. Why not declare that the directive needs to be the very first statement inside a namespace scope (unless the directive block syntax is used). This way it would be easily verifiable for the user if strict mode is in place or not. But then again, we could also argue that is up to code conventions/code guidelines and they should specify whether mixing both modes is ok and where the directive has to be placed. So re-rethinking what I just wrote I would say it is fine as it is now but we should at least consider if we want to enforce some code practice to avoid a mess. Now another point: "Whether or not the function being called was declared in a file that uses strict or weak type checking is entirely irrelevant. The type checking mode depends on the file where the function is called." Seems quite strange to me but fair enough, why not -- actually makes perfectly sense for this RFC -> leaving it to the user to decide what he/she likes :-)

Andrew Faulds

11 years ago
Hey Robert,
> On 14 Jan 2015, at 08:22, Robert Stoll <php@tutteli.ch> wrote: > > I had a few thoughts on the new proposed declare(strict_typehints=TRUE); construct and I must say I do not really like that we would have different behaviour just based on a directive. This is quite ugly from a readability point of view since I as user cannot easily see whether somewhere (above) in the code the directive was set (I have changed my mind a little bit below - left it here for traceability purposes). Which brings me to the question what happens with the following code: > > function foo(int $a){} //is weak right? > declare(strict_typehinting=TRUE); > > > I guess it is weak since you wrote: "If this boolean value is TRUE, strict type-checking mode is used for function calls in the remainder of the file" > Maybe it is a good idea to add such an example to the examples as well.
Yes, it only affects stuff which comes after it. But in the example you just gave it doesn’t do anything, because the type checking mode is about the caller (where the function is called), not the callee (where the function is defined). A better example: <?php foo(1.0); // weak declare(strict_typehints=TRUE); foo(1); // strict
> Now, having rethought my own email, I think we should enforce some code style to avoid a huge mess. Why not declare that the directive needs to be the very first statement inside a namespace scope (unless the directive block syntax is used). This way it would be easily verifiable for the user if strict mode is in place or not. But then again, we could also argue that is up to code conventions/code guidelines and they should specify whether mixing both modes is ok and where the directive has to be placed. So re-rethinking what I just wrote I would say it is fine as it is now but we should at least consider if we want to enforce some code practice to avoid a mess.
We could possible require it to be at the top of the file, maybe. Though I expect people will probably do this anyway. I’m sure it’ll become part of PSR-whatever and there’ll be some sort of standard. By the way, you can mark some blocks as having different behaviour, e.g.: <?php declare(strict_typehints=TRUE) { foo(1); } declare(strict_typehints=FALSE) { bar(2); } This way, it’s more obvious that they have different behaviour.
> Now another point: "Whether or not the function being called was declared in a file that uses strict or weak type checking is entirely irrelevant. The type checking mode depends on the file where the function is called." > Seems quite strange to me but fair enough, why not -- actually makes perfectly sense for this RFC -> leaving it to the user to decide what he/she likes :-)
That’s the idea. I didn’t like the idea of having an API force you to deal with a particular approach, especially since it’d mean some of your calls would be strict, others weak. This way it’s completely consistent: everything is strict, or everything is weak, and you get to choose. :) Thanks for your comments.
-- Andrea Faulds http://ajf.me/

Marcio Almada

11 years ago
Andrea, With all the respect this RFC is way worst than the v0.1: We still have a BC break but now we also have code with **mutant** behavior that might become buggy (do unexpected things) if a `declare` is used. As a language user and a package maintainer it would be a huge problem. Imagine how would be to maintain a package that can be used with both strict and coercive type checking. We would have to write 2x more tests and yet pollute code with manual type checks (is_string, is_integer) for the non strict runtime mode when type check is necessary. This RFC is a huge regression, IMMO, -1 here 2015-01-14 5:22 GMT-03:00 Robert Stoll <php@tutteli.ch>:

Andrew Faulds

11 years ago
Hi Marcio,
> On 14 Jan 2015, at 18:52, Marcio Almada <marcio.web2@gmail.com> wrote: > > We still have a BC break but now we also have code with **mutant** behavior that might become buggy (do unexpected things) if a `declare` is used. As a language user and a package maintainer it would be a huge problem. Imagine how would be to maintain a package that can be used with both strict and coercive type checking. We would have to write 2x more tests and yet pollute code with manual type checks (is_string, is_integer) for the non strict runtime mode when type check is necessary.
I don’t see why this would create “mutant” or “buggy” behaviour. You always get the type you ask for: the weak behaviour is precisely the same as in v0.1. The strict behaviour is fairly intuitive. In no case will you ever receive the wrong type. I don’t understand.
-- Andrea Faulds http://ajf.me/

Arvids Godjuks

11 years ago
On 15 Jan 2015, at 0:33, Andrea Faulds <ajf@ajf.me>: Hi Marcio,
> On 14 Jan 2015, at 18:52, Marcio Almada <marcio.web2@gmail.com> wrote: > > We still have a BC break but now we also have code with **mutant**
behavior that might become buggy (do unexpected things) if a `declare` is used. As a language user and a package maintainer it would be a huge problem. Imagine how would be to maintain a package that can be used with both strict and coercive type checking. We would have to write 2x more tests and yet pollute code with manual type checks (is_string, is_integer) for the non strict runtime mode when type check is necessary. I don’t see why this would create “mutant” or “buggy” behaviour. You always get the type you ask for: the weak behaviour is precisely the same as in v0.1. The strict behaviour is fairly intuitive. In no case will you ever receive the wrong type. I don’t understand.
-- Andrea Fauld s Hello Andrea! Consider what a mess was register_globals and problems it had, but at least it was a global setting. Declare will work on per file basis, and it will end up even more of a mess. I think PHP development community learned that lesson and that's why you get pushback, and not only from internals, but also from the userland. Me including. Rergards, Arvids.

Nikita

11 years ago
On Thu, 15 Jan 2015 14:30:48 +0300, Arvids Godjuks <arvids.godjuks@gmail.com> wrote:
> Hello Andrea! > > Consider what a mess was register_globals and problems it had, but at > least > it was a global setting. Declare will work on per file basis, and it will > end up even more of a mess. > > I think PHP development community learned that lesson and that's why you > get pushback, and not only from internals, but also from the userland. Me > including. >
What does it have with register_globals in common? Why would it be a mess?

Lester Caine

11 years ago
On 15/01/15 15:28, Niktia Nefedov wrote:
>> Consider what a mess was register_globals and problems it had, but at >> least >> it was a global setting. Declare will work on per file basis, and it will >> end up even more of a mess. >> >> I think PHP development community learned that lesson and that's why you >> get pushback, and not only from internals, but also from the userland. Me >> including. > > What does it have with register_globals in common? Why would it be a mess?
Removing 'register_globals' breaks code for users who have no idea that their sites are even using it. deprecating on one version - which one is told to switch off the warnings for - just means that when the hosting skips a version the site simply stops working. That is why 5.2 is still around and why hosting companies have problems ... and I still have code which relies on 'register_globals' today because those sites are simply working. There is simply no time to 'fix' them :( At the end of the day the whole of the legacy codebase either has to be brought forward, or PHP5 will be hanging around for some of the same reasons PHP4 did. Bringing in more areas where differences between code bases can diverge again over time is creating the same black holes in the future.
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Benjamin Eberlei

11 years ago
On Fri, Jan 16, 2015 at 11:08 AM, Lester Caine <lester@lsces.co.uk> wrote:
> On 15/01/15 15:28, Niktia Nefedov wrote: > >> Consider what a mess was register_globals and problems it had, but at > >> least > >> it was a global setting. Declare will work on per file basis, and it > will > >> end up even more of a mess. > >> > >> I think PHP development community learned that lesson and that's why you > >> get pushback, and not only from internals, but also from the userland. > Me > >> including. > > > > What does it have with register_globals in common? Why would it be a > mess? > > Removing 'register_globals' breaks code for users who have no idea that > their sites are even using it. deprecating on one version - which one is > told to switch off the warnings for - just means that when the hosting > skips a version the site simply stops working. That is why 5.2 is still > around and why hosting companies have problems ... and I still have code > which relies on 'register_globals' today because those sites are simply > working. There is simply no time to 'fix' them :( > > At the end of the day the whole of the legacy codebase either has to be > brought forward, or PHP5 will be hanging around for some of the same > reasons PHP4 did. Bringing in more areas where differences between code > bases can diverge again over time is creating the same black holes in > the future. >
You keep bringing this up, but there is a workaround to manually "enable" register globals again if you need to have it for migration. It should just work (TM) (haven't actually used it) foreach ($_REQUEST as $k => $v) { $GLOBALS[$k] = $v; } Not sure why we have to discuss this over and over again on this list.

Lester Caine

11 years ago
On 16/01/15 11:05, Benjamin Eberlei wrote:
> You keep bringing this up, but there is a workaround to manually "enable"
On PHP5.4 or later? We are stuck with 5.3 unless code is modified. Same with other removed functions in 5.4.
> register globals again if you need to have it for migration. It should just > work (TM) (haven't actually used it) > > foreach ($_REQUEST as $k => $v) { $GLOBALS[$k] = $v; } > > Not sure why we have to discuss this over and over again on this list.
Yes there are work arounds which once one knows that is why a site has failed can be applied, but it is one of the reasons PHP5.2/3 is still remaining on shared hosting. No body has the time to hand hold their customers through the changes. The CORRECT fix is to work out why it is needed, and properly sort out the code, as with so many of the breaks brought into PHP5. It is still a brick wall that users have to scale, so in the context of current discussions can we possibly avoid adding more of them with PHP7 which is I am sure why Arvids brough it up.
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Leigh

11 years ago
On 14 January 2015 at 00:16, Andrea Faulds <ajf@ajf.me> wrote:
> Good evening, > > I’ve made some quite significant changes to my Scalar Type Hints RFC, and bumped its version to 0.2. > > Here: https://wiki.php.net/rfc/scalar_type_hints > > This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the updated RFC from the v0.1 RFC. > > Please tell me your thoughts. >
I really don't like this behaviour being changed at the call site. If I design a function that I _know_ should only take a string, then I want it to be an error if the user supplies anything else, so that they know they messed up. Also, there's this, that you might be able to re-purpose. https://github.com/php/php-src/blob/d5dd29/Zend/zend_compile.c#L7199

Andrew Faulds

11 years ago
Hi Leigh,
> On 14 Jan 2015, at 09:17, Leigh <leight@gmail.com> wrote: > > I really don't like this behaviour being changed at the call site. If > I design a function that I _know_ should only take a string, then I > want it to be an error if the user supplies anything else, so that > they know they messed up.
I don’t like the idea of being forced to use strict (or weak) type checking because the API author decided as much. More importantly, having the function and not its caller decide makes the addition of type hints to existing code difficult, because it will (possibly unintentionally) rely on PHP’s weak typing and thus error when faced with a strict type check. On the other hand, having the callee decide means that you can relatively safely add type hints to existing code and its consumers will not error. You can then gradually migrate that consuming code over to strict type-checking, if you so wish.
> Also, there's this, that you might be able to re-purpose. > https://github.com/php/php-src/blob/d5dd29/Zend/zend_compile.c#L7199
I don’t want to get rid of that easter egg, and I prefer the declare() syntax since it’s more obviously some sort of directive (use strict; looks like an innocuous use statement) and supports the block syntax.
-- Andrea Faulds http://ajf.me/

Zeev Suraski

11 years ago
> -----Original Message----- > From: Andrea Faulds [mailto:ajf@ajf.me] > Sent: Wednesday, January 14, 2015 11:33 AM > To: Leigh > Cc: PHP Internals List > Subject: Re: [PHP-DEV] [RFC] Scalar Type Hints v0.2 > > Hi Leigh, > > > On 14 Jan 2015, at 09:17, Leigh <leight@gmail.com> wrote: > > > > I really don't like this behaviour being changed at the call site. If > > I design a function that I _know_ should only take a string, then I > > want it to be an error if the user supplies anything else, so that > > they know they messed up. > > I don’t like the idea of being forced to use strict (or weak) type > checking > because the API author decided as much.
I don't either. But I don't like the user to do it either, it's something that is a part of the language definition. I completely agree with both Robert and Leigh. I liked the v0.1 one, but v0.2 is DOA from my point of view. Arguably, from my POV, it's the one option that's even worse than having strict typing exclusively. Zeev

Richard Quadling

11 years ago
On 14 January 2015 at 09:41, Zeev Suraski <zeev@zend.com> wrote:
> > -----Original Message----- > > From: Andrea Faulds [mailto:ajf@ajf.me] > > Sent: Wednesday, January 14, 2015 11:33 AM > > To: Leigh > > Cc: PHP Internals List > > Subject: Re: [PHP-DEV] [RFC] Scalar Type Hints v0.2 > > > > Hi Leigh, > > > > > On 14 Jan 2015, at 09:17, Leigh <leight@gmail.com> wrote: > > > > > > I really don't like this behaviour being changed at the call site. If > > > I design a function that I _know_ should only take a string, then I > > > want it to be an error if the user supplies anything else, so that > > > they know they messed up. > > > > I don’t like the idea of being forced to use strict (or weak) type > > checking > > because the API author decided as much. > > I don't either. But I don't like the user to do it either, it's something > that is a part of the language definition. > > I completely agree with both Robert and Leigh. I liked the v0.1 one, but > v0.2 is DOA from my point of view. Arguably, from my POV, it's the one > option that's even worse than having strict typing exclusively. > > Zeev
The issue of scalar type hinting has been around for a while, with various proposals and RFCs, but no consensus. Each time a certain level of progress is made, more issues arise. It would seem that the major issues is that whatever a library/framework developer decides, the user of that library/framework would have to develop their application to fit. Is this such a bad thing? The comeback to that is that PHP supports type juggling, so there is a different mechanism for non-scalars to scalars. Fair enough. From the lib developer's perspective, if a parameter to a function/method is going to be treated as an integer and is expected to be an integer, then they should be able to force/limit this just like they can when they say it must be an array/callable/class/interface. But take into account the option to enforce the type juggling. I get 3 questions from this. 1 - Should the type hint restrict non matching types? 2 - When should the value be juggled to match the type hint if it is different? 3 - Could we allow different signatures for the same method name? - A different question entirely, but one that may be worth having in relation to this proposal. Whatever mechanism is used, it needs to be of zero effort for the user, but fully understood of the effect. I think to answer all of this, and to provide enough flexibility that everyone can be made happy and understand the effect, I think the issues could be resolved with the following. 1 - A type hint of 'scalar' is required. This excludes other types (array/callable/class/interface) and would specifically mean that no type juggling will take place as part of the parameter passing. If no type juggling is going to take place, why does it matter what the type hint is? The advantage of having 'scalar' as a type hint is, as I said, excludes non-scalars. Now, if the method does something to the value and the value is passed by reference, then that would need to be documented clearly. 2 - A scalar type type hint will automatically juggle. PHP is a dynamic language and, as such, type juggling is used throughout. It shouldn't be any different when a parameter is type hinted for scalars. The frustration seems to be that without a way to say that this scalar will NOT be type juggled (loose) or that it will be (strong) then we cannot move forward. Now, some of the comments related to this proposal (and others) is what to do when the scalar type is of a different type to the parameter. I think I've covered this by the use of the type hint 'scalar'. Scalars get type juggled. Period. For good or bad. Until PHP becomes a strongly type language, type juggling exists. With the hinting, we can let users know that type juggling will now also apply to parameters. So. <?php // Any type. function anyType($a){} // Current types. function anArray(array $b){} function aCallable(callable $c){} function aClass(stdclass $d){} function anInterface(Countable $e){} // Any scalar - not juggled. function anyScalar(scalar $f){} // Any scalar - juggled function willBeJuggledToBool(bool $g){} function willBeJuggledToString(string $h){} function willBeJuggledToFloat(float $i){} function willBeJuggledToInteger(integer $j){} ?> Considering that there are no errors generated when type juggling of scalars take place, there should be no errors when type juggling scalar type hints for parameters. In essence, if you are coding with scalars (ignore type hinting) and relying on PHP to do the right thing when type juggling takes place, then the same level of acceptance should be used when type juggling of scalar parameters. TL;DR; Rejecting calls to a scalar type typehinted function because the value is of the wrong type doesn't fit with PHP's type juggling.
-- Richard Quadling

Zeev Suraski

11 years ago
I don’t think we’re ever going to get consensus. But judging by the feedback to the v0.1 version, I tend to disagree that the opposers would have blocked it. There were certainly opposers – but not that many of them as far as I could tell. I think it stood a good chance to pass at a 2/3. Unlike strict typing – we didn’t even go to a vote on it, which I think is unfortunate (and should be changed, before changing course completely as this v0.2 suggests). We’re definitely not going to have consensus on introducing both options as per this RFC. I for one think it’s the worst possible option. Zeev *From:* Richard Quadling [mailto:rquadling@gmail.com] *Sent:* Wednesday, January 14, 2015 3:23 PM *To:* Zeev Suraski *Cc:* Andrea Faulds; Leigh; PHP Internals List *Subject:* Re: [PHP-DEV] [RFC] Scalar Type Hints v0.2 On 14 January 2015 at 09:41, Zeev Suraski <zeev@zend.com> wrote:
> -----Original Message----- > From: Andrea Faulds [mailto:ajf@ajf.me] > Sent: Wednesday, January 14, 2015 11:33 AM > To: Leigh > Cc: PHP Internals List > Subject: Re: [PHP-DEV] [RFC] Scalar Type Hints v0.2 > > Hi Leigh, > > > On 14 Jan 2015, at 09:17, Leigh <leight@gmail.com> wrote: > > > > I really don't like this behaviour being changed at the call site. If > > I design a function that I _know_ should only take a string, then I > > want it to be an error if the user supplies anything else, so that > > they know they messed up. > > I don’t like the idea of being forced to use strict (or weak) type > checking > because the API author decided as much.
I don't either. But I don't like the user to do it either, it's something that is a part of the language definition. I completely agree with both Robert and Leigh. I liked the v0.1 one, but v0.2 is DOA from my point of view. Arguably, from my POV, it's the one option that's even worse than having strict typing exclusively. Zeev The issue of scalar type hinting has been around for a while, with various proposals and RFCs, but no consensus. Each time a certain level of progress is made, more issues arise. It would seem that the major issues is that whatever a library/framework developer decides, the user of that library/framework would have to develop their application to fit. Is this such a bad thing? The comeback to that is that PHP supports type juggling, so there is a different mechanism for non-scalars to scalars. Fair enough. From the lib developer's perspective, if a parameter to a function/method is going to be treated as an integer and is expected to be an integer, then they should be able to force/limit this just like they can when they say it must be an array/callable/class/interface. But take into account the option to enforce the type juggling. I get 3 questions from this. 1 - Should the type hint restrict non matching types? 2 - When should the value be juggled to match the type hint if it is different? 3 - Could we allow different signatures for the same method name? - A different question entirely, but one that may be worth having in relation to this proposal. Whatever mechanism is used, it needs to be of zero effort for the user, but fully understood of the effect. I think to answer all of this, and to provide enough flexibility that everyone can be made happy and understand the effect, I think the issues could be resolved with the following. 1 - A type hint of 'scalar' is required. This excludes other types (array/callable/class/interface) and would specifically mean that no type juggling will take place as part of the parameter passing. If no type juggling is going to take place, why does it matter what the type hint is? The advantage of having 'scalar' as a type hint is, as I said, excludes non-scalars. Now, if the method does something to the value and the value is passed by reference, then that would need to be documented clearly. 2 - A scalar type type hint will automatically juggle. PHP is a dynamic language and, as such, type juggling is used throughout. It shouldn't be any different when a parameter is type hinted for scalars. The frustration seems to be that without a way to say that this scalar will NOT be type juggled (loose) or that it will be (strong) then we cannot move forward. Now, some of the comments related to this proposal (and others) is what to do when the scalar type is of a different type to the parameter. I think I've covered this by the use of the type hint 'scalar'. Scalars get type juggled. Period. For good or bad. Until PHP becomes a strongly type language, type juggling exists. With the hinting, we can let users know that type juggling will now also apply to parameters. So. <?php // Any type. function anyType($a){} // Current types. function anArray(array $b){} function aCallable(callable $c){} function aClass(stdclass $d){} function anInterface(Countable $e){} // Any scalar - not juggled. function anyScalar(scalar $f){} // Any scalar - juggled function willBeJuggledToBool(bool $g){} function willBeJuggledToString(string $h){} function willBeJuggledToFloat(float $i){} function willBeJuggledToInteger(integer $j){} ?> Considering that there are no errors generated when type juggling of scalars take place, there should be no errors when type juggling scalar type hints for parameters. In essence, if you are coding with scalars (ignore type hinting) and relying on PHP to do the right thing when type juggling takes place, then the same level of acceptance should be used when type juggling of scalar parameters. TL;DR; Rejecting calls to a scalar type typehinted function because the value is of the wrong type doesn't fit with PHP's type juggling.
-- Richard Quadling

Pavel Kouřil

11 years ago
Hello, personally, as a language user, I really dislike the idea of both options for scalar type hinting to be the part of the language. Especially since you would have to declare the strict typing in each file (if you are going by 1 class per file in a bigger project, that's a LOT of declare directives to write in the long run) and if you'd forgot once, it would make the calling of methods somehow inconsistent. I wish there was just one way to do it; I don't care if the weak or strong variant is going to be accepted, IMHO most programmers will be able to adapt to either of them. The weak version makes probably more sense for PHP and how it handles scalar types (at least from userland developer's standpoint), but either of them is better than no typehints at all. :) PS: Personally, I find the "scalar" typehint idea useless and cannot find a real use case for it. Richard, would you mind giving an example? Regards Pavel Kouril On Wed, Jan 14, 2015 at 2:35 PM, Zeev Suraski <zeev@zend.com> wrote:

Arvids Godjuks

11 years ago
2015-01-14 16:00 GMT+02:00 Pavel Kouřil <pajousek@gmail.com>:
> Hello, > > personally, as a language user, I really dislike the idea of both > options for scalar type hinting to be the part of the language. > Especially since you would have to declare the strict typing in each > file (if you are going by 1 class per file in a bigger project, that's > a LOT of declare directives to write in the long run) and if you'd > forgot once, it would make the calling of methods somehow > inconsistent. > > I wish there was just one way to do it; I don't care if the weak or > strong variant is going to be accepted, IMHO most programmers will be > able to adapt to either of them. The weak version makes probably more > sense for PHP and how it handles scalar types (at least from userland > developer's standpoint), but either of them is better than no > typehints at all. :) > > PS: Personally, I find the "scalar" typehint idea useless and cannot > find a real use case for it. Richard, would you mind giving an > example? > > Regards > Pavel Kouril
As a userland developer, have to agree with this message fully. -1 on the v0.2 version, the declare() approach is gonna make our job misserable after a few years when this gets adopted and misused by a lot of people...

Richard Quadling

11 years ago
On 14 January 2015 at 14:00, Pavel Kouřil <pajousek@gmail.com> wrote:
> > > PS: Personally, I find the "scalar" typehint idea useless and cannot > find a real use case for it. Richard, would you mind giving an > example? >
The point of the 'scalar' typehint comes about because we need to reject non compatible types. Just like we do when we say array or callable. Currently, if we want a method/function to accept a scalar, then we cannot put any type hinting in and so we can supply an array, callable, class or interface. Being able to say 'scalar' would mean I can instantly inform the user that any scalar can be used and that no type juggling will happen automatically. For example, take ... <?php function sum(scalar $left, scalar $right) { return $left + $right;} ?> Now in this example, sure the parameters will be juggled because of the + operator. But without the typehint, and the lack of operator overloading, you would get an error if non-scalars are supplied in the addition, rather than in the call. The + is fine, it is the wrong params to the function that should be the problem. And a scalar typehint is the better place I think. Now if we have polymorphic behaviour ... <?php function sum(scalar $left, scalar $right) { return $left + $right;} // Type juggled addition function sum(array $left, array $right) { return array_merge($left, $right);} // Array merging function sum(string $left, string $right) { return $left . $right;} // String concatenation. ?> (OK, 'sum' isn't a perfect example, but you see the point I hope). Richard.
-- Richard Quadling Twitter : @RQuadling EE : http://e-e.com/M_248814.html Zend : http://bit.ly/9O8vFY

Ole Markus With

11 years ago
On 01/14/2015 02:35 PM, Zeev Suraski wrote:
> I don’t think we’re ever going to get consensus. But judging by the > feedback to the v0.1 version, I tend to disagree that the opposers would > have blocked it. There were certainly opposers – but not that many of them > as far as I could tell. I think it stood a good chance to pass at a 2/3. > Unlike strict typing – we didn’t even go to a vote on it, which I think is > unfortunate (and should be changed, before changing course completely as > this v0.2 suggests). >
Hi guys, I completely agree. I would have gone through with voting on v0.1 first. Then later (maybe) propose v0.2 as an improvement. For me v0.1 is better than no hinting, and no hinting is better than v0.2.
-- Ole Markus

Andrew Faulds

11 years ago
Hi Zeev,
> On 14 Jan 2015, at 13:35, Zeev Suraski <zeev@zend.com> wrote: > > I don’t think we’re ever going to get consensus. But judging by the feedback to the v0.1 version, I tend to disagree that the opposers would have blocked it. There were certainly opposers – but not that many of them as far as I could tell. I think it stood a good chance to pass at a 2/3. Unlike strict typing – we didn’t even go to a vote on it, which I think is unfortunate (and should be changed, before changing course completely as this v0.2 suggests). > > We’re definitely not going to have consensus on introducing both options as per this RFC. I for one think it’s the worst possible option.
It’s certainly possible it would’ve succeeded on internals. However, it is also worth considering the opinions of those who do not frequent internals and don’t have the right to vote. From what I can see, the larger PHP community is generally in favour of strict typing, and among them, the previous RFC revision was received quite poorly. Myself, I might have been somewhat happy with just weak hints, but it would upset an awful lot of developers who would like some measure of strict typing. Developers who would most likely not use the new scalar type hints, because they weren’t strict. And if nobody uses them, why add them? This revision hopes to possibly placate both weak and strict typing advocates. Of course, it also will lose some support in that it allows a choice. Plus, it gives the user choice, not the API designer, which I expect will be somewhat controversial. But I am hopeful. Thanks.
-- Andrea Faulds http://ajf.me/

Christoph Becker

11 years ago
Andrea Faulds wrote:
> From what I can see, the larger PHP community is generally in favour > of strict typing, and among them, the previous RFC revision was > received quite poorly. Myself, I might have been somewhat happy with > just weak hints, but it would upset an awful lot of developers who > would like some measure of strict typing. Developers who would most > likely not use the new scalar type hints, because they weren’t > strict. And if nobody uses them, why add them? > > This revision hopes to possibly placate both weak and strict typing > advocates. Of course, it also will lose some support in that it > allows a choice. Plus, it gives the user choice, not the API > designer, which I expect will be somewhat controversial. But I am > hopeful.
Just a thought: what about having weak scalar type hints which throw E_STRICT_TYPE if a value of another type is passed?
-- Christoph M. Becker

Pavel Kouřil

11 years ago
> On Wed, Jan 14, 2015 at 11:28 PM, Andrea Faulds <ajf@ajf.me> wrote: > From what I can see, the larger PHP community is generally in favour of strict typing, and among them, the previous RFC revision was received quite poorly. Myself, I might have been somewhat happy with just weak hints, but it would upset an awful lot of developers who would like some measure of strict typing. Developers who would most likely not use the new scalar type hints, because they weren’t strict. And if nobody uses them, why add them?
Actually, what's the big difference, making weak typing worse and less useable? The people who write libraries are guaranteed either way that the input parameters for their methods will be of desired type in both cases. And the people who use them either can do the conversion themselves (in strong typing case) or let the language help with it for them (in weak typing case) - which is IMHO fine, as long as the conversions are kinda predictable and 100% documented. And yesterday I was pointed out one thing: the RFC states "With this approach, an argument is only accepted if its type is exactly the same as the parameter.". Does this mean you cannot pass integer to a function with float argument in the strict mode? Is it strong or strict, btw? I always thought it's supposed to be "strongly typed", but since I saw "strict typing" here used by everyone, I'm not sure now. Pavel Kouril

Lester Caine

11 years ago
On 15/01/15 07:26, Pavel Kouřil wrote:
> And yesterday I was pointed out one thing: the RFC states "With this > approach, an argument is only accepted if its type is exactly the same > as the parameter.". Does this mean you cannot pass integer to a > function with float argument in the strict mode?
One of the nice features of PHP when I started using it all those years ago was that I did not have to create separate functions different types did exist in the source data. int/float/num/double and others all needed separate handling in c/c++, and one could not easily add a different 'type' of data. Nowadays I get around many of the problems that are currently all being debated by passing an 'id' or an array of data as the only parameter to a function. If the bigint 'id' is already loaded, the cached version is used, if not it is loaded or an empty default object created. If an array is passed then the relevant fields are actioned. With the current discussions I see what has become a style of working based on how PHP USED to work is now being pushed into the 'that is not the way to do it' box? I have named parameters, they are the elements of the array, order is not relevant, I can skip ones, or add new ones without affecting anything. I can see that for some nailing everything down and avoiding any flexibility is their target while others DO still subscribe to the lighter approach which allows in my book greater flexibility. So perhaps we are at a point where a big switch is needed much like e_strict to isolate the 'strict mode' from 'flexible mode'? I can see third party libraries having to provide different versions of the same code if this particular discussion goes down the wrong path?
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Pavel Kouřil

11 years ago
On Thu, Jan 15, 2015 at 9:29 AM, Lester Caine <lester@lsces.co.uk> wrote:
> > One of the nice features of PHP when I started using it all those years > ago was that I did not have to create separate functions different types > did exist in the source data. int/float/num/double and others all needed > separate handling in c/c++, and one could not easily add a different > 'type' of data. >
If you have a function which requires a "double" in C# (a strongly typed language), you can safely pass int to the function and it will work, because you are not narrowing the possible values. So making the PHP accept only the argument if its type is exactly the same as the parameter (paraphrased from RFC for the strict version of type hints) seems like a step in a wrong direction. If I'm not mistaken, Java behaves the same way. How exactly does it work in C++ and C? I haven't used C in years, so I'm a little bit rusty on this detail. Pavel Kouril

Zeev Suraski

11 years ago
> -----Original Message----- > From: Andrea Faulds [mailto:ajf@ajf.me] > Sent: Thursday, January 15, 2015 12:29 AM > To: Zeev Suraski > Cc: RQuadling@gmail.com; Leigh; PHP Internals List > Subject: Re: [PHP-DEV] [RFC] Scalar Type Hints v0.2 > > Hi Zeev, > > > On 14 Jan 2015, at 13:35, Zeev Suraski <zeev@zend.com> wrote: > > > > I don’t think we’re ever going to get consensus. But judging by the > feedback to the v0.1 version, I tend to disagree that the opposers would > have blocked it. There were certainly opposers – but not that many of > them > as far as I could tell. I think it stood a good chance to pass at a 2/3. > Unlike > strict typing – we didn’t even go to a vote on it, which I think is > unfortunate > (and should be changed, before changing course completely as this v0.2 > suggests). > > > > We’re definitely not going to have consensus on introducing both options > as per this RFC. I for one think it’s the worst possible option. > > It’s certainly possible it would’ve succeeded on internals. However, it is > also > worth considering the opinions of those who do not frequent internals and > don’t have the right to vote. > > From what I can see, the larger PHP community is generally in favour of > strict > typing, and among them, the previous RFC revision was received quite > poorly.
Andrea, I'm not sure what you're basing that assumption on. The incidental interactions you (or anybody) may have with 'the community', by no way represent the opinion of the community at large. The vast majority of the PHP community never ever interacts with internals@, never attend conferences, don't write blog posts about PHP and are generally completely 'under the radar'. I would actually go to argue that the people who do attend conferences, participate on internals@ or write blog posts - are not representative of the PHP userbase at large. The vast majority of developers I bump into - you will never ever hear from. They constitute the vast majority of the ~5M strong PHP developer base. So even though my belief / educated guess is that the vast majority of the PHP userbase would prefer to see strict typing kept off this language, I'm not going to argue that - but we must not argue the opposite either, based on the non-representative anecdotal data from a few dozen people.
>Myself, I might have been somewhat happy with just weak hints, but > it would upset an awful lot of developers who would like some measure of > strict typing. Developers who would most likely not use the new scalar > type > hints, because they weren’t strict. And if nobody uses them, why add them?
How do you deduce that 'nobody uses them' from the fact that some group of people said they won't? I'm sorry, but it makes no sense, especially given the positive feedback you saw on internals, making it clear that there would be in fact people using it. Note that unlike the opposition to strong typing - which has always been about the fact that the concept of strict typing is alien to and inconsistent with rest of PHP - the opposition to auto-casting typing is "I won't use it because it doesn't do what I'd like it to do". People who don't want to use it won't use it, but based on the feedback v0.1 received, it was clear plenty of people would.
> This revision hopes to possibly placate both weak and strict typing > advocates. Of course, it also will lose some support in that it allows a > choice. > Plus, it gives the user choice, not the API designer, which I expect will > be > somewhat controversial. But I am hopeful.
I'm not sure what to say, so I'll repeat what I said before. If there's one thing that's worse than introducing an alien concept like strict typing into PHP, it's introducing it as a feature that will include all the negatives of this alien concept, PLUS have the ability to radically change how it behaves based on a runtime option. It's so bad that we decided more than a decade ago that we want to refrain from ever introducing such elements to PHP again (e.g. magic_quotes_runtime), and I'm not sure why we're even discussing it. To be honest, before you wrote the v0.1 RFC I was talking with Dmitry regarding the possibility of writing one up myself. You saved me a lot of work by working on one. I hope that based on the feedback from numerous people here you'll abandon v0.2, but if not, I'd want take over v0.1 of the RFC and propose it as an alternative. v0.2 as disastrous for PHP. Zeev

Rowan Collins

11 years ago
Zeev Suraski wrote on 15/01/2015 11:56:
> PLUS have the ability to radically > change how it behaves based on a runtime option. It's so bad that we > decided more than a decade ago that we want to refrain from ever introducing > such elements to PHP again (e.g. magic_quotes_runtime), and I'm not sure why > we're even discussing it.
Just on this point, I do think declare() is potentially less evil than ini_set() / php.ini. A declare() directive is scoped to a particular section of code, so library authors shouldn't need to care which setting their users prefer, only the version they themselves wish to use. This contrasts completely with things like mbstring.func_overload, which makes shared library code run differently in different configurations. As has been clarified elsewhere on this thread, under this proposal a library author writing function foo(int $foo) will ALWAYS receive an integer, regardless of how that integer is arrived at. Very approximately, the declare() directive effectively gives the caller a choice between two pieces of syntactic sugar, both of which guarantee that the callee's contract will be met: if ( is_int($foo) ) { foo($foo); } else { raise_type_error($foo); } or foo ( (int)$foo ); So, just to repeat, this is NOT like register_globals or mbstring.func_overload, because shared code never needs to handle both settings. That's not to say I'm 100% convinced that this is the right way to go, just that it's not as abominable as some people are making out. Regards,
-- Rowan Collins [IMSoP]

Andrew Faulds

11 years ago
Hey Rowan,
> On 15 Jan 2015, at 13:02, Rowan Collins <rowan.collins@gmail.com> wrote: > > Zeev Suraski wrote on 15/01/2015 11:56: >> PLUS have the ability to radically >> change how it behaves based on a runtime option. It's so bad that we >> decided more than a decade ago that we want to refrain from ever introducing >> such elements to PHP again (e.g. magic_quotes_runtime), and I'm not sure why >> we're even discussing it. > > Just on this point, I do think declare() is potentially less evil than ini_set() / php.ini. A declare() directive is scoped to a particular section of code, so library authors shouldn't need to care which setting their users prefer, only the version they themselves wish to use. This contrasts completely with things like mbstring.func_overload, which makes shared library code run differently in different configurations.
Yeah, that’s the idea behind it. The hope is that you could have strictly-typed and weakly-typed code interact seamlessly with minimal issues. And, for the most part, this should allow that. A large part of the motivation behind this was avoiding the problems that adding separate strict and weak hints would have. Inevitably, people who were fans of weak typing would use a weak hint all the time, and people who were fans of strict typing would use a strict hint all the time. There would also be the odd few who might mix them, but I don’t think that would happen terribly much. It’s much easier to deal with this: foo(1.0, 1); // strict $qux = bar(“foo”); // also strict foobar($qux, baz(true)); // also strict or this: foo(1.0, 1); // weak $qux = bar(“foo”); // also weak foobar($qux, baz(true)); // also weak Than it would be to have to deal with this: foo(1.0, 1); // weak $qux = bar(“foo”); // strict foobar($qux, baz(true)); // baz is strict, foobar is weak This RFC would guarantee that, for the most part, you’re dealing with the first case (strict mode) or the second case (default). I fear that separate strict and weak hints would result in the third case being commonplace. I was also worried that if we just added weak hints, people who didn’t like them would not use them and instead use manual assertions. Similarly, I think something similar might happen if we just added strict hints. In both cases, you would be ending up with the third situation. Also bear in mind that if we added strict hints and did not change the behaviour of extension and built-in PHP functions, we’d also be dealing with that third situation, since zend_parse_parameters essentially does a kind of weak typing. Of course, this RFC does still lead to dealing with both weak and strict modes sometimes, but at least it’d always be the same mode within a given file, and by extension, within a given function, method or class. I think that’s more practical than dealing with two or more different modes within three lines of code.
> As has been clarified elsewhere on this thread, under this proposal a library author writing function foo(int $foo) will ALWAYS receive an integer, regardless of how that integer is arrived at. Very approximately, the declare() directive effectively gives the caller a choice between two pieces of syntactic sugar, both of which guarantee that the callee's contract will be met: > > if ( is_int($foo) ) { foo($foo); } else { raise_type_error($foo); } > > or > > foo ( (int)$foo ); > > So, just to repeat, this is NOT like register_globals or mbstring.func_overload, because shared code never needs to handle both settings. > > That's not to say I'm 100% convinced that this is the right way to go, just that it's not as abominable as some people are making out.
Right.
-- Andrea Faulds http://ajf.me/

Andrew Faulds

11 years ago
Hi Zeev,
> On 15 Jan 2015, at 11:56, Zeev Suraski <zeev@zend.com> wrote: > > Andrea, > > I'm not sure what you're basing that assumption on. The incidental > interactions you (or anybody) may have with 'the community', by no way > represent the opinion of the community at large. The vast majority of the > PHP community never ever interacts with internals@, never attend > conferences, don't write blog posts about PHP and are generally completely > 'under the radar'. I would actually go to argue that the people who do > attend conferences, participate on internals@ or write blog posts - are not > representative of the PHP userbase at large. The vast majority of > developers I bump into - you will never ever hear from. They constitute the > vast majority of the ~5M strong PHP developer base. > > So even though my belief / educated guess is that the vast majority of the > PHP userbase would prefer to see strict typing kept off this language, I'm > not going to argue that - but we must not argue the opposite either, based > on the non-representative anecdotal data from a few dozen people.
Whether or not they are in the majority, a very large portion of PHP developers would prefer strict typing. In particular, the most vocal ones would seem to. There are also a lot of PHP developers who would prefer weak typing. Thus we have a problem: either approach to scalar hints will upset a large portion of the community.
> >> Myself, I might have been somewhat happy with just weak hints, but >> it would upset an awful lot of developers who would like some measure of >> strict typing. Developers who would most likely not use the new scalar >> type >> hints, because they weren’t strict. And if nobody uses them, why add them? > > How do you deduce that 'nobody uses them' from the fact that some group of > people said they won't? I'm sorry, but it makes no sense, especially given > the positive feedback you saw on internals, making it clear that there would > be in fact people using it.
Not all of it was positive. Sure, a lot of people would use them though, but I’ve heard quite a few developers say they wouldn’t use them and continue to use manual (!is_int($foo))-style assertions.
> If there's one thing that's worse than introducing an alien concept like > strict typing into PHP, it's introducing it as a feature that will include > all the negatives of this alien concept, PLUS have the ability to radically > change how it behaves based on a runtime option.
This isn’t a runtime option, it is entirely compile-time. Much like namespaces are not a runtime option. There isn’t even the ability to toggle it at runtime, unless we somehow add some ability to edit the flags on individual opcodes. Thanks.
-- Andrea Faulds http://ajf.me/

Zeev Suraski

11 years ago
> -----Original Message----- > From: Andrea Faulds [mailto:ajf@ajf.me] > Sent: Thursday, January 15, 2015 4:10 PM > To: Zeev Suraski > Cc: RQuadling@gmail.com; Leigh; PHP Internals List > Subject: Re: [PHP-DEV] [RFC] Scalar Type Hints v0.2 > > Hi Zeev, > > Whether or not they are in the majority, a very large portion of PHP > developers would prefer strict typing. In particular, the most vocal ones > would seem to. There are also a lot of PHP developers who would prefer > weak typing. Thus we have a problem: either approach to scalar hints will > upset a large portion of the community.
That's correct. As I said though, the source of the opposition is fundamentally different. The camp which opposes weak typing opposes it based on the idea that it doesn't behave in the way that would suit their needs. The camp which opposes strict typing - which incidentally includes most of the people who originally created the language - opposes it based on the assertion that it goes against the spirit of the language. That is equally true for the v0.2 proposal you've just submitted.
> > How do you deduce that 'nobody uses them' from the fact that some > > group of people said they won't? I'm sorry, but it makes no sense, > > especially given the positive feedback you saw on internals, making it > > clear that there would be in fact people using it. > > Not all of it was positive. Sure, a lot of people would use them though, > but > I’ve heard quite a few developers say they wouldn’t use them and continue > to use manual (!is_int($foo))-style assertions.
Of course not all of it was positive, but it was overwhelmingly positive. Very few opposed. Someone saying they won't use it doesn't count as opposition. You see, PHP exists for 15-20 years now. There aren't any must-have features that aren't in it. No single feature we add will be used by everyone, and people telling us they won't use this feature shouldn't 'deter' us in any way.
> > If there's one thing that's worse than introducing an alien concept > > like strict typing into PHP, it's introducing it as a feature that > > will include all the negatives of this alien concept, PLUS have the > > ability to radically change how it behaves based on a runtime option. > > This isn’t a runtime option, it is entirely compile-time. Much like > namespaces > are not a runtime option. There isn’t even the ability to toggle it at > runtime, > unless we somehow add some ability to edit the flags on individual > opcodes.
Compile time and runtime in PHP are intertwined when you factor in cross-file interaction. Zeev

Mike Willbanks

11 years ago
Hello Andrea, On Thu, Jan 15, 2015 at 8:09 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Zeev, > > > On 15 Jan 2015, at 11:56, Zeev Suraski <zeev@zend.com> wrote: > > > > Andrea, > > > > I'm not sure what you're basing that assumption on. The incidental > > interactions you (or anybody) may have with 'the community', by no way > > represent the opinion of the community at large. The vast majority of > the > > PHP community never ever interacts with internals@, never attend > > conferences, don't write blog posts about PHP and are generally > completely > > 'under the radar'. I would actually go to argue that the people who do > > attend conferences, participate on internals@ or write blog posts - are > not > > representative of the PHP userbase at large. The vast majority of > > developers I bump into - you will never ever hear from. They constitute > the > > vast majority of the ~5M strong PHP developer base. > > > > So even though my belief / educated guess is that the vast majority of > the > > PHP userbase would prefer to see strict typing kept off this language, > I'm > > not going to argue that - but we must not argue the opposite either, > based > > on the non-representative anecdotal data from a few dozen people. > > Whether or not they are in the majority, a very large portion of PHP > developers would prefer strict typing. In particular, the most vocal ones > would seem to. There are also a lot of PHP developers who would prefer weak > typing. Thus we have a problem: either approach to scalar hints will upset > a large portion of the community. >
I actually quite disagree with that statement. Both as a library/framework developer and a user land developer I find strict typing to be more of an issue. For instance: function foo(int $foo) foo('23'); This would be a pain and cause constant glue from userland: Option A: Force Cast aka (int) '23' Option B: Check for digits via ctype_digits then force cast etc. To provide more of a point here, variables coming from HTTP are always a string, this makes strict casting a troubling item, considering that the main way of fetching input is coming from the web specifically. I'm certain this would also affect other areas as well such as reading csv files and more. To me this point alone makes a vastly strong statement against strict typing and as such, it would make life far more difficult for library developers and user land developers alike.
> > > > >> Myself, I might have been somewhat happy with just weak hints, but > >> it would upset an awful lot of developers who would like some measure of > >> strict typing. Developers who would most likely not use the new scalar > >> type > >> hints, because they weren’t strict. And if nobody uses them, why add > them? > > > > How do you deduce that 'nobody uses them' from the fact that some group > of > > people said they won't? I'm sorry, but it makes no sense, especially > given > > the positive feedback you saw on internals, making it clear that there > would > > be in fact people using it. > > Not all of it was positive. Sure, a lot of people would use them though, > but I’ve heard quite a few developers say they wouldn’t use them and > continue to use manual (!is_int($foo))-style assertions. > > > If there's one thing that's worse than introducing an alien concept like > > strict typing into PHP, it's introducing it as a feature that will > include > > all the negatives of this alien concept, PLUS have the ability to > radically > > change how it behaves based on a runtime option. > > This isn’t a runtime option, it is entirely compile-time. Much like > namespaces are not a runtime option. There isn’t even the ability to toggle > it at runtime, unless we somehow add some ability to edit the flags on > individual opcodes. >
I agree with the others in that declarative syntax to change it is a bad idea. It actually reminds me of ECMAScript 5's "use strict" ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) condition. Changing the definition based on user land scripts can lead to bugs and inconsistencies in a library developers purpose of a package and cause bad conditions. It also means that then a library developer would need to handle conditions on both sides (when in weak vs. strict). So I don't really understand where the gains of this would come from and it actually causes me concern in that what if a developer forgets to define strict and you're entire system is built on strict. Regards, Mike

Stas Malyshev

11 years ago
Hi!
> We’re definitely not going to have consensus on introducing both options as > per this RFC. I for one think it’s the worst possible option.
I agree. Being wrong is bad, making a mistake is bad, but having split personality language and not knowing in which world you are - or even worse, having to deal with both worlds in the same code and being thrown back and forth between them by some little switch which is easy to miss - IMO is worse. I don't like strict typing in PHP because I think it is contrary to the idea of how dynamic languages should work, but I'd rather have that then two sets of rules living within the same code, especially when looking at the function I can't even know how it would work without checking if there's a declare hiding somewhere. And refactoring becomes a nightmare - what if I moved function from strict world to non-strict world or vice versa? I also agree with Dmitry in other thread - if some conv rules are so bad everybody hates them (or at least you think it is the case :), we can change them. We are already on that track with some weird ones like array->string. Even with BC effects, IMO better than too many sets of rules.
-- Stas Malyshev smalyshev@gmail.com

Andrew Faulds

11 years ago
Hi Stas,
> On 14 Jan 2015, at 23:29, Stanislav Malyshev <smalyshev@gmail.com> wrote: > > I agree. Being wrong is bad, making a mistake is bad, but having split > personality language and not knowing in which world you are - or even > worse, having to deal with both worlds in the same code and being thrown > back and forth between them by some little switch which is easy to miss > - IMO is worse. I don't like strict typing in PHP because I think it is > contrary to the idea of how dynamic languages should work, but I'd > rather have that then two sets of rules living within the same code, > especially when looking at the function I can't even know how it would > work without checking if there's a declare hiding somewhere. And > refactoring becomes a nightmare - what if I moved function from strict > world to non-strict world or vice versa?
It’s not about the location of the function, but the call site. You can place a function anywhere and it will behave identically.
> I also agree with Dmitry in other thread - if some conv rules are so bad > everybody hates them (or at least you think it is the case :), we can > change them. We are already on that track with some weird ones like > array->string. Even with BC effects, IMO better than too many sets of > rules.
There are some minor issues with the conversion rules that could be fixed, but a lot of people have a problem not just with the conversion rules, but with the implicit conversion itself. The previous RFC (Scalar Type Hinting with Casts) wasn’t popular with many people for that reason: sure, it had stricter rules, but that won’t please people who want no conversion whatsoever. Thanks.
-- Andrea Faulds http://ajf.me/

Thomas Nunninger

11 years ago
Hi, On 01/14/2015 10:32 AM, Andrea Faulds wrote:
> Hi Leigh, > >> On 14 Jan 2015, at 09:17, Leigh <leight@gmail.com> wrote: >> >> I really don't like this behaviour being changed at the call site. If >> I design a function that I _know_ should only take a string, then I >> want it to be an error if the user supplies anything else, so that >> they know they messed up. > > I don’t like the idea of being forced to use strict (or weak) type checking because the API author decided as much.
What happens with that code: ---------------- $i = 1; $a = myFunc( $i ); declare(strict_typehints=TRUE); function myFunc( float $f ) { return otherFunc( $f ); } function otherFunc( float $f ) { ... } ---------------- As author of strict code I need to replace return otherFunc( $f ); by return otherFunc( (float) $f ); I'm not sure - if this is what a strict coder wants and - if you find an acceptable way to test your strict code if it works with non-strict code. Regards Thomas

Andrew Faulds

11 years ago
Hi Thomas,
> On 14 Jan 2015, at 10:08, Thomas Nunninger <thomas@nunninger.info> wrote: > > ---------------- > $i = 1; > $a = myFunc( $i ); > > declare(strict_typehints=TRUE); > > function myFunc( float $f ) > { > return otherFunc( $f ); > } > > function otherFunc( float $f ) > { > ... > } > ---------------- > > As author of strict code I need to replace > > return otherFunc( $f ); > > by > > return otherFunc( (float) $f ); > > > I'm not sure > > - if this is what a strict coder wants and > > - if you find an acceptable way to test your strict code if it works with non-strict code.
I don’t understand, I’m sorry. If you are using declare(strict_typehints=TRUE); then all calls in a file are “strict”. If you are not, all calls in a file are “weak”.
-- Andrea Faulds http://ajf.me/

Thomas Nunninger

11 years ago
Hi Andrea, On 01/14/2015 11:20 AM, Andrea Faulds wrote:
> Hi Thomas, > >> On 14 Jan 2015, at 10:08, Thomas Nunninger <thomas@nunninger.info> wrote: >> >> ---------------- >> $i = 1; >> $a = myFunc( $i ); >> >> declare(strict_typehints=TRUE); >> >> function myFunc( float $f ) >> { >> return otherFunc( $f ); >> } >> >> function otherFunc( float $f ) >> { >> ... >> } >> ---------------- >> >> As author of strict code I need to replace >> >> return otherFunc( $f ); >> >> by >> >> return otherFunc( (float) $f ); >> >> >> I'm not sure >> >> - if this is what a strict coder wants and >> >> - if you find an acceptable way to test your strict code if it works with non-strict code. > > I don’t understand, I’m sorry. > > If you are using declare(strict_typehints=TRUE); then all calls in a file are “strict”. If you are not, all calls in a file are “weak”.
Sorry, if my mail was not clear. My point was: If I write a library in strict mode and someone else is using it from his non-strict mode, he can pass an integer to myFunc() without an error. If I use this integer in my library and hand it over to otherFunc() (in my library) this will fail as integer is not accepted for float. Or did I misunderstood the RFC and there is a casting of the integer to a float when calling myFunc()? Regards Thomas

Andrew Faulds

11 years ago
Hi Thomas,
> On 14 Jan 2015, at 13:04, Thomas Nunninger <thomas@nunninger.info> wrote: > > Sorry, if my mail was not clear. My point was: If I write a library in strict mode and someone else is using it from his non-strict mode, he can pass an integer to myFunc() without an error. If I use this integer in my library and hand it over to otherFunc() (in my library) this will fail as integer is not accepted for float. > > Or did I misunderstood the RFC and there is a casting of the integer to a float when calling myFunc()?
The value would be casted, yes. From the function author’s perspective, there’s no need to worry about strict vs. weak typing: in both cases, you get the type you asked for. Thanks.
-- Andrea Faulds http://ajf.me/

Rowan Collins

11 years ago
Andrea Faulds wrote on 14/01/2015 13:15:
> Hi Thomas, > >> On 14 Jan 2015, at 13:04, Thomas Nunninger <thomas@nunninger.info> wrote: >> >> Sorry, if my mail was not clear. My point was: If I write a library in strict mode and someone else is using it from his non-strict mode, he can pass an integer to myFunc() without an error. If I use this integer in my library and hand it over to otherFunc() (in my library) this will fail as integer is not accepted for float. >> >> Or did I misunderstood the RFC and there is a casting of the integer to a float when calling myFunc()? > The value would be casted, yes. From the function author’s perspective, there’s no need to worry about strict vs. weak typing: in both cases, you get the type you asked for. >
Perhaps it would be clearer if the RFC (and the documentation, if this is accepted) referred to the non-strict as something other than "weak". It makes it sound like only a weak check will be performed, and some values of the "wrong" type will be allowed through, when in reality you will always get exactly the type asked for. Maybe "coercive type-checking" would more accurately reflect the functionality? Regards,
-- Rowan Collins [IMSoP]

Andrew Faulds

11 years ago
Hi Rowan,
> On 14 Jan 2015, at 15:45, Rowan Collins <rowan.collins@gmail.com> wrote: > > Perhaps it would be clearer if the RFC (and the documentation, if this is accepted) referred to the non-strict as something other than "weak". It makes it sound like only a weak check will be performed, and some values of the "wrong" type will be allowed through, when in reality you will always get exactly the type asked for. > > Maybe "coercive type-checking" would more accurately reflect the functionality?
Yeah, that’s an issue I’m aware of, “type checking" would suggest it merely “checks”, but it actually has the same implicit conversion behaviour used by extension and built-in PHP functions. I’m not sure what to call it. I don’t really think “coercive type-checking” is particularly better. Anyone who has a suggestion for a name, please feel free to offer it. Thanks.
-- Andrea Faulds http://ajf.me/

Julien Pauli

11 years ago
On Wed, Jan 14, 2015 at 1:16 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Good evening, > > I’ve made some quite significant changes to my Scalar Type Hints RFC, and > bumped its version to 0.2. > > Here: https://wiki.php.net/rfc/scalar_type_hints > > This is a new thread because I’ve made a significant revision to the RFC, > so it’d be sensible to separate discussion of the updated RFC from the v0.1 > RFC. > > Please tell me your thoughts. > > Thanks! > -- > Andrea Faulds > http://ajf.me/
Hello, Using declare() IMO, is a PITA. Everything that can be done without the use of declare(), must be done without declare(). I would have prefered different syntax, like the ones we disccussed many years ago , having strict checks with the foo(string $a) syntax, and non-strict check with the foo((string) $a) syntax. Julien.P

Andrew Faulds

11 years ago
Hi Julien,
> On 14 Jan 2015, at 10:14, Julien Pauli <jpauli@php.net> wrote: > > Using declare() IMO, is a PITA. > Everything that can be done without the use of declare(), must be done without declare(). > > I would have prefered different syntax, like the ones we disccussed many years ago , having strict checks with the foo(string $a) syntax, and non-strict check with the foo((string) $a) syntax.
Actually, this approach came about mostly to avoid that. I don’t really like the idea of mixing and matching weak and strict type checks. Having some functions using (int) and (string), others use int and string, and others still use both, would be confusing. Plus, it would mean that you’d be forced to follow the personal preference of the API authors. With this RFC, yes, you have to put an extra line at the top of the file. But it has the advantage that everything follows the same behaviour, even extension/built-in functions. That’s what I like about it.
-- Andrea Faulds http://ajf.me/

Andrey Andreev

11 years ago
Hello, On Wed, Jan 14, 2015 at 12:22 PM, Andrea Faulds <ajf@ajf.me> wrote:
> > Hi Julien, > >> On 14 Jan 2015, at 10:14, Julien Pauli <jpauli@php.net> wrote: >> >> Using declare() IMO, is a PITA. >> Everything that can be done without the use of declare(), must be done without declare(). >> >> I would have prefered different syntax, like the ones we disccussed many years ago , having strict checks with the foo(string $a) syntax, and non-strict check with the foo((string) $a) syntax. > > Actually, this approach came about mostly to avoid that. I don’t really like the idea of mixing and matching weak and strict type checks. Having some functions using (int) and (string), others use int and string, and others still use both, would be confusing. Plus, it would mean that you’d be forced to follow the personal preference of the API authors. > > With this RFC, yes, you have to put an extra line at the top of the file. But it has the advantage that everything follows the same behaviour, even extension/built-in functions. That’s what I like about it.
I don't understand why it should be a bad thing that the API author forces rules on the consumer. The opposite is IMO fundamental to the concept of an API - the rules specified by the author are a contract that the consumer agrees to, and which allows for the whole thing to work properly. In this form, I don't get any benefit from strict type checks, because I only want them so that writing foo(int $bar) guarantees me that the caller *passed* an integer. Instead, I'd have to NOT use a type hint, and instead do an is_int($bar) check inside ... this beats the whole purpose. This caller-controlled switch very much reminds me of mbstring.func_overload, which I didn't care much for, until one day I saw how it breaks all crypto code that authors had otherwise written very carefully. I prefer Julien's (int) $weak vs. int $strong syntax better (which is what I've always wanted), but I don't care much if it's a declare() statement, just as long as the author controls the behavior. And while I'm on that - thank you for this proposal (specifically the 0.2 version), Andrea. Finally an RFC that allows both weak and strict scalar type checks instead of the "can't go in both directions" nonsense that has blocked this feature for years. Cheers, Andrey.

Andrew Faulds

11 years ago
Hi Andrey,
> On 14 Jan 2015, at 11:10, Andrey Andreev <narf@devilix.net> wrote: > > I don't understand why it should be a bad thing that the API author > forces rules on the consumer. The opposite is IMO fundamental to the > concept of an API - the rules specified by the author are a contract > that the consumer agrees to, and which allows for the whole thing to > work properly. > > In this form, I don't get any benefit from strict type checks, because > I only want them so that writing foo(int $bar) guarantees me that the > caller *passed* an integer. Instead, I'd have to NOT use a type hint, > and instead do an is_int($bar) check inside ... this beats the whole > purpose.
Why? What is wrong with a caller choosing to use weak type hints? Either way you receive an integer.
> This caller-controlled switch very much reminds me of > mbstring.func_overload, which I didn't care much for, until one day I > saw how it breaks all crypto code that authors had otherwise written > very carefully. > > I prefer Julien's (int) $weak vs. int $strong syntax better (which is > what I've always wanted), but I don't care much if it's a declare() > statement, just as long as the author controls the behavior. > And while I'm on that - thank you for this proposal (specifically the > 0.2 version), Andrea. Finally an RFC that allows both weak and strict > scalar type checks instead of the "can't go in both directions" > nonsense that has blocked this feature for years.
I don’t like going in both directions if I’ll have to deal with both at the same time. I want consistency. Either everything weak or everything strict. That’s why I like this approach. At least within a single file, everything will follow the same approach, rather than it being mix-and-match.
-- Andrea Faulds http://ajf.me/

Andrey Andreev

11 years ago
Hi again, On Wed, Jan 14, 2015 at 1:21 PM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Andrey, > >> On 14 Jan 2015, at 11:10, Andrey Andreev <narf@devilix.net> wrote: >> >> I don't understand why it should be a bad thing that the API author >> forces rules on the consumer. The opposite is IMO fundamental to the >> concept of an API - the rules specified by the author are a contract >> that the consumer agrees to, and which allows for the whole thing to >> work properly. >> >> In this form, I don't get any benefit from strict type checks, because >> I only want them so that writing foo(int $bar) guarantees me that the >> caller *passed* an integer. Instead, I'd have to NOT use a type hint, >> and instead do an is_int($bar) check inside ... this beats the whole >> purpose. > > Why? What is wrong with a caller choosing to use weak type hints? Either way you receive an integer.
Because it's pointless. Why would I want strict checks if I only cared for getting an integer? The whole point is that I care for what the caller passed, that I want specifically a check instead of a cast. Cheers, Andrey.

Marc Bennewitz

11 years ago
Hi Andrea, I have some notes about this RFC from a users POV with only little knowledge about internals. I didn't read 100% of the theads of this RFC so I'm sorry if some notes of this email was already discussed. 1. Inconsistencies of ZPP and explicit casts In my opinion it should be the same if you call a function in weak type mode and calling a function in strict type mode with explicit cast. But that would require to remove inconsistencies of ZPP and explicit casts. 2. Only one choice for the language In my opinion scalar types should be hinted strict and the caller of an API have to be sure to pass the right types. The caller have to know about the function he calls and he already should know what the function expects. This is the point were the caller have to know the type of an expected argument and he should know his own types. So he is the one how can pass the variable or make an explicit type cast. To do so see [1] 3. Reserved words I don't like it adding so much reserved words. As I understand it correctly the reservation is because of naming collisions on type-hints with scalars and classes/interfaces. Why not adding these types as classes (marked final and not allowed to be initialized for know)? Than you can use the already existing standards of classes as type-hints. This would allow you using your own class of a different namespace with the same name and would reduce BC break drastically. The only consequence would be that you have to reference the root namespace or import (use) the classes of the root namespace to use the type-hints. As sugar it should be possible to use inheritance and polymorphism to better hint what you really need. E.g.: class Integer extends Scalar implements Numeric 4. Only one naming I dislike the proposed aliases. The type names should be defined once without aliases and the manual and error massages should be changed to be consistent. Because of PHP internally already allows different names this should persist to be BC safe but should be reviewed and documented what is the real type name and what are aliases. The aliases could be deprecated in another RFC. Btw. The type float is used also as double and real. I don't see if these aliases are supported in your RFC or not. Marc Am 14.01.2015 um 01:16 schrieb Andrea Faulds:

Andrew Faulds

11 years ago
Hi Marc,
> On 14 Jan 2015, at 19:01, Marc Bennewitz <dev@mabe.berlin> wrote: > > 1. Inconsistencies of ZPP and explicit casts > > In my opinion it should be the same if you call a function in weak type mode and calling a function in strict type mode with explicit cast. > > But that would require to remove inconsistencies of ZPP and explicit casts.
Explicit casts and implicit casts have different behaviour, and that is definitely a good thing. Implicit casts can and should fail if the conversion isn’t sensible. Explicit casts aren’t supposed to fail.
> 2. Only one choice for the language > > In my opinion scalar types should be hinted strict and the caller of an API have to be sure to pass the right types. The caller have to know about the function he calls and he already should know what the function expects. This is the point were the caller have to know the type of an expected argument and he should know his own types. So he is the one how can pass the variable or make an explicit type cast.
This is all very well and good, and strict typing has its advantages, but there are a lot of people who do *not* want to have to deal with a strictly-typed API.
> 3. Reserved words > > I don't like it adding so much reserved words.
This doesn’t add any reserved words. It prevents the usage of some names for class names.
> As I understand it correctly the reservation is because of naming collisions on type-hints with scalars and classes/interfaces. > > Why not adding these types as classes (marked final and not allowed to be initialized for know)?
Because then you’d have to do this at the top of every single file: use php\typehint\int; use php\typehint\float; use php\typehint\string; use php\typehint\bool; Considering how much people seem to dislike the idea of using declare() for strict typing, I can see how poorly that would go down. More importantly, this would be inconsistent with our existing type hints like array and callable.
> 4. Only one naming > > I dislike the proposed aliases. The type names should be defined once without aliases and the manual and error massages should be changed to be consistent.
In an ideal world we would only have the short or long form, sure. But this isn’t an ideal world, and PHP doesn’t have compile-time validation of type hints. It would be too easy to write foo(integer $bar) and miss that it is broken if the function isn’t called. I don’t think having both int and integer is really a problem. It’s not going to cause confusion, they are obviously the same type. Coding style guides will mandate one or the other. Thanks.
-- Andrea Faulds http://ajf.me/

Marc Bennewitz

11 years ago
Am 14.01.2015 um 23:39 schrieb Andrea Faulds:
> Hi Marc, > >> On 14 Jan 2015, at 19:01, Marc Bennewitz <dev@mabe.berlin> wrote: >> >> 1. Inconsistencies of ZPP and explicit casts >> >> In my opinion it should be the same if you call a function in weak type mode and calling a function in strict type mode with explicit cast. >> >> But that would require to remove inconsistencies of ZPP and explicit casts. > Explicit casts and implicit casts have different behaviour, and that is definitely a good thing. Implicit casts can and should fail if the conversion isn’t sensible. Explicit casts aren’t supposed to fail.
That's a big problem for the strict type mode because of you have to explicit cast to pass function signature which would result in a much unsafer behavior were you originally wont a strict behavior. The only way to be safe would be to use extra function calls for casting.
> >> 2. Only one choice for the language >> >> In my opinion scalar types should be hinted strict and the caller of an API have to be sure to pass the right types. The caller have to know about the function he calls and he already should know what the function expects. This is the point were the caller have to know the type of an expected argument and he should know his own types. So he is the one how can pass the variable or make an explicit type cast. > This is all very well and good, and strict typing has its advantages, but there are a lot of people who do *not* want to have to deal with a strictly-typed API.
It's only a personal feeling for scrict typing but it requires casting to be fixed. But I have to agree with that casting is part of the caller with or without this choice. The library author only defines the type he requires but the caller is the one have have to do so. Week typing in this case only helps the caller to automatically cast.
> >> 3. Reserved words >> >> I don't like it adding so much reserved words. > This doesn’t add any reserved words. It prevents the usage of some names for class names.
Preventing usage of some names means the same as reserved names at least in the contest of class names.
> >> As I understand it correctly the reservation is because of naming collisions on type-hints with scalars and classes/interfaces. >> >> Why not adding these types as classes (marked final and not allowed to be initialized for now)? > Because then you’d have to do this at the top of every single file: > > use php\typehint\int; > use php\typehint\float; > use php\typehint\string; > use php\typehint\bool; > > Considering how much people seem to dislike the idea of using declare() for strict typing, I can see how poorly that would go down.
Such types should be on the root namespace. So the only difference would be a backslash and only if you are within a namespace. And to reaped myself you can do vary useful: // internal pseudo code class Scalar {} interface Numeric {} class Integer extends Scalar implements Numeric {} class Float extends Scalar implements Numeric {} class String extends Scalar {} class Array implements Traversable {} // users code function increment(numeric $num) { return $num + 1; } function incrementInt(integer $int) { return $int + 1; } function incrementFloat(float $float) { return $float + 1; } // in namespace function increment(\numeric $num) { return $num + 1; } function incrementInt(\integer $int) { return $int + 1; } function incrementFloat(\float $float) { return $float + 1; }
> More importantly, this would be inconsistent with our existing type hints like array and callable.
It would only be inconsistent if you don't think it through end but sure it's more work. I have no idea how much. On calling a function in week mode one or more magic methods could be used to add auto cast behavior like: public function __toInt(); public function __toFloat(); public function __toString(); // it will be called already public function __toArray(); // Not part of this RFC public function __toInstanceOf($name); // Will be called if no one of the other pass
>> 4. Only one naming >> >> I dislike the proposed aliases. The type names should be defined once without aliases and the manual and error massages should be changed to be consistent. > In an ideal world we would only have the short or long form, sure. But this isn’t an ideal world, and PHP doesn’t have compile-time validation of type hints. It would be too easy to write foo(integer $bar) and miss that it is broken if the function isn’t called.
Please let us make PHP more ideal ;) Your argument is nonsense. As long as you never test your (unittest or manual) you can't be sure to work well. The same argument could pass for current type-hinting. If that argument is serious you have to eg. automatically fix type errors in class names. Btw. IDEs already warn if you use something undeclared project wide.
> I don’t think having both int and integer is really a problem. It’s not going to cause confusion, they are obviously the same type. Coding style guides will mandate one or the other.
What about double and real?
> Thanks. > -- > Andrea Faulds > http://ajf.me/ >
Thanks Marc

Dmitry Stogov

11 years ago
In my opinion, version 0.1 was consistent enough. handling two different approaches just makes mess... We have internal function strlen(string $s), and it may be called with integer argument e.g. strlen(123) -> 3 I think user functions should follow the same rules. If some rules are "bad", lets change that rules for both internal and user functions. But it's better to do it in a separate RFC (after scalar type hinting 0.1 accepted), or we will stick forever. Thanks. Dmitry. On Wed, Jan 14, 2015 at 3:16 AM, Andrea Faulds <ajf@ajf.me> wrote:

Andrew Faulds

11 years ago
Hey Dmitry,
> On 14 Jan 2015, at 20:40, Dmitry Stogov <dmitry@zend.com> wrote: > > In my opinion, version 0.1 was consistent enough. > > handling two different approaches just makes mess... > > We have internal function strlen(string $s), and it may be called with integer argument e.g. strlen(123) -> 3 > I think user functions should follow the same rules.
This RFC does that. In the “weak” mode that would continue work, and it would also for userland functions with scalar type hints. In the “strict” mode that would break, and it would also break for a similar userland function with a scalar type hint.
> > If some rules are "bad", lets change that rules for both internal and user functions. > But it's better to do it in a separate RFC (after scalar type hinting 0.1 accepted), or we will stick forever.
I’m not sure the weak typing approach to function parameters is bad per se, but a lot of developers would certainly prefer the strict typing approach. That’s why the RFC allows choice: for all the people that weak typing works for, good, you can keep using that. The people who want strict typing get strict typing without forcing the people who want weak typing to use it. Thanks.
-- Andrea Faulds http://ajf.me/

Laruence

11 years ago
Hey: On Thu, Jan 15, 2015 at 6:42 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Hey Dmitry, > >> On 14 Jan 2015, at 20:40, Dmitry Stogov <dmitry@zend.com> wrote: >> >> In my opinion, version 0.1 was consistent enough. >> >> handling two different approaches just makes mess... >> >> We have internal function strlen(string $s), and it may be called with integer argument e.g. strlen(123) -> 3 >> I think user functions should follow the same rules. > > This RFC does that. In the “weak” mode that would continue work, and it would also for userland functions with scalar type hints. In the “strict” mode that would break, and it would also break for a similar userland function with a scalar type hint.
sounds like a hell to me..... sorry for saying that, but I don't like the whole "declare" thing... could we please strict to v0.1, only make it first ? thanks
> >> >> If some rules are "bad", lets change that rules for both internal and user functions. >> But it's better to do it in a separate RFC (after scalar type hinting 0.1 accepted), or we will stick forever. > > I’m not sure the weak typing approach to function parameters is bad per se, but a lot of developers would certainly prefer the strict typing approach. That’s why the RFC allows choice: for all the people that weak typing works for, good, you can keep using that. The people who want strict typing get strict typing without forcing the people who want weak typing to use it. > > Thanks. > -- > Andrea Faulds > http://ajf.me/ > > > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
-- Xinchen Hui @Laruence http://www.laruence.com/

Pierre Joye

11 years ago
hi Andrea, On Wed, Jan 14, 2015 at 1:16 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Good evening, > > I’ve made some quite significant changes to my Scalar Type Hints RFC, and bumped its version to 0.2. > > Here: https://wiki.php.net/rfc/scalar_type_hints > > This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the updated RFC from the v0.1 RFC. > > Please tell me your thoughts.
As much as I like the concept, it adds a bit too much confusions and options for my taste. My feeling (as you and other said already many many times), a relatively large part of the users would prefer strict type hinting over something that relies on the current conversion behaviors, for clarity. There are still some people opposed to strict hinting or opposed to hinting but that was pretty much the same when we discussed the additions of OO related features. Instead of having one option full of compromises, I would suggest to go with the 0.1 version with two options, strict and matching the current conversions behaviors and move on. No matter how we look at it, there is no way we can find compromises between one or the other solution. It is only about strict or current conversions, everything else is going to be an endless discussion about the exact same arguments, pros, cons, etc. Cheers,
-- Pierre @pierrejoye | http://www.libgd.org

Jordi Boggiano

11 years ago
On 14/01/2015 00:16, Andrea Faulds wrote:
> Here: https://wiki.php.net/rfc/scalar_type_hints > > This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the updated RFC from the v0.1 RFC.
Reading the thread at this point shows so much confusion, it seems half the people reading the spec misunderstood that the declare() line affects function calls only and not the API/implementation level. As much I think it was a smart idea and workaround, it is perhaps too clever for its own good if nobody gets it. Anyway, as v0.2 appears to be v0.1 + declare(), why not keep those two options separated in the vote? a) should be add weak typing b) should we also add declare() for to get strict typing at call-site. If *a* passes it would be a great stepping stone towards adding *b* later perhaps, or tweaking internal coercion rules to improve the behavior of the weak types, having scalars in return hints (since return hints seem likely to pass), etc. If *b* passes as well great we have a complete picture and every team can have declare() Y/N in their own coding guidelines based on preference. Cheers
-- Jordi Boggiano @seldaek - http://nelm.io/jordi

Pavel Kouřil

11 years ago
On Thu, Jan 15, 2015 at 4:11 PM, Jordi Boggiano <j.boggiano@seld.be> wrote:
> > Reading the thread at this point shows so much confusion, it seems half the > people reading the spec misunderstood that the declare() line affects > function calls only and not the API/implementation level. > > As much I think it was a smart idea and workaround, it is perhaps too clever > for its own good if nobody gets it. > > Anyway, as v0.2 appears to be v0.1 + declare(), why not keep those two > options separated in the vote? > > a) should be add weak typing > b) should we also add declare() for to get strict typing at call-site. > > If *a* passes it would be a great stepping stone towards adding *b* later > perhaps, or tweaking internal coercion rules to improve the behavior of the > weak types, having scalars in return hints (since return hints seem likely > to pass), etc. > > If *b* passes as well great we have a complete picture and every team can > have declare() Y/N in their own coding guidelines based on preference. >
Yeah, while the confusion is definitely still there, I would personally argue that definitely some people who oppose the declare() get that it's only for calls in the file - and still don't find it clever. The potential issues with this are pretty real, to be honest. Simple things like moving a method from one class to another (let's say to parent or descendant) and getting to another typing context may cause unpredictable behavior if the user forgets to have declare() in both files. Pavel Kouril

Benjamin Eberlei

11 years ago
On Thu, Jan 15, 2015 at 4:25 PM, Pavel Kouřil <pajousek@gmail.com> wrote:
> On Thu, Jan 15, 2015 at 4:11 PM, Jordi Boggiano <j.boggiano@seld.be> > wrote: > > > > Reading the thread at this point shows so much confusion, it seems half > the > > people reading the spec misunderstood that the declare() line affects > > function calls only and not the API/implementation level. > > > > As much I think it was a smart idea and workaround, it is perhaps too > clever > > for its own good if nobody gets it. > > > > Anyway, as v0.2 appears to be v0.1 + declare(), why not keep those two > > options separated in the vote? > > > > a) should be add weak typing > > b) should we also add declare() for to get strict typing at call-site. > > > > If *a* passes it would be a great stepping stone towards adding *b* later > > perhaps, or tweaking internal coercion rules to improve the behavior of > the > > weak types, having scalars in return hints (since return hints seem > likely > > to pass), etc. > > > > If *b* passes as well great we have a complete picture and every team can > > have declare() Y/N in their own coding guidelines based on preference. > > > > Yeah, while the confusion is definitely still there, I would > personally argue that definitely some people who oppose the declare() > get that it's only for calls in the file - and still don't find it > clever. > > The potential issues with this are pretty real, to be honest. Simple > things like moving a method from one class to another (let's say to > parent or descendant) and getting to another typing context may cause > unpredictable behavior if the user forgets to have declare() in both > files. >
This alone is a very big argument against it imho. Next argument would be using different libraries in one file and wanting one of them to be strict the other not. I get the idea following something like "use strict;" approaches of Perl/Javascript, however AFAIK they only affect the file itself, not calls from the file to another one.

Jordi Boggiano

11 years ago
On 15/01/2015 15:30, Benjamin Eberlei wrote:
> The potential issues with this are pretty real, to be honest. Simple > things like moving a method from one class to another (let's say to > parent or descendant) and getting to another typing context may cause > unpredictable behavior if the user forgets to have declare() in both > files. > > > This alone is a very big argument against it imho. Next argument > would be using different libraries in one file and wanting one of them > to be strict the other not.
If you want both you can just use the non-strict default and do type checks yourself where you see fit. If you had strict typing only or weak only you anyway could not choose which library should be strict, each library would decide for you. Cheers
-- Jordi Boggiano @seldaek - http://nelm.io/jordi

Jordi Boggiano

11 years ago
On 15/01/2015 15:25, Pavel Kouřil wrote:
> The potential issues with this are pretty real, to be honest. Simple > things like moving a method from one class to another (let's say to > parent or descendant) and getting to another typing context may cause > unpredictable behavior if the user forgets to have declare() in both > files.
Agreed there are gotchas but not only with declare(). Many things can go wrong when you move a function somewhere else, for example you might leave `use` statements behind and suddenly a `catch (FooException $e)` will fail to match exceptions or something sneaky like that. I don't necessarily think that's enough to kill the feature. Note that you can only get problems going from weak to strict context by the way, the other way around should not cause any issues, code would just work when it otherwise would have triggered strict errors. Since you usually move code into places you own, I'd assume you know it if you are using strict typing. Cheers
-- Jordi Boggiano @seldaek - http://nelm.io/jordi

Andrew Faulds

11 years ago
Hi Pavel,
> On 15 Jan 2015, at 15:25, Pavel Kouřil <pajousek@gmail.com> wrote: > > On Thu, Jan 15, 2015 at 4:11 PM, Jordi Boggiano <j.boggiano@seld.be> wrote: >> >> Reading the thread at this point shows so much confusion, it seems half the >> people reading the spec misunderstood that the declare() line affects >> function calls only and not the API/implementation level. > > Yeah, while the confusion is definitely still there, I would > personally argue that definitely some people who oppose the declare() > get that it's only for calls in the file - and still don't find it > clever. > > The potential issues with this are pretty real, to be honest. Simple > things like moving a method from one class to another (let's say to > parent or descendant) and getting to another typing context may cause > unpredictable behavior if the user forgets to have declare() in both > files.
This is true, you would sometimes have problems if you’re mixing the strict and weak type checking modes in your codebase. The intention is that you’d use one or the other exclusively, perhaps with some minor exceptions as and where necessary. The fact it’s weak by default means you could add scalar type hints gradually without breaking things, because the weak mode is quite permissive. Then, if you wanted to, you could gradually migrate each file in your codebase over to strict mode. Essentially, you get “gradual typing” like Hack, but without Hack’s approach which I don’t particularly like. Hack’s approach is to simply not enforce type hints if they’re a problem. On the other hand, this RFC would alway enforces them, but the weak mode is less strict. So, I anticipate that while it would cause problems during a transition, I think codebases would end up using one mode or the other exclusively and wouldn’t have problems once they had done so. Thanks.
-- Andrea Faulds http://ajf.me/

Andrew Faulds

11 years ago
Hi Jordi,
> On 15 Jan 2015, at 15:11, Jordi Boggiano <j.boggiano@seld.be> wrote: > > On 14/01/2015 00:16, Andrea Faulds wrote: >> Here: https://wiki.php.net/rfc/scalar_type_hints >> >> This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the updated RFC from the v0.1 RFC. > > Reading the thread at this point shows so much confusion, it seems half the people reading the spec misunderstood that the declare() line affects function calls only and not the API/implementation level. > > As much I think it was a smart idea and workaround, it is perhaps too clever for its own good if nobody gets it. > > Anyway, as v0.2 appears to be v0.1 + declare(), why not keep those two options separated in the vote? > > a) should be add weak typing > b) should we also add declare() for to get strict typing at call-site. > > If *a* passes it would be a great stepping stone towards adding *b* later perhaps, or tweaking internal coercion rules to improve the behavior of the weak types, having scalars in return hints (since return hints seem likely to pass), etc. > > If *b* passes as well great we have a complete picture and every team can have declare() Y/N in their own coding guidelines based on preference.
I may consider another RFC that just does weak typing, or reviving v0.1 if this RFC doesn’t pass. But I’m not really sure about it. I’m not sure it’s fair on all the people who would prefer a strict approach.
-- Andrea Faulds http://ajf.me/

Derick Rethans

11 years ago
On Thu, 15 Jan 2015, Jordi Boggiano wrote:
> On 14/01/2015 00:16, Andrea Faulds wrote: > > Here: https://wiki.php.net/rfc/scalar_type_hints > > > > This is a new thread because I’ve made a significant revision to the RFC, so > > it’d be sensible to separate discussion of the updated RFC from the v0.1 > > RFC. > > Reading the thread at this point shows so much confusion, it seems half the > people reading the spec misunderstood that the declare() line affects function > calls only and not the API/implementation level. > > As much I think it was a smart idea and workaround, it is perhaps too clever > for its own good if nobody gets it. > > Anyway, as v0.2 appears to be v0.1 + declare(), why not keep those two options > separated in the vote? > > a) should be add weak typing > b) should we also add declare() for to get strict typing at call-site.
What about a : c) should we also add declare() for to get strict typing at *declaration-site*. It could be the author of a library deciding whether they prefer strict type "hints". But then again, it doesn't really matter as long as the library's method get the correct type I suppose. cheers, Derick

Dennis Birkholz

11 years ago
Hello together, I have followed the discussion from the outside (as I am not to vote here) but I am a (not representative) PHP developer. I think the main problem here is that you mix two things up: 1. Scalar type hints for functions 2. Conversion rules From what I have read, most of you agree that scalar type hints for functions are really useful. If you define function foo(int $i) you don't want is_int-checks and throw InvalidArgumentExceptions. The real controversy is about what variables can be passed to the type hinted functions. And that falls into 2) There seem to be two types of conversion currently present in the code: - the one used for arguments of build-in/extension functions max("1", 2.0); - the one used for implicit conversion in php code $i = "1" + 2.0; The discussion now revolves around: which of both conversions is right if I typehint my pure PHP function? Or are both wrong? I feel there should be a separate RFC that addresses a unification of implicit conversion rules and that matter should not be in the type hinting discussion. Thanks for listening, Dennis Birkholz

Matthew Leverton

11 years ago
On Tue, Jan 13, 2015 at 6:16 PM, Andrea Faulds <ajf@ajf.me> wrote:
> I’ve made some quite significant changes to my Scalar Type Hints RFC, and bumped its version to 0.2. > > Here: https://wiki.php.net/rfc/scalar_type_hints > > This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the updated RFC from the v0.1 RFC. > > Please tell me your thoughts. >
I don't like this at all. I'd prefer raising a new warning type (e.g., E_AUTOCAST) over this. Does the voting system support instant-runoffs? If people could rate their preferences of: 1) strict scalar types 2) weak scalar types (auto cast) 3) both - different syntaxes. e.g, (int) $foo vs int $foo 4) no scalar types we could reach a compromised consensus without some building Frankenstein. I really think having either basic strict or weak types is far preferred to nothing. There are good arguments on both sides ... let the voters decide. After that, additional RFCs could be created to address raising errors on auto case, using declares to toggle behavior, etc - depending of course on what was decided on prior vote.
-- Matthew Leverton

Andrew Faulds

11 years ago
Hi Matthew,
> On 15 Jan 2015, at 16:59, Matthew Leverton <leverton@gmail.com> wrote: > > I don't like this at all. I'd prefer raising a new warning type (e.g., > E_AUTOCAST) over this.
That error type would cause absolute chaos, unless people decided not to make use of it. Custom error handlers are global and affect all code, including in libraries. I can’t see how this would be even slightly useful.
> Does the voting system support instant-runoffs? If people could rate > their preferences of: > > 1) strict scalar types > 2) weak scalar types (auto cast) > 3) both - different syntaxes. e.g, (int) $foo vs int $foo > 4) no scalar types > > we could reach a compromised consensus without some building > Frankenstein.
I don’t think supporting both approaches is really a “Frankenstein”. It would work out quite cleanly in practice. I had considered holding multiple votes, but I decided against it. Thanks.
-- Andrea Faulds http://ajf.me/

Andrew Faulds

11 years ago
Good evening, The RFC has been updated to cover return types, since Levi’s Return Types RFC has passed. The patch is a work in progress: it works, but lacks tests for return types. Version 0.3 of the RFC can be found here: https://wiki.php.net/rfc/scalar_type_hints Thanks!
-- Andrea Faulds http://ajf.me/

Dmitry Stogov

11 years ago
As I already told, in my opinion, version 0.1 was the perfect solution that fit into PHP semantic very well. declare(strict_types=1); - is really weird solution. It changes type hinting behavior per file scope, so, just to try strict type hinting in a big project, people will have to change every single PHP file. From the RFC text, I didn't completely understand, if declare() affects call site or declaration. Will we able to call the same function using weak type hinting from on file and with strict from the other? "The strict type checking mode also affects extension and built-in PHP functions", sin(1) - error !!! Strict type hinting is not suitable for PHP by definition (as a weakly typed language), however, I see, it may be useful in some cases. I would prefer to have "weak" types at first, then think about introducing ability to switch to "strict" type hinting in context of use-cases. Thanks. Dmitry. On Mon, Feb 2, 2015 at 2:49 AM, Andrea Faulds <ajf@ajf.me> wrote:

Andrew Faulds

11 years ago
Hi Dmitry,
-- Andrea Faulds http://ajf.me/

Andrew Faulds

11 years ago
Hi Dmitry,
> On 2 Feb 2015, at 07:02, Dmitry Stogov <dmitry@zend.com> wrote: > > As I already told, in my opinion, version 0.1 was the perfect solution that > fit into PHP semantic very well.
I don't like the original. Weak types work to a degree, but they don't fulfill the use case of a lot of developers, and consequently the RFC wasn't too popular outside internals.
> declare(strict_types=1); - is really weird solution.
It is unusual, that is true. But it has some benefits.
> It changes type hinting behavior per file scope, so, just to try strict > type hinting in a big project, people will have to change every single PHP > file. > From the RFC text, I didn't completely understand, if declare() affects > call site or declaration.
Ah, my bad. It affects function calls and return statements within the declare block, or remainder of the file if there's no declare block. So parameter types are checked using the mode chosen by the calling code, while return types are checked using the mode chosen by the called code.
> Will we able to call the same function using weak > type hinting from on file and with strict from the other?
Yes, for the parameter type hints anyway. That means that strict and weak code is interoperable without enforcing a model on each other.
> "The strict type checking mode also affects extension and built-in PHP > functions", sin(1) - error !!!
That particular case is probably unpopular - although strict type hinting for ints and floats can prevent nastier errors later (float out of int range, or silent loss of precision from int to float).
> Strict type hinting is not suitable for PHP by definition (as a weakly > typed language), however, I see, it may be useful in some cases. > I would prefer to have "weak" types at first, then think about introducing > ability to switch to "strict" type hinting in context of use-cases.
That'd be possible, but I fear that we'd just end up with weak typing only and no strict solution. Regardless of its merits, a large portion of the community is in favour of a strictly-typed solution. There are also a lot of people who are in favour of weak typing. So, this RFC tries to make a compromise. Thanks.
-- Andrea Faulds http://ajf.me/

Andrey Andreev

11 years ago
Hi, On Mon, Feb 2, 2015 at 10:41 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Dmitry, > >> On 2 Feb 2015, at 07:02, Dmitry Stogov <dmitry@zend.com> wrote: >> >> As I already told, in my opinion, version 0.1 was the perfect solution that >> fit into PHP semantic very well. > > I don't like the original. Weak types work to a degree, but they don't fulfill the use case of a lot of developers, and consequently the RFC wasn't too popular outside internals. >
I still think that caller-controlled "strict mode" doesn't fulfill that use case either. Cheers, Andrey.

Andrew Faulds

11 years ago
Hi Andrey,
> On 2 Feb 2015, at 08:55, Andrey Andreev <narf@devilix.net> wrote: > > Hi, > >> On Mon, Feb 2, 2015 at 10:41 AM, Andrea Faulds <ajf@ajf.me> wrote: >> Hi Dmitry, >> >>> On 2 Feb 2015, at 07:02, Dmitry Stogov <dmitry@zend.com> wrote: >>> >>> As I already told, in my opinion, version 0.1 was the perfect solution that >>> fit into PHP semantic very well. >> >> I don't like the original. Weak types work to a degree, but they don't fulfill the use case of a lot of developers, and consequently the RFC wasn't too popular outside internals. > > I still think that caller-controlled "strict mode" doesn't fulfill > that use case either.
How doesn't it? It doesn't force the model upon your users, sure, but something like that is never going to get past internals anyway.
-- Andrea Faulds http://ajf.me/

Andrey Andreev

11 years ago
Hi Andrea, On Mon, Feb 2, 2015 at 11:05 AM, Andrea Faulds <ajf@ajf.me> wrote:
> > Hi Andrey, > >> On 2 Feb 2015, at 08:55, Andrey Andreev <narf@devilix.net> wrote: >> >> Hi, >> >>> On Mon, Feb 2, 2015 at 10:41 AM, Andrea Faulds <ajf@ajf.me> wrote: >>> Hi Dmitry, >>> >>>> On 2 Feb 2015, at 07:02, Dmitry Stogov <dmitry@zend.com> wrote: >>>> >>>> As I already told, in my opinion, version 0.1 was the perfect solution that >>>> fit into PHP semantic very well. >>> >>> I don't like the original. Weak types work to a degree, but they don't fulfill the use case of a lot of developers, and consequently the RFC wasn't too popular outside internals. >> >> I still think that caller-controlled "strict mode" doesn't fulfill >> that use case either. > > How doesn't it? It doesn't force the model upon your users, sure, but something like that is never going to get past internals anyway. >
We already had a long exchange of arguments on this, there's no point in repeating them. But if you're concerned about it getting approved by internals ... is there anybody on internals supporting this version of it? I might've missed a mail or two, but so far I've seen only criticism. Cheers, Andrey.

Dmitry Stogov

11 years ago
On Mon, Feb 2, 2015 at 11:41 AM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Dmitry, > > > On 2 Feb 2015, at 07:02, Dmitry Stogov <dmitry@zend.com> wrote: > > > > As I already told, in my opinion, version 0.1 was the perfect solution > that > > fit into PHP semantic very well. > > I don't like the original. Weak types work to a degree, but they don't > fulfill the use case of a lot of developers, and consequently the RFC > wasn't too popular outside internals. >
I sent a separate email to collect use-cases for strict typing. Please, answer there.
> > > declare(strict_types=1); - is really weird solution. > > It is unusual, that is true. But it has some benefits. > > > It changes type hinting behavior per file scope, so, just to try strict > > type hinting in a big project, people will have to change every single > PHP > > file. > > From the RFC text, I didn't completely understand, if declare() affects > > call site or declaration.ans > > Ah, my bad. It affects function calls and return statements within the > declare block, or remainder of the file if there's no declare block. So > parameter types are checked using the mode chosen by the calling code, > while return types are checked using the mode chosen by the called code. >
not your bad, it's exactly what I read, I just couldn't believe that.
> > > Will we able to call the same function using weak > > type hinting from on file and with strict from the other? > > Yes, for the parameter type hints anyway. That means that strict and weak > code is interoperable without enforcing a model on each other. >
At first I thought, this is ugly solution. Now I'm not completely sure.
> > > "The strict type checking mode also affects extension and built-in PHP > > functions", sin(1) - error !!! > > That particular case is probably unpopular - although strict type hinting > for ints and floats can prevent nastier errors later (float out of int > range, or silent loss of precision from int to float). >
I see, but this would require declare(strict_types=1) everywhere that would turn PHP into Java.
> Strict type hinting is not suitable for PHP by definition (as a weakly > > typed language), however, I see, it may be useful in some cases. > > I would prefer to have "weak" types at first, then think about > introducing > > ability to switch to "strict" type hinting in context of use-cases. > > That'd be possible, but I fear that we'd just end up with weak typing only > and no strict solution. Regardless of its merits, a large portion of the > community is in favour of a strictly-typed solution. There are also a lot > of people who are in favour of weak typing. So, this RFC tries to make a > compromise. >
I see, but I afraid that compromise is worse than one or the other. Thanks. Dmitry.

Andrew Faulds

11 years ago
Hi Dmitry,
> On 2 Feb 2015, at 09:24, Dmitry Stogov <dmitry@zend.com> wrote: > > > Will we able to call the same function using weak > > type hinting from on file and with strict from the other? > > Yes, for the parameter type hints anyway. That means that strict and weak code is interoperable without enforcing a model on each other. > > At first I thought, this is ugly solution. Now I'm not completely sure.
I did as well when I first saw the idea proposed (someone else originally suggested it). It does seem ugly on the surface, but it has some advantages. Sure, you have to add this extra line of code to each file, that’s annoying. But, it means full backwards-compatibility, easier migration of existing codebases, and most importantly, allows people to choose one mode or another without affecting other users that have to call their code.
> I see, but this would require declare(strict_types=1) everywhere that would turn PHP into Java.
Well, not quite Java, but yes. Typing it out is annoying. But it’s better than implicit strict typing for a directory, and it means we avoid having two or three different kinds of scalar type hint, so there’s no mixing of systems within the same file. After a while I think people will get used to it. PHP programmers already have to type out "<?php namespace foobar;” at the start of each file, Perl programmers need "#!/usr/bin/perl” and “use warnings; use strict”, JS programmers need “(function () { ‘use strict’; }());” etc. Also, IDEs would help.
> > Strict type hinting is not suitable for PHP by definition (as a weakly > > typed language), however, I see, it may be useful in some cases. > > I would prefer to have "weak" types at first, then think about introducing > > ability to switch to "strict" type hinting in context of use-cases. > > That'd be possible, but I fear that we'd just end up with weak typing only and no strict solution. Regardless of its merits, a large portion of the community is in favour of a strictly-typed solution. There are also a lot of people who are in favour of weak typing. So, this RFC tries to make a compromise. > > I see, but I afraid that compromise is worse than one or the other.
I’m actually convinced that this compromise is in some ways better than one or the other. One of the nice things about strict mode only applying to code which asks for it, is that if a function if an API has type hints added, it won’t suddenly break calling code that didn’t strictly match types, if that calling code uses the default weak mode behaviour (which it will if it was written pre-PHP 7). For example, say I have some sort of Response object that lets you set a body: class Response { public function setBody($message); } In PHP 5, it’s perfectly fine to pass something that’s not a string for $message: $foo = new Response; $foo->setBody(67); Absurd example, but this sort of thing does happen in real world code, often accidentally. Now, let’s say we add a string type hint in a new version of the library: interface Response { public function setBody(string $message); } If PHP’s type hints were always strict, then our existing PHP 5 code from earlier that took advantage of PHP’s weak typing would now produce an error: Catchable fatal error: Argument 1 passed to Response::setBody() must be of the type string, integer given This isn’t good - it makes migration of the existing codebase difficult. Weak typing solves this problem because it allows conversions. However, it’s not really good that the code was passing an integer in the first place - it should really be passing a string. The solution, then, is what this RFC offers. By default, weak typing is used, so your existing code doesn’t break initially. But once you’ve added type hints in a few places, you can switch to strict typing, and that error will be detected and can be fixed. This way, we can have stricter types without sacrificing compatibility or complicating migration. Thanks.
-- Andrea Faulds http://ajf.me/

Dmitry Stogov

11 years ago
So, one of the advantages of strict type hinting is the ability to catch potential errors. For example when we pass 67 to setBody(string $message). Thanks. Dmitry. On Mon, Feb 2, 2015 at 7:30 PM, Andrea Faulds <ajf@ajf.me> wrote:

Andrew Faulds

11 years ago
Hi Dmitry,
> On 2 Feb 2015, at 18:22, Dmitry Stogov <dmitry@zend.com> wrote: > > So, one of the advantages of strict type hinting is the ability to catch potential errors. > For example when we pass 67 to setBody(string $message).
Yes, that sort of thing is easily caught by strict type checks. They’re also able to catch things that are sometimes okay for weak hints, sometimes not. For example, some *but not all* strings are accepted for integer and float parameters, and some *but not all* floats are accepted for integer parameters. Strict checks make this much simpler and not dependant on the value: either some type is accepted, or it isn’t. Because of that, strict types can actually be effectively analysed ahead-of-time by static analysers, IDEs and so on, and so you can catch some types of errors while editing your code, without even needing to run it. This is quite a powerful feature. Nikita might have more to say on that. Thanks.
-- Andrea Faulds http://ajf.me/

Alex Sky

11 years ago
2015-02-02 21:12 GMT+02:00 Andrea Faulds <ajf@ajf.me>:
> Hi Dmitry, > >> On 2 Feb 2015, at 18:22, Dmitry Stogov <dmitry@zend.com> wrote: >> >> So, one of the advantages of strict type hinting is the ability to catch potential errors. >> For example when we pass 67 to setBody(string $message). > > Yes, that sort of thing is easily caught by strict type checks. They’re also able to catch things that are sometimes okay for weak hints, sometimes not. For example, some *but not all* strings are accepted for integer and float parameters, and some *but not all* floats are accepted for integer parameters. Strict checks make this much simpler and not dependant on the value: either some type is accepted, or it isn’t. > > Because of that, strict types can actually be effectively analysed ahead-of-time by static analysers, IDEs and so on, and so you can catch some types of errors while editing your code, without even needing to run it. This is quite a powerful feature. Nikita might have more to say on that. > > Thanks. > -- > Andrea Faulds > http://ajf.me/ > > > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
Strict type checking, has its advantages. We all external data convert to native PHP types. The database we use option MYSQLI_OPT_INT_AND_FLOAT_NATIVE. Inputs are validated and converted to native PHP types. In Redis data are stored as serialize string. In our API we may require strict adherence to type because the integer as strings $id = "123" to impossible, i need catch these as logical error. But I also fully endorse, cast without loss of accuracy, because it gives you more options and less of a problem for those who do not have the conversion of external data. Not to discuss endlessly two options, it is reasonable send to voting the Strict type checking, voting will be fail :), then will be easier to discuss technical issues as do korektno cast without losing data, good luck!

Dmitry Stogov

11 years ago
On Mon, Feb 2, 2015 at 10:12 PM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Dmitry, > > > On 2 Feb 2015, at 18:22, Dmitry Stogov <dmitry@zend.com> wrote: > > > > So, one of the advantages of strict type hinting is the ability to catch > potential errors. > > For example when we pass 67 to setBody(string $message). > > Yes, that sort of thing is easily caught by strict type checks. They’re > also able to catch things that are sometimes okay for weak hints, sometimes > not. For example, some *but not all* strings are accepted for integer and > float parameters, and some *but not all* floats are accepted for integer > parameters. Strict checks make this much simpler and not dependant on the > value: either some type is accepted, or it isn’t. >
Agree. Strict type checks are simple and may be implemented more efficient. But in case we have to support both - weak and strict, this won't make any advantage.
> > Because of that, strict types can actually be effectively analysed > ahead-of-time by static analysers, IDEs and so on, and so you can catch > some types of errors while editing your code, without even needing to run > it. This is quite a powerful feature. Nikita might have more to say on that. >
Static analyzers can work with weak conversion rules as well. Anyway, this is not directly related to run-time semantic we discuss now. Thanks. Dmitry.

Andrew Faulds

11 years ago
Hi Dmitry,
> On 2 Feb 2015, at 19:26, Dmitry Stogov <dmitry@zend.com> wrote: > > Agree. Strict type checks are simple and may be implemented more efficient. > But in case we have to support both - weak and strict, this won't make any advantage.
I think this still works even if we support both. The RFC’s approach means that within one file everything is strictly-typed, for example (except in rare cases of declare() block usage).
> Static analyzers can work with weak conversion rules as well.
This is true, but weak conversion rules are less useful for error-checking in practice: for some conversions, you can’t say AOT if they’ll work or fail, just that they’ll “maybe” succeed. So I think analysis of strictly-typed code would be more effective.
> Anyway, this is not directly related to run-time semantic we discuss now.
This is true. Thanks.
-- Andrea Faulds http://ajf.me/

Derick Rethans

11 years ago
On Mon, 2 Feb 2015, Dmitry Stogov wrote:
> As I already told, in my opinion, version 0.1 was the perfect solution that > fit into PHP semantic very well. > > declare(strict_types=1); - is really weird solution. > It changes type hinting behavior per file scope, so, just to try strict > type hinting in a big project, people will have to change every single PHP > file.
THis is why I believe it makes more sense to have this switch on the callee side, instead of on the calling side. cheers, Derick

Andrew Faulds

11 years ago
Hey Derick,
> On 2 Feb 2015, at 16:35, Derick Rethans <derick@php.net> wrote: > > On Mon, 2 Feb 2015, Dmitry Stogov wrote: > >> As I already told, in my opinion, version 0.1 was the perfect solution that >> fit into PHP semantic very well. >> >> declare(strict_types=1); - is really weird solution. >> It changes type hinting behavior per file scope, so, just to try strict >> type hinting in a big project, people will have to change every single PHP >> file. > > THis is why I believe it makes more sense to have this switch on the > callee side, instead of on the calling side.
That does have its advantages. But it also has some quite severe problems. For starters, if you set that flag on the callee side, you just broke everything that uses that function and passes the “wrong” type. That’s a migration headache. It also means that you don’t have any choice over strictness as the user of an API: some APIs are strict, others weak. That means three lines of code might use three different approaches argument strictness. I don’t like that terribly much. Thanks.
-- Andrea Faulds http://ajf.me/

Andrey Andreev

11 years ago
Hi, On Mon, Feb 2, 2015 at 6:39 PM, Andrea Faulds <ajf@ajf.me> wrote:
> Hey Derick, > >> On 2 Feb 2015, at 16:35, Derick Rethans <derick@php.net> wrote: >> >> On Mon, 2 Feb 2015, Dmitry Stogov wrote: >> >>> As I already told, in my opinion, version 0.1 was the perfect solution that >>> fit into PHP semantic very well. >>> >>> declare(strict_types=1); - is really weird solution. >>> It changes type hinting behavior per file scope, so, just to try strict >>> type hinting in a big project, people will have to change every single PHP >>> file. >> >> THis is why I believe it makes more sense to have this switch on the >> callee side, instead of on the calling side. > > That does have its advantages. But it also has some quite severe problems. > > For starters, if you set that flag on the callee side, you just broke everything that uses that function and passes the “wrong” type. That’s a migration headache. > > It also means that you don’t have any choice over strictness as the user of an API: some APIs are strict, others weak. That means three lines of code might use three different approaches argument strictness. I don’t like that terribly much. >
As already said, we're just going around in circles at this point, but a migration issue? Whatever code using the scalar type hints should be *new* code in userland. You're basing your whole argument on the assumption that all internal functions would break with strict=1 ... nobody needs that and it doesn't have to be done. Cheers, Andrey.

Andrew Faulds

11 years ago
Hi Andrey,
> On 2 Feb 2015, at 16:48, Andrey Andreev <narf@devilix.net> wrote: > > As already said, we're just going around in circles at this point, but > a migration issue? > > Whatever code using the scalar type hints should be *new* code in > userland.
Why not existing userland code? If only new code adds type hints, the ability to detect errors in code is severely curtailed. That would be really unfortunate.
> You're basing your whole argument on the assumption that all > internal functions would break with strict=1 ... nobody needs that and > it doesn't have to be done.
I wasn’t talking about internal functions… I’m talking about userland code in the hypothetical case that we added strict-only hints. I don’t see where you’ve gotten that impression from. Thanks.
-- Andrea Faulds http://ajf.me/

Andrey Andreev

11 years ago
Hi, On Mon, Feb 2, 2015 at 6:52 PM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Andrey, > >> On 2 Feb 2015, at 16:48, Andrey Andreev <narf@devilix.net> wrote: >> >> As already said, we're just going around in circles at this point, but >> a migration issue? >> >> Whatever code using the scalar type hints should be *new* code in >> userland. > > Why not existing userland code? If only new code adds type hints, the ability to detect errors in code is severely curtailed. That would be really unfortunate. > >> You're basing your whole argument on the assumption that all >> internal functions would break with strict=1 ... nobody needs that and >> it doesn't have to be done. > > I wasn’t talking about internal functions… I’m talking about userland code in the hypothetical case that we added strict-only hints. > > I don’t see where you’ve gotten that impression from. >
Well ... existing userland code doesn't have scalar type hints, it couldn't possibly do. How can you have migration issues with it? Cheers, Andrey.

Andrew Faulds

11 years ago
Hi Andrey,
> On 2 Feb 2015, at 16:57, Andrey Andreev <narf@devilix.net> wrote: > > On Mon, Feb 2, 2015 at 6:52 PM, Andrea Faulds <ajf@ajf.me> wrote: >> Hi Andrey, >> >>> On 2 Feb 2015, at 16:48, Andrey Andreev <narf@devilix.net> wrote: >>> >>> As already said, we're just going around in circles at this point, but >>> a migration issue? >>> >>> Whatever code using the scalar type hints should be *new* code in >>> userland. >> >> Why not existing userland code? If only new code adds type hints, the ability to detect errors in code is severely curtailed. That would be really unfortunate. >> >>> You're basing your whole argument on the assumption that all >>> internal functions would break with strict=1 ... nobody needs that and >>> it doesn't have to be done. >> >> I wasn’t talking about internal functions… I’m talking about userland code in the hypothetical case that we added strict-only hints. >> >> I don’t see where you’ve gotten that impression from. >> > > Well ... existing userland code doesn't have scalar type hints, it > couldn't possibly do. How can you have migration issues with it?
I’ll just quote my previous message:
> One of the nice things about strict mode only applying to code which asks for it, is that if a function if an API has type hints added, it won’t suddenly break calling code that didn’t strictly match types, if that calling code uses the default weak mode behaviour (which it will if it was written pre-PHP 7). > > For example, say I have some sort of Response object that lets you set a body: > > class Response { > public function setBody($message); > } > > In PHP 5, it’s perfectly fine to pass something that’s not a string for $message: > > $foo = new Response; > $foo->setBody(67); > > Absurd example, but this sort of thing does happen in real world code, often accidentally. > > Now, let’s say we add a string type hint in a new version of the library: > > interface Response { > public function setBody(string $message); > } > > If PHP’s type hints were always strict, then our existing PHP 5 code from earlier that took advantage of PHP’s weak typing would now produce an error: > > Catchable fatal error: Argument 1 passed to Response::setBody() must be of the type string, integer given > > This isn’t good - it makes migration of the existing codebase difficult. > > Weak typing solves this problem because it allows conversions. However, it’s not really good that the code was passing an integer in the first place - it should really be passing a string. > > The solution, then, is what this RFC offers. By default, weak typing is used, so your existing code doesn’t break initially. But once you’ve added type hints in a few places, you can switch to strict typing, and that error will be detected and can be fixed. > > This way, we can have stricter types without sacrificing compatibility or complicating migration.
Basically, strict-only types complicates their addition to existing codebases, including libraries. What this RFC proposes is similar to Hack’s gradual typing, in a sense, in that it allows you to gradually add types to your codebase without breaking things.
-- Andrea Faulds http://ajf.me/

Alain Williams

11 years ago
On Mon, Feb 02, 2015 at 05:00:08PM +0000, Andrea Faulds wrote:
> Hi Andrey, > ...
Just to give thanks to Andrea on persisting with a highly contentious RFC, one that has defeated several others over the years. I hope that we will end up with something acceptable to most and will be able to finally put this issue to bed. Thanks again.
-- Alain Williams Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer. +44 (0) 787 668 0256 http://www.phcomp.co.uk/ Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php #include <std_disclaimer.h>

Andrey Andreev

11 years ago
On Mon, Feb 2, 2015 at 7:00 PM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Andrey, > >> On 2 Feb 2015, at 16:57, Andrey Andreev <narf@devilix.net> wrote: >> >> On Mon, Feb 2, 2015 at 6:52 PM, Andrea Faulds <ajf@ajf.me> wrote: >>> Hi Andrey, >>> >>>> On 2 Feb 2015, at 16:48, Andrey Andreev <narf@devilix.net> wrote: >>>> >>>> As already said, we're just going around in circles at this point, but >>>> a migration issue? >>>> >>>> Whatever code using the scalar type hints should be *new* code in >>>> userland. >>> >>> Why not existing userland code? If only new code adds type hints, the ability to detect errors in code is severely curtailed. That would be really unfortunate. >>> >>>> You're basing your whole argument on the assumption that all >>>> internal functions would break with strict=1 ... nobody needs that and >>>> it doesn't have to be done. >>> >>> I wasn’t talking about internal functions… I’m talking about userland code in the hypothetical case that we added strict-only hints. >>> >>> I don’t see where you’ve gotten that impression from. >>> >> >> Well ... existing userland code doesn't have scalar type hints, it >> couldn't possibly do. How can you have migration issues with it? > > I’ll just quote my previous message: > >> One of the nice things about strict mode only applying to code which asks for it, is that if a function if an API has type hints added, it won’t suddenly break calling code that didn’t strictly match types, if that calling code uses the default weak mode behaviour (which it will if it was written pre-PHP 7). >> >> For example, say I have some sort of Response object that lets you set a body: >> >> class Response { >> public function setBody($message); >> } >> >> In PHP 5, it’s perfectly fine to pass something that’s not a string for $message: >> >> $foo = new Response; >> $foo->setBody(67); >> >> Absurd example, but this sort of thing does happen in real world code, often accidentally. >> >> Now, let’s say we add a string type hint in a new version of the library: >> >> interface Response { >> public function setBody(string $message); >> } >> >> If PHP’s type hints were always strict, then our existing PHP 5 code from earlier that took advantage of PHP’s weak typing would now produce an error: >> >> Catchable fatal error: Argument 1 passed to Response::setBody() must be of the type string, integer given >> >> This isn’t good - it makes migration of the existing codebase difficult. >> >> Weak typing solves this problem because it allows conversions. However, it’s not really good that the code was passing an integer in the first place - it should really be passing a string. >> >> The solution, then, is what this RFC offers. By default, weak typing is used, so your existing code doesn’t break initially. But once you’ve added type hints in a few places, you can switch to strict typing, and that error will be detected and can be fixed. >> >> This way, we can have stricter types without sacrificing compatibility or complicating migration. > > > Basically, strict-only types complicates their addition to existing codebases, including libraries. > > What this RFC proposes is similar to Hack’s gradual typing, in a sense, in that it allows you to gradually add types to your codebase without breaking things. >
Eh ... sorry for not mentioning that in the same mail, but I've never suggested a strict-only approach. Cheers, Andrey.

André Rømcke

11 years ago
> > On 02 Feb 2015, at 17:35 , Derick Rethans <derick@php.net> wrote: > > On Mon, 2 Feb 2015, Dmitry Stogov wrote: > >> As I already told, in my opinion, version 0.1 was the perfect solution that >> fit into PHP semantic very well. >> >> declare(strict_types=1); - is really weird solution. >> It changes type hinting behavior per file scope, so, just to try strict >> type hinting in a big project, people will have to change every single PHP >> file.
declare() might not be beautiful, but it is pragmatic as it already exists. As for full project switch, can’t we easily do a followup RFC with a command line flag/ini setting to run unit tests in strict mode for instance?
> > THis is why I believe it makes more sense to have this switch on the > callee side, instead of on the calling side.
I’m not sure I see why that would make more sense. On the callee side what you get is strictly what you asked for anyway, no matter what mode on the calling side. This is the true beauty of what Andrea has come up with here, allowing weak PHP like forgiveness to co-exists with opt in for strict behavior. Best, André

Michael Wallner

11 years ago
> On 02 02 2015, at 00:49, Andrea Faulds <ajf@ajf.me> wrote: > > Good evening, > > The RFC has been updated to cover return types, since Levi’s Return Types RFC has passed. The patch is a work in progress: it works, but lacks tests for return types. > > Version 0.3 of the RFC can be found here: https://wiki.php.net/rfc/scalar_type_hints
I think v0.1 had pretty good chances to get accepted, but I’m not so sure about anything that followed. I’m definitely -1 on declare(strict). Regards, Mike

Matteo Beccati

11 years ago
On 02/02/2015 09:49, Michael Wallner wrote:
> >> On 02 02 2015, at 00:49, Andrea Faulds <ajf@ajf.me> wrote: >> >> Good evening, >> >> The RFC has been updated to cover return types, since Levi’s Return Types RFC has passed. The patch is a work in progress: it works, but lacks tests for return types. >> >> Version 0.3 of the RFC can be found here: https://wiki.php.net/rfc/scalar_type_hints > > I think v0.1 had pretty good chances to get accepted, but I’m not so sure about anything that followed. > I’m definitely -1 on declare(strict).
I agree. I understand that someone might prefer strict typing, but declare() seems so different from anything else in php. I think I've only used it when I needed signal handling and even in that case it felt so weird. Cheers
-- Matteo Beccati Development & Consulting - http://www.beccati.com/

Lester Caine

11 years ago
On 02/02/15 08:53, Matteo Beccati wrote:
>> I think v0.1 had pretty good chances to get accepted, but I’m not so >> sure about anything that followed. >> I’m definitely -1 on declare(strict). > > I agree. I understand that someone might prefer strict typing, but > declare() seems so different from anything else in php. I think I've > only used it when I needed signal handling and even in that case it felt > so weird.
Add to that 'E_STRICT' ... just what is the preferred way of doing things?
-- Lester Caine - G8HFL ----------------------------- Contact - http://lsces.co.uk/wiki/?page=contact L.S.Caine Electronic Services - http://lsces.co.uk EnquirySolve - http://enquirysolve.com/ Model Engineers Digital Workshop - http://medw.co.uk Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

Unnamed Person

11 years ago
what about giving several voting options? yes/no for scalar type hints and yes/no for declare-strict Regards Thomas Michael Wallner schrieb am 2. Feb 2015 09:49:

Markus Fischer

11 years ago
Hello Andrea, On 02.02.15 00:49, Andrea Faulds wrote:
> The RFC has been updated to cover return types, since Levi’s Return Types RFC has passed. The patch is a work in progress: it works, but lacks tests for return types. > > Version 0.3 of the RFC can be found here: https://wiki.php.net/rfc/scalar_type_hints
although my involvement here is very sparse at the moment, please let me tell you that I a) find it great that you don't give up, are persistently going for your idea while b) still being objective rather then emotional. I'm really happy to see such technical, lively discussion you initiated so far. Thank you :-) That said ... - I dislike the RFC since the introduction of the declare() adaption (effectively 0.2/0.3 now) and did not 100% agree with 0.1 - Since consensus on the strict mode does part the community (or, the greater community also outside @internals) my impression is that the current best way to move forward would be - get the rfc to only go for weak types for now - using the "cast-like syntax": function foo( (int) $bar ); and ultimately keep the strict type out for /now/ and try it at a later time, the "function foo( int $bar )"-syntax. I'm actually not really in favor of just weak types, I would consider myself a "strict type" voter, but through the community communication here I saw a) the benefits of weak types hinting/casting b) without getting in the way of a possible future strict type (e.g. with the "non-cast-like syntax"). thank you, - Markus

Andrew Faulds

11 years ago
Hi Markus,
> On 2 Feb 2015, at 14:25, Markus Fischer <markus@fischer.name> wrote: > > - Since consensus on the strict mode does part the community (or, the > greater community also outside @internals) my impression is that the > current best way to move forward would be > > - get the rfc to only go for weak types for now > - using the "cast-like syntax": function foo( (int) $bar ); > > and ultimately keep the strict type out for /now/ and try it at a later > time, the "function foo( int $bar )"-syntax.
I’m not sure that really works that well. It’s not a terribly good compromise: If you want strict typing, you not only haven’t got it, but even worse, you’ll be forced to deal with weak typing if you use the wrong library, because the (int) syntax would be specifically for weak types. It’s not really a compromise at all, actually.
> I'm actually not really in favor of just weak types, I would consider > myself a "strict type" voter, but through the community communication > here I saw a) the benefits of weak types hinting/casting b) without > getting in the way of a possible future strict type (e.g. with the > "non-cast-like syntax”).
Well this RFC tries to strike a different balance: rather than having the chaos of some functions using weak types, others strict types, others both, it just adds scalar types and lets you choose the behaviour that suits you. It means weak typing fans can live in their weakly-typed world, and strict typing fans can live in their strictly-typed world. That’s the idea, anyway. But I’m just going in circles at this point. :P Thanks for your contributions.
-- Andrea Faulds http://ajf.me/

Andrey Andreev

11 years ago
Hi, On Mon, Feb 2, 2015 at 6:17 PM, Andrea Faulds <ajf@ajf.me> wrote:
> Hi Markus, > >> On 2 Feb 2015, at 14:25, Markus Fischer <markus@fischer.name> wrote: >> >> - Since consensus on the strict mode does part the community (or, the >> greater community also outside @internals) my impression is that the >> current best way to move forward would be >> >> - get the rfc to only go for weak types for now >> - using the "cast-like syntax": function foo( (int) $bar ); >> >> and ultimately keep the strict type out for /now/ and try it at a later >> time, the "function foo( int $bar )"-syntax. > > I’m not sure that really works that well. It’s not a terribly good compromise: If you want strict typing, you not only haven’t got it, but even worse, you’ll be forced to deal with weak typing if you use the wrong library, because the (int) syntax would be specifically for weak types. It’s not really a compromise at all, actually. > >> I'm actually not really in favor of just weak types, I would consider >> myself a "strict type" voter, but through the community communication >> here I saw a) the benefits of weak types hinting/casting b) without >> getting in the way of a possible future strict type (e.g. with the >> "non-cast-like syntax”). > > Well this RFC tries to strike a different balance: rather than having the chaos of some functions using weak types, others strict types, others both, it just adds scalar types and lets you choose the behaviour that suits you. It means weak typing fans can live in their weakly-typed world, and strict typing fans can live in their strictly-typed world. That’s the idea, anyway. > > But I’m just going in circles at this point. :P >
If chaos is what you call it - we want chaos. :P Cheers, Andrey.

Matthew Leverton

11 years ago
On Sun, Feb 1, 2015 at 5:49 PM, Andrea Faulds <ajf@ajf.me> wrote:
> Good evening, > > The RFC has been updated to cover return types, since Levi’s Return Types RFC has passed. The patch is a work in progress: it works, but lacks tests for return types. > > Version 0.3 of the RFC can be found here: https://wiki.php.net/rfc/scalar_type_hints >
After thinking and talking this over, I do think your RFC is the only option that makes sense *if* you want to support both weak and strict. However, I think the usage of declare() makes it dead in the water. Fair or not, I have a hard time looking past that. I'm opposed to other compromises because I think it will be a big mess from the caller's perspective. (Some functions would be strict, some would not ... eventually forcing everybody to just use strict types.) And, as I've stated previously, I prefer strict types. Does the implementation of strict-only work for testing right now? (If so, what branch is it on, etc?) It's easy for everybody to theorize about how this would work, but why not actually take the time to "strictify" some part of a commonly used library and see how it actually works in practice? But a library with type-hints + a script to prepend "use strict" to every PHP file would make testing impact on real-world usage easy for anybody.
-- Matthew Leverton

Andrew Faulds

11 years ago
Hi Matthew,
> On 2 Feb 2015, at 16:45, Matthew Leverton <leverton@gmail.com> wrote: > > On Sun, Feb 1, 2015 at 5:49 PM, Andrea Faulds <ajf@ajf.me> wrote: >> Good evening, >> >> The RFC has been updated to cover return types, since Levi’s Return Types RFC has passed. The patch is a work in progress: it works, but lacks tests for return types. >> >> Version 0.3 of the RFC can be found here: https://wiki.php.net/rfc/scalar_type_hints >> > After thinking and talking this over, I do think your RFC is the only > option that makes sense *if* you want to support both weak and strict. > However, I think the usage of declare() makes it dead in the water. > Fair or not, I have a hard time looking past that.
Ah, that’s unfortunate. I know declare() is ugly and a little unwieldy, but I can’t see another way to do it which doesn’t cause bigger problems. I am convinced that if this RFC passed, people would probably get used to declare(). IDEs and command-line tools do exist.
> I'm opposed to other compromises because I think it will be a big mess > from the caller's perspective. (Some functions would be strict, some > would not ... eventually forcing everybody to just use strict types.) > And, as I've stated previously, I prefer strict types.
That’s how I feel as well.
> Does the implementation of strict-only work for testing right now? (If > so, what branch is it on, etc?) It's easy for everybody to theorize > about how this would work, but why not actually take the time to > "strictify" some part of a commonly used library and see how it > actually works in practice? But a library with type-hints + a script > to prepend "use strict" to every PHP file would make testing impact on > real-world usage easy for anybody.
The implementation does work for testing. I still need to write tests for return types but they seem to work. Parameter types are fully-working, though, and they have extensive tests, so I know they’re working fine and you could add them to an existing project. Strictifying an existing library is a good idea. I’ll try “strictifying” one of my bigger personal projects (PictoSwap, a 3DS browser application with a PHP backend) and see how it goes. I expect it’ll be fairly smooth, we’ll see. Thanks for your thoughts.
-- Andrea Faulds http://ajf.me/

Andrew Faulds

11 years ago
Hey everyone,
> On 2 Feb 2015, at 16:50, Andrea Faulds <ajf@ajf.me> wrote: > > The implementation does work for testing. I still need to write tests for return types but they seem to work. Parameter types are fully-working, though, and they have extensive tests, so I know they’re working fine and you could add them to an existing project. > > Strictifying an existing library is a good idea. I’ll try “strictifying” one of my bigger personal projects (PictoSwap, a 3DS browser application with a PHP backend) and see how it goes. I expect it’ll be fairly smooth, we’ll see.
I just went and did this on PictoSwap, it was fairly painless. It’s quite a small application, to be fair, but it is “real-world code”. First, I compiled my branch with the following configure command: YACC=/usr/local/opt/bison27/bin/bison ./configure --enable-debug --enable-phpdbg --disable-all --with-gd --enable-pdo --with-sqlite3 --with-pdo-sqlite --enable-session --enable-json Ignore the YACC=, I only need to do that because OS X is weird. As you can see, PictoSwap requires Gd, PDO-SQLite, Session and JSON. Then, I ran my site with the freshly-compiled version of PHP. Actually, that’s not quite true - I compiled several times, each time finding an error because of a missing extension. Eventually I got to this configure line which included all the ones my app needed. Second, I added declare(strict_types=1); to each file along with type hints. I did this file by file, and tested with each file. For most of the files, nothing was broken by the addition of strict type hints. However, some files did cause issues. When I added hints to my graphics functions in include/graphics.php and turned on strict types, I got an error because of a type mismatch, which lead to me discovering a bug. It turns out I’d been assuming that gd takes float pixel positions, but it actually takes integer pixels! This means that those crucial .5s had been truncated off all this time, and I was none-the-wiser. I added explicit integer casts. Now it’s obvious that the results are being truncated. Adding strict hints to include/user.php, which includes the “business logic” as such turned up the most issues. It showed me a few different things. One thing I learned was that return types are crippled by the lack of nullable returns. For most of my functions, I need to return TRUE (success) or a string (error message). I’d be fine with switching to NULL (success) or string (error) so it’s hintable, but I can’t actually do that, because we lack nullable returns. That means I’m omitting return types on most of my functions, unfortunately. I hope that the Nullable Types RFC can pass and fix this. Another thing I learned was how I really needed to convert the values going into and coming out of my database (SQLite 3, in this case). Turns out most of the data in there was strings, as SQLite is dynamically-typed, and so my JSON output was ending up filled with strings, where it should have had numbers or booleans. Type mismatch errors allowed me to spot where this was happening. It’s only because JavaScript is similarly merciful to PHP that my web app worked at all! I also learned that my session data didn’t have correct types: the user ID had ended up a string, not an integer. This was trivially fixed, but something I wouldn’t have noticed without strict typing. Now, the addition of type hints to include/user.php broke my web-facing code (htdocs/api.php), because I wasn’t converting types properly. However, this only broke it when it used strict typing mode. If I turned off strict typing mode, as I expected, PHP happily converted the types and everything worked swimmingly. The fixes weren’t that difficult, but not having to make everything strict at once made adding type hints easier, because I could disable strict types in code that wasn’t yet ready and my app would keep running fine, then turn on strict types one it was updated. The end result of this was better code, and I spotted some errors. The migration was eased, as I had hoped, by the ability to make some files strict and others weak. It also shows that my web app works fine without modifications on PHP 7, which is great. Admittedly, my web app is quite small. But I think this makes a good case for the usefulness of this RFC, and in particular of the declare() system, and strict hints vs. weak hints. :) You can see the diff here: https://github.com/TazeTSchnitzel/PictoSwap/compare/php7-strict Thanks!
-- Andrea Faulds http://ajf.me/

Dmitry Stogov

11 years ago
Hi Andrea, In you proposal you disable declaration of classes with names, that may be used for scalar type hints - Int, Float, ... What do you think about using only lowercase type names for scalar type hints? In this case we won't have to introduce any limitations. function foo(int $a) // expects integer function foo(Int $a) // expects instance of class Int Thanks. Dmitry. On Tue, Feb 3, 2015 at 12:40 AM, Andrea Faulds <ajf@ajf.me> wrote:

Sebastian Bergmann

11 years ago
Am 04.02.2015 um 06:44 schrieb Dmitry Stogov:
> What do you think about using only lowercase type names for scalar type > hints? In this case we won't have to introduce any limitations.
This would be inconsistent with the rest of PHP being case-insensitive and only lead to confusion.

Andrew Faulds

11 years ago
Hi Dmitry and Sebastian,
> On 4 Feb 2015, at 05:49, Sebastian Bergmann <sebastian@php.net> wrote: > > Am 04.02.2015 um 06:44 schrieb Dmitry Stogov: >> What do you think about using only lowercase type names for scalar type >> hints? In this case we won't have to introduce any limitations. > > This would be inconsistent with the rest of PHP being case-insensitive > and only lead to confusion.
This is how I feel. Array and Callable work, yet if Integer and String didn’t it’d be inconsistent. Also, we’d *still* have a BC issue, because who says that people with String classes didn’t use a lowercase type hint? I think the BC cost, while unfortunate, is unavoidable. Luckily, code can be changed in such a way that it’ll keep working fine on PHP 5 and only break on PHP 7, by using class_alias(). Thanks.
-- Andrea Faulds http://ajf.me/

Pascal Chevrel

11 years ago
Le 14/01/2015 01:16, Andrea Faulds a écrit :
> Good evening, > > I’ve made some quite significant changes to my Scalar T ype Hints RFC, and bumped its version to 0.2. > > Here: https://wiki.php.net/rfc/scalar_type_hints > > This is a new thread because I’ve made a significant revision to the RFC, so it’d be sensible to separate discussion of the updated RFC from the v0.1 RFC. > > Please tell me your thoughts. > > Thanks!
Hi Andrea, I am probably going to ask a stupid question, but do we really need the =1 part in declare? declare(strict_types=1) couldn't be declare(strict_types)? Or does it mean that there would be cases when strict typing would be deactivated after being activated with declare(strict_types=0)? To be honest, I don't like declare() because it looks like a function call, not a setting for the file like a namespace declaration would be. Also, in the case of declare(ticks=1), 1 is not a boolean but an interval so I find it a bit confusing that strict_types=1 would be a boolean in that case. Or maybe declare(strict_types=true) then? Personnally I would prefer a syntax like: declare strict; which is just shorter and more readable in my opinion. I know it is mostly cosmetic but I don't really understand why declare uses parenthesis if it is a language construct and not a function (and yes, I think that declare(ticks=1) also looks silly ;) ); So basically instead of that at the top of my files: <?php namespace Foo; use Bar; declare(strict_types=1); I would prefer having that: <?php namespace Foo; use Bar; declare strict; It's probably a detail in the whole discussion, but for some weird psychological reason, it matters to me :), Cheers, Pascal

Andrew Faulds

11 years ago
Hi Pascal,
> On 5 Feb 2015, at 00:02, Pascal Chevrel <pascal.chevrel@free.fr> wrote: > > I am probably going to ask a stupid question, but do we really need the =1 part in declare? > > declare(strict_types=1) couldn't be declare(strict_types)? > > Or does it mean that there would be cases when strict typing would be deactivated after being activated with declare(strict_types=0)?
Oh, I made it like that because that’s the existing syntax of declare(), it takes a name and a value. But I suppose it could be modified to allow just a name. I don’t think we should modify it just for this specific case, really… less exceptions to a rule and more consistency are generally a good thing. There is a use for declare(strict_types=0), which is to make part of a file weak while having the rest strict. It’s not something you’d want to do very often, but it may be useful in some rare cases. If we have declare(strict_types=1), then it makes sense to also have declare(strict_types=0). It’d be rather odd to not allow it.
> To be honest, I don't like declare() because it looks like a function call, not a setting for the file like a namespace declaration would be. Also, in the case of declare(ticks=1), 1 is not a boolean but an interval so I find it a bit confusing that strict_types=1 would be a boolean in that case. Or maybe declare(strict_types=true) then?
I originally had it be a boolean, but considering how often this would be used, I changed it to 1 for terseness. Using 1 is common for INI settings, so I don’t think it’d be that confusing, but I see your point.
> Personnally I would prefer a syntax like: > declare strict; > > which is just shorter and more readable in my opinion. I know it is mostly cosmetic but I don't really understand why declare uses parenthesis if it is a language construct and not a function (and yes, I think that declare(ticks=1) also looks silly ;) ); > > So basically instead of that at the top of my files: > <?php > namespace Foo; > use Bar; > declare(strict_types=1); > > I would prefer having that: > <?php > namespace Foo; > use Bar; > declare strict; > > It's probably a detail in the whole discussion, but for some weird psychological reason, it matters to me :),
I can see the appeal, though I’m not really sure about adding new syntax just for this. By the way, I think declare() would be easily distinguished from a function for two reasons. Firstly, you can’t assign to constants, and secondly, it’ll be syntax-highlights differently. I can understand your concerns, though. :) Thanks for voicing them.
-- Andrea Faulds http://ajf.me/