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 <adamj...@gmail.com>

> On Thu, Mar 1, 2012 at 4:36 AM, Lazare Inepologlou <linep...@gmail.com>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
>
>

Reply via email to