Re: [RFC] Scalar Type Hinting With Casts (re-opening)

From: Date: Mon, 14 Jul 2014 14:03:08 +0000
Subject: Re: [RFC] Scalar Type Hinting With Casts (re-opening)
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-75462@lists.php.net to get a copy of this message
Andrea Faulds wrote (on 14/07/2014):
One of the issues with the RFC as it stands is how to handle bool casting. While int, float and string only allow lossless casting (with the exception of objects, but we can’t really do anything about that), bool’s behaviour at the moment is quite different. I don’t think it makes sense so I won’t discuss the current behaviour, only possible new ones.
I'm actually coming round to the idea of quite a strict definition of "lossless" cast: (source_type)(target_type)$value == $value That handles all the existing int, float, and string cases, e.g. (string)(int)'42' == '42' (string)(int)'42abc' != '42abc' It implies only the following for booleans: boolean(false), boolean(true), string(''), string('1'), int(0), int(1), float(0), float(1): (string)(bool)'1' == '1' (string)(bool)'2' != '2' The only special case required is to hand-wave away these three cases for arrays, which aren't allowed by the existing typehints, and don't "feel" like lossless casts to me: (int)(array)1 == 1 (float)(array)1 == 1 (bool)(array) true == true (string)(array)'Array' == 'Array' Note that I previously suggested allowing ' 42 ' as an int; I've changed my mind, and think that pre-processing such as calling foo(trim($_GET['id'])); makes more sense (note that this will not behave the same as foo(intval($_GET['id']));). After all, you *might* want to strip out all non-digits, and pass that as your integer; there is no need for the function signature to have that ability. Looking at the current table in the RFC, I'm not clear why NULL should pass as any value, but not array. Could it not behave the same as the existing type hints, i.e. accepted only if declared as a default? function foo(array $bar) { } foo(null); // ERROR function foo(array $bar=null) { } foo(null); // OK, $bar == NULL function foo(int $bar) { } foo(null); // ERROR function foo(int $bar=null) { } foo(null); // OK, $bar == NULL In summary, I think if the rules can be explained concisely, and the table derived from those rules, it will feel less confusing than having to consult the table to be sure of the effect. Having to say "for arrays, the logic is this; for strings, this; for integers, this; for booleans, the other" makes the whole thing seem like a bit of a kludge, and is exactly what the existing "lossy" casts suffer from. I would stress that I see this as a new definition of "lossless cast"; this RFC is intentionally *not* using the existing cast logic, as explicit casts *never fail*, so "but existing casts work this way" is not relevant. Regards, -- Rowan Collins [IMSoP]

« previous php.internals (#75462) next »