for (
;
(*to = *from) != 0;
++from, ++to
)
;
Whereas the idiomatic version seems simpler: for (; (*to = *from) != 0; ++from, ++to);41–50 of 69 posts
for (
;
(*to = *from) != 0;
++from, ++to
)
;
Whereas the idiomatic version seems simpler: for (; (*to = *from) != 0; ++from, ++to);For example, even fairly basic textbooks make extensive use of footnotes, endnotes, marginal notes, sidebars, illustrations, tabular material, bibliographies, and other similar tools. What these all have in common is that they remove valuable supporting information from the main text, but keep it available (with varying degrees of immediacy) for readers who want to refer to it, and provide conventions to help the reader find it. In some cases, they also present that material in a structured way that is more effective than plain text.
With modern interactive IDEs, we have the ability to use not only all the same tricks that traditional book typesetting does but also many more because ours can be dynamic, interactive, graphical, or any combination of the above. We can add supporting material on any of four sides around a code listing, or even overlay information on the listing itself, and we can change the information we show in those places automatically with context and/or at the reader’s request based on what they want to do next. And yet, except for debugging and for navigating around large projects, we tend to make very little use of these tools. We still mostly try to present code as a single static column of monospaced material with the occasional extra vertical space and a bit of horizontal alignment to emphasize structure, and maybe a left sidebar with line numbers and a couple of icons for bookmarks or breakpoints, or perhaps a bit of trivial dynamic highlighting during things like find/replace work.
What if instead we tried to make the main code area focus on the core logic and data, and move anything else out of the way? There are many opportunities to do that. Type annotations? Supporting data. Comments? Supporting data. Long list of module.names.before.useful.identifier? Probably supporting data as long as it’s unambiguous, probably something you want to draw attention to if it’s not. Even keywords like ‘var’ in the example code snippets don’t help a human reader much. And that’s just with the kind of conventions and languages we use today, without even considering the endless possibilities of languages and tools designed with alternative presentation in mind from the start.
None of this even needs to get in the way of the tried and tested practice of storing code in plain text files. It could all be dealt with in your editor/IDE using exactly the same kinds of techniques as the standardised-formatting tools other posters have mentioned here, and saving a file could record the supporting data in a standardised text format that is friendly to version control systems, code review tools, automated diffs, and so on.
In short, if we’re going to address readability and presentation in programming, let’s think outside the box a bit. We have the most powerful information sharing and presentation tools in human history at our disposal, and a mountain of data about usability and interface design. We can do more than worrying about how many spaces we should have between tab stops.
Reading Code Complete (and listening to Crockford's talks) has really opened my mind to writing clearer code constructs. For example, the for-loop's job in the first example should be to track indexes. There shouldn't be code that "does stuff" between parens. Instead of superficially breaking the for-loop into several lines and wasting time on aligning semicolons, it could be re-written as a while loop with clarity i…
Personally, I've always found code with a "table structure" prettier but less readable in practice. It's also fussy and time-consuming to maintain. I favor information density and flow.
We could definitely do a better job with source code typography, but if the goal is to make the code more readable, I think the points discussed here are setting the bar pretty low for what we could achieve instead of today’s norms. For example, even fairly basic textbooks make extensive use of footnotes, endnotes, marginal notes, sidebars, illustrations, tabular material, bibliographies, and other similar tools. Wha…
When I first started programming in C, I did the same thing with pointers (i.e., char* str; instead of char *str; ). Unfortunately, this creates the wrong impression that char* str1, str2; creates two pointer-to-char variables, whereas actually str1 is a char pointer and str2 is simply a char. Indeed, I was confused on this point myself when I was a newbie, which led to great confusion later on. The clearest way I've…
What is wrong with having str1 and str2 declared on separate lines? Like this: char* str1; char* str2; What is gained with combining these declarations (except for less typing)?
Would like to know whether the author feels his rewrite is more successful than the original. The following takes me longer to read: for ( ; (*to = *from) != 0; ++from, ++to ) ; Whereas the idiomatic version seems simpler: for (; (*to = *from) != 0; ++from, ++to);
When I was younger I did a lot more interior alignment between lines, like with the list of variable declarations. Over the years I've found that they add a lot of busywork effort to the editing process. Everyone talks about optimizing for reading, but not optimizing for editing, which in some cases is really what you need to be optimizing for. But even laying that aside, the readability improvement of such spacing was debatable. Sometimes it's making visible a repetition (presumably one that couldn't be done with an actual loop), but a lot of times it feel more like a novelist who decided that the main verbs of their sentences should be vertically aligned. Agreed, it's making something visible -- but is that really what the average reader cares about? Ultimately the typography should not be a distraction from discerning the sense of a piece of code.
I positively hate that for loop rewrite. Having the semi-colon so expressly indented looks awful, especially on it's own line. I really feel that the for loop should be converted to a while loop - that would probably make the intent clearer.
When I first started programming in C, I did the same thing with pointers (i.e., char* str; instead of char *str; ). Unfortunately, this creates the wrong impression that char* str1, str2; creates two pointer-to-char variables, whereas actually str1 is a char pointer and str2 is simply a char. Indeed, I was confused on this point myself when I was a newbie, which led to great confusion later on. The clearest way I've…
What is wrong with having str1 and str2 declared on separate lines? Like this: char* str1; char* str2; What is gained with combining these declarations (except for less typing)?
And again, the wrong impression is conveyed (that you are declaring a variable of type char* instead of a pointer type that dereferences to a char).
With more complex types, not understanding what is really going on makes code incredibly opaque (and that typographical style ad hoc). What would you do with this:
char *((*func)(char *));
That isn't a char pointer at all. It's a pointer to a function that takes a char pointer as an argument and returns (i.e., evaluates to) a char pointer. It looks incredibly dense (to me, at least), unless I think of it in the way I talked about above (in which case it all makes sense and is kind of cool).With the convention used in the article, the declaration would be something like this:
char* ((* func)(char*));
Which doesn't make clear why the outside parentheses are needed, or why there is a dereference (or multiplication?) operator in front of the variable name.The idea of a variable declaration being an expression that evaluates to a basic type is actually the reason why the same symbol * is used in the declaration and in the dereferencing of pointers: they mean the same thing.
Basically, what I am trying to say is that the typographical practice used in the article is at odds with the actual meaning of the statement (and the explanation he gives shows he clearly does misunderstand the statement), which can only lead to confusion in the long run, especially when you encounter code written by other people. Or, as with your example, it can lead to eschewing a useful feature of a language simply because it doesn't look pretty according to your arbitrary whitespace conventions.