8 ms·
Why 1 && 2 == 2
- jcampbell1 13y agoThank god he didn't try php. echo 2 && 1; // 1 echo 1 && 2; // 1 echo 2 || 1; // 1 echo 1 || 2; // 1 echo 2 ?: 1; // 2 In php ?: is javascript's || Unfortunately there is no && that works correctly.
- mattparlane 13y agoCame here to say this. If you use var_dump you can see it's coercing the result to a bool. $ php -r 'var_dump(1 && 2);' bool(true)
- RossM 13y agoExactly, it's not that bizarre. PHP assumes when you're using && you're going to have a boolean outcome. The odd bit is that casting a boolean to a string[0] with echo coerces the result to (string) "1" for true and (string) "" for false. [0]: http://www.php.net/manual/en/language.types.string.php#language.types.string.casting http://www.php.net/manual/en/language.types.string.php#langu...
- comex 13y agoIncidentally, this is identical to the result in GNU C.
- pbsd 13y agoIn C++, << has higher precedence than &&, so in effect what is being done is (cout << 1) && 2; ...which is not an error, since the result of operator<< is an std::ostream, which is convertible to bool. Therefore operator&&(bool, bool) is invoked but the result is, of course, discarded. Disambiguating the expression with parentheses should output 1 in every case.
- chewxy 13y agoI wrote the article (didn't plan on HN traffic, thanks Boyter). I've fixed it with your comment. Thanks
- adamnemecek 13y agoJust FYI, you are doing something wrong if your C code segfaults. EDIT: Oh, missed the errata.
- rayiner 13y agoHow did he get an expression that shouldn't involve any memory references to segfault?
- chewxy 13y agoI suck at C?
- cldr 13y agoHe probably thought pointers are the only kind of variables and that he needed to dereference them. I imagine something like int *a = 1, *b = 2; printf("%d\n", *a && *b); Either that or he used `%s` as a format specifier. That seems more probable. Edit: Or, as I just realised the people below me meant, printf(a && b);
- chewxy 13y agoNah mate, it's just some compiler flag that I didn't turn on (don't know which. my gcc-fu is fail since it's been really a long time since I touched C)
- cldr 13y agoJust for my curiosity's sake, would you mind posting the code you tried that segfaulted?
- georgemcbay 13y agoYeah I'm dying to see the original C code but it isn't on the page anywhere, AFAICT. From the article, about the C version: "Mine hadn't worked, which I suspect is some sort of compiler issue." Yeah I'm going to go out on a limb and proclaim that there's no way this was due to a compiler "issue" in gcc. Not that gcc is perfect, but there's no way it is barfing on one of these handful of line programs that does nothing but some logical operations and printfs.
- binarycrusader 13y agoFor Python, a common idiom is to do this: condition and truecase or falsecase See "Boolean operations" and "Conditional expressions": http://docs.python.org/3/reference/expressions.html#boolean-operations http://docs.python.org/3/reference/expressions.html#boolean-...
- Xixi 13y agoThis idiom is however out of flavor, unless you need to support python 2.4. Nowadays you would do this: truecase if condition else falsecase
- binarycrusader 13y agoHeh; my "age" is starting to show. The first version of Python I learned was Python 2.4 and it was only a few years ago I finally moved to 2.6. Skipping 2.7 and moving to 3.3+ soon. Personally, I prefer the brevity of the older syntax, but to each his own. However, I understand the "ternary" expression was added because the older syntax was error-prone: http://mail.python.org/pipermail/python-dev/2005-September/056510.html http://mail.python.org/pipermail/python-dev/2005-September/0... http://www.python.org/dev/peps/pep-0308/ http://www.python.org/dev/peps/pep-0308/
- jes5199 13y agoah! I've been trying to write Python lately (I'm more of a Rubyist) and the internet suggested: truecase if condition else falsecase which is so inside-out that it hurts. It didn't occur to me to use the boolean style - I guess I think of that as a perl idiom, and assumed that it would get sneered at in py-land
- comex 13y agoIt was mostly used before the creation of the ternary operator in Python 2.5.
- pyre 13y agoI've never seen: $CONDITION && $TRUE_CASE || $FALSE_CASE used as a Perl idiom in lieu of: $CONDITION ? $TRUE_CASE : $FALSE_CASE I can't claim to have worked with Perl much prior to Perl 5.6/5.8 though, so it may have been an older idiom (though I doubt it as one of Perl's influences was Awk, which also has a C ternary operator, IIRC). That said, using truthy/falsey values in Python doesn't seem super common. I surprised a couple of interviewers by doing that while implementing some tree manipulation functions.
- lotharbot 13y agoOnce you understand short-circuit evaluation, it opens up certain coding tricks. The line "[operation] or [error condition]" will attempt the operation on the left. If it succeeds, the program continues on the next line, ignoring the part about the error condition. If it fails, the error condition will execute instead. This might be something like "open file or die". Likewise, "[operation] and [success condition]" will attempt the operation on the left, and if it succeeds, perform the operation on the right. This might be something like "read input and process it", which will perform the (possibly expensive) processing step only when input is received. Code written in this style is sometimes, but not always, faster to execute. It's also sometimes, but not always, clearer. See also http://en.wikipedia.org/wiki/Short-circuit_evaluation http://en.wikipedia.org/wiki/Short-circuit_evaluation
- cldr 13y agoThis is commonly seen in Perl and PHP with stuff like launchMissiles() or die('failure');
- k3n 13y agoUgh, `or` is mostly useless in PHP. That code is identical to: launchMissiles() || die('failure');
- ars 13y agoThat code is the same, but or has a lower priority than ||, so they are not the same is the code before the or is an expression. Also, using or instead or || for these types of things is more readable since it makes your intent of conditional code execution (as opposed to boolean evaluation) clear.
- k3n 13y agoMeh, it's not more unreadable unless you have issues understanding || in the first place... and "or" is still a boolean operation. Considering 99.9% of it's use in PHP is some variant of "connect() or die()", I stand by my statement. Besides, those "connect() or die()" expressions are widely considered bad-practice in the first place.
- betterunix 13y agoCommon Lisp treats any non-nil value as "true," so the behavior is not bad for the "and" macro (yes, it is a macro). Additionally, the standard says that "and" should evaluate to nil if any argument evaluates to nil, or to its last argument otherwise: http://www.lispworks.com/documentation/HyperSpec/Body/m_and.htm http://www.lispworks.com/documentation/HyperSpec/Body/m_and....
- CamperBob2 13y agoI like how cout << 2 && 1 demonstrates the lameness of the whole C++ iostreams syntax. I'll have to remember that the next time an argument arises.
- cldr 13y agoFeel free to change it to how you like it if you feel that another syntax would be more convenient. You can choose another operator or just create a variadic template function and use function syntax to avoid operator precedence issues.
- CamperBob2 13y agoprintf("%d", 2 && 1); seems to work OK.
- ctide 13y agoI think it's a sign that I've been programming (predominantly in ruby) too long when I didn't think twice about why 1 && 2 == 2.
- codyb 13y agoWorth it for the memoization (I guess that's not really a word?) in Ruby. Cool new operator I did not know about.
- city41 13y agoIt's not a new operator, but rather the X= form, where `foo X= 4` is sugar for `foo = foo X 4` Just be careful with this in JavaScript, as the greater number of things that are falsy can bite you if you do `a = a || 10;`, which is a very common JS bug.
- cheald 13y agoWatch out for this with boolean values. If you are attempting to memoize a method that returns a boolean, it'll be re-evaluated if the last iteration returned false.
- psuter 13y agoI sometimes wish that x * y would short circuit on x = 0. Just because you could.
- valleyer 13y agoYou mean, like, in the compiler? If x is actually a macro that expands to zero, that will (or at least should, for a sufficiently smart compiler) happen. Otherwise, I can’t imagine a runtime check of this being appreciably faster than hardware multiply. Right?
- lubomir 13y agoI would guess he/she meant something along the lines of x * some_really_complicated_expression. If x is 0, you would not need to evaluate the other operand at all. It may even be a faster, but I doubt any compiler does this sort of optimization, since it is not safe in languages with non-pure functions. The complicated expression could change some global state or perform input/output. E.g. in Haskell, it would be possible to do this safely, because it is guaranteed by the type system that there are no side effects. However, even with literal 0 in the code the other operand still gets evaluated.
- valleyer 13y agoAh OK. That makes sense.
- eridius 13y agoYou wrote at the end that you weren't sure why literal values were returned instead of TRUE and FALSE. The practical answer is that literal values are far more useful. The simple answer is that, since the literal value already represents TRUE (or FALSE), returning it makes just as much sense as returning a literal TRUE/FALSE, and is simpler to do.
- unlimitedbacon 13y agoI am not a programmer, but it seems to me the logical thing to do would be to operate on the binary values of 1 and 2. Since 1d = 01b and 2d = 10b... 1 AND 2 = 01 AND 10 = 00 = 0 1 OR 2 = 01 OR 10 = 11 = 3
- chewxy 13y agoThat's kinda what binary logical operations are for. Typically AND is denoted by the symbol '&', and OR is denoted by the symbol '|'