From: rmartin@thor.Rational.COM (Bob Martin)
Newsgroups: comp.lang.c++
Subject: Re: Tiny proposal for named loops.
Date: 25 Aug 92 14:33:28 GMT

rgp@mpd.tandem.com (Ramon Pantin) writes:

|In article <rmartin.714670566@thor> rmartin@thor.Rational.COM (Bob Martin) writes:

|>A loop is defined by a loop condition and a body.  By using a flag in
|>the loop condition, I am immediately expressing that condition.  By
|>using a break I am postponing the expression of that condition until I
|>happen to think of it in the midst of the loop.

|The CONDITIONS FOR SETTING YOUR FLAGS inside the loop are not evident
|from reading the head of the loop.  You still have to search for the
|places where that variable is set in the loop and constantly ask yourself:

|	Ok, the "done" variable was set here, in the MIDDLE of
|	the loop.  Does it mean that nothing else will be executed
|	for this case?  Can't assume that.  I will have to read all
|	the code that follows and see if something else happens for
|	this case.  Who knows, maybe some code below sets "done" to
|	FALSE under some other condition and the loop is not exited
|	at all for this case ...

|By the time you have "cached" in your brain a couple of these "thoughts"
|for the first occurrences of assignments to "done", "error", etc,
|you will have a much harder time reading the rest of the code.

Yes, flags can be abused, no doubt about it.  However, in a loop which
lacks break and continue statements, the concerns you mention above
don't often materialize.  This is because you can very easily follow
the if/else blocks and prove that no other code is executed after the
flag has been set.  

I do not recommend that flags be used without caution.  I recommend
that they be used in preference to break and continue.  I also
recommend that they be used "judiciously" (i.e. with judgement) to
avoid the problems that you mention above.

|>|	- Continue, I'm done with this case, the code that follows
|>|	  doesn't apply to this case, lets go to the next iteration.
|>
|>This is what 'else' statements are for.  every continue should be
|>replaced by an else.

|No!  There could be code AFTER the whole "if else" statement.  If I see
|an "if else" construct then I HAVE TO ASSUME that something else might
|happen for either case after the "if else" statement.  By reading the
|test at the head of the "if" I can't tell that, it is not expressing the
|intentions of the programmer.

We can argue this forever, and for every example you give me, I can
give you a counter example.  Believe me, I have written tens of
thousands of lines of code which do not require breaks or continues.
Nor have I had to reach very far to do this.  Just like OOP, it
becomes a very natural way to think after you do it for a while.

The if/else blocks within a loop can always be arranged in a way that
makes "continue" redundant.

|>|	- Return, I'm done, lets get out of this function.
|>
|>But first you'd better check to be sure that you have freed and closed
|>and taken care of everything else. Premature exit is a significant
|>cause of memory leaks, unclosed files, and other problems of pairity.

|There is no replacement for properly written code, if you structure
|your code correctly, then things occur naturally in the right places.
|If you have to do free/close/cleanup in multiple places then your
|code is probably poorly written.  

My point exactly.

|It is funny to note that you had
|to "duplicate code" in YOUR structured example below which is exactly
|the problem that you are trying to avoid when you say "one open, one
|close" ...

I duplicated code, (probably a function call), not a close or free.
The duplication of small bits of code is preferable to tangling the
code with breaks or continues.  Moreover, it is my experience that
such duplicated code is only coincidentaly identical.  As the code is
maintained and new features are added, the "duplicated blocks" often
diverge, since they live in different contexts.  Thus, they should
never have been combined.

If the code is truly identical, and there are more then a few lines,
then perhaps a function is indicated.

|If at the beginning of my function I do some validation of the arguments
|then there is nothing more natural than returning when an invalid argument
|has been detected.  These are the problems of trying to force this error
|return occur at the end of the function:
|	- The "if else" problem described above.
|	- The "normal" code is harder to read because it is indented
|	  one level deeper and it is not clear by looking at the code
|	  that this is the normal code.  The reader might wonder if
|	  there is more code after the "if else".  The "if else"
|	  problem occurs twice here!

Yes, by forcing returns at the end of a function, you get deeper
nesting.  This is both good an bad.  It is bad because of the number
of nesting levels.  It is often advisable to break up the code into
functions.  It is good because of a simple heuristic:  The real work
of the function occurs in the inner most block, all error conditions
are handled in subsequent else blocks, all clean up code (free, close,
etc) occurs at the end of non-else blocks.  (typically)

In short, functions with one return are full of landmarks that are
easy to recognize. The nesting structure exposes the places where
certain tasks are always performed.

[.. lots of argument deleted ..]

|>So, let me reverse the challenge.  I suggest that you try writing a
|>substantial amount of code without breaks, gotos, or mid-function
|>returns.  You might really like it!

|Inexperienced programmers might benefit from the structured
|programming concepts.  Like you (and everybody else) I have programmed
|in a variety of languages.  I don't need to restrain myself to these
|things to be able to write good code.  I trust my common sense,
|aesthetic sense, rationality and experience.

Meaning that you won't try it, right?  You "know" already. Fine.

Come on, give it a try.  Try it for 5,000 lines of code.  After that,
if you haven't derived the benefits that I claim, you can post a
scathing review proving that you were right all along.  


--
Robert Martin                        Training courses offered in:
R. C. M. Consulting                       Object Oriented Analysis
2080 Cranbrook Rd.                        Object Oriented Design
Green Oaks, Il 60048 (708) 918-1004       C++
Newsgroups: comp.lang.c++