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

From: Date: Mon, 14 Jul 2014 13:33:04 +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-75457@lists.php.net to get a copy of this message
On 14 July 2014 13:58, Andrea Faulds <ajf@ajf.me> wrote: > Hello again, > > 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. > > One option is simply to forget about being lossless and make the bool type hint accept any > value, meaning any truthy value or any falsey value would yield what is expected without error. This > would ensure that if some stupid programmer (like myself ;) has passed in a non-boolean > truthy/falsey value to your function, it’ll be handled correctly. It would mean all your bit hacks > ($foo & FLAG etc.) would work, anything you got from $_GET (e..g. ?foobar=1). However, this is > unlikely to catch bugs in code, because literally any PHP value would work. For that reason, I’m > not sure this is the way forward. > > Another option is go completely strict and allow only boolean values, failing everything else. > This would be unlike the int, float and string hints, which are flexible and cast, but would be more > helpful for catching bugs. However, not casting at all isn’t very “PHP-like”, and forcing > people to manually cast with (bool) might not be ideal. If we were to go for this one, I might also > accept objects casting to bool (which the default handler does), because I don’t want to stop > extension developers from making bool-like objects if they so please. > > The final option I’m thinking about is a limited set of values. TRUE, FALSE and NULL would be > accepted, along with the integer and float values 1 and 0 (which are the int/float TRUE and FALSE > cast to, respectively), ‘1’ and the empty string (which are the string values TRUE and FALSE > cast to), and ‘0’ (which (string)(int)FALSE would give you), along with objects casting to > boolean. It’s not a perfect solution, but I currently feel that this is the most sensible option > bar going for full strictness. > > I’m not really decided, however. Every time I try to think about this, I usually end up going > in circles. Anthony doesn’t seem to be decided either. Hence I’m putting this up for discussion. > > What are your thoughts? > > -- > Andrea Faulds > http://ajf.me/ I've already said this in IRC but summing up for the benefit of everyone else: 1) We already have a place where there is an implicit boolean cast, namely if ($var). Personally I would find it somewhat counter-intuitive if a parameter declared as bool didn't behave the same way. 2) A common-ish use case here would be: function foo(bool $bool) {} foo($flags & A_FLAG); The intent of the expression $flags & A_FLAG is obvious to the reader as fetching a boolean, but the result will often be an integer that is neither 1 nor 0. This cannot be handled by foo((bool)$flags & A_FLAG); because of precedence, foo((bool)($flags & A_FLAG)); is messy. Andrea suggested foo($flags & A_FLAG != 0); which is better but still a little messy. Personally I would rather just accept data loss and stay consistent with the rest of the language (i.e. condition evaluation), but I do understand the PoV of those resistant to it.

« previous php.internals (#75457) next »