PHP currently allows users to provide type hints for functions and methods,
although the type hints are currently limited to objects and arrays:
http://en.wikipedia.org/wiki/Type_system#Variable_levels_of_type_checking
Restricting the type hinting to arrays and objects makes sense, as PHP's
type juggling (similar in many ways to JavaScript's), a core feature of the
language, performs automatic conversions between scalars as determined by
context:
http://php.net/manual/en/language.types.type-juggling.php
However, the lack of scalar hinting does limit the ability of a developer
to declare his/her intentions for function/method parameters. A non-hinted
parameter expecting a scalar could be sent an object or an array, breaking
the expectations (and much of the time, the functionality) of the code.
That is to say, there is a value in declaring what the parameter IS NOT,
too.
For example, the function below could have an object or array passed as the
first argument, even though the expectation is a scalar:
function foo($arg){
// $arg is supposed to be a scalar and will be used as an int
}
What if PHP added the hint scalar? The example could be rewritten as:
function foo(scalar $arg){
// $arg is supposed to be a scalar and will be used as an int
}
The idea is that the failure to send a valid scalar argument to the
function would result in the same feedback that currently occurs when array
or object hints are not heeded. Now, the expectations for each
function/method parameter can be explicitly declared (or, at least, more
explicitly.)
And, what if PHP added the following aliases for the hint scalar:
- bool
- int
- float
- string
The function could then be rewritten as below:
function foo(int $arg){
// $arg is supposed to be a scalar and will be used as an int
}
Now, the aliases wouldn't buy any more precision in terms of PHP's parser
expectations. Your function/method parameters can only expect objects,
arrays, or scalars. However, the aliases would allow developers to better
communicate intentions AND provide more information for IDE's and static
analyses tools. And, again, the use of the scalar hint and its aliases
would preclude sending objects and arrays to functions expecting otherwise.
I realize this subject is heated, and people's patience has worn thin. I'm
just hoping to toss out this idea I've had for some time while all of the
concerns on both sides are still fresh in my head.
Thanks for reading :)
Adam
However, the aliases would allow developers to better communicate
intentions AND provide more information for IDE's and static analyses
tools.
-
You are trying to solve a social problem through technology. That
usually does not work. -
What you want to achieve is already possible through docblocks.
--
Sebastian Bergmann Co-Founder and Principal Consultant
http://sebastian-bergmann.de/ http://thePHP.cc/
First, phpunit is a fantastic tool! I'm thankful for your contributions to
all of the PHP community (especially with the code coverage capabilities.)
I speak to your 2 points inline below:
On Wed, Feb 29, 2012 at 9:36 PM, Sebastian Bergmann sebastian@php.netwrote:
However, the aliases would allow developers to better communicate
intentions AND provide more information for IDE's and static analyses
tools.
- You are trying to solve a social problem through technology. That
usually does not work.
I believe technology can provide effective tools for social problems,
although I won't go so far as to say that it usually does work. More
importantly, I believe programming is riddled with social problems:
"Let us change our traditional attitude to the construction of programs.
Instead of imagining that our main task is to instruct a computer what to
do, let us concentrate rather on explaining to human beings what we want a
computer to do."
D. Knuth
- What you want to achieve is already possible through docblocks.
The greater part of the proposal rests on the general scalar hint. That
said, I still believe the aliases for the scalars hold value. Sure, the
communicative aspect of the aliases can be achieved through use of
docblocks. However, in cognitive psychology and human factors research,
proximity of relevant information plays a role in perception and
processing, and I would posit that code with the type intentions displayed
closer to the actual body of the function would hold benefits (this would
be very testable, though, and research could prove me wrong.) When
available, the scalar aliases could then be used to help auto-generate the
docblocks.
I would appreciate the scalar hinting, along with the aliases I outlined
very much in my code. I believe that this form of hinting stays true to the
PHP principles outlined in Richard's PHP Philosophy thread (a great read),
and I believe it helps developers who want to better enforce (scalar
hinting) and communicate (scalar aliases) the intentions of their code.
Thank you for the feedback,
Adam
Hi, Adam
I just get the feeling that this is exactly what we're currently discovered
in some other threads in this mailing-list.
We're now getting more and more closer to what we really want and a good
way to write it the PHP-way.
Please try to get a rough overview over the last messages we wrote on the
following threads:
- [PHP-DEV] PHP Philosophy (was RE: [PHP-DEV] Scalar type hinting)
- RE: [PHP-DEV] Scalar type hinting
The second one is quite big ;) and sometimes the messages contain only
religious stuff like "This will never be, go away" - but that's just
because we're in discussion. Like the wind blows. But I think we'll get to
list of rock-solid possible solutions here.
I think we'll soon create a RFC for that and discuss it after we have it
"on one paper".
I would kind-of like the idea to add the *scalar *type in addition just to
avoid objects or arrays in there, but let's look how the discussion goes.
Bye
Simon
2012/3/1 Adam Jon Richardson adamjonr@gmail.com
First, phpunit is a fantastic tool! I'm thankful for your contributions to
all of the PHP community (especially with the code coverage capabilities.)I speak to your 2 points inline below:
On Wed, Feb 29, 2012 at 9:36 PM, Sebastian Bergmann <sebastian@php.net
wrote:
However, the aliases would allow developers to better communicate
intentions AND provide more information for IDE's and static analyses
tools.
- You are trying to solve a social problem through technology. That
usually does not work.I believe technology can provide effective tools for social problems,
although I won't go so far as to say that it usually does work. More
importantly, I believe programming is riddled with social problems:"Let us change our traditional attitude to the construction of programs.
Instead of imagining that our main task is to instruct a computer what to
do, let us concentrate rather on explaining to human beings what we want a
computer to do."D. Knuth
- What you want to achieve is already possible through docblocks.
The greater part of the proposal rests on the general scalar hint. That
said, I still believe the aliases for the scalars hold value. Sure, the
communicative aspect of the aliases can be achieved through use of
docblocks. However, in cognitive psychology and human factors research,
proximity of relevant information plays a role in perception and
processing, and I would posit that code with the type intentions displayed
closer to the actual body of the function would hold benefits (this would
be very testable, though, and research could prove me wrong.) When
available, the scalar aliases could then be used to help auto-generate the
docblocks.I would appreciate the scalar hinting, along with the aliases I outlined
very much in my code. I believe that this form of hinting stays true to the
PHP principles outlined in Richard's PHP Philosophy thread (a great read),
and I believe it helps developers who want to better enforce (scalar
hinting) and communicate (scalar aliases) the intentions of their code.Thank you for the feedback,
Adam
hi Sebastian,
usually does not work.
2) What you want to achieve is already possible through docblocks.
I am not saying that I like the idea of scalar type arguments, but you
keep saying that docblocks solve such issue. They are totally
unrelated to what is discussed here, they are documentations. They
have nothing to do with runtime information (The same concept applied
to the annotations, if you remember it).
However, following your logic, class type hinting was a mistake?
Cheers,
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
However, following your logic, class type hinting was a mistake?
The Type Hinting we currently have for arrays, callables, classes, and
interfaces is not a mistake. Why? Because the types in question are not
affected by the "type juggling".
--
Sebastian Bergmann Co-Founder and Principal Consultant
http://sebastian-bergmann.de/ http://thePHP.cc/
However, following your logic, class type hinting was a mistake?
The Type Hinting we currently have for arrays, callables, classes, and
interfaces is not a mistake. Why? Because the types in question are not
affected by the "type juggling".
That's a different discussion, your second argument is simply plain wrong.
--
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
Pierre Joye wrote:
usually does not work.
- What you want to achieve is already possible through docblocks.
I am not saying that I like the idea of scalar type arguments, but you
keep saying that docblocks solve such issue. They are totally
unrelated to what is discussed here, they are documentations. They
have nothing to do with runtime information (The same concept applied
to the annotations, if you remember it).
But one of the reasons given for wanting this is as simple documentation?
Does providing more checks at runtime actually add anything when in many cases
we already need to check for valid input anyway. I can't help thinking that in
many cases people proposing this are working on a basis that the variables they
are passing are fully nailed down as to what is in them? When in practice we are
not passing well typed variables around - until they have been checked.
It would be interesting to establish just how many developers already use IDE's
which provide all of this hinting and more important detailed error checking
which does not rely on adding anything more to the runtime engine. I kill most
of these problems before the scripts ever get run anyway ...
--
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//
Firebird - http://www.firebirdsql.org/index.php
However, the lack of scalar hinting does limit the ability of a developer
to declare his/her intentions for function/method parameters. A non-hinted
parameter expecting a scalar could be sent an object or an array, breaking
the expectations (and much of the time, the functionality) of the code.
That is to say, there is a value in declaring what the parameter IS NOT,
too.
+1
What if PHP added the hint scalar? The example could be rewritten as:
function foo(scalar $arg){
// $arg is supposed to be a scalar and will be used as an int
}The idea is that the failure to send a valid scalar argument to the
function would result in the same feedback that currently occurs when array
or object hints are not heeded. Now, the expectations for each
function/method parameter can be explicitly declared (or, at least, more
explicitly.)
And, what if PHP added the following aliases for the hint scalar:
- bool
- int
- float
- string
The function could then be rewritten as below:
function foo(int $arg){
// $arg is supposed to be a scalar and will be used as an int
}
A nice compromise for a heated issue. This would also open the way to more
complete checking (as has been discussed) at some time in the future.
It would provide a better alternative to some of the ghastly pseudo comment
conventions that are currently used as means of documentations.
Programming is about communication of intent, not just with the computer
(compiler) but also with programmers who subsequently read the code.
--
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
And, what if PHP added the following aliases for the hint scalar:
-
bool
-
int
-
float
-
string
If an object has a __toString method, does it qualify as a valid value to
be passed to a scalar argument? In my opinion, it should.
Your suggestion has a future compatibility problem. The introduction of new
type casting methods (like __toInt or like __castTo) is an open
possibility. In such a case, if those keywords are nothing but aliases for
"scalar", then there will be no way to choose which type casting method
should be chosen.
Lazare INEPOLOGLOU
Ingénieur Logiciel
2012/3/1 Adam Jon Richardson adamjonr@gmail.com
PHP currently allows users to provide type hints for functions and methods,
although the type hints are currently limited to objects and arrays:
http://en.wikipedia.org/wiki/Type_system#Variable_levels_of_type_checkingRestricting the type hinting to arrays and objects makes sense, as PHP's
type juggling (similar in many ways to JavaScript's), a core feature of the
language, performs automatic conversions between scalars as determined by
context:
http://php.net/manual/en/language.types.type-juggling.phpHowever, the lack of scalar hinting does limit the ability of a developer
to declare his/her intentions for function/method parameters. A non-hinted
parameter expecting a scalar could be sent an object or an array, breaking
the expectations (and much of the time, the functionality) of the code.
That is to say, there is a value in declaring what the parameter IS NOT,
too.For example, the function below could have an object or array passed as the
first argument, even though the expectation is a scalar:function foo($arg){
// $arg is supposed to be a scalar and will be used as an int
}What if PHP added the hint scalar? The example could be rewritten as:
function foo(scalar $arg){
// $arg is supposed to be a scalar and will be used as an int
}The idea is that the failure to send a valid scalar argument to the
function would result in the same feedback that currently occurs when array
or object hints are not heeded. Now, the expectations for each
function/method parameter can be explicitly declared (or, at least, more
explicitly.)And, what if PHP added the following aliases for the hint scalar:
- bool
- int
- float
- string
The function could then be rewritten as below:
function foo(int $arg){
// $arg is supposed to be a scalar and will be used as an int
}Now, the aliases wouldn't buy any more precision in terms of PHP's parser
expectations. Your function/method parameters can only expect objects,
arrays, or scalars. However, the aliases would allow developers to better
communicate intentions AND provide more information for IDE's and static
analyses tools. And, again, the use of the scalar hint and its aliases
would preclude sending objects and arrays to functions expecting otherwise.I realize this subject is heated, and people's patience has worn thin. I'm
just hoping to toss out this idea I've had for some time while all of the
concerns on both sides are still fresh in my head.Thanks for reading :)
Adam
On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou linepogl@gmail.comwrote:
And, what if PHP added the following aliases for the hint scalar:
bool
int
float
string
If an object has a __toString method, does it qualify as a valid value to
be passed to a scalar argument? In my opinion, it should.Your suggestion has a future compatibility problem. The introduction of
new type casting methods (like __toInt or like __castTo) is an open
possibility. In such a case, if those keywords are nothing but aliases for
"scalar", then there will be no way to choose which type casting method
should be chosen.Lazare INEPOLOGLOU
Ingénieur Logiciel
You raise interesting points, Lazare, but I don't believe the compatibility
issues you're concerned about are valid.
Failing fast, similar to the Poka-Yoke principal in manufacturing, suggests
that system failure should occur as soon as possible to reduce software
bugs:
http://www.martinfowler.com/ieeeSoftware/failFast.pdf
Consider the following example:
// example class that does not implement __toString()
class test{
}
function foo($arg1, $arg2, $arg3){
if ($arg1) {
return "The answer is: " . $arg1;
}
if ($arg2) {
return "The answer is: " . $arg2;
}
if ($arg3) {
return "The answer is: " . $arg3;
}
}
$test = new test();
echo foo($arg1 = "string", $arg2 = 100, $arg3 = $test); // echos The answer
is: string
echo foo($arg1 = false, $arg2 = 100, $arg3 = $test); // echos The answer
is: 100
echo foo($arg1 = false, $arg2 = false, $arg3 = $test); // catchable fatal
error
A developer using this function would only see this issue some of the time,
as this code fails late WITHIN some branches of the function, and the bug
is harder to identify.
We can do better, though. If the scalar type hint were applied, users would
merely have to cast the object to a string ON ENTRY to the function (and,
of note, this would work for your __toInt and __castTo concerns):
echo foo($arg1 = "string", $arg2 = 100, $arg3 = (string)$test);
// catchable fatal error
Because the cast is performed on entry to the call, the bug shows up
immediately. I would argue that this code is clean (the cast to string in
the foo() call is a small amount of noise/keystrokes), visibly conformant
to the intentions of the foo() function, and more likely to catch bugs
early on in the process.
Adam
Yes, I agree, the casting (or the failing to cast) has to happen on entry,
for the reasons that you have very well explained.
However, I cannot understand what it means to cast an object to a scalar.
Does it always mean casting to string? Wouldn't that be slow in many cases?
Simple example:
class A {
public $value = 1234;
public function __toString(){ return (string)$this->value; }
}
function foo( int $x ) { // here "int" is used as an alias to "scalar" as
you suggest
return $x + 1;
}
$a = new A;
foo( $a ); // casting $a to scalar upon calling, as it is possible after
all
In this example, the integer value will have to be cast to a string only to
be cast back to integer (unless something else happens under the hoods that
I am not aware).
Lazare INEPOLOGLOU
Ingénieur Logiciel
2012/3/1 Adam Jon Richardson adamjonr@gmail.com
On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou linepogl@gmail.comwrote:
And, what if PHP added the following aliases for the hint scalar:
bool
int
float
string
If an object has a __toString method, does it qualify as a valid value to
be passed to a scalar argument? In my opinion, it should.Your suggestion has a future compatibility problem. The introduction of
new type casting methods (like __toInt or like __castTo) is an open
possibility. In such a case, if those keywords are nothing but aliases for
"scalar", then there will be no way to choose which type casting method
should be chosen.Lazare INEPOLOGLOU
Ingénieur LogicielYou raise interesting points, Lazare, but I don't believe the
compatibility issues you're concerned about are valid.Failing fast, similar to the Poka-Yoke principal in manufacturing,
suggests that system failure should occur as soon as possible to reduce
software bugs:
http://www.martinfowler.com/ieeeSoftware/failFast.pdfConsider the following example:
// example class that does not implement __toString()
class test{
}function foo($arg1, $arg2, $arg3){
if ($arg1) {
return "The answer is: " . $arg1;
}if ($arg2) {
return "The answer is: " . $arg2;
}if ($arg3) {
return "The answer is: " . $arg3;
}
}$test = new test();
echo foo($arg1 = "string", $arg2 = 100, $arg3 = $test); // echos The
answer is: string
echo foo($arg1 = false, $arg2 = 100, $arg3 = $test); // echos The answer
is: 100
echo foo($arg1 = false, $arg2 = false, $arg3 = $test); // catchable fatal
errorA developer using this function would only see this issue some of the
time, as this code fails late WITHIN some branches of the function, and the
bug is harder to identify.We can do better, though. If the scalar type hint were applied, users
would merely have to cast the object to a string ON ENTRY to the function
(and, of note, this would work for your __toInt and __castTo concerns):echo foo($arg1 = "string", $arg2 = 100, $arg3 = (string)$test);
// catchable fatal errorBecause the cast is performed on entry to the call, the bug shows up
immediately. I would argue that this code is clean (the cast to string in
the foo() call is a small amount of noise/keystrokes), visibly conformant
to the intentions of the foo() function, and more likely to catch bugs
early on in the process.Adam
Please do not implement int, float, etc as an alias to scalar. That's
going to cause nothing but trouble later on. It will instantly close
the door to any type of casting magic (due to BC concerns), be
completely non-obvious ("I hinted for int, why is it a boolean?"), and
cause nothing but confusion.
If you only want to add a scalar hint, I'm fine with that (for now),
but please only add the scalar hint, no aliases...
Anthony
Yes, I agree, the casting (or the failing to cast) has to happen on entry,
for the reasons that you have very well explained.However, I cannot understand what it means to cast an object to a scalar.
Does it always mean casting to string? Wouldn't that be slow in many cases?
Simple example:class A {
public $value = 1234;
public function __toString(){ return (string)$this->value; }
}function foo( int $x ) { // here "int" is used as an alias to "scalar" as
you suggest
return $x + 1;
}$a = new A;
foo( $a ); // casting $a to scalar upon calling, as it is possible after
allIn this example, the integer value will have to be cast to a string only to
be cast back to integer (unless something else happens under the hoods that
I am not aware).Lazare INEPOLOGLOU
Ingénieur Logiciel2012/3/1 Adam Jon Richardson adamjonr@gmail.com
On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou linepogl@gmail.comwrote:
And, what if PHP added the following aliases for the hint scalar:
bool
int
float
string
If an object has a __toString method, does it qualify as a valid value to
be passed to a scalar argument? In my opinion, it should.Your suggestion has a future compatibility problem. The introduction of
new type casting methods (like __toInt or like __castTo) is an open
possibility. In such a case, if those keywords are nothing but aliases for
"scalar", then there will be no way to choose which type casting method
should be chosen.Lazare INEPOLOGLOU
Ingénieur LogicielYou raise interesting points, Lazare, but I don't believe the
compatibility issues you're concerned about are valid.Failing fast, similar to the Poka-Yoke principal in manufacturing,
suggests that system failure should occur as soon as possible to reduce
software bugs:
http://www.martinfowler.com/ieeeSoftware/failFast.pdfConsider the following example:
// example class that does not implement __toString()
class test{
}function foo($arg1, $arg2, $arg3){
if ($arg1) {
return "The answer is: " . $arg1;
}if ($arg2) {
return "The answer is: " . $arg2;
}if ($arg3) {
return "The answer is: " . $arg3;
}
}$test = new test();
echo foo($arg1 = "string", $arg2 = 100, $arg3 = $test); // echos The
answer is: string
echo foo($arg1 = false, $arg2 = 100, $arg3 = $test); // echos The answer
is: 100
echo foo($arg1 = false, $arg2 = false, $arg3 = $test); // catchable fatal
errorA developer using this function would only see this issue some of the
time, as this code fails late WITHIN some branches of the function, and the
bug is harder to identify.We can do better, though. If the scalar type hint were applied, users
would merely have to cast the object to a string ON ENTRY to the function
(and, of note, this would work for your __toInt and __castTo concerns):echo foo($arg1 = "string", $arg2 = 100, $arg3 = (string)$test);
// catchable fatal errorBecause the cast is performed on entry to the call, the bug shows up
immediately. I would argue that this code is clean (the cast to string in
the foo() call is a small amount of noise/keystrokes), visibly conformant
to the intentions of the foo() function, and more likely to catch bugs
early on in the process.Adam
Please do not implement int, float, etc as an alias to scalar. That's
going to cause nothing but trouble later on. It will instantly close
the door to any type of casting magic (due to BC concerns), be
completely non-obvious ("I hinted for int, why is it a boolean?"), and
cause nothing but confusion.If you only want to add a scalar hint, I'm fine with that (for now),
but please only add the scalar hint, no aliases...Anthony
Anthony, can you provide an example so I can better understand your
concerns?
Thanks,
Adam
Adam,
Sure. Basically, if you alias the int hint to scalar:
function foo(int $i) {
}
The following are all valid values for $i:
$i = 1;
$i = 1.5;
$i = "1.9"
$i = "foo"
$i = true
$i = fopen($file);
So, in the future, if we wanted to implement loss-less casting
(casting if possible without loosing information, but erroring
otherwise, so passing "foo" to (int $i) would generate an error.
This will change the meaning of the int type hint, so production code
using it will break. Therefore we wouldn't be able to add magic
casting because of BC breaks...
Whereas if you implemented just the scalar hint without the aliases,
it wouldn't be a problem at all to add them, since there would be no
BC break at all...
Anthony
Please do not implement int, float, etc as an alias to scalar. That's
going to cause nothing but trouble later on. It will instantly close
the door to any type of casting magic (due to BC concerns), be
completely non-obvious ("I hinted for int, why is it a boolean?"), and
cause nothing but confusion.If you only want to add a scalar hint, I'm fine with that (for now),
but please only add the scalar hint, no aliases...Anthony
Anthony, can you provide an example so I can better understand your
concerns?Thanks,
Adam
On Thu, Mar 1, 2012 at 8:33 AM, Lazare Inepologlou linepogl@gmail.comwrote:
Yes, I agree, the casting (or the failing to cast) has to happen on entry,
for the reasons that you have very well explained.However, I cannot understand what it means to cast an object to a scalar.
Does it always mean casting to string? Wouldn't that be slow in many cases?
Simple example:
I'm not sure I understand, so if I mischaracterize your concerns, please
let me know.
Of note, the scalar type hinting I've outlined does not automatically
perform casts to any particular type of scalar. Rather, it would be the
programmer's responsibility to perform the cast (as I performed in my
example.) This way, only necessary, reasonable casts are performed, and
information loss can be avoided.
That said, in terms of performance, PHP's type juggling performs these
types of casts all the time, so I don't think I'd be concerned. Any time we
check for equality using ==, perform string concatenation with ints, etc.,
PHP's beautiful type juggling automatically performs these conversions for
us without any effort on our part. I've never seen where this is the source
of any performance issues in my profiling, but I must admit that I don't
know the internals well enough to preclude this from ever being an issue.
class A {
public $value = 1234;
public function __toString(){ return (string)$this->value; }
}function foo( int $x ) { // here "int" is used as an alias to "scalar" as
you suggest
return $x + 1;
}$a = new A;
foo( $a ); // casting $a to scalar upon calling, as it is possible after
allIn this example, the integer value will have to be cast to a string only
to be cast back to integer (unless something else happens under the hoods
that I am not aware).
Speaking to your example, it would throw a catchable fatal error because
the variable $a contains an object of type A and the function foo expects a
scalar. The object would first have to be cast to a scalar. However, as you
pointed out, currently objects can only implement the __toString() method
(i.e., there's no __toInt, etc.), so one can't directly cast an object to
an int.
This seems contrived, though, because in the case of your example, if a
function expects an integer, wouldn't you just call it with the appropriate
object property:
foo ($a->value); // works because the value property is a scalar (int)
Thanks for your commentary :)
Adam
Of note, the scalar type hinting I've outlined does not automatically
perform casts...
Thank you for your answer. Maybe, this exact fact is what I don't like
about your suggestion. Please read the following RFC, where Lukas Smith and
Zeev Suraski explain very well why strict type checking without
auto-casting is a not a great idea. Of course it is just an RFC, but I find
it quite correct.
https://wiki.php.net/rfc/typecheckingstrictandweak
My concern is that if your suggestion is adopted (as it is, without
auto-casting) then an eventual introduction of auto-casting will be
impossible without breaking BC.
Lazare INEPOLOGLOU
Ingénieur Logiciel
2012/3/1 Adam Jon Richardson adamjonr@gmail.com
On Thu, Mar 1, 2012 at 8:33 AM, Lazare Inepologlou linepogl@gmail.comwrote:
Yes, I agree, the casting (or the failing to cast) has to happen on
entry, for the reasons that you have very well explained.However, I cannot understand what it means to cast an object to a scalar.
Does it always mean casting to string? Wouldn't that be slow in many cases?
Simple example:I'm not sure I understand, so if I mischaracterize your concerns, please
let me know.Of note, the scalar type hinting I've outlined does not automatically
perform casts to any particular type of scalar. Rather, it would be the
programmer's responsibility to perform the cast (as I performed in my
example.) This way, only necessary, reasonable casts are performed, and
information loss can be avoided.That said, in terms of performance, PHP's type juggling performs these
types of casts all the time, so I don't think I'd be concerned. Any time we
check for equality using ==, perform string concatenation with ints, etc.,
PHP's beautiful type juggling automatically performs these conversions for
us without any effort on our part. I've never seen where this is the source
of any performance issues in my profiling, but I must admit that I don't
know the internals well enough to preclude this from ever being an issue.class A {
public $value = 1234;
public function __toString(){ return (string)$this->value; }
}function foo( int $x ) { // here "int" is used as an alias to "scalar"
as you suggest
return $x + 1;
}$a = new A;
foo( $a ); // casting $a to scalar upon calling, as it is possible
after allIn this example, the integer value will have to be cast to a string only
to be cast back to integer (unless something else happens under the hoods
that I am not aware).Speaking to your example, it would throw a catchable fatal error because
the variable $a contains an object of type A and the function foo expects a
scalar. The object would first have to be cast to a scalar. However, as you
pointed out, currently objects can only implement the __toString() method
(i.e., there's no __toInt, etc.), so one can't directly cast an object to
an int.This seems contrived, though, because in the case of your example, if a
function expects an integer, wouldn't you just call it with the appropriate
object property:foo ($a->value); // works because the value property is a scalar (int)
Thanks for your commentary :)
Adam
On Thu, Mar 1, 2012 at 10:36 AM, Lazare Inepologlou linepogl@gmail.comwrote:
Of note, the scalar type hinting I've outlined does not automatically
perform casts...
Thank you for your answer. Maybe, this exact fact is what I don't like
about your suggestion. Please read the following RFC, where Lukas Smith and
Zeev Suraski explain very well why strict type checking without
auto-casting is a not a great idea. Of course it is just an RFC, but I find
it quite correct.
https://wiki.php.net/rfc/typecheckingstrictandweak
I believe we interpret that RFC differently. Those who wrote it can correct
me if I'm in error. The RFC is a very interesting approach to providing
some form of type hinting for scalar parameters in functions and methods. I
liked the RFC, but I understand some of the concerns that come up when
discussing something like it.
First, I believe that when the RFC contrasts strict and weak typing, it
would be fair to say this is what many others would describe as strong vs
weak typing:
http://en.wikipedia.org/wiki/Type_system#Strong_and_weak_typing
The RFC makes the case that strict typing is "is an alien concept to PHP",
and that it "goes against PHP's type system", while pointing out other
issues. The RFC makes it clear that trying to map strict typing onto PHP is
problematic, and on this issue I tend to agree.
The RFC then offers three options for weak type hinting. One main point I'd
bring out for all of the options is that they all strengthen the typing
(that is, while still a weak type system, it moves slightly towards the
strong side of the continuum) beyond PHP's default type juggling rules
because some type of error would be raised in the event of data loss.
So, their proposal outlines weak forms of type hinting for scalars, and
mine is similar but weaker, as there is no auto casting, there are no new
errors raised for data loss, and all checks are against the generic scalar
type (whether with or without the aliases.) This brings my proposal even
closer to the fundamental typing characteristics of PHP, whilst protecting
against the potential errors pointed out in my earlier examples.
My concern is that if your suggestion is adopted (as it is, without
auto-casting) then an eventual introduction of auto-casting will be
impossible without breaking BC.
This is a potential concern if the aliases for scalar were included (bool,
int, float, string), as Anthony mentioned, although merely implementing the
first part of the proposal (scalar type hinting) wouldn't cause any trouble.
However, the more a proposal moves away from PHP's current typing
conventions, the less likely it is to be considered, let alone approved.
I'm not confident a more aggressive proposal (e.g., auto-casting with
checks for information loss) would be approved any time soon. PHP is one of
the most practically oriented programming languages I'm aware of, and my
practicalities just want to put forward ideas that improve some issues AND
that might actually get done :)
Again, thanks for the commentary, Lazare.
Adam
This is a potential concern if the aliases for scalar were included (bool,
int, float, string), as Anthony mentioned, although merely implementing the
first part of the proposal (scalar type hinting) wouldn't cause any trouble.
Yes, exactly. I was only talking about this specific aspect.
Otherwise, it is a fine and welcome proposal. I would love to have
type-checking as long as it does not close the door to type-juggling some
time in the future.
Lazare INEPOLOGLOU
Ingénieur Logiciel
2012/3/1 Adam Jon Richardson adamjonr@gmail.com
On Thu, Mar 1, 2012 at 10:36 AM, Lazare Inepologlou linepogl@gmail.comwrote:
Of note, the scalar type hinting I've outlined does not automatically
perform casts...
Thank you for your answer. Maybe, this exact fact is what I don't like
about your suggestion. Please read the following RFC, where Lukas Smith and
Zeev Suraski explain very well why strict type checking without
auto-casting is a not a great idea. Of course it is just an RFC, but I find
it quite correct.https://wiki.php.net/rfc/typecheckingstrictandweak
I believe we interpret that RFC differently. Those who wrote it can
correct me if I'm in error. The RFC is a very interesting approach to
providing some form of type hinting for scalar parameters in functions and
methods. I liked the RFC, but I understand some of the concerns that come
up when discussing something like it.First, I believe that when the RFC contrasts strict and weak typing, it
would be fair to say this is what many others would describe as strong vs
weak typing:http://en.wikipedia.org/wiki/Type_system#Strong_and_weak_typing
The RFC makes the case that strict typing is "is an alien concept to PHP",
and that it "goes against PHP's type system", while pointing out other
issues. The RFC makes it clear that trying to map strict typing onto PHP is
problematic, and on this issue I tend to agree.The RFC then offers three options for weak type hinting. One main point
I'd bring out for all of the options is that they all strengthen the typing
(that is, while still a weak type system, it moves slightly towards the
strong side of the continuum) beyond PHP's default type juggling rules
because some type of error would be raised in the event of data loss.So, their proposal outlines weak forms of type hinting for scalars, and
mine is similar but weaker, as there is no auto casting, there are no new
errors raised for data loss, and all checks are against the generic scalar
type (whether with or without the aliases.) This brings my proposal even
closer to the fundamental typing characteristics of PHP, whilst protecting
against the potential errors pointed out in my earlier examples.My concern is that if your suggestion is adopted (as it is, without
auto-casting) then an eventual introduction of auto-casting will be
impossible without breaking BC.This is a potential concern if the aliases for scalar were included (bool,
int, float, string), as Anthony mentioned, although merely implementing the
first part of the proposal (scalar type hinting) wouldn't cause any trouble.However, the more a proposal moves away from PHP's current typing
conventions, the less likely it is to be considered, let alone approved.
I'm not confident a more aggressive proposal (e.g., auto-casting with
checks for information loss) would be approved any time soon. PHP is one of
the most practically oriented programming languages I'm aware of, and my
practicalities just want to put forward ideas that improve some issues AND
that might actually get done :)Again, thanks for the commentary, Lazare.
Adam