Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!decwrl!netcomsv!jls From: jls@netcom.COM (Jim Showalter) Newsgroups: comp.object Subject: Re: Functions without side effects (was Old confusion) Message-ID: <1991Jun24.195257.12734@netcom.COM> Date: 24 Jun 91 19:52:57 GMT References: <130242@tut.cis.ohio-state.edu> <4888@osc.COM> <72893@microsoft.UUCP> <4116@ssc-bee.ssc-vax.UUCP> <4907@osc.COM> <1991Jun19.173 <1991Jun21.013944.23970@netcom.COM> Organization: Netcom - Online Communication Services UNIX System {408 241-9760 guest} Lines: 158 >Good, good. The last time I made a similar posting, no one would bite. Uh oh... ;-) >You cite a major consideration, but not the only one. How local is the >definition of Default_Print to its use in the code? Does keeping it local >break other conventions? Is it worth the trouble of adding it? By doing so, >you double the code length in this example. (That is, it's more than a small >constant amount of extra code. Otherwise the answer is of obviously "Yes.".) As with so many issues of good style, rules are made to be broken. Would I always rename Default_Print to make subsequent code more readable? Depends on the surrounding context. As you point out, in some cases this would just be overkill. In other cases, it would be the right thing to do. It is this subjective variability of proper style that makes me so suspicious of coding style guides, at least the ones that allow for no flexibility--"No loop shall have multiple exits", etc. Why not? What if the cleanest way to implement the code is with multiple exits in this particular case? And so forth. >> I regard most comments as an admission of failure and/or a design flaw in the >> implementation language. >This is too easy a mark at face value. Please qualify. I regard most comments as a failure to encode the same information in the source itself. This comes about either because the programmer has done a lousy job of naming, etc, so that the code is a cryptic mess that NEEDS comments (as opposed to well-written code, in which case the comments would be superfluous paraphrasings), or it comes about because the language itself lacks certain constructs, making the use of comments a necessary evil as a workaround (for example, not having formal parameter names forces the programmer to document each parameter with a comment). I do believe there is a role for higher-level documentation, such as an overall architecture/design document--but this sort of information is not appropriate for the code OR the comments. > /* No further processing is usually required. However, such-n-such */ > /* sometimes forces the condition, which is relatively rare. */ > if (condition) > then {/* Increment page counter */ > i <- i + 1} > else {/* An exception has occurred, probably by such-n-such. ... */ > ...} In Ada: begin Page_Counter := Page_Counter + 1; exception when Rare_Condition => [deal with error event] end; Note that this version requires no comments, and reads as clearly as the one with comments. This is an example of what I'm talking about: the lack of an exception construct in the C example is a LANGUAGE flaw, and so comments are required to work around it. (If the lack of exceptions is NOT a language flaw, why is Stroustrup working so hard to add them to C++?...) >In looking at your Default_Print, it's just too verbose for the job, and >non-local. Consider > #define _local_print(comment) print(comment, 5, laserprinter, helvetica) > _local_print("a"); > _local_print("b"); > _local_print("c"); > #undef _local_print Okay. So I'm a maintainer. I come along with no clue what you're up to, and I'm supposed to reason my way around the above example (don't even get me STARTED on the evils of macros and conditional compilation...). My first question is--what is the mystery number 5 for? Does it print the comment 5 times? Does it print the comment with 5 lines of spacing? Does it print the comment in a point size of 5? These are perfectly reasonable questions for a maintainer to ask, and they cannot be answered with just the code you show above, because the semantic content is insufficient. Yes, if I have a good development environment I can probably look up the original print operation fairly quickly...but what if I don't? What if I just have a gigantic cross reference listing, perhaps aggravated by overloading? In my "verbose" Ada example, there is no ambiguity or confusion: procedure Local_Print (This_Comment : in String; With_Line_Spacing : in Positive := 5; ... The maintainer is informed immediately that the spacing is 5. The information is local to its use. There is no mystery number. There is no need to look anything up. And there is no need for comments to explain what is going on. As a maintainer, I'd MUCH prefer the latter example to your example, and would not consider it verbose at all: I would appreciate your having been considerate enough to include as much information as I needed to get my job done as efficiently as possible. If "verbose" means "easily maintainable", then I guess I'm all in favor of verbosity. Sometimes I get the idea that when people say "verbose" what they are really saying is "I'm a slow typist", and that the issue really boils down to someone being to lazy to enter the requisite number of keystrokes to make their code easily comprehensible by others. This is an act of utmost selfishness, and could probably best be addressed by a remedial course in touch typing. > if c if c if c > then {s1 then { then > s2 s1 { > s3} s2 s1 > else {s4 s3 s2 > s5} } s3 > else { } > s4 else > s4 { > } s4 > s5 > } Well, in Ada the "then" and the "else" (and the "elsif"--missing from C) ARE the compound statement delimiters, so the above translates to: if c then s1; s2; s3; else s4; s5; end if; This is roughly equivalent to the first (and shortest) example given, with the added advantage that the dangling "else" problem is eliminated in Ada (there is a clear distinction between an "if" nested inside an "else" and an "elsif", eliminating a common source of errors). Or am I missing something? ;-) >such transformation >is only MOSTLY mechanical, so such transformations might not be perfect. With the ambiguity of the dangling else removed, the transformation is perfect. You can reorganize the lexical indentation of the branching construct to your heart's content and it will remain semantically identical. This remarkable innovation, by the way, existed when C was being invented, but for some reason it was deemed unworthy of inclusion... -- *** LIMITLESS SOFTWARE, Inc: Jim Showalter, jls@netcom.com, (408) 243-0630 **** *Proven solutions to software problems. Consulting and training on all aspects* *of software development. Management/process/methodology. Architecture/design/* *reuse. Quality/productivity. Risk reduction. EFFECTIVE OO usage. Ada/C++. *