All,
As I mentioned numerous times scalar type hinting is a very
controversial feature in my mind and requires some substantial
discussion before we move ahead to implement it.
As such, I think we should revert the patch that was committed to
trunk and move to discuss it first instead.
My (& Lukas') thoughts on the subject are detailed at
http://wiki.php.net/rfc/typecheckingstrictandweakhttp://wiki.php.net/rfc/typecheckingstrictandweak
As one of the key people who designed PHP's type system I consider
strict type checks completely alien to and counterintuitive in PHP
and am therefore pushing to implement 'weak' typing instead, in a way
that's consistent and familiar to users.
Zeev
FYI - I did some fairly major editing on the issues with strict type
hinting and advantages of auto-converting type hinting in the RFC
(beforehand I focused primarily on the conversion table).
I encourage everyone to take another look at this RFC even if you've
read it before.
Thanks,
Zeev
At 18:04 22/05/2010, Zeev Suraski wrote:
All,
As I mentioned numerous times scalar type hinting is a very
controversial feature in my mind and requires some substantial
discussion before we move ahead to implement it.
As such, I think we should revert the patch that was committed to
trunk and move to discuss it first instead.My (& Lukas') thoughts on the subject are detailed at
http://wiki.php.net/rfc/typecheckingstrictandweakhttp://wiki.php.net/rfc/typecheckingstrictandweakAs one of the key people who designed PHP's type system I consider
strict type checks completely alien to and counterintuitive in PHP
and am therefore pushing to implement 'weak' typing instead, in a
way that's consistent and familiar to users.Zeev
Zeev,
First of all as far as I can tell majority of the changes relate to 2 new
type hints you are suggesting to introduce which are numeric and scalar. I
don't see any issue with adding those two hints, predominantly for people
who don't want to be specific with their type requirements. So, +1 on that
portion of the RFC.
However, after reviewing your suggested changes to some of the type-specific
hints, I think the changes you are suggesting would only introduce
confusion. There is a substantial WTF factor for developers, whereby (int)1
=== boolean, but (int)12 !== boolean. Or that (int) 12 is either a valid int
or a double, but (double)12 is only a double.
For one strict type hints are much clearer, if function/method expects type
X and anything but type X is provided an error is generated.
I think adding the scalar and numeric hints should be a sufficient.
FYI - I did some fairly major editing on the issues with strict type
hinting and advantages of auto-converting type hinting in the RFC
(beforehand I focused primarily on the conversion table).I encourage everyone to take another look at this RFC even if you've read
it before.Thanks,
Zeev
At 18:04 22/05/2010, Zeev Suraski wrote:
All,
As I mentioned numerous times scalar type hinting is a very controversial
feature in my mind and requires some substantial discussion before we move
ahead to implement it.
As such, I think we should revert the patch that was committed to trunk
and move to discuss it first instead.My (& Lukas') thoughts on the subject are detailed at <
http://wiki.php.net/rfc/typecheckingstrictandweak>
http://wiki.php.net/rfc/typecheckingstrictandweakAs one of the key people who designed PHP's type system I consider strict
type checks completely alien to and counterintuitive in PHP and am therefore
pushing to implement 'weak' typing instead, in a way that's consistent and
familiar to users.Zeev
At 19:25 22/05/2010, Ilia Alshanetsky wrote:
Zeev,
First of all as far as I can tell majority of the changes relate to
2 new type hints you are suggesting to introduce which are numeric
and scalar. I don't see any issue with adding those two hints,
predominantly for people who don't want to be specific with their
type requirements. So, +1 on that portion of the RFC.
The majority of changes (make sure you look at the latest version as
of about an half an hour ago) is not in terms of what's in there, but
what isn't ('less is more'). The other major change is
auto-conversion when possible, instead of failure.
However, after reviewing your suggested changes to some of the
type-specific hints, I think the changes you are suggesting would
only introduce confusion. There is a substantial WTF factor for
developers, whereby (int)1 === boolean, but (int)12 !== boolean. Or
that (int) 12 is either a valid int or a double, but (double)12 is
only a double.
I think you make a good case, and it wasn't easy to decide how much
(if at all) the auto-conversion rules should be stricter than PHP's
default type conversion rules. I think we can tweak that table. The
only ones I feel strongly about is that we shouldn't accept "abc"
strings as numbers, or arrays/objects as any scalar type. Had we
designed the language from scratch today, we would have probably not
accepted those for auto-conversion either.
For one strict type hints are much clearer, if function/method
expects type X and anything but type X is provided an error is generated.
They may be simpler for you and me to understand, but IMHO not for
the general PHP userbase. Moreover - the fact they may be clearer to
some doesn't necessarily make them more useful. I think
auto-converting type hints are much more useful than strict ones (for
reasons explained in the updated RFC).
Zeev
I encourage everyone to take another look at this RFC even if you've read
it before.Thanks,
Zeev
Hi internals,
Last time Zeev wrote an RFC for type hinting, I was (as a user) all for it.
This time is no different. Please let me add to my post back in october '09.
The RFC introduction should have said everything, but some people seem to
disregard some things.
I see two kinds of API available in PHP: internals which is written in C
(some with strict typing, some not), and userland which is written in PHP
with no typing/checking (for the moment at least).
Similarly, I see two different kinds of PHP users: those who write any kind
of code used by other PHP users (let's call them API developers), and the
users who write the final applications with PHP, using a combination of
internals API and userland API (let's call them API consumers). I don't
beleive those two groups of users have the same background knowledge or the
same expectations from PHP.
From what I understand, strict type checking (or strict typing) only looks
at the type of the variables, while type hinting also converts their value
if necessary.
Let's start by some basic understanding of what writing an API implies. As
an API developer, you don't now when or how your functions are called. You
simply have no say in this. You could write documentation, but there will be
situations where the API consumer does not have the will, the time or any
other notion that would prevent him from reading and applying good practice.
Saying "just read the doc" is not enough. In some situations, your code will
be wrongly used, and you can avoid disaster if you correctly validate the
values passed to you. If you don't, passing the right type but the wrong
value could be more problematic than passing the wrong type with the right
value, which is what would happen most of the time without any kind of
hinting/checking. As the API developer, you have some responsibility to make
sure your code works on most cases. The API consumers count on that, because
they often do not have the same understanding of the consequences as you do.
That does not mean your code should work in every single case, but whenever
it is expected to work (from their perspective).
Here is a general case when a parameter of the wrong type is passed:
With strict typing, the API tells the consumer that it is doing something
wrong. Adding a cast to his code, he can go on.
With type hinting as proposed by Zeev and Lukas, your code converts the
variable. No need to manually cast anything, same results.
Since PHP has weak types, as a consumer I can not know for sure at any time
of what type each of my variables is. Therefore, with strict typing, I would
have to cast each of my variables each time I used any API function. And of
course, any modification made to that API would mean parsing all of my code
to reflect the changes. Not only would it be very frustrating, but also very
confusing for newcomers who have been told for a decade that PHP is simple
to learn. I think API developers would easily cope, but API consumers would
likely be driven away.
Best regards,
--
Guillaume Rossolini
As one of the key people who designed PHP's type system I consider strict
type checks completely alien to and counterintuitive in PHP and am therefore
pushing to implement 'weak' typing instead, in a way that's consistent and
familiar to users.
I would normally refrain from posting on the dev list but as a "user"
I feel the need to make sure that my position isn't misrepresented, so
here it is.
As you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.
Thanks for reading.
JD
At 19:30 22/05/2010, Josh Davis wrote:
As one of the key people who designed PHP's type system I consider strict
type checks completely alien to and counterintuitive in PHP and
am therefore
pushing to implement 'weak' typing instead, in a way that's consistent and
familiar to users.I would normally refrain from posting on the dev list but as a "user"
I feel the need to make sure that my position isn't misrepresented, so
here it is.
I think that users' opinion about language direction is very
important, so thanks for writing.
As you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system.
Well I actually wrote PHP's type hinting system too :) And it's no
coincidence there are no type hints for scalars, and that stems
directly from PHP's type system. As a part of introducing type hints
to PHP back in 2003, there was a discussion about whether or not to
add scalar type hints. Consensus was against it, and actually as a
part of the agreement to add type hints to PHP - we agreed we'll
'never' introduce scalar type hints because of the baggage and
inconsistency it comes with. Never is not a very long time when it
comes to software though...
As far as I know, there's no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.
That's true, but then, there's also no way to auto-convert class Foo
to class Bar - while there is a way to auto-convert between scalar
types in many (if not most) cases.
Consider a simple example - class Child extends Parent {} strict
type hinting is the equivalent of not allowing an object of class
Child when a function expects an object of class Parent. Much like
Child is_a Parent, "123" is_a int.
Zeev
As you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.
can we please just stop calling a something a "type hinting" system, which leads to a catchable fatal error when the type does not strictly match? thats a very misleading euphemism. its simply strict typing, it has nothing to do with hinting.
anyway, yes there is a proposal for an actual hinting system as Zeev has pointed out just a few mails early in the thread than yours:
http://wiki.php.net/rfc/typecheckingstrictandweak
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
So which RFC should I be reviewing? Does this RFC reflect what Ilia's
patch does? I just want to be sure we are talking about the same thing
and can review and comment on it in detail. We've had many discussions
on this topic over the years and different people had different things
in mind so we need to make sure we have a good structured discussion
(and documented via RFC).
Andi
-----Original Message-----
From: Lukas Kahwe Smith [mailto:mls@pooteeweet.org]
Sent: Saturday, May 22, 2010 1:39 PM
To: Josh Davis
Cc: Zeev Suraski; internals@lists.php.net
Subject: Re: [PHP-DEV] Type hintingAs you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's
no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.can we please just stop calling a something a "type hinting" system,
which leads
to a catchable fatal error when the type does not strictly match?
thats a very
misleading euphemism. its simply strict typing, it has nothing to do
with hinting.anyway, yes there is a proposal for an actual hinting system as Zeev
has pointed
out just a few mails early in the thread than yours:
http://wiki.php.net/rfc/typecheckingstrictandweakregards,
Lukas Kahwe Smith
mls@pooteeweet.org--
To unsubscribe,
visit:
http://www.php.net/unsub.php
Andi,
The existing functionality is very simple (no RFC) needed. It allows for
scalar type hints and ensures that the Z_TYPE of the parameter matches the
indicated type in the declaration, any mistmatch results in an error.
So which RFC should I be reviewing? Does this RFC reflect what Ilia's
patch does? I just want to be sure we are talking about the same thing
and can review and comment on it in detail. We've had many discussions
on this topic over the years and different people had different things
in mind so we need to make sure we have a good structured discussion
(and documented via RFC).Andi
-----Original Message-----
From: Lukas Kahwe Smith [mailto:mls@pooteeweet.org]
Sent: Saturday, May 22, 2010 1:39 PM
To: Josh Davis
Cc: Zeev Suraski; internals@lists.php.net
Subject: Re: [PHP-DEV] Type hintingAs you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's
no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.can we please just stop calling a something a "type hinting" system,
which leads
to a catchable fatal error when the type does not strictly match?
thats a very
misleading euphemism. its simply strict typing, it has nothing to do
with hinting.anyway, yes there is a proposal for an actual hinting system as Zeev
has pointed
out just a few mails early in the thread than yours:
http://wiki.php.net/rfc/typecheckingstrictandweakregards,
Lukas Kahwe Smith
mls@pooteeweet.org--
To unsubscribe,
visit:
http://www.php.net/unsub.php
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
any mistmatch results in an error
An error that is recoverable. So not only is the "strict typing"
optional, but "type mismatches" can be caught and handled.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iEYEARECAAYFAkv5IzsACgkQaGfFFLhbXWk3IgCfWRxGH7AMrTvwgZz0xoFA5LdP
8JIAoJl7iw8FSKZsCYTFjqXVIAHT+VCP
=pvc9
-----END PGP SIGNATURE
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1any mistmatch results in an error
An error that is recoverable. So not only is the "strict typing"
optional, but "type mismatches" can be caught and handled.
again .. are you saying that a recoverable error is more than a way to display a nice error message instead of a white screen?
anyway, the fundamental question at hand is where the "burden" of correct typing should be placed, on the API consumer or on the API provider. this also ties in with the question if API consumers are likely to have "properly" typed (aka typed in the way the various API he consumes expect) by default or not. i think this is the key question to answer when deciding to go with enabling type hinting or full out strict typing.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1any mistmatch results in an error
An error that is recoverable. So not only is the "strict typing"
optional, but "type mismatches" can be caught and handled.again .. are you saying that a recoverable error is more than a way to display a nice error message instead of a white screen?
anyway, the fundamental question at hand is where the "burden" of correct typing should be placed, on the API consumer or on the API provider. this also ties in with the question if API consumers are likely to have "properly" typed (aka typed in the way the various API he consumes expect) by default or not. i think this is the key question to answer when deciding to go with enabling type hinting or full out strict typing.
We also already have a precedent for type-caring functions in the ctype_* functions:
$ php -r 'var_dump(ctype_digit(123), ctype_digit((string) 123));'
bool(false)
bool(true)
ctype_digit()
simply returns a false when a non-string is passed in.
Everybody knows you just cast the param to string (as in my second call); and with no
help from a notice or error of any kind.
I think if we type-juggle the inputs, and threw a notice, people who care about the
precision of their data, will be informed by the notice and can change it. Everyone else
will just get expected behavior for the function with their data.
It might be useful to have some way to figure out that a variable was cast however,
is that something we can store in the ZVAL and pull out with a function? (only the type
casting that occurs due to this mechanism, not any other). I don't think this is useful
enough for any kind of performance hit mind you ;)
- Davey
At 16:10 23/05/2010, Davey Shafik wrote:
We also already have a precedent for type-caring functions in the
ctype_* functions:$ php -r 'var_dump(ctype_digit(123), ctype_digit((string) 123));'
bool(false)
bool(true)
There's a very specific reason for this behavior - ctype treats
numeric values as ASCII and checks if they're in the right
range. So, for instance, ctype_digit(48) would return true. Talk
about a high WTF factor...
Personally I think that's probably a poor decision, and I either way
I wouldn't qualify it as precedent. Sure, there are functions that
don't auto-convert and behave differently depending on the type
that's passed to them - but they're very much the exception to the rule.
Zeev
Hi!
any mistmatch results in an error
An error that is recoverable. So not only is the "strict typing"
optional, but "type mismatches" can be caught and handled.
Unfortunately, PHP doesn't have good means to handle such kind of
errors. Global "shut up" handler is not a good means, as it disables the
whole protection, effectively forcing third-party code to work with
variable it wasn't written to handle, and you have no means of
separating OK and not OK cases. And on top of that, even silent errors
are still very expensive in PHP.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
As you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.
I agree. function foo(array $x) {} foo(123); doesn't cast int(123) to
array(123) so introducing different meaning for scalar types feels
very very wrong.
can we please just stop calling a something a "type hinting" system, which leads to a catchable fatal error when the type does not strictly match? thats a very misleading euphemism. its simply strict typing, it has nothing to do with hinting.
It definitely isn't strict either:
$ php -r 'function errh() {} set_error_handler("errh",
E_RECOVERABLE_ERROR); function bar(foo $x) {echo "hello world\n";}
bar(1);'
hello world
-Hannes
can we please just stop calling a something a "type hinting" system, which leads to a catchable fatal error when the type does not strictly match? thats a very misleading euphemism. its simply strict typing, it has nothing to do with hinting.
It definitely isn't strict either:
$ php -r 'function errh() {} set_error_handler("errh",
E_RECOVERABLE_ERROR); function bar(foo $x) {echo "hello world\n";}
bar(1);'
hello world
heh ... you are selling recoverable errors as anything but a solution to display something else than a white screen?
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
At 01:01 23/05/2010, Hannes Magnusson wrote:
As you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.I agree. function foo(array $x) {} foo(123); doesn't cast int(123) to
array(123) so introducing different meaning for scalar types feels
very very wrong.
You're ignoring one simple fact - in PHP, scalar types are
interchangeable. Unlike array->scalar which has always been a corner
case and a sketchy one (and I said numerous times that had I rewrote
the language now, array->scalar conversion would have probably
resulted in an error) - string->number, number->string,
string->boolean conversions are a cornerstone of the language. If
you don't like the fact that PHP's scalar types are interchangeable -
you're in the wrong language!
In terms of consistency, the difference between array type hinting
and scalar type hinting you allude to is negligible in comparison to
the inconsistency with, well, just about every other part of the
language - operators, control structures and built-in functions
(expecting sqrt("64") to fail, since sqrt()
expects a
number? expecting if (7) to fail, since it expects a
boolean?). Auto-converting type hinting extends the same semantics
available to internal functions (through zend_parse_parameters()) to
userland functions. That consistency is by far the most important IMHO.
Zeev
On Saturday 22 May 2010 11:43:50 pm Zeev Suraski wrote:
At 01:01 23/05/2010, Hannes Magnusson wrote:
On Sat, May 22, 2010 at 22:39, Lukas Kahwe Smith mls@pooteeweet.org
wrote:As you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.I agree. function foo(array $x) {} foo(123); doesn't cast int(123) to
array(123) so introducing different meaning for scalar types feels
very very wrong.You're ignoring one simple fact - in PHP, scalar types are
interchangeable. Unlike array->scalar which has always been a corner
case and a sketchy one (and I said numerous times that had I rewrote
the language now, array->scalar conversion would have probably
resulted in an error) - string->number, number->string,
string->boolean conversions are a cornerstone of the language. If
you don't like the fact that PHP's scalar types are interchangeable -
you're in the wrong language!In terms of consistency, the difference between array type hinting
and scalar type hinting you allude to is negligible in comparison to
the inconsistency with, well, just about every other part of the
language - operators, control structures and built-in functions
(expecting sqrt("64") to fail, sincesqrt()
expects a
number? expecting if (7) to fail, since it expects a
boolean?). Auto-converting type hinting extends the same semantics
available to internal functions (through zend_parse_parameters()) to
userland functions. That consistency is by far the most important IMHO.Zeev
I have to largely agree with Zeev here. I'm not an internals developer but I
do write a lot of widely used framework-ish open source PHP.
The current OO type specifying system I have always mentally viewed, and most
people I know seem to view it, as a check not for "is this an X", but "can I
treat this as X without things exploding"? In the context of an object,
"exploding" would mean a "method not found" fatal. In the context of an
array, it would be the dreaded "parameter 1 to foreach() is not an array".
The idea is two fold: One, better documentation (especially for code
assistance IDEs), and two, if it's going to explode it should explode in a way
that's useful in terms of where it exploded. (Vis, the error message is on a
useful line and tells me what the actual problem was.)
For scalar types, exploding would mean "loss of precision". There is no loss
of precision in converting "5" to int(5), so that doesn't explode, nor should
it. There is similarly no loss of precision converting from int(5) to
float(5), so that also shouldn't explode. "123abc" does have a loss of
precision (data would get lost in the conversion) so that should fail both int
and float checks.
If anything, I'd be even more forgiving than the table in Zeev and Lukas' RFP.
float(12) converting to an int doesn't have any precision loss so I don't think
that should fail.
The RFP includes a variety of good reasons why a more naive strict check is
inconsistent to the point of making it a bug rather than a feature. One in
particular I want to call out: Everything that comes back from a database does
so as a string. To wit:
table users(user_id, name, pass, blah);
$user_id = $pdo->query("SELECT user_id FROM users WHERE name='bob' AND
pass='foo'")->fetchColumn();
doStuff($user_id);
function doStuff(int $user_id) {
// Whatever.
}
The above code will fail with the current implementation, even though we know
for a fact that user_id is integer data because that column is an int in the
database itself. Requiring an extra blind (int) stuffed in there is pointless,
and if anything just trains people to blindly cast data without thinking about
what it really is. I can see that introducing more bugs than it avoids.
--Larry Garfield
On Saturday 22 May 2010 11:43:50 pm Zeev Suraski wrote:
At 01:01 23/05/2010, Hannes Magnusson wrote:
On Sat, May 22, 2010 at 22:39, Lukas Kahwe Smith mls@pooteeweet.org
wrote:As you wrote, you worked on PHP's type system which is dynamic,
really cool, juggles strings with ints and what not. However, the
topic here is the type hinting system. As far as I know, there's no
"weak" type hinting; if a method signature hints for an array and is
given an integer, it throws a catchable fatal error. Therefore, as a
user, what I am familiar to is a strict type hinting system.
Anything else would feel inconsistent to me.I agree. function foo(array $x) {} foo(123); doesn't cast int(123) to
array(123) so introducing different meaning for scalar types feels
very very wrong.You're ignoring one simple fact - in PHP, scalar types are
interchangeable. Unlike array->scalar which has always been a corner
case and a sketchy one (and I said numerous times that had I rewrote
the language now, array->scalar conversion would have probably
resulted in an error) - string->number, number->string,
string->boolean conversions are a cornerstone of the language. If
you don't like the fact that PHP's scalar types are interchangeable -
you're in the wrong language!In terms of consistency, the difference between array type hinting
and scalar type hinting you allude to is negligible in comparison to
the inconsistency with, well, just about every other part of the
language - operators, control structures and built-in functions
(expecting sqrt("64") to fail, sincesqrt()
expects a
number? expecting if (7) to fail, since it expects a
boolean?). Auto-converting type hinting extends the same semantics
available to internal functions (through zend_parse_parameters()) to
userland functions. That consistency is by far the most important IMHO.Zeev
I have to largely agree with Zeev here. I'm not an internals developer but I
do write a lot of widely used framework-ish open source PHP.The current OO type specifying system I have always mentally viewed, and most
people I know seem to view it, as a check not for "is this an X", but "can I
treat this as X without things exploding"? In the context of an object,
"exploding" would mean a "method not found" fatal. In the context of an
array, it would be the dreaded "parameter 1 to foreach() is not an array".
The idea is two fold: One, better documentation (especially for code
assistance IDEs), and two, if it's going to explode it should explode in a way
that's useful in terms of where it exploded. (Vis, the error message is on a
useful line and tells me what the actual problem was.)For scalar types, exploding would mean "loss of precision". There is no loss
of precision in converting "5" to int(5), so that doesn't explode, nor should
it. There is similarly no loss of precision converting from int(5) to
float(5), so that also shouldn't explode. "123abc" does have a loss of
precision (data would get lost in the conversion) so that should fail both int
and float checks.If anything, I'd be even more forgiving than the table in Zeev and Lukas' RFP.
float(12) converting to an int doesn't have any precision loss so I don't think
that should fail.The RFP includes a variety of good reasons why a more naive strict check is
inconsistent to the point of making it a bug rather than a feature. One in
particular I want to call out: Everything that comes back from a database does
so as a string. To wit:table users(user_id, name, pass, blah);
$user_id = $pdo->query("SELECT user_id FROM users WHERE name='bob' AND
pass='foo'")->fetchColumn();doStuff($user_id);
function doStuff(int $user_id) {
// Whatever.
}The above code will fail with the current implementation, even though we know
for a fact that user_id is integer data because that column is an int in the
database itself. Requiring an extra blind (int) stuffed in there is pointless,
and if anything just trains people to blindly cast data without thinking about
what it really is. I can see that introducing more bugs than it avoids.--Larry Garfield
+1
Regards
Peter
--
<hype>
WWW: http://plphp.dk / http://plind.dk
LinkedIn: http://www.linkedin.com/in/plind
Flickr: http://www.flickr.com/photos/fake51
BeWelcome: Fake51
Couchsurfing: Fake51
</hype
Everything that comes back from a database does
so as a string. To wit: [...]
This is not entirely true though. mysqlnd will return native types
through PDO or mysqli if you use prepared statements [1] and hopefully
other queries someday. [2]
As for your example, I think that this usage is within the realm of
data validation rather than type checking. The only thing I expect
from type checking is to answer this question: "is it an int? Y/N" And
that's where the schism is; the "strict" side wants type checking
to... well, check the PHP type of a variable. The "weak" side wants to
check the contents of a variable.
-JD
[1] http://blog.ulf-wendel.de/?p=193
[2] http://blog.ulf-wendel.de/?p=198
Hi!
I agree. function foo(array $x) {} foo(123); doesn't cast int(123) to
array(123) so introducing different meaning for scalar types feels
very very wrong.
Casting integers to arrays never happened in PHP. Casting strings to
integers and back always happened. Including in internal functions. Now
internal and user functions would work differently, and half of PHP
would be dynamically typed while another half would be statically typed.
I fail to see how it may be a good thing.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
As one of the key people who designed PHP's type system I consider strict
type checks completely alien to and counterintuitive in PHP and am therefore
pushing to implement 'weak' typing instead, in a way that's consistent and
familiar to users.I would normally refrain from posting on the dev list but as a "user"
I feel the need to make sure that my position isn't misrepresented, so
here it is.
OK, another 'user' input. I'll start by taking a step back and asking why
type hinting/checking seems desirable to me:
- If I write some low level function I don't want to have to check the types
of my arguments because:
a) it makes my code bigger/slower/more-complex
b) error reporting may be hard (in really generic code)
c) input should have been validated looong before it is passed to my function
d) I expect my users (who are programmers) to have read my documentation
e) I expect type errors to be rare (a reiteration of (a) above) - If there is a type error it could break my code, type checking will protect
me without the penalty of me checking. - Type hinting may allow the PHP engine to run faster;
a) eg: we know that $count is int - so no need to forever check.
b) eg: juggle $count to int when the function is called, then
it does not need to be juggled at every point that it is used.
I like the idea of strict & weak checking; they do 2 different things:
- strict checking
- Checking in the manner of === -- no juggling at all
- prob used internally within a package, eg for 'private' methods
- used where there is certainty of the type that is being passed
- weak checking
- Ensure that the value is what I expect
- Type juggle iff this can be done 100% cleanly, so allow:
- int as float
- float as int if it will pass a range check
- "12" as int, but not "12a" or ""
- Juggling is to prevent my user having to use casts
- Juggling then means that I can call functions that specify strict checking
- The user has passed the correct value, it is not just the correct
type, eg: $age is "12", a string, because it came from a validated form or
from a database.
I view strict checking as 'rigid' use within related functions.
I view weak checking as an 'input filter' to my type checked code.
I note that someone said that this would just result in people casting values without
proper checking. This may be true, but you can't protect those who won't use
the tools that you give them. Maybe there ought to be strong/weak casting...
eg (+int).
Lukas' proposal does not cover everything, eg the types of elements of an array
are not dealed with. However I believe that the checking of scalars would be
a great improvement.
Regards
--
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
Past chairman of UKUUG: http://www.ukuug.org/
#include <std_disclaimer.h
Hello,
All,
As I mentioned numerous times scalar type hinting is a very controversial
feature in my mind and requires some substantial discussion before we move
ahead to implement it.
As such, I think we should revert the patch that was committed to trunk and
move to discuss it first instead.My (& Lukas') thoughts on the subject are detailed at
http://wiki.php.net/rfc/typecheckingstrictandweakhttp://wiki.php.net/rfc/typecheckingstrictandweakAs one of the key people who designed PHP's type system I consider strict
type checks completely alien to and counterintuitive in PHP and am therefore
pushing to implement 'weak' typing instead, in a way that's consistent and
familiar to users.
-1, this table is very counter intuitive and is definitely not
consistent with the rest of PHP. Either make it strict or loose but
not halfway and in a bizarre way.
Zeev
--
--
Etienne Kneuss
http://www.colder.ch
As one of the key people who designed PHP's type system I consider
strict type checks completely alien to and counterintuitive in PHP and
am therefore pushing to implement 'weak' typing instead, in a way that's
consistent and familiar to users.-1, this table is very counter intuitive and is definitely not
consistent with the rest of PHP. Either make it strict or loose but not
halfway and in a bizarre way.
I agree. I added to the RFC a table with the current behavior of current
behavior of zend_parse_parameters (not sure if I should, feel free to move
it elsewhere). There are many differences between two. I think the
conversions should either be the same or it should be strict.
Are users supposed to distinguish "string" as it appears in the
documentation from this new "string" in the functions' declaration? Adding
another inconsistency to PHP is not a very good idea, in my opinion.
--
Gustavo Lopes
At 03:53 24/05/2010, spam@geleia.net wrote:
As one of the key people who designed PHP's type system I consider
strict type checks completely alien to and counterintuitive in PHP and
am therefore pushing to implement 'weak' typing instead, in a way that's
consistent and familiar to users.-1, this table is very counter intuitive and is definitely not
consistent with the rest of PHP. Either make it strict or loose but not
halfway and in a bizarre way.I agree. I added to the RFC a table with the current behavior of current
behavior of zend_parse_parameters (not sure if I should, feel free to move
it elsewhere). There are many differences between two. I think the
conversions should either be the same or it should be strict.Are users supposed to distinguish "string" as it appears in the
documentation from this new "string" in the functions' declaration? Adding
another inconsistency to PHP is not a very good idea, in my opinion.
I have to say that I don't really see the logic in "either it should
be identical to PHP's conversion rules or it should be 100.000%
different (strict)". Adding strict typing would be the largest
inconsistency in PHP's core syntax, ever.
For that reason, I prefer pretty much any variation of the proposed
solution over strict type checking.
I see three key options going forward:
- Implement the table along the lines of what it looks like now,
perhaps with minor changes. - Implement identical conversion rules to the ones that exist in
PHP; That effectively turns type hinting into scalar casting
operators (not saying that's a bad thing!) - Implement identical conversion rules to the ones that exist in
PHP, except for when they really suck. Namely, lose the
array->scalar conversions and silent conversions of non-numeric
strings to numbers.
I personally lean towards #3.
Zeev
On Monday 24 May 2010 12:09:30 am Zeev Suraski wrote:
I have to say that I don't really see the logic in "either it should
be identical to PHP's conversion rules or it should be 100.000%
different (strict)". Adding strict typing would be the largest
inconsistency in PHP's core syntax, ever.For that reason, I prefer pretty much any variation of the proposed
solution over strict type checking.I see three key options going forward:
- Implement the table along the lines of what it looks like now,
perhaps with minor changes.- Implement identical conversion rules to the ones that exist in
PHP; That effectively turns type hinting into scalar casting
operators (not saying that's a bad thing!)- Implement identical conversion rules to the ones that exist in
PHP, except for when they really suck. Namely, lose the
array->scalar conversions and silent conversions of non-numeric
strings to numbers.I personally lean towards #3.
Zeev
#3 is the one that seems like it would be most useful in practice, with one
caveat. If given an input of float(5.4) and a function parameter specified as
int, there is data loss if you just do the equivalent of (int)$foo so that
falls into the "really suck" category and should also explode. (float(5),
however, has no data loss in that operation so it's safe.)
I don't know if there's performance issues to address with that addition that
may nix it, but that would be the ideal.
--Larry Garfield
Hi!
I see three key options going forward:
- Implement the table along the lines of what it looks like now,
perhaps with minor changes.- Implement identical conversion rules to the ones that exist in
PHP; That effectively turns type hinting into scalar casting
operators (not saying that's a bad thing!)- Implement identical conversion rules to the ones that exist in
PHP, except for when they really suck. Namely, lose the
array->scalar conversions and silent conversions of non-numeric
strings to numbers.
I'm for 3, Array->scalar must die, as for non-numeric to numbers, I
don't have strong opinion as I see no point in it, IMO if it failed, I'd
be OK with it.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Stas Malyshev wrote:
Hi!
I see three key options going forward:
- Implement the table along the lines of what it looks like now,
perhaps with minor changes.- Implement identical conversion rules to the ones that exist in
PHP; That effectively turns type hinting into scalar casting
operators (not saying that's a bad thing!)- Implement identical conversion rules to the ones that exist in
PHP, except for when they really suck. Namely, lose the
array->scalar conversions and silent conversions of non-numeric
strings to numbers.I'm for 3, Array->scalar must die, as for non-numeric to numbers, I
don't have strong opinion as I see no point in it, IMO if it failed, I'd
be OK with it.
In case we remove 'Array->scalar' and others everywhere, #3 would be the
same as #2. I'm for that.
Thanks. Dmitry.
Hi!
In case we remove 'Array->scalar' and others everywhere, #3 would be the
same as #2. I'm for that.
AFAIK parse_parameters already rejects Array->scalar, so if we can tweak
it so that it would make sense for all cases, even better.
As for implicit/explicit casts, I'm not sure - it might make sense for
explicit cast to behave a bit differently, but maybe that's not worth
it. So if we can find a set of rules that work for all cases, such as:
implicit casts ($a+$b, "$a", etc.), explicit casts ((int)$a), internal
function and user-space functions - it'd be excellent, I'd be all for it.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
I see three key options going forward:
- Implement the table along the lines of what it looks like now, perhaps
with minor changes.- Implement identical conversion rules to the ones that exist in PHP; That
effectively turns type hinting into scalar casting operators (not saying
that's a bad thing!)- Implement identical conversion rules to the ones that exist in PHP,
except for when they really suck. Namely, lose the array->scalar
conversions and silent conversions of non-numeric strings to numbers.
Given this is a new feature, my preference is #1, with the addition of
the scalar and numeric hints mentioned upthread for less strict
checking. I see scalar type hinting as a way of saying "I want a
variable of type X", not "I want a variable that may have been lossily
coerced into type X"; the developers mentioned in the RFC who are
presently unaware of PHP's typing system strike me as being unlikely
to use type hinting regardless of how it's implemented.
That said, I don't think #3 would be the end of the world, either. My
vote is admittedly a little selfish; it just doesn't line up as well
as #1 with what I'd actually want to use scalar type hinting for.
Adam
At 03:53 24/05/2010, spam@geleia.net wrote:
As one of the key people who designed PHP's type system I consider
strict type checks completely alien to and counterintuitive in PHP
and am therefore pushing to implement 'weak' typing instead, in a
way that's consistent and familiar to users.I agree. I added to the RFC a table with the current behavior of
current behavior of zend_parse_parameters (not sure if I should, feel
free to move it elsewhere). There are many differences between two. I
think the conversions should either be the same or it should be strict.Are users supposed to distinguish "string" as it appears in the
documentation from this new "string" in the functions' declaration?
Adding another inconsistency to PHP is not a very good idea, in my
opinion.I have to say that I don't really see the logic in "either it should
be identical to PHP's conversion rules or it should be 100.000% different
(strict)". Adding strict typing would be the largest
inconsistency in PHP's core syntax, ever.
I disagree. The === operator already checks the type of the variables.
Saying that the PHP programmers shouldn't have to worry about the type of
the variables (that it's just an implementation detail) is pure fantasy.
Let's say I want to check whether some arbitrary user input is 0.
if (array_key_exists('quantity', $_POST) &&
!is_array($_POST['quantity']) && $_POST['quantity'] == 0) { ... }
Now I have the condition evaluate to true if the user input was "abc". I'm
sure I come up with lots of examples where the type is important in PHP
and the programmer must be aware of it.
For that reason, I prefer pretty much any variation of the proposed
solution over strict type checking.I see three key options going forward:
- Implement the table along the lines of what it looks like now,
perhaps with minor changes.- Implement identical conversion rules to the
ones that exist in PHP; That effectively turns type hinting into scalar
casting operators (not saying that's a bad thing!)- Implement identical conversion rules to the ones that exist in PHP,
except for when they really suck. Namely, lose the array->scalar
conversions and silent conversions of non-numeric strings to numbers.
That said, I don't think strict type checking is the best option. I just
think it's better than inventing a new complex set of rules that are
inconsistent with everything else. Otherwise, an "int" could mean that the
type is int (is_int), that zend_parse_parameters would accept it with the
flag "l" or "L", or that it is an int in this new weak sense. Maybe we
could also add "is castable to an int" (which works with arrays, but not
with objects unless they implement get/cast). That would put us at 4
different meanings.
I think the best option is to align the type checking with
zend_parse_parameters (this is not the same as an implicit cast) and make
it stricter. This includes:
- disallow string to float/int when it contains non-numeric characters
(includes "123abc") - disallow string/float to int when it causes overflow instead of the
current behavior (triple cast (long)(unsigned long)(long long)). "L" would
retain the current behavior.
Although a depart from backwards compatibility, I doubt this would cause
much brekage.
--
Gustavo Lopes
I think the best option is to align the type checking with
zend_parse_parameters (this is not the same as an implicit cast) and make
it stricter. This includes:
- disallow string to float/int when it contains non-numeric characters
(includes "123abc")- disallow string/float to int when it causes overflow instead of the
current behavior (triple cast (long)(unsigned long)(long long)). "L" would
retain the current behavior.Although a depart from backwards compatibility, I doubt this would cause
much brekage.
If you're suggesting to change the default behavior of type casts, I
think this would be a fairly big BC issue. I know I've (ab)used and
have seen it used as well by others the fact that (int)"123abc" gives
you 123, for example parsing urls that have id-some-name, you just
cast it to int and you've got the id.
I would welcome such change in the next major release, but you have to
realize it will break stuff.
As for the specific issue of type hints, I'd vote for 3rd approach,
too strict (1) will be a nightmare given PHP's flexible nature, and
current rules (2) are really too permissive so if you use that you
basically still have to validate everything, not much benefit from
adding type hints. Basically if the conversion is loss-less, it should
be allowed, otherwise the API user should validate beforehand.
Cheers
--
Jordi Boggiano
@seldaek :: http://seld.be/
At 14:48 24/05/2010, spam@geleia.net wrote:
Adding strict typing would be the largest
inconsistency in PHP's core syntax, ever.
I disagree. The === operator already checks the type of the variables.
We can agree to disagree regarding the level of understanding the
average PHP developer has about zval.type - but it doesn't change my
opinion that strict type checking would be the biggest inconsistency
in PHP's core syntax ever. These two assertions are independent from
each other.
That said, I don't think strict type checking is the best option. I just
think it's better than inventing a new complex set of rules that are
inconsistent with everything else.
Suggest we put aside the 'is strict typing better than variant X of
auto-conversion or not' discussion since it's mostly academic. I
think we both agree that we need to find the best version of auto-conversion.
I think the best option is to align the type checking with
zend_parse_parameters (this is not the same as an implicit cast) and make
it stricter. This includes:
- disallow string to float/int when it contains non-numeric characters
(includes "123abc")- disallow string/float to int when it causes overflow instead of the
current behavior (triple cast (long)(unsigned long)(long long)). "L" would
retain the current behavior.Although a depart from backwards compatibility, I doubt this would cause
much brekage.
Sounds acceptable to me, that's along the lines of the 3rd option
which appears to be getting the most traction. I'd also no
conversion of arrays to scalars to that list.
Zeev
Hi,
another end-user perspective:
Am Montag, 24. Mai 2010 14:12:41 schrieb Zeev Suraski:
At 14:48 24/05/2010, spam@geleia.net wrote:
Adding strict typing would be the largest
inconsistency in PHP's core syntax, ever.
I disagree. The === operator already checks the type of the variables.
We can agree to disagree regarding the level of understanding the
average PHP developer has about zval.type - but it doesn't change my
opinion that strict type checking would be the biggest inconsistency
in PHP's core syntax ever. These two assertions are independent from
each other.
I don't know if I have a full understanding about zval.type on internal
C-level. But in my code I always use strict type checking in comparisons and
in functions like in_array that offer that possibility. That's because I
learned the hard way how much debugging time it saves if I handle my variable
types with care. (Things like '11111111111111111' == '11111111111111112'
evaluating to true on 32 bit don't make it better.)
I'd say: the type-juggling is not the big plus of PHP. BTW: if I read
some "PHP is so enterprise-ready" articles, I never read about the advantages
of weak types. (I'd even liked it, if there would be an optional(!)
possibility of variable type declaration. Who cares, could use it - others
ignore it.)
In contrast to "normal" PHP behavior where the user doesn't care about
variable types, with type hinting in methods/functions it is explicit what's
required. Every non-strict type handling is contra-productive. So if someone
wants to use my function with hints, he needs to care about his types.
My opinion:
-
Don't introduce another kind of type juggling related to type hinting -
that's making it worse because many users won't know/see/understand the
differences. -
If it's not strict, I don't see a real advantage of type hinting (besides
static code analysis and no need to declare types in doc blocks). -
If you want to support weak type hints, declare strict and weak hints.
Because I like strict type checks. And I don't see, why I shouldn't be able
to have strict checks but others that do not care about their types should
have something that looks like type hinting. (I guess, they won't use it
anyway if they don't care about types.) PHP offers both ways of strict and
weak handling with comparisons and some functions - so it should offer both
ways here as well. -
If you don't want to distinguish beetween strict and weak hints, create some
ini setting that influences the behavior. (I'm not a fan of that.) -
I see that there will be problems when a developer, who doesn't care about
types, wants to use an external library with strict hinting. So perhaps the
way to go is: provide strict and weak hinting plus an ini setting to reduce
strict to weak hints if someone wants to include a "strict" library. (I guess
the other way round - make weak hints to strict hints - is probably not so
usefull, as I can't rely on a library with weak hinting to be 100% strict
hinting compliant internally.)
I hope this post is not to offensive. Just wanted to make my point clear that
I want to be able to use strict hinting, because I don't like the weak types
regarding software quality. (No, I'm not using the wrong language.)
Regards,
Thomas
That said, I don't think strict type checking is the best option. I just
think it's better than inventing a new complex set of rules that are
inconsistent with everything else.Suggest we put aside the 'is strict typing better than variant X of
auto-conversion or not' discussion since it's mostly academic. I
think we both agree that we need to find the best version of
auto-conversion.I think the best option is to align the type checking with
zend_parse_parameters (this is not the same as an implicit cast) and make
it stricter. This includes:
- disallow string to float/int when it contains non-numeric characters
(includes "123abc")- disallow string/float to int when it causes overflow instead of the
current behavior (triple cast (long)(unsigned long)(long long)). "L" would
retain the current behavior.Although a depart from backwards compatibility, I doubt this would cause
much brekage.Sounds acceptable to me, that's along the lines of the 3rd option
which appears to be getting the most traction. I'd also no
conversion of arrays to scalars to that list.Zeev
Hi Zeev:
- Implement the table along the lines of what it looks like now,
perhaps with minor changes.- Implement identical conversion rules to the ones that exist in PHP;
That effectively turns type hinting into scalar casting operators (not
saying that's a bad thing!)- Implement identical conversion rules to the ones that exist in PHP,
except for when they really suck. Namely, lose the array->scalar
conversions and silent conversions of non-numeric strings to numbers.
My preference depends on what option 3 really means and what tweaks would
be made to 1. I like the RFC's "list of examples" table over the
recently added "zend_parse_parameters" table.
Important changes to the example table seem to be:
- string representations of int would be okay for int and float
- string representations of float would be okay for float
- maybe have null and '' be okay as bool.
On a side note, I hope the hinting will allow the ability to do something
something like "int|null" for graceful handling of optional parameters.
Thanks,
--Dan
--
T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y
data intensive web and database programming
http://www.AnalysisAndSolutions.com/
4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409
At 18:39 24/05/2010, Daniel Convissor wrote:
On a side note, I hope the hinting will allow the ability to do something
something like "int|null" for graceful handling of optional parameters.
There was an idea to allow null if you use 'int foo = null' - but
only that particular use case (e.g., no support for the equivalent of
string|int).
Zeev