4 ms·
I've become a advocate for the idea that the only values which should evaluate in boolean context are actual booleans. If you need to test for the number zero o
by whoopdedo 13y ago
I've become a advocate for the idea that the only values which should evaluate in boolean context are actual booleans. If you need to test for the number zero or a null value, you explicitly write 'value == 0' or 'value is null'. Is it more verbose? Yes. But it avoids any ambiguity about what you intend to evaluate. Typing speed should not be a determinant in the language you use.
- eru 13y agoIn Haskell, you can have your cake and eat it too. Normally, the language follows your comments philosophy, but it's really easy to add arbitrary truthiness and falsiness definitions: class ToBool a where toBool :: a -> Bool if' :: ToBool a => a -> b -> b -> b if' cond th el = if toBool cond then th else el And add instances like these: instance ToBool Int where toBool 0 = False ToBool _ = True instance ToBool String where toBool "" = False toBool _ = True Or even: instance ToBool TimeStamp where toBool = not . isMidnight Lisp, of course, can do similar things via Macros.
- mercurial 13y agoOn the other hand, any attempt at writing something like this in production code warrants the firing squad.
- eru 13y agoWhy? It seems unnecessary, but not overly hard to read. Some re-education should be enough.
- gleenn 13y agoIt's bad because it beckons bad behavior. Instead of doing the simple thing and changing your if-statement which puts the idiosyncrasy in the relevant piece of code, you are tucking away the behavior out of sight when something like this almost definitely belongs directly in front of your eye-balls. This is a bit of a strawman, but being able to do class Foo(object): def __bool__(self): return random.random() > 0.5 shows how crazy you could be. If you really want something weird, put it in the if-statement
- eru 13y agoI do agree with you. That particular bit of craziness wouldn't be possible in Haskell. (Since that would require declared side-effects, and my interface above didn't have any declared.)
- mercurial 13y agoNorth Korea-style? It's unidiomatic. Usually, when you find yourself writing unidiomatic style, it's a symptom of one of two issues, or both: - you are doing something you shouldn't - you are doing it in the wrong language
- mercurial 13y ago(replying to myself) It's particularly bad because it is the kind of "clever" unnecessary code which is unlikely to see widespread adoption, clashes with existing conventions, and will eventually be disposed of after the author has left the company to pursue other opportunities. Don't write clever code!
- mooism2 13y agoI don't think this is a good idea. If you have a `ToBool` instance it should really do the right thing in all circumstances. And this doesn't: if the `Int` in question is the exit status of a process, then 0 should be truthy and everything else falsy. Better to make the test explicit. If the test is at all complex you wrap it up in its own function anyway, so it's not like it makes the if expression harder to read. Consider also the instance for `Maybe`: which of these is right? instance ToBool (Maybe a) where toBool = isJust instance ToBool a => ToBool (Maybe a) where toBool = maybe False toBool
- eru 13y agoI agree with you. I just wanted to point out, that the relaxed booleans do not have to be a property of the language, but can be done in a library. (Hey, even `if' could be a library function in Haskell. (And really, should be.))
- mooism2 13y agoYou also have to supply alternatives to && || and not; that still leaves functions (e.g. filter) and constructors with Boolean parameters. Whether you're fighting the language or the standard library is a moot point: you're fighting it instead of working with it.
- eru 13y ago> You also have to supply alternatives to && || and not; that still leaves functions (e.g. filter) and constructors with Boolean parameters. There's some lifting approaches that construct those functions mostly automatically for you, as wrappers around the base functions on Booleans.
- tormeh 13y agoYes, but then you're relying on pattern-matching to define if. PM is not better than if, it's just different.
- icebraining 13y agoHow is that different than in Python? Normally, an Object would always be truthy, if you didn't implement the __nonzero__ method. The problem is that the Datetime class does implement that method, on purpose.
- ufo 13y agoI think that this kind of goes against the point of the previous post. If you add a ToBool instance to everything then `toBool` then you get a similar problem to Python, where conditionals silently accept everything you pass to them, even if its not the type you actually want. For example, if you accidentally write `if n then` instead of `if n > 0 then` you will get an error saying that the conditional is an integer. However, if you do `toBool n` instead of `toBool (n > 0)` then it will compile but do the wrong thing.
- anon4 13y agoThis is also not possible in a dynamic language like Python. The compiler can't check that you're only entering boolean expressions in the if clause, because it's all dynamically typed. The best alternative is Ruby's "nil and false are the only things that are false". The other option is throwing an exception at runtime if the if clause evaluates to a non-boolean, which strikes me as way too anal.