8 ms·
Bravo. That comparison makes worrying about vertical space seem ludicrous.
by Cushman 14y ago
Bravo. That comparison makes worrying about vertical space seem ludicrous.
- jblow 14y agoUgh. I prefer the Carmack version. This example turns the code into something that appears more airy but in fact is much harder to understand due to extensive use of ? :. I find that one of my own major steps toward programming maturity happened when I stopped doing goofy things like this and started writing code that was as simple as possible to logically follow, and that was as un-special-cased as possible. (By this latter I mean, if you change the code a little bit, you don't have to rewrite it; it looks basically the same. Imagine you want to do more than just assign one variable inside the clauses of the 'if'. In the Carmack version you just add more code there. In the proposed substitute, you have to rewrite the whole thing.)
- dchichkov 14y agoThe assignment sides[i] = ... with "? :" formatted as a table (in table notation) should be red as a single statement. It is a relatively common element, you will find in easy to read, once you see it a few hundred times.
- Garoof 14y agoI like the last one better. I think it reads more like "assign one of these values to sides[i]" and less like "do one of these three things". "By this latter I mean, if you change the code a little bit, you don't have to rewrite it; it looks basically the same." I'd say that's kind of the point though. The first one would look "basically the same" if in the last else it assigned to sides[j] instead of sides[i]. In the last one it would look very different if it was about "doing stuff" rather than choosing which value should go to sides[i].
- dchichkov 14y agoPrecisely. And there is even a little bit more to it. 1. it reads "assign one of these values to sides[i]". 2. it would not allow some other peoples spurious code into the assignment. which is a good thing. 3. space is used to convey meaning; note how sides[i] stands next to dists[i]; ternary operation is formatted as a table, etc.
- jblow 14y agoNot allowing other code in is a bad thing. See my putty reply above.
- dchichkov 14y agoIt depends. But in this particular case, some trivial extra code inserted inside that if statement may break things. Like breaking vectorization of that 'for' (note, that we are going over vertices). When you are writing the code, some times you may want to put additional constraints on the allowed operations, modifications, etc. A trivial example in C++ would be using 'const &' instead of '&'.
- jblow 14y agoThis is true (especially: breaking vectorization). But premature optimization is not a good idea, and if you are doing real optimization, you are going to rewrite that piece of code 10 times anyway, so it is in a different class of problem and the putty stuff I was saying before does not apply (i.e. this code is in the 1% or so of the codebase that is highly performance-sensitive). Optimized code is just a different thing from general code (if one is a productive programmer).
- dchichkov 14y agoAnd again it depends. I would return to a simple example of passing a parameter by a const reference. When you are writing this const in the "const std::string &name" you are 1) constraining developers from breaking things 2) making the code more efficient 3) providing clues to other developers 4) providing clues to optimizer. All of these points are important to some degree. And it is just the same, when you are writing this assignment. And writing efficient code that provides all these clues in every way possible (including consistently and meaningfully arranging the white spaces) is certainly a good idea. Funny thing, that with experience it doesn't take extra time to do that. You just write it, and it comes out in the right way: readable, efficient and optimal down to CPU microcode and aligned memory accesses.
- jblow 14y agoMy point is that when you are writing complicated production code, and you are a good programmer such that your rate of features successfully implemented is high, then you will often be going to old code and changing that code to behave somewhat differently than it was before. When you do this, you want that old code to be like putty. You want to bend it into a new shape without having to break it and start over. Sometimes it really is better to break it, if bending would be too messy or cause problems later or otherwise sets off a red flag in your head. But if you have to break and re-make everything all the time, you won't be a very fast programmer. So you learn how to bend things, elegantly. And after a while of this, you learn how to write code that is more amenable to elegant bending in the first place. When you type code, you are not just implementing a specific piece of functionality; you are implementing that functionality plus provision for unknown future times when you will need to come back and make the code different. (To link this more thoroughly to the previous comment: it happens all the time that you write code that is not really about doing stuff, but then you later need to make that code be about doing stuff. Sometimes this is for shipping functionality reasons, sometimes it is just to temporarily insert hooks for debugging. Declaring in advance that this code shall never be about doing stuff is usually a mistake.)
- georgeorwell 14y agoIt strikes me that your argument taken to the extreme is that everybody should program in assembly language because you can do anything, anytime, anywhere. Well, at least as far as control flow structures are concerned. Certainly C is preferable to C++ if you want simple and malleable code. Do you also prefer if-else to switch statements? (I'm not sure.) Do you like to use goto? (I doubt it.) Do you eschew the use of classes and inheritance? (I doubt it.) Do you keep all your code in one file? (I'd be very surprised.) My point with these semi-facetious questions is that structure is important and regularity in a codebase does wonders for comprehensibility and maintainability. I agree with you for the case in which you do actually have something where the underlying structure is likely to change, in that then it does make sense to write it with malleability in mind. Consider something like command line options processing. You have 50 options. You might want a 51st option. It makes sense to use the most regular structures you can so that people don't start special-casing stuff in the middle of it all. That, or to use an options library that defines the allowable formats for you. Part of me thinks you're just having an allergic reaction to ?: simply because it is pretty unusual the first time you see it used seriously. But it can simplify so much: Compare: if (a) { return b; } return c; to: return a ? b : c;
- Cushman 14y ago...really? I don't even write C that often, and I didn't find that difficult at all. Even if you don't grok the syntax yet, it just does what it seems like it does at first glance. And how on earth does a two-long ternary chain strike you as "extensive"? If you want to do something in addition to assignment, it's really quite easy: Just add a new `if` block underneath. This clearly separates your conditional assignment from whatever else is going on that may or may not be related to the assignment. (What if you add something besides assignment to the if, but then want to change the conditions for only that? You have to rewrite the whole thing!)
- georgeorwell 14y agoBasically it's a concise way to do a hard-coded table lookup. Tables are better for structurally regular code than if-else precisely because they restrict what that code can do.
- chipsy 14y agoI agree with jblow. I consider ternary a "sharp knife" in that even though it saves space, I never want to see it used more than one level deep. I don't want sharp knives in my code, I want Lego bricks. If that means the source code is a little bigger or the runtime is a little slower, that's OK, the vast majority of the time. The most egregious example of I can think of in this kind of thing is JS "gurus" who try to use the fewest semicolons possible in their unminified source. It doesn't add readability, and the semicolon rules are complicated enough that one could easily write a bug while trying to stick to the style. Sometimes languages have "tricks" that aren't sharp, and those are OK to use when you know them, but one has to distinguish.
- Too 14y agoIf / else is a way of defining what to be executed based on some condition. The ternary operator is used to guarantee assignment to a variable based on some condition. It's not only a way to save space, it's a way to express your intent clearer. It simply doesn't leave any undefined code path behind. In your case of changing the code a bit, in the carmack version of the function there's a risk that you remove the assignment to sides[i] in one case and it will later be undefined. Though i agree that the syntax is horrendous since it requires you to remember exactly what the symbols ? and : do. Compare to the much nicer and to a newbie understandable python syntax: x = y if c else z
- dchichkov 14y agoSpace is important. Think that you are not writing code, but painting a picture. And you are using space to convey meaning. You literally want to paint code, not write it. :)
- Tyr42 14y agoWell then you should work in Piet (http://www.dangermouse.net/esoteric/piet.html http://www.dangermouse.net/esoteric/piet.html) :P