Sergey Mikhanov | |
Logging is the new commenting (July 3, 2013)Back in 1999, when I was in the university, I was studying the C programming language — just like every other CS major in the world. In our little programs, there were header files and implementation files and everyone in my class, myself included, learned quite early that the number of files in your project will grow twice as fast as you add what our mentor was calling “a new compilation unit.” Someone in the class — unfortunately, not me — pointed at this obvious design “flaw.” Really, why do you have to duplicate your effort? All the information compiler needs about your program is in the implementation file already. I have only learned later that this is the point where most of the programmers start their affairs with more concise programming languages. But the lesson of that day was clear — duplication is bad. One semester later everyone in class got their copy of 3rd edition of Bjarne Stroustrup’s “C++ programming language”. One quote I learned almost by heart. It was — this time, fortunately — not related to C++ itself (it’s from the chapter 6.4 Comments and Indentation):
As much as I dislike C++, the writing style of its author is excellent. For the next ten years or so of my programming career I was barely leaving any comments in the code I wrote. Of course I did understand that comments could potentially be useful in the future for anyone reading the code (myself included) but writing code seemed easy and no explaination was needed. Throughout the same years I discovered the usefulness of logging; it was so helpful that I stopped using debugger completely. Here’s an example snippet from a deliberately incomplete recent program. Note the amount of logging statements: - (NSArray *)unify:(GAClause *)query with:(NSDictionary *)base dynamicContext:(NSArray *)dynamicContext { DLog(@"Unifying query %@, dynamic context is %@", query, dynamicContext); NSMutableArray *result = [NSMutableArray array]; GATuple *selfUnified = [query selfUnify:nil dynamicContext:dynamicContext]; if (selfUnified) { DLog(@"Query self-unified, got tuple: %@ ", selfUnified); NSMutableArray *tuples = [NSMutableArray array]; for (GATuple *t in dynamicContext) { [t merge:selfUnified]; [tuples addObject:t]; } DLog(@"Merged self-unification result with dynamic context: %@", tuples); return tuples; } else { for (GAClause *left in [base allKeys]) { GAClause *right = [base objectForKey:left]; GATuple *tuple = [self unifySingle:query with:left dynamicContext:result]; DLog(@"Bindings after unifying: %@ (clauses were %@ and %@)", tuple, query, left); if (!tuple) continue; [result addObject:tuple]; DLog(@"Accumulated result: %@", result); if (![right isEqual:[GAConstant kTRUE]]) { Objective-C methods - (NSArray *)unify:(GAClause *)query with:(NSDictionary *)base dynamicContext:(NSArray *)dynamicContext { // Unifying query with dynamic context NSMutableArray *result = [NSMutableArray array]; GATuple *selfUnified = [query selfUnify:nil dynamicContext:dynamicContext]; if (selfUnified) { // If we reached here, query is self-unifyable NSMutableArray *tuples = [NSMutableArray array]; for (GATuple *t in dynamicContext) { [t merge:selfUnified]; [tuples addObject:t]; } // Merged self-unification result with dynamic context return tuples; } else { for (GAClause *left in [base allKeys]) { GAClause *right = [base objectForKey:left]; GATuple *tuple = [self unifySingle:query with:left dynamicContext:result]; // Finished unifying, variable bindings now created if (!tuple) continue; [result addObject:tuple]; // At this point we have partly accumulated result if (![right isEqual:[GAConstant kTRUE]]) { Once you’ve got the logging, the need in having lots of comments in code reduces dramatically. You don’t need to duplicate your effort. You even can get rid of the downsides described by Bjarne Stroustrup, because someone running a program and reading its logs will make sure the output is meaningful, descriptive and current. Logging therefore becomes a better commenting system, helpful both during runtime and when figuring out what a particular piece of code does. Given the flexibility and robustness of modern logging frameworks available in any language, there are very few reasons to use lots of comments. Just log more. |
|
Entries (RSS) | © 2007–2017 Sergey Mikhanov | |
|