FAQ
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

Search Discussions

  • Sebastian Bergmann at Mar 1, 2012 at 2:36 am

    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/
  • Adam Jon Richardson at Mar 1, 2012 at 4:53 am
    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 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 at Mar 1, 2012 at 8:47 am
    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:
    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
  • Pierre Joye at Mar 1, 2012 at 9:13 am
    hi Sebastian,

    On Thu, Mar 1, 2012 at 3:36 AM, Sebastian Bergmann 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,
  • Sebastian Bergmann at Mar 1, 2012 at 9:39 am

    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/
  • Pierre Joye at Mar 1, 2012 at 9:48 am

    On Thu, Mar 1, 2012 at 10:39 AM, Sebastian Bergmann 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.
  • Lester Caine at Mar 1, 2012 at 9:46 am

    Pierre Joye wrote:
    On Thu, Mar 1, 2012 at 3:36 AM, Sebastian Bergmannwrote:
    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
  • Alain Williams at Mar 1, 2012 at 8:54 am

    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>
  • Lazare Inepologlou at Mar 1, 2012 at 9:36 am
    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_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
  • Adam Jon Richardson at Mar 1, 2012 at 1:04 pm

    On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou 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 at Mar 1, 2012 at 1:33 pm
    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 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 at Mar 1, 2012 at 1:55 pm
    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 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 <adamjonr@gmail.com>
    On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou 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
  • Adam Jon Richardson at Mar 1, 2012 at 2:33 pm

    On Thu, Mar 1, 2012 at 8:55 AM, Anthony Ferrara 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 at Mar 1, 2012 at 2:55 pm
    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 wrote:
    On Thu, Mar 1, 2012 at 8:55 AM, Anthony Ferrara 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
  • Adam Jon Richardson at Mar 1, 2012 at 2:31 pm

    On Thu, Mar 1, 2012 at 8:33 AM, Lazare Inepologlou 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
  • Lazare Inepologlou at Mar 1, 2012 at 3:36 pm

    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 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 at Mar 1, 2012 at 6:32 pm

    On Thu, Mar 1, 2012 at 10:36 AM, Lazare Inepologlou 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 at Mar 2, 2012 at 8:53 am

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

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-internals @
categoriesphp
postedMar 1, '12 at 2:01a
activeMar 2, '12 at 8:53a
posts19
users8
websitephp.net

People

Translate

site design / logo © 2019 Grokbase