On Mon, Jul 14, 2014 at 01:58:25PM +0100, Andrea Faulds 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?

We are going round in circles as we are trying to second guess what programmers
will want - how they will try to use it. Part of the problem is that different
programmers will want different things AND the same programmer will want
different things in different parts of the program (think back to my 'inner' and
'outer' program parts).

One of the big items of discussion is: should this be a cast (ie convert to the
desired type) or a check (and error upon type mismatch). There are valid
arguments for both - indeed different use cases for both.

I will argue that they are not incompatible.

So: I see 3 cases and suggest a way of accomodating the different needs.

a) 'outer' code where types are not known, eg an argument might be something
   from $_GET.

   function CheckAge($age) {
       if( is_numeric($age) && $age >= 0 && $age <= 150)
           return TRUE;
       // throw error/....
   }

   CheckAge($_GET['age']);

b) 'inner' code where something will have been checked to be convertable to the
   desired type, but it might not be that type:

   function CanLegallyDrive((int) $age) {
       return $age >= 17;
   }

   if(CheckAge($_GET['age']) && CanLegallyDrive($_GET['age']))
       ....

   Note the use of '(int)' to indicate that the argument should be cast to int.
   If a conversion is not possible: the program errors in some nasty way.

   The above is prob how this will often be used, so the cast rules should
   reflect that, eg: '12' OK, '12 ' OK, '12a' Fail.

c) 'inner' code where the argument is known to be of the type and no convertion
    will be done - if there is a type mismatch - generate an error.

    function PrintMonth(int $month) {
        ...
    }

    for($mon = 0; $mon <= 12; $mon++)
        PrintMonth($mon)





I wanted to say something about function return types (good for optimisation)
but decided that that would risk of opening more cans of worms.

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

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to