8 ms·
Dislike of if confuses me. People claim to find conditions wordy or confusing. I don't find conditions particularly difficult to follow, but I have a question f
by telemachos 16y ago
Dislike of if confuses me. People claim to find conditions wordy or confusing. I don't find conditions particularly difficult to follow, but I have a question from the other side: when you use && and || as logic gates, don't you (in your mind) translate them back into conditions anyhow? Here's his first example without if:
function getEventTarget(evt) {
evt = evt || window.event;
return evt && (evt.target || evt.srcElement);
}
Sure, it's very short in this written form. But for me to understand it, I need to think, roughly: evt retains its value, if it's a truthy value; otherwise give evt the value of window.event; if evt is a true value (now), return it and the value of evt.target - if that's truthy, or, if not, add in the value of evt.srcElement; oh, and by the way, if evt was not truthy initially in the return statement, bail out early (and return no value) since && only continues on if the initial value is true.
I'm not trying to be difficult, but I don't see that as miraculously more clear.
- geuis 16y agoLook at it like this. I am a developer who prefers the terse code compared to the longer if() variety. I've been doing this long enough that its is easier, clearer, and faster for me to understand the "evt = evt || window.event" than it is to trace through all of those if() statements. I used to be the opposite, I couldn't understand the short form or how it worked. Ternaries confused the hell out of me for a while. Why? Because when I look at "evt = evt || window.event", my mind has learned about the conditionals that each of these represent. Its analogous to phrases that mean different things in different contexts. "That guy has balls", for example. So I look at it and I know that "if( evt )" is the same as "evt ? true:false" as "if( typeof evt !== 'undefined' ). I know that in the context of that statement, evt || window.event is saying "if evt exists, use that. if not, use window.event". So the reason its confusing to people is they haven't learned all of the different things the shorter code means. For me, after having spent many, many hours writing javascript I find the short form easier to understand and less tiring. Not only that, in raw numbers it just saves space. Now, the other lesson I've learned over the years is that many times it is much better to start out writing in plain old "if" statements. Get the logic right, then reduce it down. There's nothing more annoying than trying to debug someone else's poorly written code. And for god's sake, DOCUMENT!
- sesqu 16y agoI've got to agree here. The short form is great for those ubiquitous "set if null" pieces of code, but you wouldn't want to use one for a complex conditional. The advantage comes in when you recognize the intent from the way it's formulated, and so don't have to trace the syntax. If your clause is something like "y%4==0 && (y%100!=0 || y%400==0)", you may want the long form, even for null y. I feel the example return statement is pushing it. Additionally, it only works if you can trust that what is written is what is intended - which can be a problem with the gotchas in the truthiness system. If you aren't sure what type the input will have, you'll want the explicit checks, and if you don't have a helper function, those can drag on long enough to make it unreasonable to expect the reader to see the guard pattern. All in all, I consider the short form a form of self-documenting code. If your readers don't find it easy to get used to, it becomes obfuscation. YMMV.
- wmwong 16y agoI agree that in some cases, guards, defaults and ternaries flow more naturally. However, I feel that there's a contradiction. You say that it is easier to understand but have learned to write them in plain old "if" first because it's better. It's easier to get it wrong if you write it shorthand. If it's better to start writing them in "if", doesn't that mean it's easier to understand? If it is easier to use guards, defaults, and ternaries, you shouldn't have to resort to plain "if" to get the logic right. And I agree, DOCUMENT!
- scott_s 16y agoWe sometimes use if-else statements to write out some straight-up logic because we don't understand it at first. So we build it from the ground up. If, after writing it all out with primitives, we realize "Oh, it's just this anded with this and ored with that" then we actually understand the problem. Put another way: if you write a boolean expression as a sequence of statements, my assumption is you don't really understand what you're doing.
- Confusion 16y agoI've been doing this long enough that its is easier, clearer, and faster for me to understand However, are you also the only one reading the code? If not: is it also easier, clearer and faster to understand for the other ones? On the one hand, they may learn fast when reading code that uses these constructions. On the other hand: perhaps it only sinks in over time and they won't learn fast enough to properly maintain such code.
- rue 16y agoThe first line is perfectly fine to me, I read it "event is either given event or event from the window". The second part is convoluted because of poor responsibility handling: ideally this function would never be called without some event present.
- scott_s 16y agoSimply, no. I prefer to think in boolean expressions rather than sequences of statements. Personally, I'd further reduce it to (assuming there's no JavaScript subtleties I'm missing here; in C/C++ this would have the same semantics): function getEventTarget(evt) { return (evt || window.event) && (evt.target || evt.srcElement); } A boolean expression is straight-up math, and I've been trained to reason about that. With a sequence of statements, I have to first figure out what you're doing, then extrapolate the implications. The implications stare me in the face when I look at a boolean expression.
- WesleyJohnson 16y agoIn the OP's example, evt will retain it's value if passed in as "truthy" or take on the value of window.event otherwise. The return then returns evt and evt.target or evt.srcElement which may from the original passed in evt or really from window.event, which was assigned to evt in the first line. With your example, evt.target and evt.srcElement are only coming from the passed in evt which may have been passed in as "falsey" and would not take on the target or srcElement of window.event as intended. I could be mistaken, it's late and I'm rusty. Anyone is free to correct me.
- gruseom 16y agoBut that crashes on null in all three languages, no? (i.e. if evt is null and window.event is non-null.) I suppose you could do this: function getEventTarget(evt) { return (evt || (evt = window.event)) && (evt.target || evt.srcElement); } But that's probably more trouble than it's worth. Anyway, I agree with you in preferring expressions to statements on the whole. It's hard to imagine why anyone would prefer the more than 4x as long version in the OP; to me it reads like a parody.
- scott_s 16y agoIn C/C++, evt could never be null because it would have to be a stack allocated object or a reference. (We're not dereferencing a pointer.)
- 16y ago