5 ms·
Say What You Mean (in JavaScript)
- jackfoxy 16y agoWhile I endorse the argument for coding for readability (all things being equal), I don't agree with his example. I find the && syntax in javascript completely readable.
- WesleyJohnson 16y agoI find it readable if you're trying to test both sides of the && to be true -- if(foo() && bar()){ // do this } However, the way it's written in the article, the intent is to merely test foo() and then execute bar() if foo() returns true. Even though I'm familiar with &&, it took me a minute to understand this as well. I'd be eqaully annoyed seeing this in production code.
- scott_s 16y agoIt's a common idiom in many programming languages.
- JshWright 16y agoI'm with the GP on this one... Readable code is very important. Using the short-circuiting property of && doesn't decrease readability in most cases (unless someone isn't familiar with the language, or the concept of using short-circuiting for flow control).
- DrSprout 16y agoI've always found the Perl foo() or die(); idiom to be quite readable. And if you're familiar with that, this is a pretty straightforward extension.
- div 16y agoI agree. As long as the example idiom is something that's used consistently throughout the code it's all good. Even if you're new to the code and don't immediately get it, you will instantly recognize it the second and third time around.
- JeanPierre 16y agoThis is pretty straightforward and intuitive, so I agree with this reply. Maybe it's because of the equivalents in lisp (I tend to use lisp a lot): (if (foo) (bar)) equals to (and (foo) (bar))
- psyklic 16y agoI disagree -- it probably is not immediately understood by most programmers. The main flaw of the technique is that the author uses the '&&' not as a logical operator (the intuitive use) but as a conditional operator. '&&' is the 'Logical AND'. The statement "foo() && bar();" just doesn't make initial sense, because the logical result of the expression is thrown out. After thinking this, the programmer probably will realize that the functions are actually called to evaluate the expression. And then finally (hopefully) the programmer realizes that they are evaluated short-circuit. So, the code may be functional but it is not very readable.
- leokote 16y ago"the expression evaluates to true if both return True, but then why is the result thrown out" Actually, the result is not thrown out: the && operator produces the value of its first operand if the first operand is falsy, otherwise it produces the value of the second operand. For what it's worth, there's also a procedural reading of "foo() && bar()" along the lines of "fill out this form AND win a prize!".
- psyklic 16y agoI wrote 'thrown out' because the statement is "A && B;" -- the result is unused due to the terminating semicolon.
- tlrobinson 16y ago&& and || are commonly used as "short circuit" operators in JavaScript. I have no problem with this.
- chime 16y agoI prefer this: if(foo()) bar(); No {} necessary if it's just a single command.
- mshafrir 16y agoI prefer to always use {} for readability and consistency's sake, regardless of line count. Also reduces human error.
- chime 16y agoMe too. But if the goal was to shorten "if(foo()) { bar(); }, then I could just leave the {} braces out instead of making it "foo() && bar()".
- TrevorBurnham 16y agoYes, I admit that I added the curly braces unnecessarily. However, jsLint will throw a fit if you omit them, so there's an argument to be made that always putting your conditionals in curly braces is a best practice. Certainly, both styles are common in JavaScript, and they'll come out of the minifier the same way in the end.
- iamwil 16y agoI guess what you find readable also depends on where you're coming from. When I first saw that foo() && bar() line in the OP, I knew what it meant immediately. It's because I use it myself, and I've seen raganwald's andand operator and heard of Haskell's Maybe monad. I've used it for so long that it's come to mean "if the first exists, then do the second", and not just "this expression is true if both are true", and I don't really confuse the two.
- erlanger 16y agoYou'd exaggerate the problem at hand too if you were pushing some strange variant of the language criticized. Any programmer experienced with C-style languages recognizes logical constructs with && and || immediately. If function (x) { x = x || someDefaultValue; for setting non-falsy default argument values isn't a JavaScript idiom, I don't know what is.
- aaronblohowiak 16y agoi much prefer x || (x = someDefaultValue) because it doesn't require backtracking. by that i mean, when i read x = x || somedefaultValue, i am thinking x = "okay, we are in an assignment) and then i see x || and then i have to adjust and think "oh, well, this is a conditional so now i have to think about that situation." with x || (x = someDefaultValue), what you read is how it is evaluated. if x is true, the rhs is never evaluated. with the above, the assignment happens either way.
- TrevorBurnham 16y agoBut that's not the code I was criticizing. In fact, it's precisely because that's the idiom I associate with boolean operators in JavaScript that the code snippet I posted struck me as unintuitive. As to "pushing some strange variant": Guilty as charged. Have you tried CoffeeScript? It's fantastic. The code you gave above would be written as (x) -> x ||= someDefaultValue
- erlanger 16y ago> Have you tried CoffeeScript? Nope. I'm apprehensive about adding another layer to the development process when I know JS very well and don't find it at all limiting. So I'm probably not part of your target audience.
- jlongster 16y agoReplacing "if" constructions with boolean operators is powerful. The simplistic example in the article doesn't really show the purpose of using || and && to control flow. It's scalable. What if you have to test a third expression? Surely this: foo() && bar() && buzz() is more readable than if(foo()) if(bar()) buzz() It's flexible. Since an "if" statement is not an expression in most languages, you have to be careful where you place it. For example, what if you wanted to pass the result to a function? qux(foo() && bar() && buzz()); Javascript (and a few other languages) have the neat feature with boolean operators that they return the result of the last tested expression. So the above example would pass the result of buzz() to qux if all statements are true, otherwise it would pass false. Here is the same code with "if" statements: var res = false; if(foo()) if(bar()) res = buzz(); qux(res); There are many more examples of why you should be used to constructing expressions with boolean operators. It doesn't matter much for the simplistic example in the article, but the same technique allows you do write more complex code in succinct ways.
- psyklic 16y agoThis does not respond to the issue raised in the article. In all of jlongster's examples, the result of the '&&' operator is being used. So, someone reading the code can mentally consider the '&&'s to be logical operators. However, in the article's examples, the result was not being used at all. So, the '&&' was being used not as a 'logical operator' but as a 'conditional operator', which is a non-intuitive use. Also, '&&' and '||' are not Boolean operators -- they are logical operators, where order matters for short-circuiting.
- teej 16y agoFor what it's worth, I've often seen code like jlongster's example, but never seen code like the OP's example.
- aaronblohowiak 16y agousing && as a conditional operator is a common rubyism
- silvestrov 16y ago
- edw519 16y agoThe old rule of thumb was, "Online, go for readability. Batch, go for speed." This almost always translates into, "Online, use 'if' or 'case'. Batch, use Boolean." In the first case, maintenance programmers will thank you. In the second, users processing millions of records will thank you.
- bsaunder 16y agoI think sometimes what's "readable" to one person isn't to another. The more you hit a coding convention, the more readable it becomes (as with anything). So noted. Move along. There are bigger fish to fry.
- TrevorBurnham 16y agoPoint taken: I'm being really, really picky in this post. It's is far from the most confusing code I've seen today. But I'm making a larger point: JavaScript tends to be a lot less readable than code written in other languages not just because of the language itself but because of the byte-squeezing habits web developers have picked up over the years. I think JavaScript tools have advanced to the point that we can finally drop those habits.