Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] Scalar Type Intentions

Posted by Adam Jon Richardson 
Adam Jon Richardson
[PHP-DEV] Scalar Type Intentions
March 01, 2012 03:11AM
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
Sebastian Bergmann
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 03:41AM
On 02/29/2012 09:01 PM, Adam Jon Richardson wrote:
> However, the aliases would allow developers to better communicate
> intentions AND provide more information for IDE's and static analyses
> tools.

1) You are trying to solve a social problem through technology. That
usually does not work.

2) What you want to achieve is already possible through docblocks.

--
Sebastian Bergmann Co-Founder and Principal Consultant
http://sebastian-bergmann.de/ http://thePHP.cc/

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Adam Jon Richardson
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 06:00AM
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 <[email protected]>wrote:

> On 02/29/2012 09:01 PM, Adam Jon Richardson wrote:
>
>> However, the aliases would allow developers to better communicate
>> intentions AND provide more information for IDE's and static analyses
>> tools.
>>
>
> 1) 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

2) 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
Simon Schick
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 09:50AM
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 <[email protected]>

> 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 <[email protected]
> >wrote:
>
> > On 02/29/2012 09:01 PM, Adam Jon Richardson wrote:
> >
> >> However, the aliases would allow developers to better communicate
> >> intentions AND provide more information for IDE's and static analyses
> >> tools.
> >>
> >
> > 1) 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
>
> 2) 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
>
Alain Williams
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 10:00AM
On Wed, Feb 29, 2012 at 09:01:05PM -0500, Adam Jon Richardson wrote:

> 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>

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Pierre Joye
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 10:21AM
hi Sebastian,

On Thu, Mar 1, 2012 at 3:36 AM, Sebastian Bergmann <[email protected]> wrote:
 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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Lazare Inepologlou
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 10:40AM
>
> 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 <[email protected]>

> 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
>
Sebastian Bergmann
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 10:40AM
On 03/01/2012 04:13 AM, Pierre Joye wrote:
> 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/

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Lester Caine
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 10:50AM
Pierre Joye wrote:
> On Thu, Mar 1, 2012 at 3:36 AM, Sebastian Bergmann<[email protected]> wrote:
> 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).

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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Pierre Joye
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 10:50AM
On Thu, Mar 1, 2012 at 10:39 AM, Sebastian Bergmann <[email protected]> wrote:
> On 03/01/2012 04:13 AM, Pierre Joye wrote:
>>
>> 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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Adam Jon Richardson
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 02:11PM
On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou <[email protected]>wrote:

> 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
Lazare Inepologlou
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 02:41PM
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 <[email protected]>

> On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou <[email protected]>wrote:
>
>> 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
>
>
Anthony Ferrara
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 03:01PM
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

On Thu, Mar 1, 2012 at 8:33 AM, Lazare Inepologlou <[email protected]> wrote:
> 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 <[email protected]>
>
>> On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou <[email protected]>wrote:
>>
>>> 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
>>
>>

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Adam Jon Richardson
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 03:40PM
On Thu, Mar 1, 2012 at 8:33 AM, Lazare Inepologlou <[email protected]>wrote:

> 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
> 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).
>

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
Adam Jon Richardson
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 03:40PM
On Thu, Mar 1, 2012 at 8:55 AM, Anthony Ferrara <[email protected]> wrote:

> 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
Anthony Ferrara
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 04:01PM
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

On Thu, Mar 1, 2012 at 9:33 AM, Adam Jon Richardson <[email protected]> wrote:
> On Thu, Mar 1, 2012 at 8:55 AM, Anthony Ferrara <[email protected]> wrote:
>>
>> 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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Lazare Inepologlou
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 04:40PM
>
> 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 <[email protected]>

> On Thu, Mar 1, 2012 at 8:33 AM, Lazare Inepologlou <[email protected]>wrote:
>
>> 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 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).
>>
>
> 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
>
>
Adam Jon Richardson
Re: [PHP-DEV] Scalar Type Intentions
March 01, 2012 07:41PM
On Thu, Mar 1, 2012 at 10:36 AM, Lazare Inepologlou <[email protected]>wrote:

> 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
Lazare Inepologlou
Re: [PHP-DEV] Scalar Type Intentions
March 02, 2012 09:55AM
>
> 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 <[email protected]>

> On Thu, Mar 1, 2012 at 10:36 AM, Lazare Inepologlou <[email protected]>wrote:
>
>> 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
>
Sorry, only registered users may post in this forum.

Click here to login