On Oct 20, 2014, at 6:17 PM, Andrea Faulds <a...@ajf.me> wrote: >> On 21 Oct 2014, at 02:07, Josh Watzman <jwatz...@fb.com> wrote: >> >> Throwing an exception or even returning NULL seems so much better than >> returning "false" -- "false" is a boolean, not an error, and despite some >> historical cases of PHP using "false" as a poor person's error code, it >> really isn’t. > > Why isn’t FALSE an error value? NULL signifies an absence of a value, not a > bad value. We use FALSE in a lot of places to indicate an error. Heck, > filter_var uses it for errors here.
FALSE is not an error value because it is already something else. It's already a value, it's boolean false. The fact that you couldn't build a reasonable to_bool even if you wanted to, as I as well as others pointed out on this thread, indicates the very real problem with the conflation of purposes here. Derick Rethans said it pretty well: > Then to_bool() whould return false... or true? So hence, it should be > NULL, and that would also be consistent with ext/filter. You also said: >> Also, that we *couldn't* introduce a meaningful to_bool function, even if we >> decided we wanted it, indicates to me that returning false is the wrong >> thing to do. > > It would be possible to use a special value in that specific case. Though, > again, booleans have their own problems. I don’t see the point in to_bool(). Whether or not we actually should add to_bool is a separate issue; we, in principle, should be able to cleanly add it, since it's a very natural extension to what you've already designed here. The fact that, if we used FALSE for error that to_bool would have to be a special case, inconsistent with the rest, indicates to me that using FALSE is the wrong thing -- again, it's the conflation of the boolean value FALSE, which already has this meaning, with some error code. It shouldn't be conflated, FALSE should not be an error return, it means something else. >> If you want error codes, use error codes, or use exceptions, but having two >> kinds of failure, null vs false, is really confusing. > > What two kinds of error? We’re only using FALSE here. But FALSE *is* a different kind of error as you're trying to use it here, different than NULL which is specifically designed to be an error / lack of value. NULL doesn't mean anything else, it's a specially-designated value. And if you don't want to use NULL for failure because you don't think this is quite the sort of failure that NULL expresses, then throw an exception -- FALSE is just totally the wrong thing to return. >>> • If strict type hinting were added, they would fail for a nullable >>> typehint >> >> Throwing an exception also addresses this, in a much cleaner way. If you're >> worried about strict typing, then returning "false" is even worse, since the >> return type of, for example, to_int is now "int | bool" as opposed to >> "nullable-int" or "int" (if you throw). > > Exceptions make chaining more difficult. There’s also no precedent for using > them. I think the argument about chaining was addressed by someone else. With precedent, just because there's no precedent doesn't mean we can't start now :) They really feel like the right thing to do here and elsewhere, and we have to start somewhere. >>> • FALSE is a traditional error value in PHP >> >> Since this is a new function, one that doesn't interoperate in any >> complicated way with the existing library or affect BC, this doesn't seem >> that important. IMO a language should have one failure/absense-of-value, in >> most cases "null", and having a weird second case seems, well, weird. > > Failure and absence of value are different things and should not use the same > value. Otherwise, you are liable to confuse missing data and errors. But if you want to make that distinction, then you shouldn't use a value that means something else to indicate failure. You should throw an exception. Returning FALSE is liable to replace confusion between missing data and errors with confusion between some other data (i.e., the boolean FALSE) and errors. I might also argue that missing the data makes it clear there was an error, and then if someone has a nullable typehint they expressly said they accept a lack-of-int, but an exception seems a much cleaner way to deal with this anyways. >> If you have more interesting failure cases, just throw an exception, or >> return null if you want, don't continue propagating a weird second kind of >> null (that isn't actually null, it's a boolean false). > > It’s not a “weird second kind of null”, it’s a value FALSE. Which is being used as a weird second kind of failure, as opposed to NULL which is the typical failure lack-of-value, as I argue above. >> It's also interesting to look at how other languages handle failures of this >> kind. Most imperative languages I know of either throw or return null; in >> particular, Python, which has fairly similar type system to PHP in a lot of >> ways, throws. Functional languages do more interesting things; Haskell does >> something complicated but morally equivalent to returning null. But I'm not >> aware of any language which specifically returns false. > > JavaScript returns NaN here and C sets errno to an error value. PHP uses > FALSE, in some respects, like JavaScript uses NaN. But it probably shouldn't -- NaN is a special number which is not a number (and which *would* probably pass a float type annotation, no?). FALSE isn't a special integer which isn't an integer -- it is already something else, it's a boolean. JS has a few special values which are specifically designated as different failures or lack-of-values -- undefined, null, NaN, etc. PHP's FALSE does *not* fall into that category -- it *does* mean something, it means something else, the boolean value false. (FWIW, I don't think that the way JS does this feels quite right either, I don't like that there are multiple sorts of non-exception failure values, but at least they return a designated failure value that doesn't have another totally different non-error meaning.) Josh Watzman -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php