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