comp.lang.ada
 help / color / mirror / Atom feed
* Re: Software landmines (loops)
  1998-08-20  0:00                             ` adam
@ 1998-08-20  0:00                               ` Nick Leaton
  1998-08-30  0:00                                 ` Matthew Heaney
       [not found]                                 ` <m3ogt3qgca.fsf@mheaney.ni.n <1dghyt5.oik1lzhxzf2N@n207167116176.inetworld.net>
  0 siblings, 2 replies; 510+ messages in thread
From: Nick Leaton @ 1998-08-20  0:00 UTC (permalink / raw)


I have just done a quick check through some Eiffel code. 

Out of 633 loops, just 1 needed a flag for early termination of the
loop.

-- 

Nick




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-20  0:00                               ` Software landmines (loops) Nick Leaton
@ 1998-08-30  0:00                                 ` Matthew Heaney
  1998-08-30  0:00                                   ` Robert Martin
       [not found]                                 ` <m3ogt3qgca.fsf@mheaney.ni.n <1dghyt5.oik1lzhxzf2N@n207167116176.inetworld.net>
  1 sibling, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-08-30  0:00 UTC (permalink / raw)


Nick Leaton <nickle@calfp.co.uk> writes:

> I have just done a quick check through some Eiffel code. 
> 
> Out of 633 loops, just 1 needed a flag for early termination of the
> loop.

My own experience is quite different from yours.  Although I haven't
counted, I use early loop termination ALL THE TIME.

For example, I routinely implement an equality test (say, for a stack)
as

function "=" ... return Boolean is
begin
...

  for Index in Positive range 1 .. L.Depth loop
     if L.Items (Index) /= R.Items (Index) then
        return False;
     end if;
  end loop;

  return True;

end "=";


If my loop termination depends on a value I just read, then exit from
the middle is the simplest solution:

loop
   Get (N);

   exit when N = 0;

   <process N>
end loop;

For example, this is a simplest way to tokenize a lexeme.  You exit the
loop in the middle, after determining that the character just consumed
isn't part of the current token.

Exiting is how you terminate passive iteration early:

procedure For_Every_Item (Stack : in Stack_Type) is
 
   Done : Boolean := False;

begin

   for Index in reverse Positive range 1 .. Stack.Top loop
      Process (Stack.Items (Index), Done);
      exit when Done;
   end loop;

end For_Every_Item;


Searching is also implemented using early loop termination:

function Get_Position
  (C : Character; 
   S : String) return Natural is
begin
   for Index in S'Range loop
      if S (Index) = C then
         return Index;
      end if;
   end loop;

   return 0;
end Get_Position;
   

No auxilliary variables or flags are required.

Below is a portion of my response to another thread on comp.lang.ada re
the goto statement.

Matt

(start of quote)
Any theory about using (or not using) a programming construct needs to
be tested against observation, by performing an empirical study that
measures the defect rates of programmers using the construct.

If theory says use a construct, but observation reveals that programmers
who use the construct produce more errors, then the theory needs to be
thrown out.

For example, there's a pernicious myth that exiting (or returning) from
the middle of a loop is bad, and that the only proper way to write a
loop is to state the termination condition explicitly, as a predicate
appearing at the top of the loop.

This theory was indeed put to the test, and guess what?  Programmers
using a test-and-exit from the middle of the loop produced fewer errors
than those programmers who tried to put the test at the top of the loop.
The researchers found that the exit-from-the-middle construct had a
better "cognitive fit" than the other constructs.

If you want to read the gory details, the article is

Cognitive Strategies and Looping Constructs: An Empirical Study
Soloway, Bonar, Ehrlich
CACM, Nov 83, Vol 26, No 11, p 853-860

The goodness of a language construct should not be determined by
doctrinaire computer scientists or mathematicians.  The only thing that
matters is whether working programmers think it's easier to understand,
and whether by using the construct programmers inject fewer errors into
the code.

I think it was Stroustrup who said, "Programming is a human activity.
Forget that, and all is lost."
(end of quote)




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-30  0:00                                 ` Matthew Heaney
@ 1998-08-30  0:00                                   ` Robert Martin
  1998-08-30  0:00                                     ` Charles Hixson
                                                       ` (7 more replies)
  0 siblings, 8 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-30  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...

>If theory says use a construct, but observation reveals that programmers
>who use the construct produce more errors, then the theory needs to be
>thrown out.

All else being equal, that would be so.  But when observation shows that the
construct reduces the overall cost of maintaining the program, regardless of
its initial cost, then it ought not be thrown out.

>For example, there's a pernicious myth that exiting (or returning) from
>the middle of a loop is bad, and that the only proper way to write a
>loop is to state the termination condition explicitly, as a predicate
>appearing at the top of the loop.

Yes.  That pernicious myth is called "structured programming".

>This theory was indeed put to the test, and guess what?  Programmers
>using a test-and-exit from the middle of the loop produced fewer errors
>than those programmers who tried to put the test at the top of the loop.

>Cognitive Strategies and Looping Constructs: An Empirical Study
>Soloway, Bonar, Ehrlich
>CACM, Nov 83, Vol 26, No 11, p 853-860

Do you know if the citing is on line?  Was the experiment controlled?  Did
the experiment measure long term cost?  Were the participants engineers who
had been used to min-loop exits, and were strugging with a new concept?

My own experience is counter to the results of this study.  It is far easier
to understand a loop if the looping criteria are present in one place; and
the loop has a single, well known, exit.

>The researchers found that the exit-from-the-middle construct had a
>better "cognitive fit" than the other constructs.

"Cognitive fit" is probably not a very good criterion for good engineering.
GOTO has a very good cognitive fit.  So does a flat Earth.

>The goodness of a language construct should not be determined by
>doctrinaire computer scientists or mathematicians.  The only thing that
>matters is whether working programmers think it's easier to understand,
>and whether by using the construct programmers inject fewer errors into
>the code.

And whether or not the construct is maintainable over the long term.  There
are lots of constructs that make writing the initial program easy, but make
maintaining it hard.  The practice of using such constructs, i.e. ignoring
long term effects, is sometimes called "hacking".
>
>I think it was Stroustrup who said, "Programming is a human activity.
Forget that, and all is lost."


Precisely!  Programming is an activity of human creativity and human
frailty.  Forget either part, and all is lost.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-30  0:00                                   ` Robert Martin
@ 1998-08-30  0:00                                     ` Charles Hixson
  1998-08-31  0:00                                       ` Robert I. Eachus
  1998-08-31  0:00                                     ` Ell
                                                       ` (6 subsequent siblings)
  7 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-08-30  0:00 UTC (permalink / raw)


In my experience it is USUALLY a bad idea to exit from the middle of a
loop.  It is USUALLY a bad idea not to place the loop continuation test
at the start.  But there are many exceptions.  There are many loops that
require either a very complex initial test, or multiple tests, e.g.
(psuedo-code)

if (str (0) != ';')
{  while (len (str) < 0)
   {  select (str (0) )
      {  case  'A'..'Z':
		....
		exit;
	 case  'a'..'z':
               -- do something else
               -- chop off head of string
         case  '0'..'8':
               -- do something else
               -- chop off head of string
         case  '9':
		-- do something else
                -- set loop exit flag
                -- chop off head of string
         otherwise:
                -- reset loop exit flag
       }
       -- do some stuff
       when (exitFlag and lastChar != '9') exit;
    }
}

Now maybe this is what was meant by a "state-machine", as when this kind
of construct comes up I do think of goto's, which WOULD make writing the
code easier.  I just don't think that they would make understaning it
easier.
On the other hand, the test that one would need to emplace to put all
exit tests at the beginning of the loop is apalling, and I don't think
that a calculating a compound boolean flag, together with the internal
if tests to skip over code that isn't to be executed in this pass,
improves things.

Personally, I try to avoid this situation, but sometimes I just can't
("Parse this list of mailing labels that different people have created
in different systems using different software.  We can get it into csv
form, and within each list the fields will usually be in the same order,
and they won't interpolate new field very often.  Oh, yes, sometimes
people used their mailing list to attach notes to themselves about the
company being mailed to.  Could you save those separately.")
When this comes up, the idea of NOT being able to exit a processing loop
would be apalling.  Sometimes I end up just throwing the entire label
into comments (even after looking at it).  Once in awhile I'll discard
it (after looking at it).  But I've GOT to be able to handle data with
any type-compliant degree of variation.  And sometimes that means
exiting from deeply imbedded loops.

Robert Martin wrote:
> 
> Matthew Heaney wrote in message ...
> 
> >If theory says use a construct, but observation reveals that programmers
> >who use the construct produce more errors, then the theory needs to be
> >thrown out
...
> 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Mattias Lundstr�m
@ 1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Robert I. Eachus
                                                               ` (2 more replies)
  1998-09-01  0:00                                           ` Tim Ottinger
  1 sibling, 3 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2353 bytes --]


Mattias Lundstr�m wrote in message <35EAB5B1.1DA1986B@ehpt.com>...

1. Flag solution
while( ... && retval == OK ) {
...
if( ... )
  retval = NOT_OK;
}
return retval;

vs

2. Multiple exits
while( ... ) {
...
if( ... )
  return NOT_OK;
}
return OK;


>(Ie The maintenance argument - that the second code version
>becomes harder to read and understand (and thus maintain) -
>since the return statement may well not be obvious if there
>is a lot of other code within the loop. I do not agree
>with this, but it is certainly an argument worth considering.
>IMHO This should be covered by good comments where applicable.)


It's not so much a matter of being harder to read and understand.  Rather it
is that there is no good place to make certain kinds of changes to the code.

For example,  let's say that we had to make a change that forced us to open
and close a file that the body of the loop needed to read.  Then:

1. Flag solution
File* f = fopen(...);
while( ... && retval == OK ) {
  ...
  if( ... )
    retval = NOT_OK;
}
fclose(f);
return retval;

vs

2. Multiple exits
File* f = fopen(...);
while( ... ) {
  ...
  if( ... ){
    fclose(f);
    return NOT_OK;
  }
}
fclose(f);
return OK;

Clearly solution 1 is easier to deal with than solution 2.  Solution 1
implies that there will be one, and only one, fclose in the function.
Whereas solution 2 implies that there will be as many fcloses as there are
early returns.  And that new fcloses will have to be added if new returns
are added.  Thus the maintainer must *remember* to add an fclose every time
he adds a new return; *and* he must remember to check every return if he
adds something else like a fopen/fclose pair in the function (e.g. a
malloc/free, a sieze/release, a lock/unlock, etc).

So, to reiterate, reading and understanding are not the sole issue.
Producing code that is easy to maintain is more to the point.  It is quite
feasible to have code that you understand perfectly well, but is very hard
to maintain.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <m31zpxqutn.fsf@mheaney.ni.net>
@ 1998-08-31  0:00             ` Jim Cochrane
  1998-09-01  0:00               ` Matthew Heaney
  1998-09-01  0:00               ` Matthew Heaney
  0 siblings, 2 replies; 510+ messages in thread
From: Jim Cochrane @ 1998-08-31  0:00 UTC (permalink / raw)


How about the following version, without multiple exit points (written in
Eiffel because it is a good language for this style [it actually doesn't
allow the multiple return style] and because I'm familiar with Eiffel.)

class STACK [G] ...
is_equal (other: STACK [G]): BOOLEAN is
        -- Are all items in Current equal to all item in other?
    require
        other /= Void
    local
        i1, i2: STACK_ITERATOR
    do
        !!i1.make (Current); !!i2.make (other)
        from
            i1.start; i2.start
        until
            i1.after or i2.after or else i1.item /= i2.item
        loop
            i1.forth; i2.forth
        end
        Result := i1.after and i2.after
    end

I don't think this is particularly hard to understand or maintain, plus it
is simpler than the algorithm below - it eliminates the if statement at the
beginning.  (STACK_ITERATOR behavior is, hopefully, obvious - i.item means
the value of item at the current cursor position of i.)  I threw this together
just for this post, so apologies if there are any bugs (and bonus points to
those that find them :-) ).

In article <m31zpxqutn.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>ahussey@it.uq.edu.au (Andrew Hussey) writes:
>
>> >Using an exit from the middle avoids the headaches (literally)
>> >engendered by using an extra flag in the predicate.  When you want to
>> >exit, you just say that you want to exit, directly.  No mental
>> >gymnastics are required in order to determine whether you'll "really"
>> >exit, as would be the case using the flag approach.
>> 
>> That's brilliant, now your code is much easier to write!
>> Now let's see who has an easier time *testing* their code.
>> I think you'll find the control-flow errors you introduce
>> in the spaghetti you produce will more than make up for
>> any gain you have from rapid coding.  
>
>Here's is something I whipped up for another post recently.  It's an
>equality operator for a bounded stack.  
>
>The implementation of the function has multiple returns.
>
>Does this implementation fit your definition of spaghetti code?
>
>Would the implementation be better by not using multiple returns?
>
>
>function "=" (L, R : Stack_Type) return Boolean is
>begin
>
>   if L.Top /= R.Top then
>      return False;
>   end if;
>
>   for Index in Positive range 1 .. L.Top loop
>      if L.Items (Index) /= R.Items (Index) then
>         return False;
>      end if;
>   end loop;
>
>   return True;
>
>end "=";
>
>
>My feeling is that trying to implement this operation using only a
>single return would just make it more complicated.
>
>


-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Matthew Heaney
@ 1998-08-31  0:00                                           ` Tim McDermott
  1998-08-31  0:00                                             ` Larry Brasfield
                                                               ` (2 more replies)
  1998-08-31  0:00                                           ` Robert Martin
                                                             ` (2 subsequent siblings)
  3 siblings, 3 replies; 510+ messages in thread
From: Tim McDermott @ 1998-08-31  0:00 UTC (permalink / raw)




Matthew Heaney wrote:

> Here's is something I whipped up for another post recently.  It's an
> equality operator for a bounded stack.
>
> The implementation of the function has multiple returns.
>
> Does this implementation fit your definition of spaghetti code?
>
> Would the implementation be better by not using multiple returns?
>
> function "=" (L, R : Stack_Type) return Boolean is
> begin
>
>    if L.Top /= R.Top then
>       return False;
>    end if;
>
>    for Index in Positive range 1 .. L.Top loop
>       if L.Items (Index) /= R.Items (Index) then
>          return False;
>       end if;
>    end loop;
>
>    return True;
>
> end "=";
>
> My feeling is that trying to implement this operation using only a
> single return would just make it more complicated.

How about this:

  function "=" (L, R : Stack_Type) return Boolean is
begin

   Boolean isEqual = True;
   Positive Index = 1;

   if L.Top /= R.Top then
      isEqual = False;
   end if;

   while Index < L.Top && isEqual loop
      if L.Items (Index) /= R.Items (Index) then
         isEqual = False;
      end if;
      Index++;
   end loop;

   return isEqual;

end "=";

What Dykstra was getting at with single entance, single exit is that you can
attempt to reason about the programs that are well structured.  In the
second version, you can make assertions about pre- and post-conditions.  In
fact they jump out of the loop test.  That is not the case with the first
version.

Tim





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-30  0:00                                     ` Charles Hixson
@ 1998-08-31  0:00                                       ` Robert I. Eachus
  0 siblings, 0 replies; 510+ messages in thread
From: Robert I. Eachus @ 1998-08-31  0:00 UTC (permalink / raw)


In article <35E9C0CD.D225D1F8@earthlink.net> Charles Hixson <charleshixsn@earthlink.net> writes:

 > Now maybe this is what was meant by a "state-machine", as when this kind
 > of construct comes up I do think of goto's, which WOULD make writing the
 > code easier.  I just don't think that they would make understaning it
 > easier.

   Yes, that is a state machine, and there are tools for making them
more understandable.  But if you try to implement one, even that
simple, in a language which doesn't allow gotos or the equivalent, you
have my sympathy.  (In the example, multiple loop exits were used as a
restricted form of goto.  If you do use a goto, you should use the
most restricted form that will do the job.  Good languages have
several available, including a general purpose form.  In Ada the goto
has a few potentially irksome restrictions (you can't use a goto from
one branch of a case statement to another, or out of a subprogram),
but I have never seen a situation where the limits affected a real
program.  (In fact, the most irksome part is probably the necessary
compile-time structures and tests for legality.)

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Tim McDermott
@ 1998-08-31  0:00                                             ` Larry Brasfield
  1998-09-01  0:00                                               ` Matthew Heaney
  1998-09-01  0:00                                             ` dewar
  1998-09-01  0:00                                             ` Matthew Heaney
  2 siblings, 1 reply; 510+ messages in thread
From: Larry Brasfield @ 1998-08-31  0:00 UTC (permalink / raw)


Tim McDermott wrote in message <35EB1706.22E7E52E@draper.com>...
>
>
>Matthew Heaney wrote:
>
>> Here's is something I whipped up for another post recently.  It's an
>> equality operator for a bounded stack.
>>
>> The implementation of the function has multiple returns.
>>
>> Does this implementation fit your definition of spaghetti code?

Not mine.  Without significant effort, I can translate your code
into "False if lengths differ, or if an element differs, else True".
The concept of returning a query result when and where it
becomes known cannot degrade clarity as I perceive it.

>> Would the implementation be better by not using multiple returns?
>>
>> function "=" (L, R : Stack_Type) return Boolean is
>> begin
>>
>>    if L.Top /= R.Top then
>>       return False;
>>    end if;
>>
>>    for Index in Positive range 1 .. L.Top loop
>>       if L.Items (Index) /= R.Items (Index) then
>>          return False;
>>       end if;
>>    end loop;
>>
>>    return True;
>>
>> end "=";
>>
>> My feeling is that trying to implement this operation using only a
>> single return would just make it more complicated.

I think this is a poor example for the structure issue.  A
better one, IMO, is one where state must be modified
and invariants discerned to be maintained "while" some
appropriately understood transformation is effected.

>How about this:
>
>  function "=" (L, R : Stack_Type) return Boolean is
>begin
>
>   Boolean isEqual = True;
>   Positive Index = 1;
>
>   if L.Top /= R.Top then
>      isEqual = False;
>   end if;
>
>   while Index < L.Top && isEqual loop
>      if L.Items (Index) /= R.Items (Index) then
>         isEqual = False;
>      end if;
>      Index++;
>   end loop;
>
>   return isEqual;
>
>end "=";
>
>What Dykstra was getting at with single entance, single exit is that you can
>attempt to reason about the programs that are well structured.  In the
>second version, you can make assertions about pre- and post-conditions.  In
>fact they jump out of the loop test.  That is not the case with the first
>version.

A bit overstated in this case, I think.  But your point is
important.  There seem to be two ways that people
analyze program segments: (1) What the code does;
and (2) What is true because the code runs/ran.  (I do
not count a myriad of fuzzy and inneffective ways.)

Multiple exits and other more complicated flow graphs
impede (but do not necessarily defeat) a "What is true"
analysis, but do not have as much effect on a "What
will/can happen when this runs" analysis, unless the
flow of control becomes difficult to sort out.

I maintain that "What is true" analysis is ultimately more
effective and reliable, especially as it is composed from
smaller chunks of analysis.  At higher levels than short,
readily grasped partial screen code fragments, simpler
flow graphs are a bigger win than is apparent from the
small examples used to illustrate such ideas, especially
for those who take the "What is true" approach.


I think a lot of the disagreement over the merits of the
less simple structure (short spaghetti?) arises from
differences in how people comprehend code.  I once
worked with a brilliant fellow whose code drove me
nuts (momentarily!) because his way of looking at
it was different from mine, in the way I've suggested.
(No offense intended, if you're reading this, D.)

That said, I find the addition of extra flags just to
remove an edge from the flow graph to be a
(slight) hindrance to comprehension.

--Larry Brasfield
Above opinions may be mine alone.
(Humans may reply at unundered larry_br@sea_net.com )







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Ell
  1998-08-31  0:00                                             ` Robert Martin
@ 1998-08-31  0:00                                             ` Phlip
  1998-08-31  0:00                                               ` Robert Martin
  1 sibling, 1 reply; 510+ messages in thread
From: Phlip @ 1998-08-31  0:00 UTC (permalink / raw)


Ell wrote:

>Please show me a Dijkstra, Dahle, Hoare quote that says "the elements
>of structure[d] programming have a single entry and single exit."

Uh, I'd be more interested in any of those guys saying "functions should be
short".

Anything else is just an excuse to keep functions remotely comprehensible
even if they'r long...

  --  Phlip                  (no replies - address changed)
======= http://users.deltanet.com/~tegan/home.html =======
  --  The lunatics have stock options in the asylum  --






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
@ 1998-08-31  0:00                                             ` Robert I. Eachus
  1998-08-31  0:00                                               ` Robert Martin
  1998-09-01  0:00                                               ` Matthew Heaney
  1998-09-01  0:00                                             ` Mattias Lundstr�m
  1998-09-01  0:00                                             ` Richard Jones
  2 siblings, 2 replies; 510+ messages in thread
From: Robert I. Eachus @ 1998-08-31  0:00 UTC (permalink / raw)


In article <6sf1dn$n52$1@hirame.wwa.com> "Robert Martin" <rmartin@oma.com> writes:

 > It's not so much a matter of being harder to read and understand.  Rather it
 > is that there is no good place to make certain kinds of changes to the code.

 > For example,  let's say that we had to make a change that forced us to open
 > and close a file that the body of the loop needed to read...

   This is why T-shirts were printed up at one of the Ada 9X
Requirements Workshops that said:  "We don't know what the problem is... 
...but Finalization is the solution."

   Finalization did end up in Ada 95, and it is the right solution to
this particular problem.  If you want the file to be closed when all
references go away, it is easy enough to put the code in one place,
and write:

   (elsewhere):

   type File_Handle is new Controlled with private...

   Now you can say:

   procedure ... is
     FH: File_Handle;
   begin
     ...
    end ...;

    And be sure that the file will be closed if necessary, but only when
the file is open and no other reference to it exists.

    Of course, no one does this, because most compiler vendors "do the
right thing" for the standard I/O packages.  (This wasn't always the
case.)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Matthew Heaney
  1998-08-31  0:00                                           ` Tim McDermott
@ 1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Gene Gajewski
                                                               ` (6 more replies)
  1998-09-01  0:00                                           ` Loryn Jenkins
  1998-09-01  0:00                                           ` Don Harrison
  3 siblings, 7 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...

>
>Would the implementation be better by not using multiple returns?

Yes.  Imagine that you had to change the function to make it thread safe;
and that the way to do that was to sieze and release a mutex while the
function was executing.  As written you would have to add the release in
three separate places.  But if you had avoided the multiple returns, you
would have had a single release.

>
>
>function "=" (L, R : Stack_Type) return Boolean is
>begin
>
>   if L.Top /= R.Top then
>      return False;
>   end if;
>
>   for Index in Positive range 1 .. L.Top loop
>      if L.Items (Index) /= R.Items (Index) then
>         return False;
>      end if;
>   end loop;
>
>   return True;
>
>end "=";
>
>
>My feeling is that trying to implement this operation using only a
>single return would just make it more complicated.


Well, let's see:   (in C++)

bool operator==(Stack& l, Stack& r)
{
  bool equal = true;
  for (int index = 1; index < l.top() && equal == true; index++)
  {
    if (l[index] != r[index])
      equal = false;
  }
  return equal;
}

If this is more complex (something that is arguable) it is not *much* more
complex.  On the other hand, it is easier to maintain.  The thread-safety
issue I talked about above would be easier to add to this function than to
the one with multiple returns.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Ell
@ 1998-08-31  0:00                                             ` Robert Martin
  1998-08-31  0:00                                               ` Ell
  1998-08-31  0:00                                             ` Phlip
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)




>RCM wrote:
>>> >>Yes.  That pernicious myth is called "structured programming".
>
>Elliott wrote:
>>> >Please cite even just a single structured programming text, or founder
>>> >where what you say here was asserted.


RCM replied:
>> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
>> 16-23 "7. On Understanding Programs"


Ell wrote in message <35ead1be.659708@news.erols.com>...
>Please show me a Dijkstra, Dahle, Hoare quote that says "the elements
>of structure[d] programming have a single entry and single exit."

p19, in the section entitled: "Notes on Structured Programming": "These
flowcharts also share the property of a single entry at the top and a single
exit at the bottom."


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                             ` Phlip
@ 1998-08-31  0:00                                               ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Phlip wrote in message <6sf8nn$34n$1@news0-alterdial.uu.net>...
>Ell wrote:
>
>>Please show me a Dijkstra, Dahle, Hoare quote that says "the elements
>>of structure[d] programming have a single entry and single exit."
>
>Uh, I'd be more interested in any of those guys saying "functions should be
>short".
>
>Anything else is just an excuse to keep functions remotely comprehensible
>even if they'r long...


Short functions can still be badly structured.  Short does not, necessarily,
imply good.  (although it can sure help).  The stack compare function is a
good example, it is short, but could still be better structured through the
use of single/entry and single/exit.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Stephen Leake
@ 1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Agent
                                                               ` (3 more replies)
  0 siblings, 4 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Stephen Leake wrote in message ...
>"Robert Martin" <rmartin@oma.com> writes:
>
>> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
>> 16-23 "7. On Understanding Programs".    Actualy this section says that
>> there are two different kinds of loops. one that is tested at the top;
and
>> another which is tested at the bottom.  But in all cases, the elements of
>> structure programming have a single entry and a single exit.  A loop that
>> exits in the middle, violates this maxim.
>
>If there is only one 'exit' statement, why is this bad?
>
>loop
>    ... stuff
>    exit when ;
>    ... stuff
>end loop;
>
>One entry, one exit. Perfectly clear. There's nothing magic about
>putting the exit statement at the top or the bottom!

In fact there is.  If the exit condition is at the top or the bottom, then
the body of the loop will always be excuted an exact integral number of
times.  However if the loop condition is in the middle, then the loop body
will be executed a fractional number of times.



Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                     ` dennison
@ 1998-08-31  0:00                                       ` Robert Martin
  1998-09-01  0:00                                         ` Matthew Heaney
  1998-09-01  0:00                                       ` Andrew Reilly
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



dennison@telepath.com wrote in message <6sebjr$b69$1@nnrp1.dejanews.com>...
>In article <6sbuod$fra$1@hirame.wwa.com>,

>The other option is to create a flag of some sort, and check it every loop
>iteration. That's even worse because I have increased the (McCabe)
complexity
>of the code to a rather non-obvious end.

Personally, I don't consider that to be a valid engineering criterion.  The
true complexity of the code has not increased; and the job of maintaining
the code is simpler.

>If I have to add code to the loop,
>even I the author have to think hard about where it goes now.

I'm not sure what you are trying to say here.  Don't you always have to
think hard about where your code goes?  Why does the flag make it harder?

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                             ` Robert Martin
@ 1998-08-31  0:00                                               ` Ell
  1998-08-31  0:00                                                 ` Robert Martin
  1998-09-01  0:00                                                 ` Charles Hixson
  0 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-08-31  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

>
>
>>RCM wrote:
>>>> >>Yes.  That pernicious myth is called "structured programming".
>>
>>Elliott wrote:
>>>> >Please cite even just a single structured programming text, or founder
>>>> >where what you say here was asserted.
>
>
>RCM replied:
>>> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
>>> 16-23 "7. On Understanding Programs"
>
>
>Ell wrote in message <35ead1be.659708@news.erols.com>...
>>Please show me a Dijkstra, Dahle, Hoare quote that says "the elements
>>of structure[d] programming have a single entry and single exit."
>
>p19, in the section entitled: "Notes on Structured Programming": "These
>flowcharts also share the property of a single entry at the top and a single
>exit at the bottom."

???

Where is the generalized design heuristic?  It certainly is not this
statement.

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
@ 1998-08-31  0:00                                             ` Agent
  1998-09-01  0:00                                               ` Ell
  1998-09-01  0:00                                             ` Phil Goodwin
                                                               ` (2 subsequent siblings)
  3 siblings, 1 reply; 510+ messages in thread
From: Agent @ 1998-08-31  0:00 UTC (permalink / raw)


Robert Martin wrote in message <6sfcft$70p$1@hirame.wwa.com>...
>Stephen Leake wrote in message ...
>>If there is only one 'exit' statement, why is this bad?
>>
>>loop
>>    ... stuff
>>    exit when ;
>>    ... stuff
>>end loop;
>>
>>One entry, one exit. Perfectly clear. There's nothing magic about
>>putting the exit statement at the top or the bottom!
>
>In fact there is.  If the exit condition is at the top or the bottom,
then
>the body of the loop will always be excuted an exact integral number of
>times.  However if the loop condition is in the middle, then the loop
body
>will be executed a fractional number of times.


There are two "loop bodies" in this case.  The upper body will be
executed n times, and the lower body will be executed n-1 times.  It is
a little more difficult to keep track of, but mid-decision loops *are*
useful; Knuth thinks so, anyway, and I agree based on my own
experiences.

-- Agent






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Matthew Heaney
@ 1998-08-31  0:00                                           ` Gene Gajewski
  1998-08-31  0:00                                           ` Ell
  1998-08-31  0:00                                           ` Patrick Logan
  2 siblings, 0 replies; 510+ messages in thread
From: Gene Gajewski @ 1998-08-31  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...
>"Robert Martin" <rmartin@oma.com> writes:
>


<schnip>

>The problem with exit at the top is that it defers the actual
>termination.  I have to make sure no code gets executed unintentionally
>between the place at which the exit flag is set, and the bottom of the
>loop.
>
>I can almost live that.  The real problem, however, is that using an
>extra flag to terminate VASTLY complicates the predicate.  In fact, the
>flag doubles the number of states I have to think about when mentally
>evaluating the predicate!  That's the real source of the loop
>termination errors.
>
>(I shouldn't have to remind anyone, but just in case: George Miller did
>a famous study about human cognitive limits, and found that people can
>remember about 7 things, plus or minus 2.  That's why complex predicates
>make a programmer's head spin, and why he often gets loop termination
>wrong.)


I've been following this thread for some time....

I wasn't aware that anyone did any specific research on cognitive limits,
but I posit this is something intuitive. I've made a post to this sometime
before. I believe we encounter such things as a rule that states 'there
shall be but one exit point' because there are those who analyze code
mechanistically, without bothering to aquire an understanding of what the
code is doing. I sat recently sat through a 'code review', which was really
a boss's one-on-one style check, and got hammered severely about some
constructs I used in a particular function. A real knock-down/drag-out bitch
fest. The words 'Well, I understand it NOW that I've read it" were actually
uttered during that session, and not by me....










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
@ 1998-08-31  0:00                                             ` Gene Gajewski
  1998-09-01  0:00                                             ` sureshvv
                                                               ` (5 subsequent siblings)
  6 siblings, 0 replies; 510+ messages in thread
From: Gene Gajewski @ 1998-08-31  0:00 UTC (permalink / raw)



Robert Martin wrote in message <6sf87j$47n$1@hirame.wwa.com>...

>Yes.  Imagine that you had to change the function to make it thread safe;
>and that the way to do that was to sieze and release a mutex while the
>function was executing.  As written you would have to add the release in
>three separate places.  But if you had avoided the multiple returns, you
>would have had a single release.


Sounds as if the mutex belongs outside of the function, not in it.







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Ell
@ 1998-08-31  0:00                                                 ` Robert Martin
  1998-09-01  0:00                                                   ` Tim Ottinger
  1998-09-01  0:00                                                   ` dennison
       [not found]                                                 ` <6sfqul$ggg$1@hirame. <6sidsq$e6c$1@hirame.wwa.com>
  1 sibling, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Ell wrote in message <35ed3d4a.2378710@news.erols.com>...
>"Agent" <agent@siu.edu> wrote:
>
>>Robert Martin wrote in message <6sfcft$70p$1@hirame.wwa.com>...
>>>Stephen Leake wrote in message ...

>>>>One entry, one exit. Perfectly clear. There's nothing magic about
>>>>putting the exit statement at the top or the bottom!
>>>
>>>In fact there is.  If the exit condition is at the top or the bottom,
>>then
>>>the body of the loop will always be excuted an exact integral number of
>>>times.  However if the loop condition is in the middle, then the loop
>>body
>>>will be executed a fractional number of times.
>
>So what?

The the invariants of the loop body are different depending on whether the
iteration is the last or not.  Also, a programmer must be aware that the
last statement in the loop body will not be executed on the last iteration.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                               ` Ell
@ 1998-08-31  0:00                                                 ` Robert Martin
  1998-09-03  0:00                                                   ` Steven Perryman
  1998-09-01  0:00                                                 ` Charles Hixson
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Ell wrote in message <35eb36d9.729148@news.erols.com>...
>"Robert Martin" <rmartin@oma.com> wrote:
>
>>
>>
>>>RCM wrote:
>>>>> >>Yes.  That pernicious myth is called "structured programming".
>>>
>>>Elliott wrote:
>>>>> >Please cite even just a single structured programming text, or
founder
>>>>> >where what you say here was asserted.
>>
>>
>>RCM replied:
>>>> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972.
p.
>>>> 16-23 "7. On Understanding Programs"
>>
>>
>>Ell wrote in message <35ead1be.659708@news.erols.com>...
>>>Please show me a Dijkstra, Dahle, Hoare quote that says "the elements
>>>of structure[d] programming have a single entry and single exit."
>>
>>p19, in the section entitled: "Notes on Structured Programming": "These
>>flowcharts also share the property of a single entry at the top and a
single
>>exit at the bottom."
>
>???
>
>Where is the generalized design heuristic?  It certainly is not this
>statement.


The chapter that I have cited and quoted is a general description of
structured programming, its constituents, its motivations, and its benefits.
If you are looking for a one-liner, I'm afraid that Dijkstra wasn't
anticipating you.  But the design heuristic is in the chapter in any case;
just not conviently isolated into a single quotable sentence.

The essence of the chapter is that all programs ought to be constructed from
simpler elements that have singly entry points and single exit points.  The
motivation is understandabililty and provability.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Matthew Heaney
@ 1998-08-31  0:00                                               ` Robert Martin
  1998-09-01  0:00                                                 ` Gerhard Menzl
  1998-09-02  0:00                                                 ` Tres Seaver
  0 siblings, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...
>"Robert Martin" <rmartin@oma.com> writes:
>
>> >Would the implementation be better by not using multiple returns?
>>
>> Yes.  Imagine that you had to change the function to make it thread safe;
>> and that the way to do that was to sieze and release a mutex while the
>> function was executing.  As written you would have to add the release in
>> three separate places.  But if you had avoided the multiple returns, you
>> would have had a single release.
>
>Well...  The proper way to use a mutex is to wrap it in a controlled
>type, so that release is called automatically as a result of subprogram
>exit, no matter what the reason.  (Controlled types in Ada have
>operations that are roughly analagous to constructors and deconstructors
>in C++.)

In a language that supports such things, using controlled types is *a* way
(not necessarily the "proper" way).  (it happens to be the way that I choose
in many cases).  But this has nothing really to do with the issue at hand.
Yes, it may be feasible to put some resource management code into a
controlled type and avoid the issues of maintenance that I raised earlier;
but that doesn't eliminate the problem of structure.  In the end, if you can
make the structure of the software solve a problem, that is better than
using a special language feature to do it.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Ell
@ 1998-08-31  0:00                                             ` Gene Gajewski
  0 siblings, 0 replies; 510+ messages in thread
From: Gene Gajewski @ 1998-08-31  0:00 UTC (permalink / raw)



Ell wrote in message <35edd483.1368337@news.erols.com>...
>jdege@jdege.visi.com (Jeffrey C. Dege) wrote:
>
>
>The major advances in civilization are processes that all but wreck
>the societies in which they occur.
> -- A.N. Whitehead
>
>What better quote to show the truly clueless, and confused thinking of
>you and the other craftites?
>
>Elliott


<snip>

I would have been better reply with a quote countering his point...








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Patrick Doyle
@ 1998-08-31  0:00                                         ` Gene Gajewski
  1998-08-31  0:00                                         ` Richard D Riehle
  1998-09-01  0:00                                         ` Matthew Heaney
  2 siblings, 0 replies; 510+ messages in thread
From: Gene Gajewski @ 1998-08-31  0:00 UTC (permalink / raw)



Patrick Doyle wrote in message ...

<snip>

>Doubles the number of states, compared to what?  The *only* difference
>is that the exit-in-the-middle code has one of the exit conditions
>hidden inside the loop, instead of being stated explicitly at the
>top or bottom.

Each time you enter a block of code, you carry forward all the assumptions
(exit conditions) of that block, and any of those it is nested in. All of
these, assumptions or exit conditions must be held in mind in observance as
the code is created. Reducing the number of assumptions, or predicates as
some like to call them, allows a cleaner process thought process. It is not
coducive to analysis by exit points. Analysis by predicates requires that
you actually follow the code.








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                             ` Robert I. Eachus
@ 1998-08-31  0:00                                               ` Robert Martin
  1998-09-01  0:00                                                 ` Matthew Heaney
  1998-09-01  0:00                                               ` Matthew Heaney
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Robert I. Eachus wrote in message ...
>
>   Finalization did end up in Ada 95, and it is the right solution to
>this particular problem.

I am not sure of the semantics of 'finalization' in ADA9X, but if it works
like Java's, then it does not solve the problem created by multiple exits
from loops.  Again, the issue is structure.  When a single-entry/single-exit
model is followed, the code attains a structure that is conducive to
resource management.  Consider:  (C++ with a finally clause (which I wish it
had!))

int f()
{
  char* p = 0;
  File* f = 0;
  try{
    p = malloc(80);
    if (!p) return 1;

    f = fopen("myFile", "r");
    if (!f) return 2;

    fread(f, p, 80);
    ...
    return 0;
  }
  finally{
    if (f) fclose(f);
    if (p) free(p);
  }
}


The problem with this is the tests in the finally clause.  Those tests are
an artifact due to loss of structure.  They take time, space, and are not
general (i.e. there might be no reasonable test to perform!)

On the other hand:

int f()
{
  int retval = 0;
  if (char* p = malloc(80))
  {
    if (File* f = fopen("myFile", "r");
    {
      fread(f, p, 80);
      ...
      fclose(f);
    }
    else // fopen failure
    {
      retval = 2;
    }
    free(p);
  }
  else // malloc failure
  {
    retval = 1;
  }
  return retval;
}

No tests necessary, structure preserved.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-30  0:00                                   ` Robert Martin
  1998-08-30  0:00                                     ` Charles Hixson
@ 1998-08-31  0:00                                     ` Ell
  1998-08-31  0:00                                       ` Robert Martin
  1998-09-01  0:00                                       ` Charles Hixson
       [not found]                                     ` <35f51e53.48044143@ <m3af4mq7f4.fsf@mheaney.ni.net>
                                                       ` (5 subsequent siblings)
  7 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-08-31  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

>Matthew Heaney wrote in message ...
>>
>>If theory says use a construct, but observation reveals that programmers
>>who use the construct produce more errors, then the theory needs to be
>>thrown out.

>All else being equal, that would be so.  But when observation shows that the
>construct reduces the overall cost of maintaining the program, regardless of
>its initial cost, then it ought not be thrown out.

Yes if what you say is true then we should keep it, but he is saying
that programmers who use it are producing more errors.  Do you grasp
that, or will you insist on stating groundless tautologies?

>>For example, there's a pernicious myth that exiting (or returning) from
>>the middle of a loop is bad, and that the only proper way to write a
>>loop is to state the termination condition explicitly, as a predicate
>>appearing at the top of the loop.

>Yes.  That pernicious myth is called "structured programming".

Please cite even just a single structured programming text, or founder
where what you say here was asserted.

>>This theory was indeed put to the test, and guess what?  Programmers
>>using a test-and-exit from the middle of the loop produced fewer errors
>>than those programmers who tried to put the test at the top of the loop.

>>Cognitive Strategies and Looping Constructs: An Empirical Study
>>Soloway, Bonar, Ehrlich
>>CACM, Nov 83, Vol 26, No 11, p 853-860

>>The researchers found that the exit-from-the-middle construct had a
>>better "cognitive fit" than the other constructs.

>"Cognitive fit" is probably not a very good criterion for good engineering.
>GOTO has a very good cognitive fit.  So does a flat Earth.

I would assert that 'goto' spaghetti coding is only a cognitive fit to
you, and handful of others, not most of us.

Flat earth is not cognitive to people living on the coast who see the
mast of a ship appear before the bow.

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                     ` Ell
@ 1998-08-31  0:00                                       ` Robert Martin
  1998-08-31  0:00                                         ` Jeffrey C. Dege
                                                           ` (2 more replies)
  1998-09-01  0:00                                       ` Charles Hixson
  1 sibling, 3 replies; 510+ messages in thread
From: Robert Martin @ 1998-08-31  0:00 UTC (permalink / raw)



Ell wrote in message <35f51e53.48044143@news.erols.com>...
>"Robert Martin" <rmartin@oma.com> wrote:
>
>>Matthew Heaney wrote in message ...
>>>
>>>If theory says use a construct, but observation reveals that programmers
>>>who use the construct produce more errors, then the theory needs to be
>>>thrown out.
>
>>All else being equal, that would be so.  But when observation shows that
the
>>construct reduces the overall cost of maintaining the program, regardless
of
>>its initial cost, then it ought not be thrown out.
>
>Yes if what you say is true then we should keep it, but he is saying
>that programmers who use it are producing more errors.  Do you grasp
>that, or will you insist on stating groundless tautologies?

I grasped it.  I am skeptical, but I grasped it.  Now, do you grasp that
initial programmer errors may not be as serious as latter maintenance
problems?  If we accept that mid loop breaks reduce initial errors by
programmers (something that I have serious doubts about) then if they also
cause severe subsequent maintenance problems, they should still be avoided.
On the other hand, if the errors produced by single exit loops are fixed
once, and then the structures afford easier maintenance, then it may still
be best to keep them.
>
>>>For example, there's a pernicious myth that exiting (or returning) from
>>>the middle of a loop is bad, and that the only proper way to write a
>>>loop is to state the termination condition explicitly, as a predicate
>>>appearing at the top of the loop.
>
>>Yes.  That pernicious myth is called "structured programming".
>
>Please cite even just a single structured programming text, or founder
>where what you say here was asserted.

"Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
16-23 "7. On Understanding Programs".    Actualy this section says that
there are two different kinds of loops. one that is tested at the top; and
another which is tested at the bottom.  But in all cases, the elements of
structure programming have a single entry and a single exit.  A loop that
exits in the middle, violates this maxim.
>
>>>The researchers found that the exit-from-the-middle construct had a
>>>better "cognitive fit" than the other constructs.
>
>>"Cognitive fit" is probably not a very good criterion for good
engineering.
>>GOTO has a very good cognitive fit.  So does a flat Earth.
>
>I would assert that 'goto' spaghetti coding is only a cognitive fit to
>you, and handful of others, not most of us.

I contend that people are more disposed to write spaghetti, than to take the
time and think through the structure of their code.  The evidence for this
is the vast array of poorly structured programs that have accumulated over
the years.  Indeed, most novices write *horrible* code, and only gain the
ability to structure it well after making the mistakes and experiencing the
cost.  Therefore I content that spaghetti is the natural state, and that it
requires experience and dedication to produce non-spaghetti.

Now, I'll grant you that spaghetti is does not have a good cognitive fit
with the reader of the code.  However, the spaghetti had a very good
cognitive fit with the *writer* of the code.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Robert Martin
  1998-08-31  0:00                                         ` Jeffrey C. Dege
  1998-08-31  0:00                                         ` Stephen Leake
@ 1998-08-31  0:00                                         ` Matthew Heaney
  1998-08-31  0:00                                           ` Gene Gajewski
                                                             ` (2 more replies)
  2 siblings, 3 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-08-31  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> >>>For example, there's a pernicious myth that exiting (or returning) from
> >>>the middle of a loop is bad, and that the only proper way to write a
> >>>loop is to state the termination condition explicitly, as a predicate
> >>>appearing at the top of the loop.
> >
> >>Yes.  That pernicious myth is called "structured programming".
> >
> >Please cite even just a single structured programming text, or founder
> >where what you say here was asserted.
> 
> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
> 16-23 "7. On Understanding Programs".

You might also want to read Structured Programming: Theory and Practice,
by Linger, Mills, and Witt (Addison-Wesley, 1979).

(It was Harlan Mills to whom I was alluding when I referred to
"doctrinaire mathematicians."  I've read his work, and what can I say,
it just doesn't speak to me.)

I also very highly recommend The Science of Programming, by David Gries.
He comes from the Dijkstra/Hoare school, and I find his advice a lot
more useful.  But your mileage may vary.


> Actually this section says that there are two different kinds of
> loops. one that is tested at the top; and another which is tested at
> the bottom.  But in all cases, the elements of structure programming
> have a single entry and a single exit.  A loop that exits in the
> middle, violates this maxim.

I think the issue is meaning vs syntax.  When I use an exit from the
middle, it's to say that "I want to terminate the loop, NOW."  

The problem with exit at the top is that it defers the actual
termination.  I have to make sure no code gets executed unintentionally
between the place at which the exit flag is set, and the bottom of the
loop.

I can almost live that.  The real problem, however, is that using an
extra flag to terminate VASTLY complicates the predicate.  In fact, the
flag doubles the number of states I have to think about when mentally
evaluating the predicate!  That's the real source of the loop
termination errors.

(I shouldn't have to remind anyone, but just in case: George Miller did
a famous study about human cognitive limits, and found that people can
remember about 7 things, plus or minus 2.  That's why complex predicates
make a programmer's head spin, and why he often gets loop termination
wrong.)

Using an exit from the middle avoids the headaches (literally)
engendered by using an extra flag in the predicate.  When you want to
exit, you just say that you want to exit, directly.  No mental
gymnastics are required in order to determine whether you'll "really"
exit, as would be the case using the flag approach.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                     ` <35f51e53.48044143@ <m3af4mq7f4.fsf@mheaney.ni.net>
@ 1998-08-31  0:00                                       ` Andrew Hussey
  1998-08-31  0:00                                         ` Mattias Lundstr�m
                                                           ` (2 more replies)
  0 siblings, 3 replies; 510+ messages in thread
From: Andrew Hussey @ 1998-08-31  0:00 UTC (permalink / raw)


In <m3af4mq7f4.fsf@mheaney.ni.net> Matthew Heaney <matthew_heaney@acm.org> writes:

>I can almost live that.  The real problem, however, is that using an
>extra flag to terminate VASTLY complicates the predicate.  In fact, the
>flag doubles the number of states I have to think about when mentally
>evaluating the predicate!  That's the real source of the loop
>termination errors.

>(I shouldn't have to remind anyone, but just in case: George Miller did
>a famous study about human cognitive limits, and found that people can
>remember about 7 things, plus or minus 2.  That's why complex predicates
>make a programmer's head spin, and why he often gets loop termination
>wrong.)

>Using an exit from the middle avoids the headaches (literally)
>engendered by using an extra flag in the predicate.  When you want to
>exit, you just say that you want to exit, directly.  No mental
>gymnastics are required in order to determine whether you'll "really"
>exit, as would be the case using the flag approach.

That's brilliant, now your code is much easier to write!
Now let's see who has an easier time *testing* their code.
I think you'll find the control-flow errors you introduce
in the spaghetti you produce will more than make up for
any gain you have from rapid coding.  

A.
 




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Robert Martin
@ 1998-08-31  0:00                                         ` Jeffrey C. Dege
  1998-08-31  0:00                                           ` Ell
  1998-08-31  0:00                                           ` Ell
  1998-08-31  0:00                                         ` Stephen Leake
  1998-08-31  0:00                                         ` Matthew Heaney
  2 siblings, 2 replies; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-08-31  0:00 UTC (permalink / raw)


On Mon, 31 Aug 1998 02:00:51 -0500, Robert Martin <rmartin@oma.com> wrote:
>
>Ell wrote in message <35f51e53.48044143@news.erols.com>...
>>
>>I would assert that 'goto' spaghetti coding is only a cognitive fit to
>>you, and handful of others, not most of us.
>
>Now, I'll grant you that spaghetti is does not have a good cognitive fit
>with the reader of the code.  However, the spaghetti had a very good
>cognitive fit with the *writer* of the code.

Spaghetti code is disorganized and confused.  To assert that it is never
a cognitive fit is to assert that the writer's cognitive state is never
disorganized and confused.  And we all know that isn't true.

-- 
The major advances in civilization are processes that all but wreck the
societies in which they occur.
		-- A.N. Whitehead




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-30  0:00                                   ` Robert Martin
                                                       ` (2 preceding siblings ...)
       [not found]                                     ` <35f51e53.48044143@ <m3af4mq7f4.fsf@mheaney.ni.net>
@ 1998-08-31  0:00                                     ` dennison
  1998-08-31  0:00                                       ` Robert Martin
  1998-09-01  0:00                                       ` Andrew Reilly
       [not found]                                     ` <35f51e53.48044143@news.erols.c <m3af4mq7f4.fsf@mheaney.ni.net>
                                                       ` (3 subsequent siblings)
  7 siblings, 2 replies; 510+ messages in thread
From: dennison @ 1998-08-31  0:00 UTC (permalink / raw)


In article <6sbuod$fra$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Matthew Heaney wrote in message ...
>
> >This theory was indeed put to the test, and guess what?  Programmers
> >using a test-and-exit from the middle of the loop produced fewer errors
> >than those programmers who tried to put the test at the top of the loop.
...
> >The goodness of a language construct should not be determined by
> >doctrinaire computer scientists or mathematicians.  The only thing that
> >matters is whether working programmers think it's easier to understand,
> >and whether by using the construct programmers inject fewer errors into
> >the code.
>
> And whether or not the construct is maintainable over the long term.  There
> are lots of constructs that make writing the initial program easy, but make
> maintaining it hard.  The practice of using such constructs, i.e. ignoring
> long term effects, is sometimes called "hacking".

I gave up mangling my code to make while loops years ago for just the reason
Matthew spoke of. Occasionally when I make a middle-exited loop I will try to
make a while loop out of it, but I almost always delete the code and go back
to the middle-exited loop. If an algorithm really is a middle-exited loop,
you just confuse things (thereby making the code harder to understand) by
tring to force a different structure on it. For me, the extra code is a prime
source of errors as well.

Continuing with my example of a naturally middle-exited loop, there are really
only two ways of "whileing" it. The first is to "unroll" one half of an
iteration (up to the test). The problem with that is now you have duplicated
code. In practice I find the odds of having to change that code and forgetting
to change it both places is distressingly high.

The other option is to create a flag of some sort, and check it every loop
iteration. That's even worse because I have increased the (McCabe) complexity
of the code to a rather non-obvious end. If I have to add code to the loop,
even I the author have to think hard about where it goes now. Also, getting
the logic on a flag reversed is one of my most common errors. I never seem to
fail to do that one if given a chance. In fact I just fixed one of those
yesterday. Additionally, there is the run-time issue. You are adding a check
into every iteration of the loop that will go one way nearly every time.
Sometimes that can get optimized out, but I wouldn't count on it.

I will admit that a naturally top-exited loop written with a top-eixted loop
construct is easier to understand than a naturally middle-exited loop written
with a middle-exited loop construct. But that does *not* mean that the
naturally middle-exited loop would have been easier to understand if twisted
to use the top-exited construct too.

As always, YMMV.

--
T.E.D.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Andrew Hussey
@ 1998-08-31  0:00                                         ` Mattias Lundstr�m
  1998-08-31  0:00                                           ` Robert Martin
  1998-09-01  0:00                                           ` Tim Ottinger
  1998-08-31  0:00                                         ` Matthew Heaney
  1998-09-01  0:00                                         ` dewarr
  2 siblings, 2 replies; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-08-31  0:00 UTC (permalink / raw)


Andrew Hussey wrote:
> 
> In <m3af4mq7f4.fsf@mheaney.ni.net> Matthew Heaney <matthew_heaney@acm.org> writes:

> >Using an exit from the middle avoids the headaches (literally)
> >engendered by using an extra flag in the predicate.  When you want to
> >exit, you just say that you want to exit, directly.  No mental
> >gymnastics are required in order to determine whether you'll "really"
> >exit, as would be the case using the flag approach.
> 
> That's brilliant, now your code is much easier to write!
> Now let's see who has an easier time *testing* their code.
> I think you'll find the control-flow errors you introduce
> in the spaghetti you produce will more than make up for
> any gain you have from rapid coding.

I just have to butt in here.
Why would this code become harder to test?

If we take a simple example (more or less C++)

1. Flag solution
while( ... && retval == OK ) {
...
if( ... )
  retval = NOT_OK;
}
return retval;

vs

2. Multiple exits
while( ... ) {
...
if( ... )
  return NOT_OK;
}
return OK;

the control flow is basically the same (the same number
of paths functionally identical) so the number and nature 
of tests that are needed have not been affected.

Personally I prefer the second version in many cases
since I believe it is normally easier to write as well
as understand. (Specifically the exceptional exits are 
handled in this way (with return codes) in our projects).

(Ie The maintenance argument - that the second code version
becomes harder to read and understand (and thus maintain) -
since the return statement may well not be obvious if there
is a lot of other code within the loop. I do not agree 
with this, but it is certainly an argument worth considering.
IMHO This should be covered by good comments where applicable.)

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Matthew Heaney
  1998-08-31  0:00                                           ` Gene Gajewski
  1998-08-31  0:00                                           ` Ell
@ 1998-08-31  0:00                                           ` Patrick Logan
  1998-09-01  0:00                                             ` dewarr
  2 siblings, 1 reply; 510+ messages in thread
From: Patrick Logan @ 1998-08-31  0:00 UTC (permalink / raw)


In comp.object Matthew Heaney <matthew_heaney@acm.org> wrote:

: > Actually this section says that there are two different kinds of
: > loops. one that is tested at the top; and another which is tested at
: > the bottom.  But in all cases, the elements of structure programming
: > have a single entry and a single exit.  A loop that exits in the
: > middle, violates this maxim.

: I think the issue is meaning vs syntax.  When I use an exit from the
: middle, it's to say that "I want to terminate the loop, NOW."  

Almost every time I am tempted to terminate a loop in the middle, I
ultimately choose not to.

More important than that, IMHO, is that a loop's body not have a lot
of text in it. If it is a five or ten line loop, at the most, then
even if it terminates in the middle it will be easier to read. So a
loop should communicate the control aspect of the operation, the body
should rely on procedures/methods to carry out the bulk of the work.

This also has the benefit of making the bulk of the work more
reusable.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Matthew Heaney
  1998-08-31  0:00                                           ` Gene Gajewski
@ 1998-08-31  0:00                                           ` Ell
  1998-08-31  0:00                                             ` Robert Martin
  1998-08-31  0:00                                             ` Phlip
  1998-08-31  0:00                                           ` Patrick Logan
  2 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-08-31  0:00 UTC (permalink / raw)


>"Robert Martin" <rmartin@oma.com> writes:

Matthew Heaney wrote:
>> >>>For example, there's a pernicious myth that exiting (or returning) from
>> >>>the middle of a loop is bad, and that the only proper way to write a
>> >>>loop is to state the termination condition explicitly, as a predicate
>> >>>appearing at the top of the loop.

RCM wrote:
>> >>Yes.  That pernicious myth is called "structured programming".

Elliott wrote:
>> >Please cite even just a single structured programming text, or founder
>> >where what you say here was asserted.
 
> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
> 16-23 "7. On Understanding Programs".

> Actually this section says that there are two different kinds of
> loops. one that is tested at the top; and another which is tested at
> the bottom.  But in all cases, the elements of structure programming
> have a single entry and a single exit.  A loop that exits in the
> middle, violates this maxim.

Please show me a Dijkstra, Dahle, Hoare quote that says "the elements
of structure[d] programming have a single entry and single exit."

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Jeffrey C. Dege
  1998-08-31  0:00                                           ` Ell
@ 1998-08-31  0:00                                           ` Ell
  1998-08-31  0:00                                             ` Jeffrey C. Dege
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-08-31  0:00 UTC (permalink / raw)


jdege@jdege.visi.com (Jeffrey C. Dege) wrote:

>On Mon, 31 Aug 1998 02:00:51 -0500, Robert Martin <rmartin@oma.com> wrote:
>>
>>Ell wrote in message <35f51e53.48044143@news.erols.com>...
>>>
>>>I would assert that 'goto' spaghetti coding is only a cognitive fit to
>>>you, and handful of others, not most of us.

>>Now, I'll grant you that spaghetti is does not have a good cognitive fit
>>with the reader of the code.  However, the spaghetti had a very good
>>cognitive fit with the *writer* of the code.

>Spaghetti code is disorganized and confused.  To assert that it is never
>a cognitive fit is to assert that the writer's cognitive state is never
>disorganized and confused.  And we all know that isn't true.

If I have been disorganized and confused, you've never been capable of
demonstrating it--nor anyone of your pragmatist cohorts.  So of what
value is your silliness?

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Jeffrey C. Dege
@ 1998-08-31  0:00                                           ` Ell
  1998-08-31  0:00                                             ` Gene Gajewski
  1998-08-31  0:00                                           ` Ell
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-08-31  0:00 UTC (permalink / raw)


jdege@jdege.visi.com (Jeffrey C. Dege) wrote:


The major advances in civilization are processes that all but wreck
the societies in which they occur.
		-- A.N. Whitehead

What better quote to show the truly clueless, and confused thinking of
you and the other craftites?

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Robert Martin
  1998-08-31  0:00                                         ` Jeffrey C. Dege
@ 1998-08-31  0:00                                         ` Stephen Leake
  1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                         ` Matthew Heaney
  2 siblings, 1 reply; 510+ messages in thread
From: Stephen Leake @ 1998-08-31  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
> 16-23 "7. On Understanding Programs".    Actualy this section says that
> there are two different kinds of loops. one that is tested at the top; and
> another which is tested at the bottom.  But in all cases, the elements of
> structure programming have a single entry and a single exit.  A loop that
> exits in the middle, violates this maxim.

If there is only one 'exit' statement, why is this bad?

loop
    ... stuff
    exit when ;
    ... stuff
end loop;

One entry, one exit. Perfectly clear. There's nothing magic about
putting the exit statement at the top or the bottom!

Personally, I _always_ use 'exit' in a non-'for' loop (ie, I never use
'while' or 'until'), precisely because it is clearer what the exit
conditions are, and it makes it easier to move processing to before or
after the exit as necessary.

-- Stephe




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Andrew Hussey
  1998-08-31  0:00                                         ` Mattias Lundstr�m
@ 1998-08-31  0:00                                         ` Matthew Heaney
  1998-08-31  0:00                                           ` Tim McDermott
                                                             ` (3 more replies)
  1998-09-01  0:00                                         ` dewarr
  2 siblings, 4 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-08-31  0:00 UTC (permalink / raw)


ahussey@it.uq.edu.au (Andrew Hussey) writes:

> >Using an exit from the middle avoids the headaches (literally)
> >engendered by using an extra flag in the predicate.  When you want to
> >exit, you just say that you want to exit, directly.  No mental
> >gymnastics are required in order to determine whether you'll "really"
> >exit, as would be the case using the flag approach.
> 
> That's brilliant, now your code is much easier to write!
> Now let's see who has an easier time *testing* their code.
> I think you'll find the control-flow errors you introduce
> in the spaghetti you produce will more than make up for
> any gain you have from rapid coding.  

Here's is something I whipped up for another post recently.  It's an
equality operator for a bounded stack.  

The implementation of the function has multiple returns.

Does this implementation fit your definition of spaghetti code?

Would the implementation be better by not using multiple returns?


function "=" (L, R : Stack_Type) return Boolean is
begin

   if L.Top /= R.Top then
      return False;
   end if;

   for Index in Positive range 1 .. L.Top loop
      if L.Items (Index) /= R.Items (Index) then
         return False;
      end if;
   end loop;

   return True;

end "=";


My feeling is that trying to implement this operation using only a
single return would just make it more complicated.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Ell
@ 1998-08-31  0:00                                             ` Jeffrey C. Dege
  0 siblings, 0 replies; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-08-31  0:00 UTC (permalink / raw)


On Mon, 31 Aug 1998 16:50:42 GMT, Ell <ell@access.digex.net> wrote:
>jdege@jdege.visi.com (Jeffrey C. Dege) wrote:
>
>>On Mon, 31 Aug 1998 02:00:51 -0500, Robert Martin <rmartin@oma.com> wrote:
>>>
>>>Ell wrote in message <35f51e53.48044143@news.erols.com>...
>>>>
>>>>I would assert that 'goto' spaghetti coding is only a cognitive fit to
>>>>you, and handful of others, not most of us.
>
>>>Now, I'll grant you that spaghetti is does not have a good cognitive fit
>>>with the reader of the code.  However, the spaghetti had a very good
>>>cognitive fit with the *writer* of the code.
>
>>Spaghetti code is disorganized and confused.  To assert that it is never
>>a cognitive fit is to assert that the writer's cognitive state is never
>>disorganized and confused.  And we all know that isn't true.
>
>If I have been disorganized and confused, you've never been capable of
>demonstrating it--nor anyone of your pragmatist cohorts.  So of what
>value is your silliness?

I was under the impression that were discussing novice programmers.
Why do you assume that I meant you?

-- 
When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.  




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                     ` <35f51e53.48044143@news.erols.c <m3af4mq7f4.fsf@mheaney.ni.net>
@ 1998-08-31  0:00                                       ` Patrick Doyle
  1998-08-31  0:00                                         ` Gene Gajewski
                                                           ` (2 more replies)
  0 siblings, 3 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-08-31  0:00 UTC (permalink / raw)


In article <m3af4mq7f4.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>
>I can almost live that.  The real problem, however, is that using an
>extra flag to terminate VASTLY complicates the predicate.  In fact, the
>flag doubles the number of states I have to think about when mentally
>evaluating the predicate!  That's the real source of the loop
>termination errors.

Doubles the number of states, compared to what?  The *only* difference
is that the exit-in-the-middle code has one of the exit conditions
hidden inside the loop, instead of being stated explicitly at the
top or bottom.

Exit-in-the-middle is not inherently simpler, as you seem to suggest,
or else it would be a different algorithm.

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Patrick Doyle
  1998-08-31  0:00                                         ` Gene Gajewski
@ 1998-08-31  0:00                                         ` Richard D Riehle
  1998-09-01  0:00                                           ` Simon Wright
  1998-09-02  0:00                                           ` adam
  1998-09-01  0:00                                         ` Matthew Heaney
  2 siblings, 2 replies; 510+ messages in thread
From: Richard D Riehle @ 1998-08-31  0:00 UTC (permalink / raw)



>In article <m3af4mq7f4.fsf@mheaney.ni.net>,
>Matthew Heaney  <matthew_heaney@acm.org> wrote:
>>
>>I can almost live that.  The real problem, however, is that using an
>>extra flag to terminate VASTLY complicates the predicate.  In fact, the
>>flag doubles the number of states I have to think about when mentally
>>evaluating the predicate!  That's the real source of the loop
>>termination errors.

I recall a bunch of IV&V people coming to review a project a few years ago.
They were the typical doctrinaire, fresh-out-of-school youngsters who
one expects to find assigned by the big consulting companies, trained to
look for "checkbox" violations rather than to think about the software
process.  One enthusiastic fellow began to insist that programmers remove
all the exits from their loops -- convert them into while or for loops.

It seems to me that the people who make up rules for programmers are people
who either no long write real programs or never have written production
code.  The debate about exits within loops seems silly, particularly when
talking about Ada.  Nobody writes exits in Ada code unless the loop has a
label, and the compiler tests to see if the exit contains the label of the
loop as well as checking that the named loop has an "end label."  This makes
maintenance very easy.    

An exit is not another form of sphagetti code anymore than a return from
within a procedure or function.  In many algorithms there are perfectly good
reasons for interrupting a flow of control early.  Putting on a dogamtic
face to deny that will simply result in more incomprehensible code.  

The talk about spaghetti code is colorful but unproductive.  By this
analogy, perhaps we should call the modular code, "ravioli code."
Now we have this little plate of raviolis, each representing a software
module.  Oh, and then we could thread them together with one long strand of
spaghetti. Yes, I do know what that implies.    
 
Richard Riehle
richard@adaworks.com
http://www.adaworks.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Matthew Heaney
  1998-08-31  0:00                                           ` Tim McDermott
  1998-08-31  0:00                                           ` Robert Martin
@ 1998-09-01  0:00                                           ` Loryn Jenkins
  1998-09-01  0:00                                             ` Matthew Heaney
  1998-09-01  0:00                                           ` Don Harrison
  3 siblings, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-01  0:00 UTC (permalink / raw)


How is this more complicated? 

equal (l,r: LIST): BOOLEAN is
	require
		l.count = r.count
	do
		Result := l.first /= r.first
		if Result then
			from
				l.start; r.start
			until
				not Result or l.off
			loop
				Result := l.item /= r.item
				l.forth; r.forth
			end
		end
	end

Sorry for the language change ... it's the one I'm familiar with.

By the way, I'm not sure whether it's a problem in your Ada code, but my
Eiffel code could fail if r has greater or fewer items than l. Hence the
precondition.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Agent
@ 1998-09-01  0:00                                             ` Phil Goodwin
  1998-09-01  0:00                                               ` Robert Martin
  1998-09-01  0:00                                             ` Matthew Heaney
  1998-10-01  0:00                                             ` Charles H. Sampson
  3 siblings, 1 reply; 510+ messages in thread
From: Phil Goodwin @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sfcft$70p$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Stephen Leake wrote in message ...
> >"Robert Martin" <rmartin@oma.com> writes:
> >
> >> "Structured Programming", Dijkstra, Dahl, Hoare, Academic Press, 1972. p.
> >> 16-23 "7. On Understanding Programs".    Actualy this section says that
> >> there are two different kinds of loops. one that is tested at the top;
> and
> >> another which is tested at the bottom.  But in all cases, the elements of
> >> structure programming have a single entry and a single exit.  A loop that
> >> exits in the middle, violates this maxim.
> >
> >If there is only one 'exit' statement, why is this bad?
> >
> >loop
> >    ... stuff
> >    exit when ;
> >    ... stuff
> >end loop;
> >
> >One entry, one exit. Perfectly clear. There's nothing magic about
> >putting the exit statement at the top or the bottom!
>
> In fact there is.  If the exit condition is at the top or the bottom, then
> the body of the loop will always be excuted an exact integral number of
> times.  However if the loop condition is in the middle, then the loop body
> will be executed a fractional number of times.

So what?

Phil

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Chris Brand
@ 1998-09-01  0:00                                               ` Robert Martin
  1998-09-01  0:00                                                 ` Biju Thomas
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Chris Brand wrote in message <35EC3440.9FA81BF1@west.raytheon.com>...
>Robert Martin wrote:
>>
>> bool operator==(Stack& l, Stack& r)
>> {
>>   bool equal = true;
>>   for (int index = 1; index < l.top() && equal == true; index++)
>>   {
>>     if (l[index] != r[index])
>>       equal = false;
>>   }
>>   return equal;
>> }
>>
>> If this is more complex (something that is arguable) it is not *much*
more
>> complex.  On the other hand, it is easier to maintain.
>
>It is open to (maintenance) errors such as
>   for (int index = 1; index < l.top() && equal = true; index++)
>which the multiple-return version isn't, so the "easier to maintain"
>argument is far from clear-cut.


I think *all* structures are vulnerable to typos.  The code above is no more
vulnerable than any other code is.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                           ` Gerry Quinn
@ 1998-09-01  0:00                                             ` Robert Martin
  1998-09-02  0:00                                               ` Gerry Quinn
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Gerry Quinn wrote in message <6shbca$66c$1@news.indigo.ie>...
>In article <6sh3qn$9p2$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com>
wrote:
>>
>>Gerry Quinn wrote in message <6sgror$je8$3@news.indigo.ie>...
>>
>>>Multiple exits to a single destination are not spaghetti.
>>
>>Spaghetti is not a well defined term.
>>
>How strange, then, that such sloppy language is endemic among those
>who believe they hold the line against sloppy coding...

It's not strange at all.  The common definition of Spaghetti is: "I don't
like it.".

Please note that in this thread I have not characterized anyone elses
examples as spaghetti.  I have tried to stick to more substantive
complaints.  I think this is important.  Spaghetti is a subjective term that
accomplishes little as a description.
>
>When cleanup is unlikely to be needed, multiple exits are unlikely to
>pose a problem.

Granted.

But do the benefits of multiple exits outweigh the risks that cleanup might
one day be needed?  That is an engineering decision; and does not have a
general answer.  There are ,indeed, times when I will use multiple exits.
But I have to be pretty sure that the code is short lived, and will not be
subject to maintenance during its short lifetime.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan









^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` James Weirich
@ 1998-09-01  0:00                                                     ` Mike Spille
  1998-09-02  0:00                                                       ` Nick Leaton
  0 siblings, 1 reply; 510+ messages in thread
From: Mike Spille @ 1998-09-01  0:00 UTC (permalink / raw)


James Weirich wrote:
> 
>     Matthew> Let's once again compare the decision tables.  If we
>     Matthew> re-write the code, to put it into Matt-like (because Matt
>     Matthew> likes it) syntax:
> 
>     Matthew> equal (l,r: LIST): BOOLEAN is
>     Matthew>       require
>     Matthew>               l /= Void and r /= Void
>     Matthew>       do
>     Matthew>               if l.count /= r.count then
>     Matthew>                  return False
>     Matthew>               end
>     Matthew>               from
>     Matthew>                  l.start; r.start
>     Matthew>               until
>     Matthew>                  l.off
>     Matthew>               loop
>     Matthew>                  if l.item /= r.item then
>     Matthew>                     return False
>     Matthew>                  end
>     Matthew>                  l.forth; r.forth
>     Matthew>               end
>     Matthew>               return True
>     Matthew>       end
> 
>     Matthew> This version has only two rules in the decision table for
>     Matthew> the loop predicate:
> 
>     Matthew>        1  2
>     Matthew> l.off  T  F
> 
> Yes, but you are ignoring the fact that there are now two loop exits.
> If you ask the question "When will the loop terminate?", you must
> consider all the exits, including the early return.
> 

Would your average programmer ask the question "Where will the loop
terminate?", or "What does the function do?".  I think the latter
question is alot more important.  I personally subscribe to
the technique of "bailing-out" as soon as possible in a function.

This has two effects: nesting later on is greatly reduced (I find
if-else nesting affects readability), and the early-bailouts give
me guarantees later in the code that I don't need to check for.

> So instead of a single, 2 entry table, you have two 2-entry tables.
> Combining them into a single table will produce the same 4 entry table
> as the one you produced for Loryn Jenkins's code.
> 
> Seems to me the complexity is about equivalent.
> 
> --
> -- Jim Weirich     jweirich@one.net    http://w3.one.net/~jweirich
> ---------------------------------------------------------------------
> -- "A distributed system is one in which I cannot get something done
> -- because a machine I've never heard of is down."   --Leslie Lamport

	-Mike




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                         ` Robert Martin
  1998-09-01  0:00                                           ` Gerry Quinn
@ 1998-09-01  0:00                                           ` Mike Spille
  1998-09-01  0:00                                             ` Robert Martin
  1998-09-02  0:00                                           ` mfinney
  1998-09-02  0:00                                           ` Gene Gajewski
  3 siblings, 1 reply; 510+ messages in thread
From: Mike Spille @ 1998-09-01  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Gerry Quinn wrote in message <6sgror$je8$3@news.indigo.ie>...
> 
> >Multiple exits to a single destination are not spaghetti.
> 
> Spaghetti is not a well defined term.
> 
> However, multiple exits to a single destination represent a problem.  The
> two exits come from two different states within the algorithm.  If the
> single destination must do some work that depends upon that state (or if in
> the future, that single destination must be modified to do work that depends
> upon that state), then the code in the single destination is going to get
> pretty ugly.
> 

OK, what if the state does not change?  For example, typical "search"
functions check for validity of arguments, valid internal state, etc
before continuing.  These checks do not affect state, and if a check
fails, there's no point in continuing.  Why complicate matters with
extra variables and nesting?

I think the problem with this argument is people are trying to fit
one solution to many problems.  Not all functions aqcuire resources.

And on the flip side, not all functions are stateless.

Should you write your functions in such a way that you're ignorant
of how it affects state?!?!  Should you add over-head to functions
that do not affect state, and by design, never will?  NO!

And if my function _does_ affect state, then it is unlikely I'll
have multiple exits.  If I do, they'll be in checks at the top
asserting correctness, and returning null (or error, or whatever)
at the top.

So what do you do when the function "grows"?  Well, first off,
most functions (in my programs at least) don't grow.  The majority
are dinky 8 or 9 liners that don't change over time.  The minority
that _do_ change over time, tend to change alot.  They're complex.
Knowing "This code only has one exit point" does not add to my
understanding of the code at all.  And if I can't understand it,
I _can't_ modify it.  If it grows significantly, I split it
into multiple functions.

> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

	-Mike




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                 ` Matthew Heaney
@ 1998-09-01  0:00                                                   ` Stephen Leake
  1998-09-01  0:00                                                     ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Stephen Leake @ 1998-09-01  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> writes:

> "Robert Martin" <rmartin@oma.com> writes:
> 
> > >   Finalization did end up in Ada 95, and it is the right solution to
> > >this particular problem.
> > 
> > I am not sure of the semantics of 'finalization' in ADA9X, but if it works
> > like Java's, then it does not solve the problem created by multiple exits
> > from loops.
> 
> "Finalization" in Ada95 is equivalent to having a constructor and
> deconstructor for an object.
> 
> If a file (or mutex) is controlled - which just means it has a
> deconstructor - then the file (mutex) will be automatically closed
> (released) when the subprogram terminates. 

In addition, Ada Finalization happens immediately when the object goes
out of scope; Java finalization happens when the garbage collector
gets around to freeing the object's memory. This means Java
finalization is NOT a solution to the resource issue (seize/release,
open/close, etc), but Ada Finalization is.

-- Stephe




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Gene Gajewski
  1998-09-01  0:00                                             ` sureshvv
@ 1998-09-01  0:00                                             ` Robert I. Eachus
  1998-09-01  0:00                                             ` Matthew Heaney
                                                               ` (3 subsequent siblings)
  6 siblings, 0 replies; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sf87j$47n$1@hirame.wwa.com> "Robert Martin" <rmartin@oma.com> writes:

 > If this is more complex (something that is arguable) it is not *much* more
 > complex.  On the other hand, it is easier to maintain.  The thread-safety
 > issue I talked about above would be easier to add to this function than to
 > the one with multiple returns.

   And as far as some of us are concerned, there is no difference,
because the way to implement the guarded function is to wrap the guard
around the test:

   function "=" (L, R : Guarded_Stack_Type) return Boolean is
     Temp: Boolean;
   begin
     Seize(L.Guard); Seize(R.Guard);
     Temp := Stack_Type(L) = Stack_Type(R);
     Release(R.Guard); Release(L.Guard);
     return Temp;
   end "=";

   With the obvious type declaration for the guarded stack:

   type Guarded_Stack_Type is new Stack with Guard: Semaphore;

   This implements the guarded equality in terms of the (known good)
test for the parent type.  Of course, this particular implementation
is subject to deadlock, so I would either use a single semaphore for
all stacks, or a more complex locking strategy, probably locking the
stack with the lower address first:

   function "=" (L, R : Guarded_Stack_Type) return Boolean is
     Temp: Boolean;
   begin
     if L'Address = R'Address then return True; end if;
     
     if L'Address < R'Address
     then Seize(L.Guard); Seize(R.Guard);
     else Seize(R.Guard); Seize(L.Guard);
     end if;

     Temp := Stack_Type(L) = Stack_Type(R);
     Release(R.Guard); Release(L.Guard); -- release order doesn't matter.
     return Temp;

   end "=";
   
   Now we have a tasking/thread safe comparison, but we didn't have to
mix up the three cases here with the three cases in the original "=".
So I have six cases to test, not nine.  Actually, I get more benefit,
because I only have three NEW cases to test.

   Note to Ada programmers:  At first it seems right to make the
entire stack type a protected object.  But how would you define the
"=" and any other two stack operations in that case?  Once you realize
that there needs to be a pair of seize and release operations, you
might as well associate them with a new component of the object
anyway.

   Also--for Ada and non-Ada programmers--the norm would be to do all
this in the body of the package which defined Guarded_Stack_Type as a
private extension of Stack_Type.  Now the interface profile of the two
types can be the same, since all the semaphore manipulations can be
hidden from view.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                     ` Ell
  1998-08-31  0:00                                       ` Robert Martin
@ 1998-09-01  0:00                                       ` Charles Hixson
  1 sibling, 0 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-01  0:00 UTC (permalink / raw)


Actually, flat earth is a good example.  Flat-earth makes a good local
map (for a properly choosen size of local).  It just doesn't extend well
to a global solution.  The same is true of 'goto'.

Ell wrote:
> 
> "Robert Martin" <rmartin@oma.com> wrote:
> 
... 
> >"Cognitive fit" is probably not a very good criterion for good engineering.
> >GOTO has a very good cognitive fit.  So does a flat Earth.
> 
> I would assert that 'goto' spaghetti coding is only a cognitive fit to
> you, and handful of others, not most of us.
> 
> Flat earth is not cognitive to people living on the coast who see the
> mast of a ship appear before the bow.
> 
> Elliott
> --
>    :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
>                  Hallmarks of the best SW Engineering
>          "The domain object model is the foundation of OOD."
>  Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
>    Copyright 1998 Elliott. exclusive of others' writing. may be copied
>      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
                                                               ` (4 preceding siblings ...)
  1998-09-01  0:00                                             ` Phil Goodwin
@ 1998-09-01  0:00                                             ` Richard Melvin
  1998-09-01  0:00                                               ` Robert Martin
  1998-09-02  0:00                                               ` Jim Cochrane
  1998-09-01  0:00                                             ` Chris Brand
  6 siblings, 2 replies; 510+ messages in thread
From: Richard Melvin @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sf87j$47n$1@hirame.wwa.com>, Robert Martin
<rmartin@oma.com> writes
>bool operator==(Stack& l, Stack& r)
>{
>  bool equal = true;
>  for (int index = 1; index < l.top() && equal == true; index++)
>  {
>    if (l[index] != r[index])
>      equal = false;
>  }
>  return equal;
>}

Now, following convoluted conditionals[1] like the above always makes my
head spin, but it looks to me like the above code would always return
true when comparing against an empty stack.

Given that this is a trivial piece of code, written by an expert, read
by half of usenet, and nobody seems to have spotted the problem, I think
this has to count as a significant data point on the side of the
multiple returns camp.

Richard

[1] It's not particularly complicated, but it does combine into one
expression two tests with completely different purposes, which I think
is always a source of confusion. Of course, the 1-based indexing doesn't
help, with 0-based being more usual in C++ - this is probably a second
bug, but I'd have to see the specification of top and operator[] to find
out.
 
-- 
Richard Melvin




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Robert Martin
@ 1998-09-01  0:00                                                 ` Robert I. Eachus
  1998-09-01  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                 ` Mattias Lundstr�m
  1998-09-02  0:00                                                 ` Mattias Lundstr�m
  2 siblings, 1 reply; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sh2rp$8v3$1@hirame.wwa.com> "Robert Martin" <rmartin@oma.com> writes:

 > Now certainly it is easier to write the functions with multiple exits.  And
 > if the functions never change, then you have won; and using a structured
 > programming approach would be a net loss.  However, functions generally
 > don't remain the same.  Most of the time they <<grow>> (remember Kahn
 > talking about how his "pets" enter through your ear and live inside your
 > brain?  "Later", he said, " as they <<grow>>...") Functions that have not
 > been built using structured programming can degrade pretty badly when they
 > <<grow>>.

   (First some flame retardant, hopefully unnecessary.  What follows
talks about how the difference in paradigms between Ada and other
languages affect which style--multiple exit--Ada programmers prefer.
That doesn't mean that Ada is better, even though it is. ;-)

    Ada programmers are not used to functions growing.  An abstraction
is written once, then used forever.  If it needs to be extended, you
derive from it (called subtyping or subclassing in other OO languages),
or extend the type locally with locally declared subprograms.
Modifying existing code is a very rare process, and it usually
involves changes, not growth.  Package specs often grow during
development, but that is usually due to recognizing the need or
potential need for some additional operation to be exported.

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                               ` Ell
  1998-08-31  0:00                                                 ` Robert Martin
@ 1998-09-01  0:00                                                 ` Charles Hixson
  1 sibling, 0 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-01  0:00 UTC (permalink / raw)


Possibly instead of discussing what the original documents said, years
before any (or at least any common) languages supported structured
programming, we should talk about either our own experiences, or about
studies of people using structured languages (since most of them contain
facilities enabling non-structured programming also).
I was impressed by structured programming when I first read a book
describing how to do it in PL/1, and immediately started trying to
restructure the FORTRAN programs that I was writing.

This was NOT encouraged by the language design, but the results were
encouraging enough to convince me to switch to more structured languages
as they became available to me.  They did NOT convince me that
EVERYTHING should be structured.  I feel free to allow myself one
unstructrued construct per routine, provided that it is well documented,
and has only local effect.  I rarely need this permission, but sometimes
I do.  If I need two unstructured constructs, then I try REALLY HARD to
break the routine in half.

This rule keeps the routines intelligible, and lets me do whatever I
need to do.

Theory is great, and I try to be guided by those theories that I
consider best.  But I am, at heart, a practitioner, and my test for how
good I think a theory is, is "How well can I use this?"




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` Stephen Leake
@ 1998-09-01  0:00                                                     ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Stephen Leake wrote in message ...
Java finalization happens when the garbage collector
>gets around to freeing the object's memory. This means Java
>finalization is NOT a solution to the resource issue (seize/release,
>open/close, etc.

True.  But the 'finally' clause in Java *is*.  That was what the example was
showing.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Richard Melvin
@ 1998-09-01  0:00                                               ` Robert Martin
  1998-09-02  0:00                                               ` Jim Cochrane
  1 sibling, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Richard Melvin wrote in message ...
>In article <6sf87j$47n$1@hirame.wwa.com>, Robert Martin
><rmartin@oma.com> writes
>>bool operator==(Stack& l, Stack& r)
>>{
>>  bool equal = true;
>>  for (int index = 1; index < l.top() && equal == true; index++)
>>  {
>>    if (l[index] != r[index])
>>      equal = false;
>>  }
>>  return equal;
>>}
>
>Now, following convoluted conditionals[1] like the above always makes my
>head spin, but it looks to me like the above code would always return
>true when comparing against an empty stack.
>
>Given that this is a trivial piece of code, written by an expert, read
>by half of usenet, and nobody seems to have spotted the problem, I think
>this has to count as a significant data point on the side of the
>multiple returns camp.

Sorry, I copied the algorithm that someone else wrote, and dropped the two
lines that compared the size of the stack.  It was *definitely* the use of
structured programming that forced me to omit those two lines!

The evidence is right here folks, structured programming damages your brain.
You will omit lines of code if you use it.  You are better off using lots of
gotos, mid function returns, breaks, and continues so that you don't ever
accidentally omit a couple of lines of code again!

I've certainly learned my lesson.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                 ` Robert I. Eachus
@ 1998-09-01  0:00                                                   ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Robert I. Eachus wrote in message ...
>In article <6sh2rp$8v3$1@hirame.wwa.com> "Robert Martin" <rmartin@oma.com>
writes:
>
> > Now certainly it is easier to write the functions with multiple exits.
And
> > if the functions never change, then you have won; and using a structured
> > programming approach would be a net loss.  However, functions generally
> > don't remain the same.  Most of the time they <<grow>> (remember Kahn
> > talking about how his "pets" enter through your ear and live inside your
> > brain?  "Later", he said, " as they <<grow>>...") Functions that have
not
> > been built using structured programming can degrade pretty badly when
they
> > <<grow>>.
>
>    Ada programmers are not used to functions growing.  An abstraction
>is written once, then used forever.  If it needs to be extended, you
>derive from it (called subtyping or subclassing in other OO languages),
>or extend the type locally with locally declared subprograms.
>Modifying existing code is a very rare process, and it usually
>involves changes, not growth.  Package specs often grow during
>development, but that is usually due to recognizing the need or
>potential need for some additional operation to be exported.


This is, in fact, a characteristic of any good OO design that conforms to
the Open/Closed principle.  New featuers are added by adding new code; not
by changing old working code.

Nevertheless, functions sometimes do change; and when they do its nice to
have the structured so as to facilitate those changes.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Robert Martin
@ 1998-09-01  0:00                                                 ` Biju Thomas
  1998-09-01  0:00                                                   ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Biju Thomas @ 1998-09-01  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Chris Brand wrote in message <35EC3440.9FA81BF1@west.raytheon.com>...
> >Robert Martin wrote:
> >>
> >> bool operator==(Stack& l, Stack& r)
> >> {
> >>   bool equal = true;
> >>   for (int index = 1; index < l.top() && equal == true; index++)
> >>   {
> >>     if (l[index] != r[index])
> >>       equal = false;
> >>   }
> >>   return equal;
> >> }
> >>
> >> If this is more complex (something that is arguable) it is not *much*
> more
> >> complex.  On the other hand, it is easier to maintain.
> >
> >It is open to (maintenance) errors such as
> >   for (int index = 1; index < l.top() && equal = true; index++)
> >which the multiple-return version isn't, so the "easier to maintain"
> >argument is far from clear-cut.
> 
> I think *all* structures are vulnerable to typos.  The code above is no more
> vulnerable than any other code is.

If it was
1)
   for (int index = 1; index < l.top() && equal; index++)

or
2)
   for (int index = 1; index < l.top() && true == equal; index++)

it might not have been vulnerable to this type of typos (which is
frequent in C++, I think).

Of course, some people say the second style is less readable. But the
the first one seems to be best.

Biju Thomas




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Phil Goodwin
@ 1998-09-01  0:00                                               ` Biju Thomas
  1998-09-02  0:00                                                 ` Phil Goodwin
  1998-09-03  0:00                                               ` Ole-Hjalmar Kristensen
  1 sibling, 1 reply; 510+ messages in thread
From: Biju Thomas @ 1998-09-01  0:00 UTC (permalink / raw)


Phil Goodwin wrote:
> 
> I write plenty of little routines that have loops in them that exit in the
> middle. It doesn't make sense to me to alter the algorithm and write extra
> code just so that the routine might be easier to maintain someday (if ever).
> On the other hand, when I DO maintain such a routine I definitely WILL make
> sure that there is only one exit point if that's what is needed to eliminate
> duplicate code.
> 
> I adopted this position in part because of some of what I've read about
> Extreme Programming. I haven't adopted it wholesale, but I do like their
> no-nonsense philosophy. They use two balancing maxims that I've applied to
> this question: Do The Simpest Thing That Could Possibly Work; and Once And
> Only Once. So when I write a function I do the simplest thing that could
> possibly work, which sometimes means sticking a return right smack in the
> middle of a loop. I am especially likely to do this when the loop body is
> less than five lines long anyway. Then, when I have to refactor in order to
> add the aquisistion and release of some resource, I rearrange the routine so
> that I add the code once and only once. The justification for this is that I
> don't want to adopt a coding task because it _might_ be needed during
> maintenance, I would rather do it during maintenance when I KNOW that it
> needs to be done.

The problem with such refactoring during maintenance is that it may
introduce new problems, and you need to do extensive testing to make
sure that you haven't broken anything. Often, this type of extensive
testing may not be feasible at all during maintenance, because of budget
and time constraints. This type of attitude may explain why new releases
of software (which are supposed to do bug fixing too) introduce more
bugs than the original version. 

Biju Thomas




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                           ` Mike Spille
@ 1998-09-01  0:00                                             ` Robert Martin
       [not found]                                               ` <gio+van+no+ni+8-0309982212300001@dialup62.tlh.talstar.com>
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Mike Spille wrote in message <35EC1B94.CAC23CB3@tisny.com>...
>Robert Martin wrote:
>>
>> Gerry Quinn wrote in message <6sgror$je8$3@news.indigo.ie>...
>>
>> >Multiple exits to a single destination are not spaghetti.
>>
>> Spaghetti is not a well defined term.
>>
>> However, multiple exits to a single destination represent a problem.  The
>> two exits come from two different states within the algorithm.  If the
>> single destination must do some work that depends upon that state (or if
in
>> the future, that single destination must be modified to do work that
depends
>> upon that state), then the code in the single destination is going to get
>> pretty ugly.
>>
>
>OK, what if the state does not change?  For example, typical "search"
>functions check for validity of arguments, valid internal state, etc
>before continuing.  These checks do not affect state, and if a check
>fails, there's no point in continuing.  Why complicate matters with
>extra variables and nesting?

Granted.  If you are realy sure, then use the early return.  I do it
sometimes too.  But I remain aware of the cost and the risk.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <35EC1590.D50DB8F6@tisny.com>
@ 1998-09-01  0:00             ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-01  0:00 UTC (permalink / raw)


In article <35EC1590.D50DB8F6@tisny.com>,
Mike Spille  <mspille@tisny.com> wrote:
>
>Would your average programmer ask the question "Where will the loop
>terminate?", or "What does the function do?".  I think the latter
>question is alot more important.  I personally subscribe to
>the technique of "bailing-out" as soon as possible in a function.

Importance is a pretty nebulous concept, but I think there are
situations where both questions are asked.  "I want this thing
to print a message when it's finished doing xxx; where will
the loop terminate?..."

As for bailing out early in a function, that is the hallmark
of defensive programming, which is considered by some (Bertrand
Meyer, in particular) to be a harmful
practice in large-scale software development.  Defensive
programming is necesssary at the boundaries of the system,
but a system should not be designed to be internally defensive 
with respect to itself.

>This has two effects: nesting later on is greatly reduced (I find
>if-else nesting affects readability), and the early-bailouts give
>me guarantees later in the code that I don't need to check for.

Well, Design By Contract gives the same guarantees without
the extra code for checking the conditions.  This means that not
only do you have no nesting problem, but in a release build,
with assertions disabled, you also have no runtime overhead.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Loryn Jenkins
  1998-09-01  0:00                                                     ` John Volan
@ 1998-09-01  0:00                                                     ` John Volan
  1998-09-01  0:00                                                       ` Robert Martin
                                                                         ` (2 more replies)
  1998-09-01  0:00                                                     ` Darren New
  1998-09-02  0:00                                                     ` Matthew Heaney
  3 siblings, 3 replies; 510+ messages in thread
From: John Volan @ 1998-09-01  0:00 UTC (permalink / raw)


Loryn Jenkins wrote:
> 
> equal (l,r: LIST): BOOLEAN is
>       require
>           l /= Void and r /= Void
>       do
>           from
>               Result := (l.count = r.count)
>               l.start; r.start
>           until
>               not Result or l.off
>           loop
>               Result := (l.item = r.item)
>               l.forth; r.forth
>           end
>       end

This has a certain elegance, but note that:

(1) If Result is False after the first assignment, then the 'start'
calls are executed unnecessarily.

(2) If Result is False after the second assignment (in the body of the
loop), then the 'forth' calls and the 'off' test are executed
unnessarily.

This is inefficient (as you point out) but at least it is harmless ...
in this case. (More on that in a moment.)

However, suppose Eiffel allowed mid-body loop exits, say with the
following sort of syntax:

equal (l, r: LIST): BOOLEAN is
    require
        l /= Void and r /= Void
    do
	Result := (l.count = r.count)
	if Result then
            from
                l.start; r.start
            until
                l.off
            loop
                Result := (l.item = r.item)
            until 
                not Result
            then
                l.forth; r.forth
            end
        end
    end

The 'if' statement avoids the extraneous 'start' calls.  The mid-body
'until' clause terminates the loop immediately if its condition holds,
avoiding the extraneous 'forth' calls, as well as the 'off' test at the
top of the loop.

Can anybody demonstrate whether or not this sort of language extension
would have an adverse affect on Eiffel's principle of DBC, for the case
of loops?

There are situations where extraneous calls in the final loop iteration
would not be so harmless.  For instance, suppose you wished to implement
an 'out' function for a LIST class that generated strings of the form:

	"{}"    for an empty list
	"{A}"   for a list with one element "A"
	"{A, B}" for a list with two elements "A" and "B"
        etc...

In other words, separate the elements by commas, but only if there is
more than one element.  Here's a first attempt at a solution:

out: STRING is
    do
        Result := "{";
        from
            start
        until
            after 
        loop
                Result.append (item.out)
                Result.append (", ");
                forth
            end loop
        end
        Result.append ("}");
    end

Unfortunately, this is incorrect, because it places an extraneous comma
after the last element.  To correct this, we could add a test within the
body:

out: STRING is
    do
        Result := "{";
        from
            start
        until
            after 
        loop
            Result.append (item.out)
            forth
            if not after then
               Result.append (", ");
            end
        end loop
        Result.append ("}");
    end

Unfortunately, this causes the same 'after' test to be called twice on
each iteration!  To avoid this, we must unroll the loop:

out: STRING is
    do
        Result := "{";
        if not empty then
            from
                start
                Result.append (item.out)
                forth
            until
                after 
            loop
                Result.append (", ");
                Result.append (item.out)
                forth
            end loop
        end
        Result.append ("}");
    end

Unfortunately, we've been forced to duplicate code.  But suppose you
could place an 'until' clause in mid-body:

out: STRING is
    do
        Result := "{"
        if not empty then
            from
                start
            loop
                Result.append (item.out)
                forth
            until
                after
            then
                Result.append (", ")
            end
        end
        Result.append ("}")
    end                

This would seem the most elegant solution.  But again, does this pose
any difficulty for DBC in Eiffel?  I can't see any problem, but I'm only
a newbie with Eiffel.  (Just now in the process of devouring OOSC2 from
one cover to the other...)

-- 
indexing
   description: "Signatures for John Volan"
   self_plug: "Ex Ada guru", "Java 1.1 Certified", "Eiffelist wannabe"
   two_cents: "Java would be even cooler with Eiffel's generics, %
              %assertions/DBC, true MI, feature adaptation, %
              %selective export, uniform access, etc., etc..."
class JOHN_VOLAN_SIGNATURE inherit SIGNATURE invariant
   disclaimer: not (opinion implies employer.opinion)
end -- class JOHN_VOLAN_SIGNATURE




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Loryn Jenkins
@ 1998-09-01  0:00                                                     ` John Volan
  1998-09-01  0:00                                                     ` John Volan
                                                                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 510+ messages in thread
From: John Volan @ 1998-09-01  0:00 UTC (permalink / raw)


[Woops! Sorry for the re-post folks, want to fix some egregious typos:]

Loryn Jenkins wrote:
> 
> equal (l,r: LIST): BOOLEAN is
>       require
>           l /= Void and r /= Void
>       do
>           from
>               Result := (l.count = r.count)
>               l.start; r.start
>           until
>               not Result or l.off
>           loop
>               Result := (l.item = r.item)
>               l.forth; r.forth
>           end
>       end

This has a certain elegance, but note that:

(1) If Result is False after the first assignment, then the 'start'
calls are executed unnecessarily.

(2) If Result is False after the second assignment (in the body of the
loop), then the 'forth' calls and the 'off' test are executed
unnessarily.

This is inefficient (as you point out) but at least it is harmless ...
in this case. (More on that in a moment.)

However, suppose Eiffel allowed mid-body loop exits, say with the
following sort of syntax:

equal (l, r: LIST): BOOLEAN is
    require
        l /= Void and r /= Void
    do
        Result := (l.count = r.count)
        if Result then
            from
                l.start; r.start
            until
                l.off
            loop
                Result := (l.item = r.item)
            until 
                not Result
            then
                l.forth; r.forth
            end
        end
    end

The 'if' statement avoids the extraneous 'start' calls.  The mid-body
'until' clause terminates the loop immediately if its condition holds,
avoiding the extraneous 'forth' calls, as well as the 'off' test at the
top of the loop.

Can anybody demonstrate whether or not this sort of language extension
would have an adverse affect on Eiffel's principle of DBC, for the case
of loops?

There are situations where extraneous calls in the final loop iteration
would not be so harmless.  For instance, suppose you wished to implement
an 'out' function for a LIST class that generated strings of the form:

        "{}"    for an empty list
        "{A}"   for a list with one element "A"
        "{A, B}" for a list with two elements "A" and "B"
        etc...

In other words, separate the elements by commas, but only if there is
more than one element.  Here's a first attempt at a solution:

out: STRING is
    do
        Result := "{";
        from
            start
        until
            after 
        loop
            Result.append (item.out)
            Result.append (", ");
            forth
        end
        Result.append ("}");
    end

Unfortunately, this is incorrect, because it places an extraneous comma
after the last element.  To correct this, we could add a test within the
body:

out: STRING is
    do
        Result := "{";
        from
            start
        until
            after 
        loop
            Result.append (item.out)
            forth
            if not after then
               Result.append (", ");
            end
        end
        Result.append ("}");
    end

Unfortunately, this causes the same 'after' test to be called twice on
each iteration!  To avoid this, we must unroll the loop:

out: STRING is
    do
        Result := "{";
        if not empty then
            from
                start
                Result.append (item.out)
                forth
            until
                after 
            loop
                Result.append (", ");
                Result.append (item.out)
                forth
            end
        end
        Result.append ("}");
    end

Unfortunately, we've been forced to duplicate code.  But suppose you
could place an 'until' clause in mid-body:

out: STRING is
    do
        Result := "{"
        if not empty then
            from
                start
            loop
                Result.append (item.out)
                forth
            until
                after
            then
                Result.append (", ")
            end
        end
        Result.append ("}")
    end                

This would seem the most elegant solution.  But again, does this pose
any difficulty for DBC in Eiffel?  I can't see any problem, but I'm only
a newbie with Eiffel.  (Just now in the process of devouring OOSC2 from
one cover to the other...)

-- 
indexing
   description: "Signatures for John Volan"
   self_plug: "Ex Ada guru", "Java 1.1 Certified", "Eiffelist wannabe"
   two_cents: "Java would be even cooler with Eiffel's generics, %
              %assertions/DBC, true MI, feature adaptation, %
              %selective export, uniform access, etc., etc..."
class JOHN_VOLAN_SIGNATURE inherit SIGNATURE invariant
   disclaimer: not (opinion implies employer.opinion)
end -- class JOHN_VOLAN_SIGNATURE




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Phil Goodwin
@ 1998-09-01  0:00                                               ` Robert Martin
  1998-09-02  0:00                                                 ` Ell
       [not found]                                                 ` <gio+van+no+ni+8-0309982225160001@dialup62.tlh.talstar.com>
  0 siblings, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Phil Goodwin wrote in message <6shp40$ec8$1@nnrp1.dejanews.com>...
>In article <6sfcft$70p$1@hirame.wwa.com>,
>  "Robert Martin" <rmartin@oma.com> wrote:
>>
>> Stephen Leake wrote in message ...
>> >One entry, one exit. Perfectly clear. There's nothing magic about
>> >putting the exit statement at the top or the bottom!
>>
>> In fact there is.  If the exit condition is at the top or the bottom,
then
>> the body of the loop will always be excuted an exact integral number of
>> times.  However if the loop condition is in the middle, then the loop
body
>> will be executed a fractional number of times.
>
>So what?


So...  I can guarantee that any line of code placed at the end of the loop
body will be executed for each iteration of the loop.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                     ` John Volan
@ 1998-09-01  0:00                                                       ` Robert Martin
  1998-09-02  0:00                                                       ` Nick Leaton
  1998-09-02  0:00                                                       ` Chris Saunders
  2 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



John Volan wrote in message <35ECB8F1.6B33FA56@ac3i.dseg.ti.com>...

>There are situations where extraneous calls in the final loop iteration
>would not be so harmless.  For instance, suppose you wished to implement
>an 'out' function for a LIST class that generated strings of the form:
>
> "{}"    for an empty list
> "{A}"   for a list with one element "A"
> "{A, B}" for a list with two elements "A" and "B"
>        etc...


Another solution to this problem is (in C++)

void PrintList(vector<string>& list)
{
  cout << "{";
  string separator = "";
  vector<string>::iterator i;
  for (i = list.begin(); i != list.end(); i++)
  {
    cout << separator << *i;
    separator = ", ";
  }
  cout << "}" << endl;
}

This is a bit inefficient because the separator variable is needlessly set
to ", " in every iteration of the loop.  If this inefficiency is really too
much to deal with, then we can create a special class to deal with it:

class Separator
{
  public:
   virtual void Separate(ostream& o) = 0;
   static Separator* theSeparator = &initial;
   static InitialSeparator initial;
   static CommanSeparator comma;
};

class InitialSeparator : public Separator
{
  public:
    virtual void Separate(ostream& o)
    {
      theSeparator = &comma;
    }
};

class CommaSeparator : public Separator
{
  public:
    virtual void Separate(ostream& o)
    {
      o << ", ";
    }
};

void PrintList(vector<string>& list)
{
  cout << "{";
  vector<string>::iterator i;
  for (i = list.begin(); i != list.end(); i++)
  {
    theSeparator.Separate();
    cout << *i;
  }
  cout << "}" << endl;
}

This uses the a variation of the 'State' pattern from the Design Patterns
book to implement a little finite state machine that ensures that the list
is output properly.

Actually, a finite state machine is probably a good way to represent this
algorithm...
The following is a simple state transition table:

currentstate event newstate   action
------------ ----- --------   ----------------
Starting     Start Initial    {OutputOpenBrace}
Initial      Item  Subsequent {OutputItem}
Initial      Done  EndState   {OutputClosingBrace}
Subsequent   Item  Subsequent {OutputComma OutputItem}
Subsequent   Done  EndState   {OutputClosingBrace}
EndState     *     *          {}

Now we could use SMC (see the freeware section of my website) to build the
program:

class ListPrinter
{
  public:
    void OutputOpenBrace() {cout << "{";}
    void OutputClosingBrace() {cout << "}"}
    void OutputItem() {cout << itsItem;}
    void OutputComma() {cout << ", ";}

    void SetItem(string& s) {itsItem = s;}

  private:
    string itsItem;
};

///////////////////////////
// Input to SMC
// Ouput will be a C++ class named ListPrinterFSM
//
Context ListPrinter
FSMName ListPrinterFSM
Initial Starting
{
Starting     Start Initial    {OutputOpenBrace}
Initial      Item  Subsequent {OutputItem}
Initial      Done  EndState   {OutputClosingBrace}
Subsequent   Item  Subsequent {OutputComma OutputItem}
Subsequent   Done  EndState   {OutputClosingBrace}
EndState     *     *          {}
}

void PrintList(vector<string>& list)
{
  ListPrinterFSM fsm;
  fsm.Start();
  vector<string>::iterator i;
  for (i=list.begin(); i != list.end(); i++)
  {
    fsm.SetItem(*i);
    fsm.Item();
  }
  fsm.Done();
}


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                 ` Biju Thomas
@ 1998-09-01  0:00                                                   ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Biju Thomas wrote in message <35EC91EB.BEF1DB23@ibm.net>...

>
>If it was
>1)
>   for (int index = 1; index < l.top() && equal; index++)
>
>or
>2)
>   for (int index = 1; index < l.top() && true == equal; index++)
>
>it might not have been vulnerable to this type of typos (which is
>frequent in C++, I think).

Not very frequent.  First, most compilers issue warnings when structures
like "a=b" appear in a conditional context (e.g.  if (a=0))

Secondly, you only need make the mistake a few times before you <<know>>.


>Of course, some people say the second style is less readable. But the
>the first one seems to be best.

I agree.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Ell
@ 1998-09-01  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                     ` Richard MacDonald (dogmat)
                                                                       ` (5 more replies)
  0 siblings, 6 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Ell wrote in message ...
>In comp.object Robert Martin <rmartin@oma.com> wrote:
>
>: Phil Goodwin wrote in message <6shp40$ec8$1@nnrp1.dejanews.com>...
>:>In article <6sfcft$70p$1@hirame.wwa.com>,
>:>  "Robert Martin" <rmartin@oma.com> wrote:
>:>>
>:>> Stephen Leake wrote in message ...
>:>> >One entry, one exit. Perfectly clear. There's nothing magic about
>:>> >putting the exit statement at the top or the bottom!
>:>>
>:>> In fact there is.  If the exit condition is at the top or the bottom,
>: then
>:>> the body of the loop will always be excuted an exact integral number of
>:>> times.  However if the loop condition is in the middle, then the loop
>: body
>:>> will be executed a fractional number of times.
>:>
>:>So what?
>
>
>: So...  I can guarantee that any line of code placed at the end of the
loop
>: body will be executed for each iteration of the loop.
>
>Maybe, juuussst maybe, you like many of the rest of us might be able to
>design the loop so that "any line of code placed at the end of loop"
>doesn't matter if the exit/return occurs before the end of the loop?


Lets just say, for grins, that I must make a change to the loop.  For some
odd reason I must count the number of times that the loop body completes.
Where do I put the code that does this counting?  I'd like to make it the
last line of the loop.  But if there are early exits, then I must find each
and every early exit and add the code just before they exit.

Of course, later, someone else will make a change that forces yet another
early exit.  They find where to add the early exit, but they must remember
to bump the counter before they exit.

Of course later on, someone asks us to sieze and release a mutex for each
iteration of the loop.  We'd like to put the seize as the first line of the
loop body, and the release as the last line of the loop body.  But if there
are early exits, then we must put a release before every exit.

Of course later on someone adds yet another early exit to the loop, and must
remember to bump the counter and release the mutex.

....  Has anybody out there ever had an experience like this?


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                       ` Andrew Reilly
@ 1998-09-01  0:00                                                         ` Robert Martin
  1998-09-02  0:00                                                           ` dennison
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Andrew Reilly wrote in message <6si29e$1ul@gurney.reilly.home>...
>In article <6sh4o4$afu$1@hirame.wwa.com>,
> "Robert Martin" <rmartin@oma.com> writes:
>>
>> dennison@telepath.com wrote in message
<6sh30l$k4i$1@nnrp1.dejanews.com>...
>>>In article <6sfqul$ggg$1@hirame.wwa.com>,
>>>  "Robert Martin" <rmartin@oma.com> wrote:
>>>> iteration is the last or not.  Also, a programmer must be aware that
the
>>>> last statement in the loop body will not be executed on the last
iteration.
>>>
>>>Yes, but if that's what the algorithm is *supposed* to do, rephrasing it
with
>>>flags and if statements won't change that.
>>
>> On the contrary, it is possible to create a loop body with a single
>> invariant, and whose last line will be executed in every iteration.
>
>How can you say this?
>
>Or are you counting the endloop statement as the last line?


Correct.  More specifically, I can guarantee that if I put a line of code
just above the endloop statement (closing brace in my case) it will be
executed in every iteration.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Robert I. Eachus
  1998-09-01  0:00                                             ` Mattias Lundstr�m
@ 1998-09-01  0:00                                             ` Richard Jones
  1998-09-02  0:00                                               ` Mattias Lundstr�m
                                                                 ` (3 more replies)
  2 siblings, 4 replies; 510+ messages in thread
From: Richard Jones @ 1998-09-01  0:00 UTC (permalink / raw)


Robert Martin <rmartin@oma.com> wrote:

> Mattias Lundstr�m wrote in message <35EAB5B1.1DA1986B@ehpt.com>...

> It's not so much a matter of being harder to read and understand.  Rather it
> is that there is no good place to make certain kinds of changes to the code.

> For example,  let's say that we had to make a change that forced us to open
> and close a file that the body of the loop needed to read.  Then:

> 1. Flag solution
> File* f = fopen(...);
> while( ... && retval == OK ) {
>   ...
>   if( ... )
>     retval = NOT_OK;
> }
> fclose(f);
> return retval;

> vs

> 2. Multiple exits
> File* f = fopen(...);
> while( ... ) {
>   ...
>   if( ... ){
>     fclose(f);
>     return NOT_OK;
>   }
> }
> fclose(f);
> return OK;

Both of you miss the point that exceptions solve this problem
neatly and naturally, i.e. in some sort of bastardized
Java/C++ hybrid you might write:

    File f ("name", File::OpenReadOnly);
    while (...) {

      if (error_condition) throw new ErrorException;
    }
    return;

Rich.

-- 
Richard Jones rjones@orchestream.com Tel: +44 171 598 7557 Fax: 460 4461
Orchestream Ltd.  125 Old Brompton Rd. London SW7 3RP PGP: www.four11.com
"boredom ... one of the most overrated emotions ... the sky is made
of bubbles ..."   Original message content Copyright � 1998




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` sureshvv
@ 1998-09-01  0:00                                               ` Robert Martin
  1998-09-02  0:00                                                 ` sureshvv
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



sureshvv@hotmail.com wrote in message <6sh6ic$o8p$1@nnrp1.dejanews.com>...
>In article <6sf87j$47n$1@hirame.wwa.com>,
>  "Robert Martin" <rmartin@oma.com> wrote:
>>

>1. Early returns aid in limiting the amount of code that has to be
processed
>and understood.

I disagree.  It only limits the amount of code to read for one particular
iteration of the loop.  But to understand the loop you have to read it all.
>
>2. Understandability is the most important criterion for maintainability.

I disagree again.  An easily modifiable structure is much more important
than understandability.  *Any* structure built by a human can be understood
by most other humans.  Once understood, the work is over.  But a structure
that is hard to maintain, remains hard to maintain until you redesign it.
There are many structures that are easy to understand but hard to maintain.

>Making the code as simple as possible in order to solve the problem at hand
>is more important than trying to make it easier to change against some
>imaginary future changes.

I disagree one last time.  Two digit dates are much easier to deal with than
four digit dates.  Until the century changes...  The engineer who does not
design for maintainability, is doing a disservice to himself, his fellow
engineers, and his employer.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Richard D Riehle
@ 1998-09-01  0:00                                           ` Simon Wright
  1998-09-02  0:00                                           ` adam
  1 sibling, 0 replies; 510+ messages in thread
From: Simon Wright @ 1998-09-01  0:00 UTC (permalink / raw)


Richard D Riehle <laoXhai@ix.netcom.com> writes:

>                     Nobody writes exits in Ada code unless the loop has a
> label, and the compiler tests to see if the exit contains the label of the
> loop as well as checking that the named loop has an "end label."  This makes
> maintenance very easy.    

::blush::

I think I'd better revisit the coding standards.

-- 
Simon Wright                        Work Email: simon.j.wright@gecm.com
GEC-Marconi Radar & Defence Systems            Voice: +44(0)1705-701778
Command & Information Systems Division           FAX: +44(0)1705-701800




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                             ` Robert I. Eachus
  1998-08-31  0:00                                               ` Robert Martin
@ 1998-09-01  0:00                                               ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


eachus@spectre.mitre.org (Robert I. Eachus) writes:

>    Finalization did end up in Ada 95, and it is the right solution to
> this particular problem.  If you want the file to be closed when all
> references go away, it is easy enough to put the code in one place,
> and write:
> 
>    (elsewhere):
> 
>    type File_Handle is new Controlled with private...
> 
>    Now you can say:
> 
>    procedure ... is
>      FH: File_Handle;
>    begin
>      ...
>     end ...;
> 
>     And be sure that the file will be closed if necessary, but only when
> the file is open and no other reference to it exists.
> 
>     Of course, no one does this, because most compiler vendors "do the
> right thing" for the standard I/O packages.  (This wasn't always the
> case.)

I made a similar suggestion wrt the use of a semaphore.  

I guess great minds think alike, eh, Bob?

Matt




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Robert Martin
@ 1998-09-01  0:00                                         ` Matthew Heaney
  1998-09-06  0:00                                           ` Charles Hixson
  0 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> >If I have to add code to the loop,
> >even I the author have to think hard about where it goes now.
> 
> I'm not sure what you are trying to say here.  Don't you always have to
> think hard about where your code goes?  Why does the flag make it harder?

The flag makes it _much_ harder, because it doubles the number of rules
in the decision table.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00             ` Jim Cochrane
  1998-09-01  0:00               ` Matthew Heaney
@ 1998-09-01  0:00               ` Matthew Heaney
  1998-09-02  0:00                 ` Jim Cochrane
  1 sibling, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


jtc@dimensional.com (Jim Cochrane) writes:

> class STACK [G] ...
> is_equal (other: STACK [G]): BOOLEAN is
>         -- Are all items in Current equal to all item in other?
>     require
>         other /= Void
>     local
>         i1, i2: STACK_ITERATOR
>     do
>         !!i1.make (Current); !!i2.make (other)
>         from
>             i1.start; i2.start
>         until
>             i1.after or i2.after or else i1.item /= i2.item
>         loop
>             i1.forth; i2.forth
>         end
>         Result := i1.after and i2.after
>     end
> 
> I don't think this is particularly hard to understand or maintain,
> plus it is simpler than the algorithm below - it eliminates the if
> statement at the beginning.  (STACK_ITERATOR behavior is, hopefully,
> obvious - i.item means the value of item at the current cursor
> position of i.)  I threw this together just for this post, so
> apologies if there are any bugs (and bonus points to those that find
> them :-) ).

I think this is a real brain teaser.  Let me show you how I try to
unravel it.

Let's start by making a decision table for the loop predicate:

                    1  2  3  4  5  6  7  8
i1.after            T  T  T  T  F  F  F  F

i2.after            T  T  F  F  T  T  F  F

i1.item /= i2.item  T  F  T  F  T  F  T  F

As you can see, there are 8 rules, which just exceeded the cognitive
limits of most of human population.  Already, we're in trouble.  But
there's more trouble ahead.

The last part of the predicate uses a short-circuit form, so we're going
to have to prune the table, by removing the rules in which i1.after and
i2.after are both false.  

Or is it both true???  As I'm writing this post, I've already spent
several minutes trying to figure out when the last part of the predicate
actually gets executed.

And I don't even know what the evaluation order rules are in Eiffel.
Does 

  i1.after or i2.after or else i1.item /= i2.item

mean

  (i1.after or i2.after) or else i1.item /= i2.item

or 

   i1.after or (i2.after or else i1.item /= i2.item)

Hmmm?  Maybe these expressions both have the same value.  I don't know,
but I'm obligated to find out.  This is mental work I shouldn't have to
do, and I'll probably get it wrong.

So I gotta ask: Is this a program, or an IQ test?

I'll just use my little decision table friend again, to help me crack
the secret of what result the predicate acually delivers.

                    1  2  3  4  5  6  7  8
i1.after            T  T  T  T  F  F  F  F

i2.after            T  T  F  F  T  T  F  F

i1.item /= i2.item  -  -  -  -  -  -  T  F

The dash (-) means "does not matter."

So the item test only influences the result (I think) when i1.after and
i2.after are both false.  (Gee, that's what I originally thought.  A
miracle happened, and I guessed right!  But how many other times will I
be this lucky?)

Now I have to actually figure out what the result of the predicate is:

                    1  2  3  4  5  6  7  8
i1.after            T  T  T  T  F  F  F  F

i2.after            T  T  F  F  T  T  F  F

i1.item /= i2.item  -  -  -  -  -  -  T  F

predicate has value T  T  T  T  T  T  T  F

Ah, so that's the secret!  The loop teriminates (I think) when all
sub-predicates yield false.

Revealed at last, after several minutes of careful analysis, which I
probably screwed up.

But wait, I did screw up!  Loop termination in Eiffel has opposite the
traditional sense, which is to terminate when the predicate is false.
So the loop terminates when the predicate is true.  Whew!

How many programmers do you think will take the time to figure all this
out?  How many programmers even know how to use a decision table?

One more issue with this example.  Following termination, calculating
the result, 

   Result := i1.after and i2.after

means i1.after and i2.after get tested again.  Why?  They were tested
already, in the loop.  Why test them twice?

Maybe I get bonus points for being able to decipher this, but is that
how we should write software?  Be rewarding those who perform mental
gymnastics?

I hope not.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                       ` Andrew Reilly
@ 1998-09-01  0:00                                         ` Matthew Heaney
  1998-09-01  0:00                                         ` dennison
  1998-09-01  0:00                                         ` dewarr
  2 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


reilly@zeta.org.au (Andrew Reilly) writes:

> I mostly do numerics, and find myself wanting something much simpler
> than the current styles, with a simple integer iteration count.
> A bit like the old Fortran do loops.  Even having to name and
> declare a loop variable is overhead (semantic baggage) I'd avoid
> if I could.

Then Ada's your language!  Although you have to name a loop variable (in
a for loop), you don't have to acually declare it via a type
declaration.  

For example, to iterate over an array, you do this

   A : Integer_Array;
begin
...
   for Index in A'Range loop
       ... A (Index) ...

This works even for the case of an array whose length is zero.

In the stack example, I showed how to iterate over a portion of the
array:

   for Index in Positive range 1 .. L.Top loop
      if L.Items (Index) /= R.Items (Index) then ...

There are other features of Ada95 (the Numerics annex, for example, and
being able to call existing Fortran code) that would appeal to a Fortran
guy.








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                               ` Robert Martin
@ 1998-09-01  0:00                                                 ` Matthew Heaney
  1998-09-01  0:00                                                   ` Stephen Leake
  0 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> >   Finalization did end up in Ada 95, and it is the right solution to
> >this particular problem.
> 
> I am not sure of the semantics of 'finalization' in ADA9X, but if it works
> like Java's, then it does not solve the problem created by multiple exits
> from loops.

"Finalization" in Ada95 is equivalent to having a constructor and
deconstructor for an object.

If a file (or mutex) is controlled - which just means it has a
deconstructor - then the file (mutex) will be automatically closed
(released) when the subprogram terminates. 





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Robert I. Eachus
@ 1998-09-01  0:00                                             ` Mattias Lundstr�m
  1998-09-01  0:00                                               ` Robert Martin
  1998-09-01  0:00                                             ` Richard Jones
  2 siblings, 1 reply; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-09-01  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Mattias Lundstr�m wrote in message <35EAB5B1.1DA1986B@ehpt.com>...

> >(Ie The maintenance argument - that the second code version
> >becomes harder to read and understand (and thus maintain) -
> >since the return statement may well not be obvious if there
> >is a lot of other code within the loop. I do not agree
> >with this, but it is certainly an argument worth considering.
> >IMHO This should be covered by good comments where applicable.)
> 
> It's not so much a matter of being harder to read and understand.  Rather it
> is that there is no good place to make certain kinds of changes to the code.

Ok. I admit. I overlooked this argument...

> 
> For example,  let's say that we had to make a change that forced us to open
> and close a file that the body of the loop needed to read.  Then:

> 2. Multiple exits
> File* f = fopen(...);
> while( ... ) {
>   ...
>   if( ... ){
>     fclose(f);
>     return NOT_OK;
>   }
> }
> fclose(f);
> return OK;

Obviously you should NOT write code like this (for the reasons
you state). If the needs for cleanup continue to grow this will
become unmanageble very quickly. Especially if we have a lot
of exits where we need to duplicate code.

If you need cleanup before leaving the function you
would need to change the original loop layout. Perhaps to:

File* f = fopen(...);
while( ... ) {
  ...
  if( ... ){
    retval = NOT_OK;
    goto leave_loop;
  }
}
leave_loop:
fclose(f);
return retval;

where I have used goto instead of break mostly to annoy  ;-)

I still think that a multi-exit solution like this is better
then juggling flags in many cases. (Question: Is this still
a multi-exit according to your defintions. It clearly is
is you choose to analyse the control flow and see the goto
as not a part of the loop predicate.)

In this case it would be more elegant to instead use a file
class that automatically closes the file when going out of 
scope, but this may be infeasible in some general cases. Eg
A. We are using a GC language and can not know when the
   object will be cleaned up.
B. There may be a need for error handling in the cleanup
   part of the code. We do NOT want to throw exceptions
   from the destructors.

> Clearly solution 1 is easier to deal with than solution 2.  Solution 1

In fact this change almost demands for the rewrite of solution 2.

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                               ` Robert Martin
@ 1998-09-01  0:00                                                 ` Gerhard Menzl
  1998-09-02  0:00                                                 ` Tres Seaver
  1 sibling, 0 replies; 510+ messages in thread
From: Gerhard Menzl @ 1998-09-01  0:00 UTC (permalink / raw)


Robert Martin wrote:

> >> Yes.  Imagine that you had to change the function to make it thread safe;
> >> and that the way to do that was to sieze and release a mutex while the
> >> function was executing.  As written you would have to add the release in
> >> three separate places.  But if you had avoided the multiple returns, you
> >> would have had a single release.
> >
> >Well...  The proper way to use a mutex is to wrap it in a controlled
> >type, so that release is called automatically as a result of subprogram
> >exit, no matter what the reason.  (Controlled types in Ada have
> >operations that are roughly analagous to constructors and deconstructors
> >in C++.)
>
> In a language that supports such things, using controlled types is *a* way
> (not necessarily the "proper" way).  (it happens to be the way that I choose
> in many cases).  But this has nothing really to do with the issue at hand.
> Yes, it may be feasible to put some resource management code into a
> controlled type and avoid the issues of maintenance that I raised earlier;
> but that doesn't eliminate the problem of structure.  In the end, if you can
> make the structure of the software solve a problem, that is better than
> using a special language feature to do it.

In the presence of structured exception handling, as in C++, controlled types
are the proper way; everything else will lead to code duplication and
unnecessary tests. This does not lead to the conclusion that multiple returns
are a good thing, but neither is resource allocation and deallocation a good
argument *against* them as far as object-oriented languages are concerned. With
purely procedural languages, I concede that you have a point.

Gerhard Menzl





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                       ` Andrew Reilly
  1998-09-01  0:00                                         ` Matthew Heaney
  1998-09-01  0:00                                         ` dennison
@ 1998-09-01  0:00                                         ` dewarr
  2 siblings, 0 replies; 510+ messages in thread
From: dewarr @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sff74$q0s@gurney.reilly.home>,
  reilly@zeta.org.au wrote:
> In article <6sebjr$b69$1@nnrp1.dejanews.com>,
> 	dennison@telepath.com writes:
> > I gave up mangling my code to make while loops years ago for just the
reason
> > Matthew spoke of. Occasionally when I make a middle-exited loop I will try
to
> > make a while loop out of it, but I almost always delete the code and go
back
> > to the middle-exited loop. If an algorithm really is a middle-exited loop,
> > you just confuse things (thereby making the code harder to understand) by
> > tring to force a different structure on it. For me, the extra code is a
prime
> > source of errors as well.
>
> Just out of interest, (and loop constructs are a significant
> interest to me), what field of human endeavour do you find
> yourself supporting (coding for) that frequently requires
> middle-exit loops?
>
> I mostly do numerics, and find myself wanting something much simpler
> than the current styles, with a simple integer iteration count.
> A bit like the old Fortran do loops.  Even having to name and
> declare a loop variable is overhead (semantic baggage) I'd avoid
> if I could.
>
> --
> Andrew Reilly                     Reilly@zeta.org.au
>

Something like

   for J in 1 .. 10 loop
      A (J) := 0;
   end loop;

The above is standard Ada code, it declares J as a local constant
in the loop, preventing its use outside the loop, or its
modification within the loop.

Robert Dewar

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Matthew Heaney
  1998-09-01  0:00                                               ` Loryn Jenkins
@ 1998-09-01  0:00                                               ` dewarr
  1998-09-04  0:00                                               ` Jean-Marc Jezequel
  2 siblings, 0 replies; 510+ messages in thread
From: dewarr @ 1998-09-01  0:00 UTC (permalink / raw)


In article <m3yas4q514.fsf@mheaney.ni.net>,
  Matthew Heaney <matthew_heaney@acm.org> wrote:
> Loryn Jenkins <loryn@s054.aone.net.au> writes:
>
> > How is this more complicated?
> >
> > equal (l,r: LIST): BOOLEAN is
> > 	require
> > 		l.count = r.count
> > 	do
> > 		Result := l.first /= r.first
> > 		if Result then
> > 			from
> > 				l.start; r.start
> > 			until
> > 				not Result or l.off
> > 			loop
> > 				Result := l.item /= r.item
> > 				l.forth; r.forth
> > 			end
> > 		end
> > 	end
>
> There are a few things I don't like about this:
>
> 1) You have to test a flag every iteration of the loop.  That adds (a
> marginal amount of) inefficiency.
>
> 2) The loop predicate has 4 possible values.  The original example had
> only 2.
>
> 3) There's more nesting.
>
> So yes, I feel the above implementation is more complex than the
> original implementation that used muliple returns.
>
> > Sorry for the language change ... it's the one I'm familiar with.
>
> AOK, I understood it OK.  (I also read the 1st ed of Bertrand's book.)
>
> > By the way, I'm not sure whether it's a problem in your Ada code, but my
> > Eiffel code could fail if r has greater or fewer items than l. Hence the
> > precondition.
>
> That's what the check L.Top /= R.Top means: if the number of items is
> different, then you know immediately that the stacks can't be equal.
> When you reach the loop, you know the stack depths are the same.
>
> The way I look at this problem, is that it's like searching for a
> specific house on an unfamiliar block.  As you're driving, when you find
> the house, you stop immediately and declare success.  You don't have to
> drive to the end of the block, and then say where the house was.
>
> Likewise for the example I provided.  Once you determine that the stacks
> are unequal, you quit and go home.  You don't need go all the way to the
> end of the subprogram to declare victory (unless of course the stacks
> happen to really be equal).
>
>



Well it is not necessarily clear that this restatement is
less efficient. A compiler could manage to optimize the awkward
flag version back to the simple version with exits. Interestingly
few compilers do this optimization. A similar case is optimizing
an awkward case statement of a finite state machine back to the
simple and efficient version with gotos.

Given how common serious goto-allergy is, especially in the
US, and seeing how many people are willing to contort their
code to avoid gotos, these are optimizations that are probably
worthwhile including in modern compilers for this class of
languages.

Robert Dewar

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00             ` Jim Cochrane
@ 1998-09-01  0:00               ` Matthew Heaney
  1998-09-01  0:00               ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


jtc@dimensional.com (Jim Cochrane) writes:

> How about the following version, without multiple exit points (written in
> Eiffel because it is a good language for this style [it actually doesn't
> allow the multiple return style] and because I'm familiar with Eiffel.)
> 
> class STACK [G] ...
> is_equal (other: STACK [G]): BOOLEAN is
>         -- Are all items in Current equal to all item in other?
>     require
>         other /= Void
>     local
>         i1, i2: STACK_ITERATOR
>     do
>         !!i1.make (Current); !!i2.make (other)
>         from
>             i1.start; i2.start
>         until
>             i1.after or i2.after or else i1.item /= i2.item
>         loop
>             i1.forth; i2.forth
>         end
>         Result := i1.after and i2.after
>     end
> 
> I don't think this is particularly hard to understand or maintain,
> plus it is simpler than the algorithm below - it eliminates the if
> statement at the beginning.  (STACK_ITERATOR behavior is, hopefully,
> obvious - i.item means the value of item at the current cursor
> position of i.)  I threw this together just for this post, so
> apologies if there are any bugs (and bonus points to those that find
> them :-) ).

I realized I had a compare op lying around implemented using the same
idea: using iterators to simultaneously traverse over a pair of
collections.

As you can see, it's more or less like the earlier example I posted.
(At least I'm consistent.)

It avoids the mental gymnastics required to understand the (Eiffel)
example shown above, because there isn't any complicated loop predicate.

The conditions under which the loop terminates should be pretty obvious.
Find a mismatch between items, and just bail out.  Pure and simple.


function ACL.Compare
  (Left  : access Left_Collection;
   Right : access Right_Collection) return Boolean is

   Length : Natural renames Get_Length (Left.all);

   Left_Iter  : Left_Iterator (Left);
   Right_Iter : Right_Iterator (Right);

begin -- Compare

   if Length /= Get_Length (Right.all) then
      return False;
   end if;

   for Index in 1 .. Length loop
      if Get_Item (Left_Iter).all /=
         Get_Item (Right_Iter).all
      then
         return False;
      end if;

      Advance (Left_Iter);
      Advance (Right_Iter);
   end loop;

   return True;

end ACL.Compare;






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Loryn Jenkins
@ 1998-09-01  0:00                                                 ` Matthew Heaney
  1998-09-01  0:00                                                   ` James Weirich
  1998-09-02  0:00                                                   ` Loryn Jenkins
  1998-09-04  0:00                                                 ` Charles Hixson
  1 sibling, 2 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


Loryn Jenkins <loryn@s054.aone.net.au> writes:

> 
>  equal (l,r: LIST): BOOLEAN is
>        require
>                l /= Void and r /= Void
>        do
>                Result := l.count /= r.count
>                if Result then
>                        from
>                                l.start; r.start
>                        until
>                                not Result or l.off
>                        loop
>                                Result := l.item /= r.item
>                                l.forth; r.forth
>                        end
>                end
>        end
> 
> 
> > The way I look at this problem, is that it's like searching for a
> > specific house on an unfamiliar block.  As you're driving, when you find
> > the house, you stop immediately and declare success.  You don't have to
> > drive to the end of the block, and then say where the house was.
> 
> Yeah, yeah. Same here, given the amended code.

No, no, not the same here.

If the test l.count /= r.count returns False, then you know immediately
what the return value of the function is, so why not deliver that
information right away?  That way you can remove the test of result
(reducing the level of nesting), and simplify the predicate,

(By way of analogy, if you've found the house, then you can park in the
driveway right way, instead of driving to the end of the block to
announce that you found the house.)

Let's once again compare the decision tables.  If we re-write the code,
to put it into Matt-like (because Matt likes it) syntax:


equal (l,r: LIST): BOOLEAN is
      require
              l /= Void and r /= Void
      do
              if l.count /= r.count then
                 return False
              end
              
              from
                 l.start; r.start
              until
                 l.off
              loop
                 if l.item /= r.item then
                    return False
                 end

                 l.forth; r.forth
              end

              return True
      end


This version has only two rules in the decision table for the loop predicate:

       1  2
l.off  T  F


The uncorrected version has four rules:

            1  2  3  4
not Result  T  T  F  F
l.off       T  F  T  F


The difference in styles is really a debate about the number of edges in
the flow graph vs the number of rules in the decision table.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                 ` Matthew Heaney
@ 1998-09-01  0:00                                                   ` James Weirich
  1998-09-01  0:00                                                     ` Mike Spille
  1998-09-02  0:00                                                   ` Loryn Jenkins
  1 sibling, 1 reply; 510+ messages in thread
From: James Weirich @ 1998-09-01  0:00 UTC (permalink / raw)



    Matthew> Let's once again compare the decision tables.  If we
    Matthew> re-write the code, to put it into Matt-like (because Matt
    Matthew> likes it) syntax:

    Matthew> equal (l,r: LIST): BOOLEAN is
    Matthew>       require
    Matthew>               l /= Void and r /= Void
    Matthew>       do
    Matthew>               if l.count /= r.count then
    Matthew>                  return False
    Matthew>               end
    Matthew>               from
    Matthew>                  l.start; r.start
    Matthew>               until
    Matthew>                  l.off
    Matthew>               loop
    Matthew>                  if l.item /= r.item then
    Matthew>                     return False
    Matthew>                  end
    Matthew>                  l.forth; r.forth
    Matthew>               end
    Matthew>               return True
    Matthew>       end

    Matthew> This version has only two rules in the decision table for
    Matthew> the loop predicate:

    Matthew>        1  2
    Matthew> l.off  T  F

Yes, but you are ignoring the fact that there are now two loop exits.
If you ask the question "When will the loop terminate?", you must
consider all the exits, including the early return.

So instead of a single, 2 entry table, you have two 2-entry tables.
Combining them into a single table will produce the same 4 entry table
as the one you produced for Loryn Jenkins's code.

Seems to me the complexity is about equivalent.

-- 
-- Jim Weirich     jweirich@one.net    http://w3.one.net/~jweirich
---------------------------------------------------------------------
-- "A distributed system is one in which I cannot get something done
-- because a machine I've never heard of is down."   --Leslie Lamport




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                     ` <35f51e53.48044143@ <904556531.666222@miso.it.uq.edu.au>
@ 1998-09-01  0:00                                       ` Gerry Quinn
  1998-09-01  0:00                                         ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Gerry Quinn @ 1998-09-01  0:00 UTC (permalink / raw)


In article <904556531.666222@miso.it.uq.edu.au>, ahussey@it.uq.edu.au (Andrew Hussey)
 <m3af4mq7f4.fsf@mheaney.ni.net> wrote:

>>Using an exit from the middle avoids the headaches (literally)
>>engendered by using an extra flag in the predicate.  When you want to
>>exit, you just say that you want to exit, directly.  No mental
>>gymnastics are required in order to determine whether you'll "really"
>>exit, as would be the case using the flag approach.
>
>That's brilliant, now your code is much easier to write!
>Now let's see who has an easier time *testing* their code.
>I think you'll find the control-flow errors you introduce
>in the spaghetti you produce will more than make up for
>any gain you have from rapid coding.  
>

A characteristic of 'spaghetti' is that the strings both start and 
finish in unpredictable places, leading to a tangled mass.

Multiple exits to a single destination are not spaghetti.

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                       ` Andrew Reilly
  1998-09-01  0:00                                         ` Matthew Heaney
@ 1998-09-01  0:00                                         ` dennison
  1998-09-01  0:00                                         ` dewarr
  2 siblings, 0 replies; 510+ messages in thread
From: dennison @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sff74$q0s@gurney.reilly.home>,
  reilly@zeta.org.au wrote:
> In article <6sebjr$b69$1@nnrp1.dejanews.com>,
> 	dennison@telepath.com writes:
> > to the middle-exited loop. If an algorithm really is a middle-exited loop,
> > you just confuse things (thereby making the code harder to understand) by
> > tring to force a different structure on it. For me, the extra code is a
prime
> > source of errors as well.
>
> Just out of interest, (and loop constructs are a significant
> interest to me), what field of human endeavour do you find
> yourself supporting (coding for) that frequently requires
> middle-exit loops?

Well, I'll go through the middle-exited loops on code I'm working on
now...

4 Parsing loops
2 Sorting loops
2 Searching loops
1 Token analysis loop
1 Error handling
2 lexicagraphical comparison loops
1 lexicagraphical incrementer

> I mostly do numerics, and find myself wanting something much simpler
> than the current styles, with a simple integer iteration count.
> A bit like the old Fortran do loops.  Even having to name and
> declare a loop variable is overhead (semantic baggage) I'd avoid
> if I could.

I suppose that would be useful if you wanted a "repeat the following code
1051 times" loop. But its very rare I need to do something like that w/o also
needing to use the iteration count as an index. In fact, if its really
simple, a lot of times you can write it as one array assignment operation in
Ada. For instance, the insertion operation in one of my sorting loops is: 
Rows(1..Sortee) := Rows(1..Sorted-1) & Rows(Sortee) & Rows(Sorted..Sortee-1);

--
T.E.D.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                                 ` Robert Martin
  1998-09-01  0:00                                                   ` Tim Ottinger
@ 1998-09-01  0:00                                                   ` dennison
  1998-09-01  0:00                                                     ` Robert Martin
  1 sibling, 1 reply; 510+ messages in thread
From: dennison @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sfqul$ggg$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Ell wrote in message <35ed3d4a.2378710@news.erols.com>...
> >"Agent" <agent@siu.edu> wrote:
> >
> >>Robert Martin wrote in message <6sfcft$70p$1@hirame.wwa.com>...
> >>>Stephen Leake wrote in message ...
>
> >>>>One entry, one exit. Perfectly clear. There's nothing magic about
> >>>>putting the exit statement at the top or the bottom!
> >>>
> >>>In fact there is.  If the exit condition is at the top or the bottom,
> >>then
> >>>the body of the loop will always be excuted an exact integral number of
> >>>times.  However if the loop condition is in the middle, then the loop
> >>body
> >>>will be executed a fractional number of times.
> >
> >So what?
>
> The the invariants of the loop body are different depending on whether the
> iteration is the last or not.  Also, a programmer must be aware that the
> last statement in the loop body will not be executed on the last iteration.

Yes, but if that's what the algorithm is *supposed* to do, rephrasing it with
flags and if statements won't change that.

--
T.E.D.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Gene Gajewski
@ 1998-09-01  0:00                                             ` sureshvv
  1998-09-01  0:00                                               ` Robert Martin
  1998-09-01  0:00                                             ` Robert I. Eachus
                                                               ` (4 subsequent siblings)
  6 siblings, 1 reply; 510+ messages in thread
From: sureshvv @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sf87j$47n$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Matthew Heaney wrote in message ...
>
> >
> >Would the implementation be better by not using multiple returns?
>
> Yes.  Imagine that you had to change the function to make it thread safe;
> and that the way to do that was to sieze and release a mutex while the
> function was executing.  As written you would have to add the release in
> three separate places.  But if you had avoided the multiple returns, you
> would have had a single release.

In C++, you could use the Resource Allocation is Initialization idiom
to deal with such cases.

1. Early returns aid in limiting the amount of code that has to be processed
and understood.

2. Understandability is the most important criterion for maintainability.
Making the code as simple as possible in order to solve the problem at hand
is more important than trying to make it easier to change against some
imaginary future changes.

suresh

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                                 ` Robert Martin
@ 1998-09-01  0:00                                                   ` Tim Ottinger
  1998-09-01  0:00                                                     ` Robert Martin
  1998-09-01  0:00                                                   ` dennison
  1 sibling, 1 reply; 510+ messages in thread
From: Tim Ottinger @ 1998-09-01  0:00 UTC (permalink / raw)


Robert Martin wrote:
> The the invariants of the loop body are different depending on whether the
> iteration is the last or not.  Also, a programmer must be aware that the
> last statement in the loop body will not be executed on the last iteration.

Of course, the example is "in the small". Very small things tend to be
fairly easy to understand. To really appreciate the rules, you have to
have a moderately complex loop with if/then/else or switch/case in the
middle, preferably nested three levels deep or more ;-)

I personally like checking rules at the front of a function, and
returning
early if conditions aren't met... at least for checking invariants.
Assert 
is better if you want to abort when the condition isn't met.

But the question I have is what happens when we have exceptions. Those
are
most certainly an early exit and may occur at unpredicted times. How
do
the rules for single entry/exit apply in an exception-supporting
language?


Tim






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Mattias Lundstr�m
  1998-08-31  0:00                                           ` Robert Martin
@ 1998-09-01  0:00                                           ` Tim Ottinger
  1 sibling, 0 replies; 510+ messages in thread
From: Tim Ottinger @ 1998-09-01  0:00 UTC (permalink / raw)


Mattias Lundstr�m wrote:
> I just have to butt in here.
> Why would this code become harder to test?
> 
> If we take a simple example (more or less C++)

I added a few comments:

> 1. Flag solution
> while( ... && retval == OK ) {
> ...
> if( ... )
>   retval = NOT_OK;
> }
> return retval;  /* SET BREAKPOINT HERE */
> 
> vs
> 
> 2. Multiple exits
> while( ... ) {
> ...
> if( ... )
>   return NOT_OK;  /* SET BREAKPOINT HERE */
> }
> return OK; /* AND ANOTHER ONE HERE */

In one case, I set a single breakpoint and can inspect
the value to see what happened. In the second, I set
more than one breakpoint, or the function will return
quietly. That can be good or bad. 

The single-return gives more options than the multiple-
return version. You can watchpoint the variable, or
you can set the break on return and inspect the variable,
or set the breaks where the return value is set.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Mattias Lundstr�m
@ 1998-09-01  0:00                                               ` Robert Martin
  1998-09-01  0:00                                                 ` Robert I. Eachus
                                                                   ` (2 more replies)
  0 siblings, 3 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3243 bytes --]


Mattias Lundstr�m wrote in message <35EB9B91.3FF8583@ehpt.com>...
>Robert Martin wrote:
>
>> 2. Multiple exits
>> File* f = fopen(...);
>> while( ... ) {
>>   ...
>>   if( ... ){
>>     fclose(f);
>>     return NOT_OK;
>>   }
>> }
>> fclose(f);
>> return OK;
>
>Obviously you should NOT write code like this (for the reasons
>you state). If the needs for cleanup continue to grow this will
>become unmanageble very quickly. Especially if we have a lot
>of exits where we need to duplicate code.
>
>If you need cleanup before leaving the function you
>would need to change the original loop layout. Perhaps to:
>
>File* f = fopen(...);
>while( ... ) {
>  ...
>  if( ... ){
>    retval = NOT_OK;
>    goto leave_loop;
>  }
>}
>leave_loop:
>fclose(f);
>return retval;
>

This is roughly equivalent to the 'finally' solution in another post.  And
I'll use the same argument.

char* p = malloc(80);
if (!p) goto error_exit;
File* f = fopen(...);
if (!f) goto error_exit;
while (...) {
  if (horrible_error)
    goto error_exit;
}
fclose(f);
free(p)
return OK;

error_exit:
  if (p) free(p);
  if (f) fclose(f);
  return NOT_OK;
}

The redundant resource cleanup, and the checks made in the error_exit
section are pretty ugly.  And this ugliness will only grow and become more
contorted over time.  Also, it is not guaranteed that all resources will
have check functions, forcing the use of flags (which is all p and f are
used for in error_exit) in order to determine when it is safe to release
such a resource.

Single-entry/single-exit (se/se) structures always have appropriate places
for acuiring and freeing resources.  The state of the algorithm is encoded
into the structure.  Multiple exits, gotos, finally clauses, destructures,
etc, all *lose* state information.  Once they are invoked, the previous
state of the algorithm can only be recaptured by investigating the data and
within the algorithm.  This means flags that cover the entire scope of the
algorithm must be maintained so that the error recovery code can determine
what to do.

Now certainly it is easier to write the functions with multiple exits.  And
if the functions never change, then you have won; and using a structured
programming approach would be a net loss.  However, functions generally
don't remain the same.  Most of the time they <<grow>> (remember Kahn
talking about how his "pets" enter through your ear and live inside your
brain?  "Later", he said, " as they <<grow>>...") Functions that have not
been built using structured programming can degrade pretty badly when they
<<grow>>.

The decision to use multiple exists (other than exceptions) is a short term
decision that will probably yeild short term benefits.  But in the long term
the decision has the potential to cause significant pain.  Personally, I
have experienced enough of that sort of pain, so I am pretty careful about
se/se.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan









^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                       ` Gerry Quinn
@ 1998-09-01  0:00                                         ` Robert Martin
  1998-09-01  0:00                                           ` Gerry Quinn
                                                             ` (3 more replies)
  0 siblings, 4 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Gerry Quinn wrote in message <6sgror$je8$3@news.indigo.ie>...

>Multiple exits to a single destination are not spaghetti.


Spaghetti is not a well defined term.

However, multiple exits to a single destination represent a problem.  The
two exits come from two different states within the algorithm.  If the
single destination must do some work that depends upon that state (or if in
the future, that single destination must be modified to do work that depends
upon that state), then the code in the single destination is going to get
pretty ugly.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` Tim Ottinger
@ 1998-09-01  0:00                                                     ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



Tim Ottinger wrote in message <35EBF28B.FD4F38EC@oma.com>...

>But the question I have is what happens when we have exceptions. Those
>are
>most certainly an early exit and may occur at unpredicted times. How
>do
>the rules for single entry/exit apply in an exception-supporting
>language?


For exceptions, they don't apply.  And because of that, language designers
have bene forced to invent a suite of extraordinary language features to
help deal with it.  In C++, we use destructors to clean up resources.  In
Java we use 'finally' clauses.  These solutions work, but suffer from the
fact that the state of the algorithm may have been by the time they are
entered; and such state may have to be recaptured by inspecting data
elements (something very difficult to do inside a destructor!).

In the end, one of the better schemes for dealing with exceptions is to
re-enstate the single-entry/single-exit (se/se) mechanism by using fine
grained try/catch blocks:

try { // block 1
  do something that might throw.
  try { // block 2, new algorithm state
    do something else that might throw.
    cleanup block 2.
  }
  catch(...)
  {
    cleanup block 2;
    throw;
  }

  cleanup block 1
}
catch(...)
{
  cleanup block 1.
  throw;
}

The 'finally' approach in Java is superior to this because it doesn't
require the duplicated cleanup code.  And when used in a fine-grained way
can almost completely recapture the tracking of algorithm state that se/se
structures do.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` dennison
@ 1998-09-01  0:00                                                     ` Robert Martin
  1998-09-02  0:00                                                       ` Andrew Reilly
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-01  0:00 UTC (permalink / raw)



dennison@telepath.com wrote in message <6sh30l$k4i$1@nnrp1.dejanews.com>...
>In article <6sfqul$ggg$1@hirame.wwa.com>,
>  "Robert Martin" <rmartin@oma.com> wrote:
>>
>> Ell wrote in message <35ed3d4a.2378710@news.erols.com>...
>> >"Agent" <agent@siu.edu> wrote:
>> >
>> >>Robert Martin wrote in message <6sfcft$70p$1@hirame.wwa.com>...
>> >>>Stephen Leake wrote in message ...
>>
>> >>>>One entry, one exit. Perfectly clear. There's nothing magic about
>> >>>>putting the exit statement at the top or the bottom!
>> >>>
>> >>>In fact there is.  If the exit condition is at the top or the bottom,
>> >>then
>> >>>the body of the loop will always be excuted an exact integral number
of
>> >>>times.  However if the loop condition is in the middle, then the loop
>> >>body
>> >>>will be executed a fractional number of times.
>> >
>> >So what?
>>
>> The the invariants of the loop body are different depending on whether
the
>> iteration is the last or not.  Also, a programmer must be aware that the
>> last statement in the loop body will not be executed on the last
iteration.
>
>Yes, but if that's what the algorithm is *supposed* to do, rephrasing it
with
>flags and if statements won't change that.


On the contrary, it is possible to create a loop body with a single
invariant, and whose last line will be executed in every iteration.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                         ` Robert Martin
@ 1998-09-01  0:00                                           ` Gerry Quinn
  1998-09-01  0:00                                             ` Robert Martin
  1998-09-01  0:00                                           ` Mike Spille
                                                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 510+ messages in thread
From: Gerry Quinn @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sh3qn$9p2$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> wrote:
>
>Gerry Quinn wrote in message <6sgror$je8$3@news.indigo.ie>...
>
>>Multiple exits to a single destination are not spaghetti.
>
>Spaghetti is not a well defined term.
>
How strange, then, that such sloppy language is endemic among those 
who believe they hold the line against sloppy coding...


>However, multiple exits to a single destination represent a problem.  The
>two exits come from two different states within the algorithm.  If the
>single destination must do some work that depends upon that state (or if in
>the future, that single destination must be modified to do work that depends
>upon that state), then the code in the single destination is going to get
>pretty ugly.
>
All code presents a problem, and a perfectionist could never write a 
line, one is so often forced to choose between alternatives each of 
which is ugly in its own way.

When cleanup is unlikely to be needed, multiple exits are unlikely to 
pose a problem, and indeed can only be avoided by artificially 
extending the process.  

All conventional computation proceeds by the discarding of algorithmic 
states, and all destinations eventually end in one, irrespective of 
the merging mechanisms employed.

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
                                                               ` (5 preceding siblings ...)
  1998-09-01  0:00                                             ` Richard Melvin
@ 1998-09-01  0:00                                             ` Chris Brand
  1998-09-01  0:00                                               ` Robert Martin
  6 siblings, 1 reply; 510+ messages in thread
From: Chris Brand @ 1998-09-01  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> bool operator==(Stack& l, Stack& r)
> {
>   bool equal = true;
>   for (int index = 1; index < l.top() && equal == true; index++)
>   {
>     if (l[index] != r[index])
>       equal = false;
>   }
>   return equal;
> }
> 
> If this is more complex (something that is arguable) it is not *much* more
> complex.  On the other hand, it is easier to maintain.

It is open to (maintenance) errors such as
   for (int index = 1; index < l.top() && equal = true; index++)
which the multiple-return version isn't, so the "easier to maintain"
argument is far from clear-cut.

-- 
Chris




An extra line to keep my news server happy




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Loryn Jenkins
  1998-09-01  0:00                                                     ` John Volan
  1998-09-01  0:00                                                     ` John Volan
@ 1998-09-01  0:00                                                     ` Darren New
  1998-09-02  0:00                                                       ` Loryn Jenkins
  1998-09-02  0:00                                                     ` Matthew Heaney
  3 siblings, 1 reply; 510+ messages in thread
From: Darren New @ 1998-09-01  0:00 UTC (permalink / raw)


Loryn Jenkins wrote:
> equal (l,r: LIST): BOOLEAN is
>       require
>           l /= Void and r /= Void
>       do
>           from
>               Result := (l.count = r.count)
>               l.start; r.start
>           until
>               not Result or l.off
>           loop
>               Result := (l.item = r.item)
>               l.forth; r.forth
>           end
>       end

And of course, this becomes much more readable when you use variables
whose names mean what they say.

equal (l,r: LIST): BOOLEAN is
       require
           l /= Void and r /= Void
       local stacks_are_known_different : BOOLEAN
       do
           from
               stacks_are_known_different := (l.count /= r.count)
               l.start; r.start
           until
               stacks_are_known_different or l.off
           loop
               stacks_are_known_different := (l.item /= r.item)
               l.forth; r.forth
           end
           Result := not stacks_are_known_different
       end

(With a minor renaming to get rid of "not". I don't *think* I broke it.)
I think picking the proper names for locals invariably clarifies the
code, even at the expense of declaring another local. The first time you
assign to "Result", you're not assigning the "result".

One of my rules of thumb for clear programming is "have a meaning for
every variable that is appropriate at every line of the algorithm".
Otherwise, you're using the same variable for multiple unrelated values.
Here, it's clear just by looking that you know the stacks are different
if the counts are different or the items are different, you stop the
loop as soon as you know the stacks are different, and the result is
whether you know the stacks are different at the bottom of the loop.

This is a bit more pendantic than I usually am, but I think it's *very*
clear, and certainly more clear than embedded returns.

-- 
Darren New / Senior Software Architect / First Virtual Holdings Inc
http://www.fv.com or info@fv.com -=|=- PGP Key: ftp://ftp.fv.com/pub/fv
Fingerprint: 61 7D AF 9E 00 CC C2 ED / D8 4C D7 AA E4 C2 A0 73




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
                                                               ` (3 preceding siblings ...)
  1998-09-01  0:00                                             ` Matthew Heaney
@ 1998-09-01  0:00                                             ` Phil Goodwin
  1998-09-01  0:00                                               ` Biju Thomas
  1998-09-03  0:00                                               ` Ole-Hjalmar Kristensen
  1998-09-01  0:00                                             ` Richard Melvin
  1998-09-01  0:00                                             ` Chris Brand
  6 siblings, 2 replies; 510+ messages in thread
From: Phil Goodwin @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sf87j$47n$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Matthew Heaney wrote in message ...
>
> >
> >Would the implementation be better by not using multiple returns?
>
> Yes.  Imagine that you had to change the function to make it thread safe;
> and that the way to do that was to sieze and release a mutex while the
> function was executing.  As written you would have to add the release in
> three separate places.  But if you had avoided the multiple returns, you
> would have had a single release.

Or you could use the Initialization is Resource Aquisition idiom and thereby
choose not to have the problem in the first place, takes care of 'returns'
caused by exceptions as well.

You could also choose to refactor the code at the time that you are adding
the mutex. First rewrite the routine with a single return and no mutex and
test it to make sure that it still works and then add the mutex and the
single release.

I write plenty of little routines that have loops in them that exit in the
middle. It doesn't make sense to me to alter the algorithm and write extra
code just so that the routine might be easier to maintain someday (if ever).
On the other hand, when I DO maintain such a routine I definitely WILL make
sure that there is only one exit point if that's what is needed to eliminate
duplicate code.

I adopted this position in part because of some of what I've read about
Extreme Programming. I haven't adopted it wholesale, but I do like their
no-nonsense philosophy. They use two balancing maxims that I've applied to
this question: Do The Simpest Thing That Could Possibly Work; and Once And
Only Once. So when I write a function I do the simplest thing that could
possibly work, which sometimes means sticking a return right smack in the
middle of a loop. I am especially likely to do this when the loop body is
less than five lines long anyway. Then, when I have to refactor in order to
add the aquisistion and release of some resource, I rearrange the routine so
that I add the code once and only once. The justification for this is that I
don't want to adopt a coding task because it _might_ be needed during
maintenance, I would rather do it during maintenance when I KNOW that it
needs to be done.

Phil

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                             ` Agent
@ 1998-09-01  0:00                                               ` Ell
  1998-08-31  0:00                                                 ` Robert Martin
       [not found]                                                 ` <6sfqul$ggg$1@hirame. <6sidsq$e6c$1@hirame.wwa.com>
  0 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-09-01  0:00 UTC (permalink / raw)


"Agent" <agent@siu.edu> wrote:

>Robert Martin wrote in message <6sfcft$70p$1@hirame.wwa.com>...
>>Stephen Leake wrote in message ...
>>>If there is only one 'exit' statement, why is this bad?
>>>
>>>loop
>>>    ... stuff
>>>    exit when ;
>>>    ... stuff
>>>end loop;
>>>
>>>One entry, one exit. Perfectly clear. There's nothing magic about
>>>putting the exit statement at the top or the bottom!
>>
>>In fact there is.  If the exit condition is at the top or the bottom,
>then
>>the body of the loop will always be excuted an exact integral number of
>>times.  However if the loop condition is in the middle, then the loop
>body
>>will be executed a fractional number of times.

So what?  Big deal.  It's *not* non-intuitive, unreadable, hard to
maintain spaghetti code (even less so with comments), and that's all
that *really* matters.  *Those* are the key issues, not blind bondage
in some imaginary stockade of dogmatic pain.

Elliott

>There are two "loop bodies" in this case.  The upper body will be
>executed n times, and the lower body will be executed n-1 times.  It is
>a little more difficult to keep track of, but mid-decision loops *are*
>useful; Knuth thinks so, anyway, and I agree based on my own
>experiences.
>
>-- Agent
>

-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                     ` dennison
  1998-08-31  0:00                                       ` Robert Martin
@ 1998-09-01  0:00                                       ` Andrew Reilly
  1998-09-01  0:00                                         ` Matthew Heaney
                                                           ` (2 more replies)
  1 sibling, 3 replies; 510+ messages in thread
From: Andrew Reilly @ 1998-09-01  0:00 UTC (permalink / raw)


In article <6sebjr$b69$1@nnrp1.dejanews.com>,
	dennison@telepath.com writes:
> I gave up mangling my code to make while loops years ago for just the reason
> Matthew spoke of. Occasionally when I make a middle-exited loop I will try to
> make a while loop out of it, but I almost always delete the code and go back
> to the middle-exited loop. If an algorithm really is a middle-exited loop,
> you just confuse things (thereby making the code harder to understand) by
> tring to force a different structure on it. For me, the extra code is a prime
> source of errors as well.

Just out of interest, (and loop constructs are a significant
interest to me), what field of human endeavour do you find
yourself supporting (coding for) that frequently requires
middle-exit loops?

I mostly do numerics, and find myself wanting something much simpler
than the current styles, with a simple integer iteration count.
A bit like the old Fortran do loops.  Even having to name and
declare a loop variable is overhead (semantic baggage) I'd avoid
if I could.

-- 
Andrew Reilly                     Reilly@zeta.org.au




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                           ` Loryn Jenkins
@ 1998-09-01  0:00                                             ` Matthew Heaney
  1998-09-01  0:00                                               ` Loryn Jenkins
                                                                 ` (2 more replies)
  0 siblings, 3 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


Loryn Jenkins <loryn@s054.aone.net.au> writes:

> How is this more complicated? 
>
> equal (l,r: LIST): BOOLEAN is
> 	require
> 		l.count = r.count
> 	do
> 		Result := l.first /= r.first
> 		if Result then
> 			from
> 				l.start; r.start
> 			until
> 				not Result or l.off
> 			loop
> 				Result := l.item /= r.item
> 				l.forth; r.forth
> 			end
> 		end
> 	end

There are a few things I don't like about this:

1) You have to test a flag every iteration of the loop.  That adds (a
marginal amount of) inefficiency.

2) The loop predicate has 4 possible values.  The original example had
only 2.

3) There's more nesting.

So yes, I feel the above implementation is more complex than the
original implementation that used muliple returns.


> Sorry for the language change ... it's the one I'm familiar with.

AOK, I understood it OK.  (I also read the 1st ed of Bertrand's book.)
 
> By the way, I'm not sure whether it's a problem in your Ada code, but my
> Eiffel code could fail if r has greater or fewer items than l. Hence the
> precondition.

That's what the check L.Top /= R.Top means: if the number of items is
different, then you know immediately that the stacks can't be equal.
When you reach the loop, you know the stack depths are the same.


The way I look at this problem, is that it's like searching for a
specific house on an unfamiliar block.  As you're driving, when you find
the house, you stop immediately and declare success.  You don't have to
drive to the end of the block, and then say where the house was.

Likewise for the example I provided.  Once you determine that the stacks
are unequal, you quit and go home.  You don't need go all the way to the
end of the subprogram to declare victory (unless of course the stacks
happen to really be equal).





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Andrew Hussey
  1998-08-31  0:00                                         ` Mattias Lundstr�m
  1998-08-31  0:00                                         ` Matthew Heaney
@ 1998-09-01  0:00                                         ` dewarr
  2 siblings, 0 replies; 510+ messages in thread
From: dewarr @ 1998-09-01  0:00 UTC (permalink / raw)


In article <904556531.666222@miso.it.uq.edu.au>,
  ahussey@it.uq.edu.au (Andrew Hussey) wrote:
> In <m3af4mq7f4.fsf@mheaney.ni.net> Matthew Heaney <matthew_heaney@acm.org>
writes:
>
> >I can almost live that.  The real problem, however, is that using an
> >extra flag to terminate VASTLY complicates the predicate.  In fact, the
> >flag doubles the number of states I have to think about when mentally
> >evaluating the predicate!  That's the real source of the loop
> >termination errors.
>
> >(I shouldn't have to remind anyone, but just in case: George Miller did
> >a famous study about human cognitive limits, and found that people can
> >remember about 7 things, plus or minus 2.  That's why complex predicates
> >make a programmer's head spin, and why he often gets loop termination
> >wrong.)
>
> >Using an exit from the middle avoids the headaches (literally)
> >engendered by using an extra flag in the predicate.  When you want to
> >exit, you just say that you want to exit, directly.  No mental
> >gymnastics are required in order to determine whether you'll "really"
> >exit, as would be the case using the flag approach.
>
> That's brilliant, now your code is much easier to write!
> Now let's see who has an easier time *testing* their code.
> I think you'll find the control-flow errors you introduce
> in the spaghetti you produce will more than make up for
> any gain you have from rapid coding.
>
> A.
>
>

If you think that the use of a goto necessarily results in
"spaghetti code", then you simply don't understand the (useful)
concept of spaghetti code. I often see this, people don't really
understand the issues at all, but want to reduce their lack of
understanding to a simple rule ("never use a goto"). I guess that
if you don't have any understanding of the issues, this is not
a terrible rule, but it will result in less clear code in some
cases.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Patrick Logan
@ 1998-09-01  0:00                                             ` dewarr
  0 siblings, 0 replies; 510+ messages in thread
From: dewarr @ 1998-09-01  0:00 UTC (permalink / raw)


In article <LRzG1.4391$f01.3488385@news.teleport.com>,
  Patrick Logan <plogan@user1.teleport.com> wrote:
> In comp.object Matthew Heaney <matthew_heaney@acm.org> wrote:
>
> : > Actually this section says that there are two different kinds of
> : > loops. one that is tested at the top; and another which is tested at
> : > the bottom.  But in all cases, the elements of structure programming
> : > have a single entry and a single exit.  A loop that exits in the
> : > middle, violates this maxim.
>
> : I think the issue is meaning vs syntax.  When I use an exit from the
> : middle, it's to say that "I want to terminate the loop, NOW."
>
> Almost every time I am tempted to terminate a loop in the middle, I
> ultimately choose not to.
>
> More important than that, IMHO, is that a loop's body not have a lot
> of text in it. If it is a five or ten line loop, at the most, then
> even if it terminates in the middle it will be easier to read. So a
> loop should communicate the control aspect of the operation, the body
> should rely on procedures/methods to carry out the bulk of the work.
>
> This also has the benefit of making the bulk of the work more
> reusable.
>
> --
> Patrick Logan    (H) mailto:plogan@teleport.com
>                  (W) mailto:patrickl@gemstone.com
>                  http://www.gemstone.com
>

Yes, that is really the key point here. The use of continue is
almost always better replaced by something else, but not quite
always. I actually feel that the provision of the keyword
continue in C is a mistake, it encourages people to overuse
this kind of skip.

In Ada, you need to use "goto Continue_Loop", to get this effect.
For those who are not hopelessly goto-allergic, this is just
right, it makes you think "do I really need to use this special
kind of goto, or is there a better way of doing things?" If
the answer is yes, you really need to use this special kind of
goto, then go ahead and use it!

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Tim McDermott
  1998-08-31  0:00                                             ` Larry Brasfield
@ 1998-09-01  0:00                                             ` dewar
  1998-09-01  0:00                                             ` Matthew Heaney
  2 siblings, 0 replies; 510+ messages in thread
From: dewar @ 1998-09-01  0:00 UTC (permalink / raw)


In article <35EB1706.22E7E52E@draper.com>,
  Tim McDermott <mcdermott@draper.com> wrote:
>
>
> Matthew Heaney wrote:
>
> > Here's is something I whipped up for another post recently.  It's an
> > equality operator for a bounded stack.
> >
> > The implementation of the function has multiple returns.
> >
> > Does this implementation fit your definition of spaghetti code?
> >
> > Would the implementation be better by not using multiple returns?
> >
> > function "=" (L, R : Stack_Type) return Boolean is
> > begin
> >
> >    if L.Top /= R.Top then
> >       return False;
> >    end if;
> >
> >    for Index in Positive range 1 .. L.Top loop
> >       if L.Items (Index) /= R.Items (Index) then
> >          return False;
> >       end if;
> >    end loop;
> >
> >    return True;
> >
> > end "=";
> >
> > My feeling is that trying to implement this operation using only a
> > single return would just make it more complicated.
>
> How about this:
>
>   function "=" (L, R : Stack_Type) return Boolean is
> begin
>
>    Boolean isEqual = True;
>    Positive Index = 1;
>
>    if L.Top /= R.Top then
>       isEqual = False;
>    end if;
>
>    while Index < L.Top && isEqual loop
>       if L.Items (Index) /= R.Items (Index) then
>          isEqual = False;
>       end if;
>       Index++;
>    end loop;
>
>    return isEqual;
>
> end "=";
>
> What Dykstra was getting at with single entance, single exit is that you can
> attempt to reason about the programs that are well structured.  In the
> second version, you can make assertions about pre- and post-conditions.  In
> fact they jump out of the loop test.  That is not the case with the first
> version.
>
> Tim
>
>
Yes, this is a very predictable response, but I MUCH prefer the
original with multiple returns, why? Because when I read

  return False;

I know that is the end of it, and I can immediately verify that
this part of the program is correct, and that the value returned
in this case is what it should be. I can then forget that case
and move to the next one.

If on the other hand I read:

>       isEqual = False;

Then I have to keep this in mind, as I read on, to make sure
some idiot has not added later on a statement like

  if some-weird-hard-to-follow-condition then
     isEqual = True;
  end if;

changing the original value.

and of course I have to keep looking, because someone may
change the value back to False.

Variables are dangerous in themselves, replacing multiple
returns by introducing a variable is in this case jumping
out of the frying pan into the fire!

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Tim McDermott
  1998-08-31  0:00                                             ` Larry Brasfield
  1998-09-01  0:00                                             ` dewar
@ 1998-09-01  0:00                                             ` Matthew Heaney
  2 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


Tim McDermott <mcdermott@draper.com> writes:

> How about this:
> 
>   function "=" (L, R : Stack_Type) return Boolean is
> begin
> 
>    Boolean isEqual = True;
>    Positive Index = 1;
> 
>    if L.Top /= R.Top then
>       isEqual = False;
>    end if;
> 
>    while Index < L.Top && isEqual loop
>       if L.Items (Index) /= R.Items (Index) then
>          isEqual = False;
>       end if;
>       Index++;
>    end loop;
> 
>    return isEqual;
> 
> end "=";
> 
> What Dykstra was getting at with single entance, single exit is that you can
> attempt to reason about the programs that are well structured.  In the
> second version, you can make assertions about pre- and post-conditions.  In
> fact they jump out of the loop test.  That is not the case with the first
> version.

I find that mentally reasoning about the behavior of this program is
more difficult.  

When the first test is finished, I have to do mental work to make sure
that, if isEqual is false, no code gets executed prior to reaching my
destination, which is the end of the subprogram.

This is mental work I wouldn't have to do had I just returned
immediately, knowing that the stack depths were different.












^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
                                                               ` (2 preceding siblings ...)
  1998-09-01  0:00                                             ` Robert I. Eachus
@ 1998-09-01  0:00                                             ` Matthew Heaney
  1998-08-31  0:00                                               ` Robert Martin
  1998-09-01  0:00                                             ` Phil Goodwin
                                                               ` (2 subsequent siblings)
  6 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> >Would the implementation be better by not using multiple returns?
> 
> Yes.  Imagine that you had to change the function to make it thread safe;
> and that the way to do that was to sieze and release a mutex while the
> function was executing.  As written you would have to add the release in
> three separate places.  But if you had avoided the multiple returns, you
> would have had a single release.

Well...  The proper way to use a mutex is to wrap it in a controlled
type, so that release is called automatically as a result of subprogram
exit, no matter what the reason.  (Controlled types in Ada have
operations that are roughly analagous to constructors and deconstructors
in C++.)

Something like:

function "=" (L, R : Stack_Type) return Boolean is

   Lock : Mutex_Lock (Mutex'Access);
begin
   <same body as before>
end "=";

When the Lock object initializes (automatically), it calls the seize
operation of the mutex.

When the Lock object finalizes (automatically, as a result of subprogram
termination - for whatever reason), it calls the release operation of
the mutex.

A subprogram could terminate because there was an unhandled exception,
which is a form of return.  In that case, release wouldn't get called.
(Unless you remembered to include a catch-all handler, to release the
mutex.  But you probably won't remember.)

So I don't buy your thread-safety argument, because the issue you raise
is a problem for any algorithm that requires a mutex, not just an
algorithm implemented using multiple returns.

> bool operator==(Stack& l, Stack& r)
> {
>   bool equal = true;
>   for (int index = 1; index < l.top() && equal == true; index++)
>   {
>     if (l[index] != r[index])
>       equal = false;
>   }
>   return equal;
> }
> 
> If this is more complex (something that is arguable) it is not *much* more
> complex.  

I find that this is indeed more complex.  A decision table for the
predicate has 4 rules instead of just 2.

> On the other hand, it is easier to maintain.  The thread-safety
> issue I talked about above would be easier to add to this function than to
> the one with multiple returns.

I agree with you, but as I pointed out, there are problems with that
implementation too.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Matthew Heaney
                                                             ` (2 preceding siblings ...)
  1998-09-01  0:00                                           ` Loryn Jenkins
@ 1998-09-01  0:00                                           ` Don Harrison
  3 siblings, 0 replies; 510+ messages in thread
From: Don Harrison @ 1998-09-01  0:00 UTC (permalink / raw)


Matthew Heaney wrote (to support the notion of multiple returns):

:Here's is something I whipped up for another post recently.  It's an
:equality operator for a bounded stack.  
:
:The implementation of the function has multiple returns.
:
:Does this implementation fit your definition of spaghetti code?
:
:Would the implementation be better by not using multiple returns?
:
:
:function "=" (L, R : Stack_Type) return Boolean is
:begin
:
:   if L.Top /= R.Top then
:      return False;
:   end if;
:
:   for Index in Positive range 1 .. L.Top loop
:      if L.Items (Index) /= R.Items (Index) then
:         return False;
:      end if;
:   end loop;
:
:   return True;
:
:end "=";
:
:
:My feeling is that trying to implement this operation using only a
:single return would just make it more complicated.

Not really. It's about the same (and the flow of control is clearer IMHO):

function "=" (L, R : Stack_Type) return Boolean is
   Result : Boolean;

begin
   Result := True;

   if L.Top /= R.Top then
      Result := False;
   else
      for Index in Positive range 1 .. L.Top loop
         if L.Items (Index) /= R.Items (Index) then
            Result := False;
            exit;
         end if;
      end loop;
   end if;

   return Result;

end "=";


Don (Harrison).   donh at syd.csa.com.au
Eiffel - Software engineering with class






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                             ` Larry Brasfield
@ 1998-09-01  0:00                                               ` Matthew Heaney
  0 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


"Larry Brasfield" <larry_br@sea_net.com> writes:

> >> Does this implementation fit your definition of spaghetti code?
> 
> Not mine.  Without significant effort, I can translate your code
> into "False if lengths differ, or if an element differs, else True".
> The concept of returning a query result when and where it
> becomes known cannot degrade clarity as I perceive it.

Ah, the voice of reason in a chaotic world.  Thanks for the dose of
pragmatism.

> That said, I find the addition of extra flags just to
> remove an edge from the flow graph to be a
> (slight) hindrance to comprehension.

Me too.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
  1998-08-31  0:00                                             ` Agent
  1998-09-01  0:00                                             ` Phil Goodwin
@ 1998-09-01  0:00                                             ` Matthew Heaney
  1998-10-01  0:00                                             ` Charles H. Sampson
  3 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> >One entry, one exit. Perfectly clear. There's nothing magic about
> >putting the exit statement at the top or the bottom!
> 
> In fact there is.  If the exit condition is at the top or the bottom, then
> the body of the loop will always be excuted an exact integral number of
> times.  However if the loop condition is in the middle, then the loop body
> will be executed a fractional number of times.

I think we're losing site of the forest through the trees.  The
important thing is the postcondition for the loop.  Is the postcondition
satisfied or not?

If the postcondition is satisfied, then what difference does the number
of iterations (fractional or otherwise) make?

Our goal is NOT "execute the loop body an integral number of times."
Our goal IS to satisfy the loop postcondition, in the simplest way
possible.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                       ` Patrick Doyle
  1998-08-31  0:00                                         ` Gene Gajewski
  1998-08-31  0:00                                         ` Richard D Riehle
@ 1998-09-01  0:00                                         ` Matthew Heaney
  2 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-01  0:00 UTC (permalink / raw)


doylep@ecf.toronto.edu (Patrick Doyle) writes:

> Doubles the number of states, compared to what?  The *only* difference
> is that the exit-in-the-middle code has one of the exit conditions
> hidden inside the loop, instead of being stated explicitly at the
> top or bottom.
>
> Exit-in-the-middle is not inherently simpler, as you seem to suggest,
> or else it would be a different algorithm.

Disagree.  

A decision table for the original solution has only 2 rules (columns).

           1  2
Iterating  Y  N
---------------


A decision table for the "improved" solution has 4 rules:

           1  2  3  4
Iterating  Y  Y  N  N
Equal      Y  N  Y  N
---------------------

This is why I say the number of states to consider is doubled by the
addition of a flag into the predicate.  The decision table has twice as
many rules.

So I really would say that the exit-in-the-middle solution is inherently
simpler.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Matthew Heaney
@ 1998-09-01  0:00                                               ` Loryn Jenkins
  1998-09-01  0:00                                                 ` Matthew Heaney
  1998-09-04  0:00                                                 ` Charles Hixson
  1998-09-01  0:00                                               ` dewarr
  1998-09-04  0:00                                               ` Jean-Marc Jezequel
  2 siblings, 2 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-01  0:00 UTC (permalink / raw)


Matthew Heaney wrote:
> 
> Loryn Jenkins <loryn@s054.aone.net.au> writes:
> 
> > How is this more complicated?
> >
> > equal (l,r: LIST): BOOLEAN is
> >       require
> >               l.count = r.count
> >       do
> >               Result := l.first /= r.first
> >               if Result then
> >                       from
> >                               l.start; r.start
> >                       until
> >                               not Result or l.off
> >                       loop
> >                               Result := l.item /= r.item
> >                               l.forth; r.forth
> >                       end
> >               end
> >       end
> 
> There are a few things I don't like about this:
> 
> 1) You have to test a flag every iteration of the loop.  That adds (a
> marginal amount of) inefficiency.

Oh well. I can live with that. (Unless my profiler tells me it is in a
hot spot ... which doesn't happen too often.)

> 2) The loop predicate has 4 possible values.  The original example had
> only 2.

And you had two exit points, and I have one. (Probably because I'm not
familiar with your style) I actually have to work a bit harder than
reading my version.

> 3) There's more nesting.

Sorry, I don't see that. You have one for loop and an if statement. I
have one if statement and a loop. Seems the same amount of nesting to
me.

> So yes, I feel the above implementation is more complex than the
> original implementation that used muliple returns.

Oh well, we'll have to agree to disagree then.

> That's what the check L.Top /= R.Top means: if the number of items is
> different, then you know immediately that the stacks can't be equal.
> When you reach the loop, you know the stack depths are the same.

Ah! For some reason, I thought you were testing the first item on the
stack. So, my amended code, to match your semantics is thus:

 equal (l,r: LIST): BOOLEAN is
       require
               l /= Void and r /= Void
       do
               Result := l.count /= r.count
               if Result then
                       from
                               l.start; r.start
                       until
                               not Result or l.off
                       loop
                               Result := l.item /= r.item
                               l.forth; r.forth
                       end
               end
       end


> The way I look at this problem, is that it's like searching for a
> specific house on an unfamiliar block.  As you're driving, when you find
> the house, you stop immediately and declare success.  You don't have to
> drive to the end of the block, and then say where the house was.

Yeah, yeah. Same here, given the amended code.

Loryn Jenkins

PS: I really would agree with you if the only counter examples were Tim
McDermott's and Jim Cochrane's ones.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                 ` Matthew Heaney
  1998-09-01  0:00                                                   ` James Weirich
@ 1998-09-02  0:00                                                   ` Loryn Jenkins
  1998-09-01  0:00                                                     ` John Volan
                                                                       ` (3 more replies)
  1 sibling, 4 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-02  0:00 UTC (permalink / raw)


Matthew Heaney wrote:
> 
> Loryn Jenkins <loryn@s054.aone.net.au> writes:
> 
> >
> >  equal (l,r: LIST): BOOLEAN is
> >        require
> >                l /= Void and r /= Void
> >        do
> >                Result := l.count /= r.count
> >                if Result then
> >                        from
> >                                l.start; r.start
> >                        until
> >                                not Result or l.off
> >                        loop
> >                                Result := l.item /= r.item
> >                                l.forth; r.forth
> >                        end
> >                end
> >        end
> >
> >
> > > The way I look at this problem, is that it's like searching for a
> > > specific house on an unfamiliar block.  As you're driving, when you find
> > > the house, you stop immediately and declare success.  You don't have to
> > > drive to the end of the block, and then say where the house was.
> >
> > Yeah, yeah. Same here, given the amended code.
> 
> No, no, not the same here.
> 
> If the test l.count /= r.count returns False, then you know immediately
> what the return value of the function is, so why not deliver that
> information right away?  That way you can remove the test of result
> (reducing the level of nesting), and simplify the predicate,
> 
> (By way of analogy, if you've found the house, then you can park in the
> driveway right way, instead of driving to the end of the block to
> announce that you found the house.)
> 
> Let's once again compare the decision tables.  If we re-write the code,
> to put it into Matt-like (because Matt likes it) syntax:
> 
> equal (l,r: LIST): BOOLEAN is
>       require
>               l /= Void and r /= Void
>       do
>               if l.count /= r.count then
>                  return False
>               end
> 
>               from
>                  l.start; r.start
>               until
>                  l.off
>               loop
>                  if l.item /= r.item then
>                     return False
>                  end
> 
>                  l.forth; r.forth
>               end
> 
>               return True
>       end
> 
> This version has only two rules in the decision table for the loop predicate:
> 
>        1  2
> l.off  T  F
> 
> The uncorrected version has four rules:
> 
>             1  2  3  4
> not Result  T  T  F  F
> l.off       T  F  T  F
> 
> The difference in styles is really a debate about the number of edges in
> the flow graph vs the number of rules in the decision table.

That we can agree on. But also note James Weirich's comment:

>Yes, but you are ignoring the fact that there are now two loop exits.
>If you ask the question "When will the loop terminate?", you must
>consider all the exits, including the early return.
>
>So instead of a single, 2 entry table, you have two 2-entry tables.
>Combining them into a single table will produce the same 4 entry table
>as the one you produced for Loryn Jenkins's code.
>
>Seems to me the complexity is about equivalent.

Now, someone else was kind enough to show me an even simpler way of
doing this ... albeit marginally less efficient (and again, I don't care
about this criteria, unless my application beforms below specification
and my profiler shows me that this is a hot spot).

equal (l,r: LIST): BOOLEAN is
      require
          l /= Void and r /= Void
      do
          from
              Result := (l.count = r.count)
              l.start; r.start
          until
              not Result or l.off
          loop
              Result := (l.item = r.item)
              l.forth; r.forth
          end
      end

This, at least, loses your nesting objection. In fact, it has less
nesting than your original example. However, it might mislead unless the
reader was aware of this sort of idiom. (It does simplify things though;
so I think I'll be using this style, where appropriate.)

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                     ` Darren New
@ 1998-09-02  0:00                                                       ` Loryn Jenkins
  1998-09-02  0:00                                                         ` Matthew Heaney
  0 siblings, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-02  0:00 UTC (permalink / raw)


> I think picking the proper names for locals invariably clarifies the
> code, even at the expense of declaring another local. The first time you
> assign to "Result", you're not assigning the "result".
> 
> One of my rules of thumb for clear programming is "have a meaning for
> every variable that is appropriate at every line of the algorithm".
> Otherwise, you're using the same variable for multiple unrelated values.
> Here, it's clear just by looking that you know the stacks are different
> if the counts are different or the items are different, you stop the
> loop as soon as you know the stacks are different, and the result is
> whether you know the stacks are different at the bottom of the loop.
> 
> This is a bit more pendantic than I usually am, but I think it's *very*
> clear, and certainly more clear than embedded returns.

That's a very good point. Thanks for making it.

Obviously, I'm with you: I agree that this is a clearer to comprehend,
easier to maintain style than the embedded returns.

Do you still disagree, Matthew? Given that the complexity is pretty
similar---perhaps with some complexity shifted from the flowgraph to the
decision table---with the resulting complexity being equivalent. And, I
think, all your other points have been addressed by this example ...
excepting the 'performance' issue.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Matthew Heaney
  1998-09-02  0:00                                                       ` Loryn Jenkins
@ 1998-09-02  0:00                                                       ` Tim McDermott
  1998-09-03  0:00                                                         ` Matthew Heaney
  1998-09-03  0:00                                                       ` Joe Gamache
  2 siblings, 1 reply; 510+ messages in thread
From: Tim McDermott @ 1998-09-02  0:00 UTC (permalink / raw)




Matthew Heaney wrote:snip

> The latter point is only a nit.  It's the first point that puts a bee in
> my bonnet.  It may not seem like much in this example, because we're
> "only" going from 2 rules to 4.  But things get scary really fast when
> going 4 to 8.

This seems a little extreme to me.  While I have great respect for
combinatorial explosion, you are talking about a 3-term boolean expression.
There are only 6 ways to put one of those together, and I have no trouble
evaluating any of the forms.  I know because I just listed them all, and ran
through their evaluation with no problem.

> This was my experience trying to decipher someone else's post, in which
> a flag was added to a decision table with 4 rules, doubling the size to
> 8.  I wouldn't have been able to figure things out without using a
> decision table.  (I haven't caught on to K-maps yet, but decision tables
> are my best friend.)

You should exercise your boolean algebra a little more.  DeMorgan's theorem is
more useful to me than truth tables.

> BTW: Treat minimizing nesting levels seriously.  Whereas Miller's limit
> was 7 plus or minus 2, for a linear sequence of items, the limit is even
> lower (around 3) for nested relationships.  (This info I read in
> Structured Design, by Constantine & Yourdon.)

That depends on the nesting relationships.  I find keeping cyclomatic
complexity below 10 is the very best rule of thumb.

Tim





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                 ` Jim Cochrane
@ 1998-09-02  0:00                   ` Richard Melvin
  1998-09-03  0:00                     ` Jim Cochrane
  1998-09-03  0:00                   ` Robert I. Eachus
  1 sibling, 1 reply; 510+ messages in thread
From: Richard Melvin @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6siqo0$hiv@flatland.dimensional.com>, Jim Cochrane
<jtc@dimensional.com> writes
>            from
>                i := 1
>            invariant
>                -- for_all j member_of {1..i - 1} it_holds
>                --   Current @ j = other @ j
>            until
>                i > count or Current @ i /= other @ i
>            loop
>                i := i + 1
>            end
>            check
>                (i - 1 /= count) implies (Current @ i /= other @ i)
>                count = other.count
>            end
>            Result := i - 1 = count

I'm not a fan of this line - if I was to translate it it into english,
it would come out as something like 'which exit path did I take from the
loop?'. In order to work this out, you have to reverse-engineer the
loop.

To me, i is an implementation detail of the loop - referring to it
outside the loop almost seems to break encapsulation.

Perhaps it would work better with more descriptive variable names?
Perhaps numTested and numFoundEqual? 
(Although that makes the -1 problematic).

-- 
Richard Melvin




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` Ell
@ 1998-09-02  0:00                                                   ` Gerry Quinn
  1998-09-02  0:00                                                     ` Robert Martin
       [not found]                                                     ` <6skqf3$ <35F0B5B0.8E2D0166@s054.aone.net.au>
  1 sibling, 2 replies; 510+ messages in thread
From: Gerry Quinn @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6sjijg$36r$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> wrote:
>
>Gerry Quinn wrote in message <6sjbso$1lk$2@news.indigo.ie>...
>
>>I would say rather that [spaghetti] is an objective term, nowadays used
>>incorrectly as a term of abuse by those who do not actually understand
>>the meaning of the word.
>
>
>FYI, here is the entry in the Hacker Jargon Dictionary:
>
>spaghetti code /n./ Code with a complex and tangled control structure, esp.
>one using many GOTOs, exceptions, or other `unstructured' branching
>constructs. Pejorative. The synonym `kangaroo code' has been reported,
>doubtless because such code has so many jumps in it.
>

Seems clear enough.  Single entry and multiple exits is not a 
complex or tangled structure.

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` adam
@ 1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` Mike Spille
                                                                     ` (2 more replies)
  1998-09-06  0:00                                                 ` Charles Hixson
  1 sibling, 3 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



adam@irvine.com wrote in message <6skcr2$i4o$1@nnrp1.dejanews.com>...
>In article <6simjo$jnh$1@hirame.wwa.com>,

>I agree that ease of writing doesn't correlate well with
>maintainability, but ease of reading seems to be a very important
>factor.  I don't see how code can be maintainable if it's not easy to
>understand.

I agree with this.  It's the converse that I don't agree with.

Yes, code must be readable to be maintainable (whatever "readable" means).
On the other hand, code that is readable is not necessarily easy to
maintain.

Simple example: the file 'error.h' is loaded with lots of #defines that
specify all the various error codes that our functions can return.
'error.h' is very easy to read, and completely understandable.  But
maintaining it is a royal pain because every time we add a new error code,
we have to recompile the world.

>For example, it seemed that one of your arguments about why fractional
>loops are worse is that you could add statements to the end of the
>loop and be assured that they would be executed every time.  I don't
>see this.  It seems to imply that a programmer should be able to just
>stick statements at the end of the loop, without understanding what
>the whole loop does, and be assured that they will be executed every
>time (how could this argument possibly make sense if the programmer
>fully understands the loop's control structure?).

Think about this for a minute.  Wouldn't it be nice if you *could* stick a
line of code at the end of every loop, or at the end of every function, and
be guaranteed that it would be called?  For example, have you every had to
put those interesting little print statements into functions:  "entering
function x", "exitting function x"?  Wouldn't it be nice if you could just
plop those print statement in without having to anlayze each and every
function for multiple returns?

(Yes, I know we can use RAI for this.  But lets pretend that we are writing
in Java, or C)

>But my experience
>is that if I try to add code to the end of a loop without completely
>understanding what's going on, I'm just as likely to add bad code to a
>loop without multiple exits than to a loop with them.  I think this
>argues that ease of reading is, in essence, the most important
>criteria, since it can't be separated from maintainability.

Yes, I agree with this, but only in part.  Sometimes you really don't have
to completely understand a function in order to make the necessary
modifications.  In those cases, if an se/se style has been adopted, it's a
lot eaiser to understand the control flow and insert the appropriate
statements.
>
>Finally, a lot of people on this thread have tried to explain why they
>find multiple exits easier to read and understand, but you seem to be
>implying that they're doing this just to justify writing code that's
>easier to *write*.  I don't see this at all, and I think it's an
>unwarranted insult.

No insult intended.  However, the "easier to write" justification has been
used in several postings.



Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                               ` Robert Martin
  1998-09-01  0:00                                                 ` Gerhard Menzl
@ 1998-09-02  0:00                                                 ` Tres Seaver
  1998-09-02  0:00                                                   ` Robert Martin
  1998-09-03  0:00                                                   ` Patrick Logan
  1 sibling, 2 replies; 510+ messages in thread
From: Tres Seaver @ 1998-09-02  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Matthew Heaney wrote in message ...
> >"Robert Martin" <rmartin@oma.com> writes:
> >
> >> >Would the implementation be better by not using multiple returns?
> >>
> >> Yes.  Imagine that you had to change the function to make it thread safe;
> >> and that the way to do that was to sieze and release a mutex while the
> >> function was executing.  As written you would have to add the release in
> >> three separate places.  But if you had avoided the multiple returns, you
> >> would have had a single release.
> >
> >Well...  The proper way to use a mutex is to wrap it in a controlled
> >type, so that release is called automatically as a result of subprogram
> >exit, no matter what the reason.  (Controlled types in Ada have
> >operations that are roughly analagous to constructors and deconstructors
> >in C++.)
> 
> In a language that supports such things, using controlled types is *a* way
> (not necessarily the "proper" way).  (it happens to be the way that I choose
> in many cases).  But this has nothing really to do with the issue at hand.
> Yes, it may be feasible to put some resource management code into a
> controlled type and avoid the issues of maintenance that I raised earlier;
> but that doesn't eliminate the problem of structure.  In the end, if you can
> make the structure of the software solve a problem, that is better than
> using a special language feature to do it.

I find it interesting to read all the "single entry / exit" argument in light of
the prolifieration of exception-based mechanisms.  Exceptions have all of the
disadvantages of multiple returns, with the added problem of invisibility. 
Adjusting one's style to remain robust in the face of exceptions automagically
makes for robustness in the presence of multiple returns, it would seem to me.

-- 
Tres Seaver                tseaver@palladion.com
Palladion Software         http://www.palladion.com
Houston, Texas, USA        Vox:  (713) 523-6582




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <6shunm$47g$1@hirame.wwa.com>
@ 1998-09-02  0:00             ` David E. Wallace
  0 siblings, 0 replies; 510+ messages in thread
From: David E. Wallace @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6shunm$47g$1@hirame.wwa.com>,
Robert Martin <rmartin@oma.com> wrote:
>This is, in fact, a characteristic of any good OO design that conforms to
>the Open/Closed principle.  New featuers are added by adding new code; not
>by changing old working code.
 
>Nevertheless, functions sometimes do change; and when they do its nice to
>have the structured so as to facilitate those changes.

But your argument against multiple exits was that even if they save
effort in initial development, they cost you effort during the
maintenance phase when you have to change the function to allocate and
deallocate a resource.  If such changes are rare, then the amount of effort
saved during such maintenance has to be huge in order to justify the
tradeoff.

In particular, let's assume that the amount of effort saved per routine
in initial development by using multiple exits is X.  If 10% of the
routines are subsequently modified in maintenance, and 10% of the changes
involve adding an allocate/deallocate action that crosses these multiple
exit points (very generous estimates in my opinion), and the average
routine that is modified is modified 5 times during the course
of maintenance, then the effort saved per allocation action added needs to
be X/((.1)(.1)(5)) = 20X in order to break even.  That calculation doesn't
even take the time value of effort into account - a resource saved
today is worth more than the same resource saved in the future,
both because of the time value of money, and also because many new projects
never make it into a significant maintenance phase, in which case any future
savings projected are non-existent.  So even with these very generous
assumptions, you need to save substantially more than 20 times the
effort in order to make the tradeoff worthwhile.

If instead we assume that only 1% of the routines are modified, and only 5%
of the changes involve adding such spanning allocates, then the
maintenance effort saved needs to be X/((.01)(.05)(5)) = 400X, not
counting the time value of effort.  Such a large effort would never
be justified (IMO) - if it really cost that much, you would simply rewrite
the offending routine instead of modifying it.

Note that the only allocate/deallocate pairs that are complicated
by the presence of multiple exits are those where (1): an early exit
occurs between the time of allocation and deallocation, and (2): the exit
transfers control to a point subsequent to the deallocation.
Early returns from a function prior to the initial allocation are
not a problem, nor are break/continue style exits from a loop
if the loop is contained within the allocate/deallocate span.
So only a fraction of the allocate/deallocate additions will encounter
problems with multiple exits.  I can live with some contortions
in those cases in order to simplify the initial development.
-- 
Dave Wallace		(wallace@netcom.com)
It is quite humbling to realize that the storage occupied by the longest
line from a typical Usenet posting is sufficient to provide a state space
so vast that all the computation power in the world can not conquer it.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00               ` Patrick Logan
@ 1998-09-02  0:00                 ` Patrick Doyle
  1998-09-02  0:00                   ` Robert Martin
  1998-09-03  0:00                   ` Patrick Logan
  0 siblings, 2 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-02  0:00 UTC (permalink / raw)


In article <NshH1.6521$f01.4705828@news.teleport.com>,
Patrick Logan  <plogan@user2.teleport.com> wrote:
>In comp.object Patrick Doyle <doylep@ecf.toronto.edu> wrote:
>
>: By this logic, polymorphism is indeterminate too.  When you call a
>: polymorphic function, you have no idea where control will
>: wind up.  This is a Good Thing.  It's what makes polymorphism
>: powerful: the fact that you're giving someone else some control
>: over the situation makes your code flexible.
>
>These are apples and oranges. Why the comparison?

Merely to point out that not knowing the distination of a transfer
of control does not make for a strong argument against exceptions.
If it did, it should apply to polymorphism too.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Ell
  1998-09-02  0:00                                                 ` Rick Smith
@ 1998-09-02  0:00                                                 ` Patrick Doyle
  1998-09-02  0:00                                                 ` adam
  1998-09-02  0:00                                                 ` Robert Martin
  3 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-02  0:00 UTC (permalink / raw)


In article <35eeea9b.2174586@news.erols.com>, Ell <ell@access.digex.net> wrote:
>
>You have not shown at all that "single entry, single exit" is a
>general coding maxim of structured programming. 

So what do you think structured programming is?

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` john-clonts
  1998-09-02  0:00                                                   ` Robert Martin
@ 1998-09-02  0:00                                                   ` Darren New
  1 sibling, 0 replies; 510+ messages in thread
From: Darren New @ 1998-09-02  0:00 UTC (permalink / raw)


john-clonts@hlp.com wrote:
> Doesn't subroutine1() here qualify as having a single entrance/exit
> *regardless* how many "return" statements happen to be coded within it?

Yes, but if there's two return statements inside Subroutine1, then at
least one structure will have multiple exits. (Or you have a wad of dead
code after the return.)

I.e., if S1 is
bool subroutine1() {
  yadda;
  hither;
  if (test) {
    yon;
    return true;
    }
  gabba;
  return false;
}

then the "if" has two exits.

-- 
Darren New / Senior Software Architect / First Virtual Holdings Inc
http://www.fv.com or info@fv.com -=|=- PGP Key: ftp://ftp.fv.com/pub/fv
Fingerprint: 61 7D AF 9E 00 CC C2 ED / D8 4C D7 AA E4 C2 A0 73




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Robert Oliver
@ 1998-09-02  0:00                                                     ` Robert Martin
  1998-09-03  0:00                                                       ` sureshvv
  1998-09-06  0:00                                                       ` Charles Hixson
  1998-09-03  0:00                                                     ` Ell
  1 sibling, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Robert Oliver wrote in message <35EDAC92.538A@hfl.tc.faa.gov>...

>
>I am not arguing against all use of multiple returns in a procedure or
>function.  I often write a function like this:
>
>void AFunction(...)
>{
>  if (SomeCondition) return;
>  if (AnotherCondition) return;
>  if (AThirdCondition) return;
>
>  // now do the real work...
>
>  return;
>}
>
>I think this makes sense when AFunction is called from many places and
>the
>conditions need to be tested each time.  I can look at the beginning of
>the
>function and know that there will be nothing done in these three
>circumstances.
>It's not without danger as RCM has pointed out, but I often choose to
>live
>with the risk.

*Deciding* to live with the risk is perfectly legitimate.  There is no way
to eliminate all risk.  Thus we must choose the risks we live with.  But it
is important that the risks be understood.
>
>Of course, it could also be written as:
>
>void AFunction(...)
>{
>  if not (SomeCondition)    and
>     not (AnotherCondition) and
>     not (AThirdCondition)  then
>
>  // now do the real work...
>
>  endif
>  return;
>}


Which is usually how I would choose to write it.  (Active voice instead of
passive voice. ;^)


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` john-clonts
@ 1998-09-02  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                   ` Darren New
  1 sibling, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



john-clonts@hlp.com wrote in message <6sken3$jv0$1@nnrp1.dejanews.com>...
>In article <35ED7082.1889@hfl.tc.faa.gov>,

>But wait:
>
>...
>  statementA;
>  statementB;
>  subroutine1();
>  statementC;
>
>Doesn't subroutine1() here qualify as having a single entrance/exit
>*regardless* how many "return" statements happen to be coded within it?


The caller can be "structured" since he sees only one entry and one exit.
But the function itself is not "structured".


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                 ` Patrick Doyle
@ 1998-09-02  0:00                   ` Robert Martin
  1998-09-03  0:00                   ` Patrick Logan
  1 sibling, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Patrick Doyle wrote in message ...
>In article <NshH1.6521$f01.4705828@news.teleport.com>,
>Patrick Logan  <plogan@user2.teleport.com> wrote:
>>In comp.object Patrick Doyle <doylep@ecf.toronto.edu> wrote:
>>
>>: By this logic, polymorphism is indeterminate too.  When you call a
>>: polymorphic function, you have no idea where control will
>>: wind up.  This is a Good Thing.  It's what makes polymorphism
>>: powerful: the fact that you're giving someone else some control
>>: over the situation makes your code flexible.
>>
>>These are apples and oranges. Why the comparison?
>
>Merely to point out that not knowing the distination of a transfer
>of control does not make for a strong argument against exceptions.
>If it did, it should apply to polymorphism too.


Did you think I was arguing *against* using exceptions?  I wasn't.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Tres Seaver
@ 1998-09-02  0:00                                                   ` Robert Martin
  1998-09-03  0:00                                                     ` sureshvv
  1998-09-03  0:00                                                   ` Patrick Logan
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Tres Seaver wrote in message <35EDB334.B65F7D81@palladion.com>...

>
>I find it interesting to read all the "single entry / exit" argument in
light of
>the prolifieration of exception-based mechanisms.  Exceptions have all of
the
>disadvantages of multiple returns, with the added problem of invisibility.
>Adjusting one's style to remain robust in the face of exceptions
automagically
>makes for robustness in the presence of multiple returns, it would seem to
me.
>


Exceptions are extraordinary.  By the time you throw an exception, things
have gone very wrong.  Yes, there is some cleanup you may need to do.  But
there is also quite a bit that you can probably ignore.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Gerry Quinn
@ 1998-09-02  0:00                                                     ` Robert Martin
  1998-09-03  0:00                                                       ` Ell
  1998-09-03  0:00                                                       ` sureshvv
       [not found]                                                     ` <6skqf3$ <35F0B5B0.8E2D0166@s054.aone.net.au>
  1 sibling, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Gerry Quinn wrote in message <6skhcm$1dr$2@news.indigo.ie>...
>In article <6sjijg$36r$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com>
wrote:
>>
>>Gerry Quinn wrote in message <6sjbso$1lk$2@news.indigo.ie>...
>>
>>>I would say rather that [spaghetti] is an objective term, nowadays used
>>>incorrectly as a term of abuse by those who do not actually understand
>>>the meaning of the word.
>>
>>
>>FYI, here is the entry in the Hacker Jargon Dictionary:
>>
>>spaghetti code /n./ Code with a complex and tangled control structure,
esp.
>>one using many GOTOs, exceptions, or other `unstructured' branching
>>constructs. Pejorative. The synonym `kangaroo code' has been reported,
>>doubtless because such code has so many jumps in it.
>>
>
>Seems clear enough.  Single entry and multiple exits is not a
>complex or tangled structure.


Nor did I say it was.  I simply said that it carries certain risks.

====================================================================

I have found the enthusiasm for this thread quite interesting; but also a
bit disquieting.  Structured Programming is one of the foundational elements
of software engineering.  Knowledge of the benefits and costs of
single-entry/single-exit functions should be firmly ingrained in all
software engineers.

In this thread I have not demanded that everyone *must* use se/se, nor have
I accused anyone of writing spaghetti, nor have I said that people who use
multiple exits are wrong to do so.  What I have done is discuss and
demonstrate some of the risks of multiple exits, and some of the benefits of
se/se.  I have pointed out that "readability" is not the only concern, and
that the simplest modules are not always the most maintainable.

And yet the reactions have ranged from: "the benefits of se/se don't really
exist" to "se/se is not a fundemental part of structured programming".  I
find these reactions puzzling, at best.

Are tree structures OK?  The word OK has no meaning in this context.  They
have a benefit, and they have a cost, and in some situations the cost and
benefit will work out such that there is a net gain.

Is it OK to write code with multiple exits?  In some cases, yes; in others,
no.  The important thing is not whether a technique is "good" or "bad", the
important thing is to understand the costs and benefits of a technique.
Engineering is the ability to make trade-offs.  To make those decisions, we
must know what we are trading off for what.  We cannot rely on simple maxims
like "readability is best", or "never use gotos", or "only do the minimum",
or "never use multiple exits".  We have to be more intelligent than that.
We have to be engineers.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
@ 1998-09-02  0:00                                                   ` Mike Spille
  1998-09-03  0:00                                                   ` Richard MacDonald
  1998-09-03  0:00                                                   ` Gerry Quinn
  2 siblings, 0 replies; 510+ messages in thread
From: Mike Spille @ 1998-09-02  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> adam@irvine.com wrote in message <6skcr2$i4o$1@nnrp1.dejanews.com>...
> >In article <6simjo$jnh$1@hirame.wwa.com>,
> 
> >I agree that ease of writing doesn't correlate well with
> >maintainability, but ease of reading seems to be a very important
> >factor.  I don't see how code can be maintainable if it's not easy to
> >understand.
> 
> I agree with this.  It's the converse that I don't agree with.
> 
> Yes, code must be readable to be maintainable (whatever "readable" means).
> On the other hand, code that is readable is not necessarily easy to
> maintain.
> 
> Simple example: the file 'error.h' is loaded with lots of #defines that
> specify all the various error codes that our functions can return.
> 'error.h' is very easy to read, and completely understandable.  But
> maintaining it is a royal pain because every time we add a new error code,
> we have to recompile the world.
> 

An interesting branch from a loop discussion :-)

> >For example, it seemed that one of your arguments about why fractional
> >loops are worse is that you could add statements to the end of the
> >loop and be assured that they would be executed every time.  I don't
> >see this.  It seems to imply that a programmer should be able to just
> >stick statements at the end of the loop, without understanding what
> >the whole loop does, and be assured that they will be executed every
> >time (how could this argument possibly make sense if the programmer
> >fully understands the loop's control structure?).
> 
> Think about this for a minute.  Wouldn't it be nice if you *could* stick a
> line of code at the end of every loop, or at the end of every function, and
> be guaranteed that it would be called?  For example, have you every had to
> put those interesting little print statements into functions:  "entering
> function x", "exitting function x"?  Wouldn't it be nice if you could just
> plop those print statement in without having to anlayze each and every
> function for multiple returns?
> 
> (Yes, I know we can use RAI for this.  But lets pretend that we are writing
> in Java, or C)
> 

As an aside...most hideous language proposals I've seen begin with
"Wouldn't it be nice if....".   The best proposals begin with "I have
a strong need for....".  I think there is a certain correlation to
your above statement....

That said, I'll re-iterate what myself and others have said: your
implication is that people should be able to muck with a function
without understanding it (e.g. syntactical constructs are enough
to tell the tale, and semantics beside the point).  I strongly
disagree - most of the maintenance goofs I've seen haven't come
about due to multiple loop exits or "badly structured code" (whatever
that may be) - it's been due to maintenance programmers not taking
the time to understand the code.

> >But my experience
> >is that if I try to add code to the end of a loop without completely
> >understanding what's going on, I'm just as likely to add bad code to a
> >loop without multiple exits than to a loop with them.  I think this
> >argues that ease of reading is, in essence, the most important
> >criteria, since it can't be separated from maintainability.
> 
> Yes, I agree with this, but only in part.  Sometimes you really don't have
> to completely understand a function in order to make the necessary
> modifications.  In those cases, if an se/se style has been adopted, it's a
> lot eaiser to understand the control flow and insert the appropriate
> statements.

Please don't take this as a personal attack, but I hope you never,
ever touch any of my code.  I would horse-whip any of my guys who
"really don't completely understand a function" and made a modification
to it.

> >
> >Finally, a lot of people on this thread have tried to explain why they
> >find multiple exits easier to read and understand, but you seem to be
> >implying that they're doing this just to justify writing code that's
> >easier to *write*.  I don't see this at all, and I think it's an
> >unwarranted insult.
> 
> No insult intended.  However, the "easier to write" justification has been
> used in several postings.
> 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

	-Mike




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                         ` Richard Melvin
@ 1998-09-02  0:00                                                           ` Tim Ottinger
  0 siblings, 0 replies; 510+ messages in thread
From: Tim Ottinger @ 1998-09-02  0:00 UTC (permalink / raw)


Richard Melvin wrote:
> This seems a weak argument, as there can easily be no way whatsoever to
> put things back the way they were - the most obvious example is a sort
> function.
> 
> (Unless you copy the initial state of the array before sorting, which
> can be done just as easily in a little stack-based transaction object.)

Actually, did you see the C++ Report articles on exception-safe
containers? This is exactly what had to be done... 

Yeah, we suddenly have to be aware of unit of work all through
our apps. We have to be able to commit or rollback at just about
any time, and ensure the commit is atomic fairly often. As if
software weren't hard enough... but it's kind of like doing
accounting. If you know that the transactions balance, then they
are very unlikely to throw the ledger off-balance when you post
them (not that you stop checking).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                       ` Ell
@ 1998-09-02  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                           ` Joe Gwinn
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Ell wrote in message ...

>If you had quotes showing that "single entry single exit" was supposed to
>be a key maxim of the structured paradigm you would quote it.  At lesast
>you should.

Elliott, if Dijkstra had provided a nice one liner, I'd be glad to give it
to you.  And, after all, maybe he did and I just haven't found it.  So what?
The chapter is only a few pages long, the book is certain to be available at
a nearby library or bookstore, so look it up.

>Because all you've shown is Flowcahrt 101, that of course a flowchart
>should have only one entry and one exit point on the *page*!

I have no idea how you could have drawn that interpretation.  First, I've
never heard of such a convention. Second, it has nothing to do with the
discussion in the cited chapter.   The chapter is about structuring the flow
of control.  Dijkstra is making the point that unrestricted flow of control
(i.e. goto) is harmful.  He then shows four flowcharts that demonstrate the
cannonical forms of flow control in structured programming.  They are,
sequence, decision, top exit iteration, and bottom exit iteration.  He then
goes on to recommend that all software be constructed of assemblages of
these four control forms; and nothing but these four control forms.  He then
describes the four forms as having a single entry and a single exit.

I strongly recommend that before you respond further to this thread, you
read Dijkstra's material.

>I've taken 4 formally named "Structured COBOL" courses so I've already
>done my homework.

Twenty-three years ago I was *teaching* "Structured COBOL" courses.
Fortunately, we are not discussing the contents of structured COBOL courses.
We are discussing the contents of Dijkstra's book "Structured Programming".
If your courses failed to teach you about single-entry/single-exit, then I
suggest you ask for your money back, because you got reamed.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                         ` Robert Martin
                                                             ` (2 preceding siblings ...)
  1998-09-02  0:00                                           ` mfinney
@ 1998-09-02  0:00                                           ` Gene Gajewski
  3 siblings, 0 replies; 510+ messages in thread
From: Gene Gajewski @ 1998-09-02  0:00 UTC (permalink / raw)


Robert Martin wrote in message <6sh3qn$9p2$1@hirame.wwa.com>...

<snip>

>However, multiple exits to a single destination represent a problem.  The
>two exits come from two different states within the algorithm.  If the
>single destination must do some work that depends upon that state (or if in
>the future, that single destination must be modified to do work that
depends
>upon that state), then the code in the single destination is going to get
>pretty ugly.


This statement could be true if computers were not the discontinous machines
they are. Code is not executed all at once, hence  'state' is a fact of
life. The existance of the exit itself is proof that the coder of the
algorithm has considered state as a factor and has determined that it is
'safe to exit'.

A maintainer of code knows intuititvely that any states he introduces
affects all code following it. There is no choice but to encapsulate the
existing code. If a particular function is written with a single exit point,
it will be easy to encapsulate simply by making changes before and after the
loop. No examination of the contents of the loop appear to be necessary.
However, the procedures and actions performed by the function are no longer
the same, the computer not being absolute at all times, some may say that
the function is not the same.

My preference is to avoid modifying a function that is correct. If
additional functionality is needed within a program, than the program needs
modification, not the function. It would be better to create a new function
containing the new state which than calls the original function - all for
what will be a new program. A modified program is new in the essence it is
not the same program, although it may appear identical from the outside.

This may not seem acceptable to some, especially if the function to be
modified is referenced in many places. On the other hand, a function so
often refrenced should be simple in design. A gross change in functionality
would indicate a poor original analysis, IMO. This is the sort of particular
problem that can be solved administratively.












^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                 ` Patrick Logan
@ 1998-09-02  0:00                   ` Robert Martin
  1998-09-04  0:00                     ` Patrick Logan
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Patrick Logan wrote in message ...
>In comp.object Robert Martin <rmartin@oma.com> wrote:
>
>: But there is a difference.  With polymorphism, though you may not know
what
>: function is actually being called, you do know that it will return to
you.
>: Thus, there is a postcondition that you can depend upon.   But once you
>: throw an exception, there is very little you can say about what happens
>: next.
>
>But you (the method developer whose method is throwing an exception)
>don't care what happens next. You only care that your method has held
>up its end of the bargain.


Agreed.

I think we are lost.

My initial point was that exceptions violate se/se structures, but we accept
that because they are extraordinary means of control transfer.   Exceptions,
due to their extraordinary character, provide a benefit that outweighs the
cost of losing the se/se structure.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Patrick Logan
@ 1998-09-02  0:00                                                   ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1084 bytes --]


Patrick Logan wrote in message ...
>In comp.object Mattias Lundstr�m <ehsmalu@ehpt.com> wrote:
>
>: Note also that in the case of Java this kind of resource
>: cleanup may not be satisfactory since we can not know when
>: the finalization (cleanup) is actually done.
>
>In Java you should always explicitly handle resource deallocation for
>all resources that are in any way "precious". Use...
>
>  try {} finally { deallocation }
>
>to ensure that deallocation will occur no later than the exit of the
>"try" body.


And, in C++, because destructors are not in the scope of the try block, I
prefer:

   try {...; cleanup();} catch(...){cleanup(); throw;}

Rather than trying to use destructors as a general solution.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` dennison
@ 1998-09-02  0:00                                                   ` Dan Higdon
  1998-09-02  0:00                                                   ` Matthew Heaney
  2 siblings, 0 replies; 510+ messages in thread
From: Dan Higdon @ 1998-09-02  0:00 UTC (permalink / raw)


Robert Martin wrote in message <6sjk3p$4tc$1@hirame.wwa.com>...
>Consider:
>
>   do {
>      Get(N);
>      if (N)
>        <process N>
>   } while (N);
>
>Structured programming allows the loop condition to be either at the top or
>the bottom.

You just rolled the loop around - you're still testing the condition twice,
you just
made the *test* redundant.  Having a single entry/exit point is good.
Forcing
the exit point to the top or bottom of the construct is artificial, IMHO.
There are
many cases (and this is a particularly good one) where the test to exit does
not naturally occur at either the top or bottom of the loop, but midway
through it.

As an aside, a valid (IMHO) Eiffel extension would be to allow loops a
little more freedom (yeah, I know, "everyone's a language designer" :-):

-- standard
from <init> until <test> loop
    <statements>
end

-- post test
from <init> loop
    <statements>
until <test> end

-- in test
from <init> loop
    <statements>
until <test> else
    <statements>
end

Ignoring {in}variants for simplicity.  (I suppose {in}variants would need to
hold
true at the "until".)

so, our example becomes
from
    <init>
loop
    Get (N)
until
    not N
else
    <process N>
end

----------------------------------------
hdan@charybdis.com
"Throwing fire at the sun"






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Ell
@ 1998-09-02  0:00                                                     ` Robert Martin
  1998-09-02  0:00                                                       ` Ell
                                                                         ` (2 more replies)
  1998-09-02  0:00                                                     ` Robert Martin
       [not found]                                                     ` <6sjnlu$83l$1@hirame.wwa.c <35EE5F67.80D@gecm.com>
  2 siblings, 3 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Ell wrote in message <35f055a5.1431187@news.erols.com>...
>On Wed, 2 Sep 1998 08:52:36 -0500, "Robert Martin" <rmartin@oma.com>
>wrote:
>
>>
>>Ell wrote in message <35eeea9b.2174586@news.erols.com>...
>>>
>>>You have not shown at all that "single entry, single exit" is a
>>>general coding maxim of structured programming.
>
>>Well, that's your opinion.
>
>It's a *fact*!

You are entitled to that opinion.

>
>>But I have cited the section of Dijkstra's book
>>"Structured Programming" that talks about this;
>>and have quoted the page where it is elaborated;
>
>That single fragment of a sentence, or at most single sentence, about
>*flowcharting* in no way made the case that *coding* in the structured
>paradigm should generally adhere to "single entry and single exit".

The point of the citing, and the quotation, was to guide you to read it for
yourself.  I'm not going to reproduce two or three pages of text for your
benfit.  The cited section is very unambiguous in its recommendation of
single-entry and single-exit.  The section was not about *flowcharting*,
rather it used four different generic flowcharts (all with single entry and
single exit) to describe the fundemental building blocks of structured
programming.

Elliott, you really ought to read the book.  I've given you enough pointers.
Do your homework.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Ell
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-02  0:00                                                     ` Robert Martin
  1998-09-02  0:00                                                       ` Ell
       [not found]                                                     ` <6sjnlu$83l$1@hirame.wwa.c <35EE5F67.80D@gecm.com>
  2 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Ell wrote in message <35f055a5.1431187@news.erols.com>...
>
>You are being ultra disengenuous to support your fantasies about
>structured programming.


HITLER!

(Thread over, I lose...)


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Ell
@ 1998-09-02  0:00                                               ` Robert Oliver
  1998-09-02  0:00                                                 ` Ell
                                                                   ` (2 more replies)
  1998-09-05  0:00                                               ` Ray Gardner
       [not found]                                               ` <m31zpq4pim.fsf@mheaney.ni.ne <m3af36wtwh.fsf@mheaney.ni.net>
  2 siblings, 3 replies; 510+ messages in thread
From: Robert Oliver @ 1998-09-02  0:00 UTC (permalink / raw)


Ell wrote:

> The assertion that "single entry, single exit" is a required, or even
> desirable, maxim of structured programming is a myth.
> 
> No one (including RCM) can show that this maxim is in fact a coding
> heuristic put forward by any of the founders of the structured
> paradigm. [Check past posts in this thread.]

Edward Yourdan, in his book Techniques of Program Structure and Design
discusses this article:

C. Bohm and G. Jacopini, "Flow Diagrams, Turing Machines, and Languages
with Only two Formation Rules", Communications of the ACM, May 1996, 
pages 366-371.

(Is this not *the* foundational article for structured programming?)

Yourdan says:

"According to Bohm and Jacopini, we need three basic building blocks in
order to construct a program:

	1. A process box.
	2. A generalized loop mechanism.
	3. A binary-decision mechanism.

The process box, shown in Fig. 4.1, may be thought of as a single
computational statement (or machine language instruction) *or as any
other proper conputational sequence with only one entry and one exit* -
such as a subtoutine."

The emphasis between *...* above is his (shown in italics) not mine.

In the next paragraph he says:

"Note that the constructs shown in Fig. 4.2(a) and 4.2(b) {the decision
and
loop control structures} can themselves be thought of as a process box 
since they have only one entry and one exit.  Thus we can define a
transformation from a looping operation to a process box ..."

I added the part between braces {}.

I do not have the Bohm and Jacopini article.  All I have is Yourdans
description of it.

However, it seems clear from his description that the "single entry -
single exit" principle is fundamental to structured programming. 
Yourdan
goes on to discuss some practical implementations such as various loop
constructs and the case statement.  During this discussion, he uses the
"single entry - single exit" principle repeatedly and refers to it as
part of the "black-box principle".

Bob Oliver




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Biju Thomas
@ 1998-09-02  0:00                                                 ` Phil Goodwin
  1998-09-02  0:00                                                   ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Phil Goodwin @ 1998-09-02  0:00 UTC (permalink / raw)


In article <35EC937F.94420C51@ibm.net>,
  bijuthom@ibm.net wrote:
> Phil Goodwin wrote:
> >
> > I write plenty of little routines that have loops in them that exit in the
> > middle. It doesn't make sense to me to alter the algorithm and write extra
> > code just so that the routine might be easier to maintain someday (if ever).
> > On the other hand, when I DO maintain such a routine I definitely WILL make
> > sure that there is only one exit point if that's what is needed to eliminate
> > duplicate code.
> >
> > I adopted this position in part because of some of what I've read about
> > Extreme Programming. I haven't adopted it wholesale, but I do like their
> > no-nonsense philosophy. They use two balancing maxims that I've applied to
> > this question: Do The Simpest Thing That Could Possibly Work; and Once And
> > Only Once. So when I write a function I do the simplest thing that could
> > possibly work, which sometimes means sticking a return right smack in the
> > middle of a loop. I am especially likely to do this when the loop body is
> > less than five lines long anyway. Then, when I have to refactor in order to
> > add the aquisistion and release of some resource, I rearrange the routine so
> > that I add the code once and only once. The justification for this is that I
> > don't want to adopt a coding task because it _might_ be needed during
> > maintenance, I would rather do it during maintenance when I KNOW that it
> > needs to be done.
>
> The problem with such refactoring during maintenance is that it may
> introduce new problems, and you need to do extensive testing to make
> sure that you haven't broken anything. Often, this type of extensive
> testing may not be feasible at all during maintenance, because of budget
> and time constraints. This type of attitude may explain why new releases
> of software (which are supposed to do bug fixing too) introduce more
> bugs than the original version.

I would posit that if you are changing the function at all you must do a
complete regression test on it. I grant you that the more you change the
routine the more likely you are to introduce bugs and that is an important
consideration. However, what we are doing here is deffering the risk of
creating a more complicated algorithm to the point in time where we know that
the risk is worthwhile. The only other option is to assume that the risk will
always turn out to be worthwhile and code the more complicated algorithm in
every case. Since we know that we aren't going to reap the benefit of the
complicated algorithm in every case we can surmise that we have done too much
work.

My position is not that strict structured programming has no benefit, it is
that it has a cost and that the cost is not justified unless the benefit is
recieved. The strategy I outlined is designed to defer the cost until the
benefit reaches its highest value.

Phil

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Robert Oliver
@ 1998-09-02  0:00                                                 ` Ell
  1998-09-02  0:00                                                   ` Robert Oliver
  1998-09-02  0:00                                                 ` Matthew Heaney
  1998-09-02  0:00                                                 ` john-clonts
  2 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Robert Oliver <oliverb@hfl.tc.faa.gov> wrote:
: Ell wrote:

:> The assertion that "single entry, single exit" is a required, or even
:> desirable, maxim of structured programming is a myth.
:> 
:> No one (including RCM) can show that this maxim is in fact a coding
:> heuristic put forward by any of the founders of the structured
:> paradigm. [Check past posts in this thread.]

: Edward Yourdan, in his book Techniques of Program Structure and Design
: discusses this article:

: C. Bohm and G. Jacopini, "Flow Diagrams, Turing Machines, and Languages
: with Only two Formation Rules", Communications of the ACM, May 1996, 
: pages 366-371.

: (Is this not *the* foundational article for structured programming?)

How can an artile written in '96 be *the* foundational article for
the structured programming paradigm which gained currency in the late
'70's?

: Yourdan says:

: "According to Bohm and Jacopini, we need three basic building blocks in
: order to construct a program:

: 	1. A process box.
: 	2. A generalized loop mechanism.
: 	3. A binary-decision mechanism.

: The process box, shown in Fig. 4.1, may be thought of as a single
: computational statement (or machine language instruction) *or as any
: other proper conputational sequence with only one entry and one exit* -
: such as a subtoutine."

Where is the proof that this underlays the structured paradigm and an
assertion that something is "proper" doesn't make it so. What structured
programming avoided was unstructured flow control. It encouraged the use
of procedure/routine calls over 'goto'.  Along with entry into a procedure
via a call, the use of 'return' is structured flow control; 'return' can
only go back to the calling procedure, unlike 'goto' which can branch to a
label anywhere. 

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-02  0:00                                                       ` Ell
  1998-09-02  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                       ` Malcolm Steel
       [not found]                                                       ` <o1fH1.543$495.1 <gwinn-0309982042490001@d8.dial-4.cmb.ma.ultra.net>
  2 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: Ell wrote in message <35f055a5.1431187@news.erols.com>...
:>On Wed, 2 Sep 1998 08:52:36 -0500, "Robert Martin" <rmartin@oma.com>
:>wrote:
:>
:>>
:>>Ell wrote in message <35eeea9b.2174586@news.erols.com>...
:>>>
:>>>You have not shown at all that "single entry, single exit" is a
:>>>general coding maxim of structured programming.
:>
:>>Well, that's your opinion.
:>
:>It's a *fact*!

: You are entitled to that opinion.

:>
:>>But I have cited the section of Dijkstra's book
:>>"Structured Programming" that talks about this;
:>>and have quoted the page where it is elaborated;
:>
:>That single fragment of a sentence, or at most single sentence, about
:>*flowcharting* in no way made the case that *coding* in the structured
:>paradigm should generally adhere to "single entry and single exit".

: The point of the citing, and the quotation, was to guide you to read it for
: yourself.  I'm not going to reproduce two or three pages of text for your
: benfit.  The cited section is very unambiguous in its recommendation of
: single-entry and single-exit.  The section was not about *flowcharting*,
: rather it used four different generic flowcharts (all with single entry and
: single exit) to describe the fundemental building blocks of structured
: programming.

: Elliott, you really ought to read the book.  I've given you enough pointers.
: Do your homework.

If you had quotes showing that "single entry single exit" was supposed to
be a key maxim of the structured paradigm you would quote it.  At lesast
you should.  

Because all you've shown is Flowcahrt 101, that of course a flowchart
should have only one entry and one exit point on the *page*! 

I've taken 4 formally named "Structured COBOL" courses so I've already
done my homework.  It's your assertion which is groundless fanatasy.

Rules about laying out flowcharts on page, as some kind of proof about the
nature of structured *coding*.  Indeed!  Gives us a darn break would 'ya?! 

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-02  0:00                                                       ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: Ell wrote in message <35f055a5.1431187@news.erols.com>...
:>
:>You are being ultra disengenuous to support your fantasies about
:>structured programming.


: HITLER!

: (Thread over, I lose...)

"HITLERITE!" is the unnecessary pain adhering to your fantasy dogma would
cause us. 

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` dennison
  1998-09-02  0:00                                                   ` Dan Higdon
@ 1998-09-02  0:00                                                   ` Matthew Heaney
  1998-09-02  0:00                                                     ` Robert Martin
  1998-09-02  0:00                                                     ` Patrick Logan
  2 siblings, 2 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-02  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> >So it's the structured approach which causes the redundancy, becuase Get
> >must be called twice.
> 
> Consider:
> 
>    do {
>       Get(N);
>       if (N)
>         <process N>
>    } while (N);
> 
> Structured programming allows the loop condition to be either at the top or
> the bottom.

The thing I dislike about the above code fragment is that N gets tested
twice.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Robert Martin
@ 1998-09-02  0:00                                               ` Phil Goodwin
  1998-09-02  0:00                                               ` adam
                                                                 ` (5 subsequent siblings)
  6 siblings, 0 replies; 510+ messages in thread
From: Phil Goodwin @ 1998-09-02  0:00 UTC (permalink / raw)


Comments interspersed...

In article <6simjo$jnh$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> mfinney@lynchburg.net wrote in message ...
>
> >And, as far as maintainability is concerned, I strictly use tree-structured
> >programming and have *never* found it to be a maintenance problem.
> >Sure, sometimes code transformations are required during maintenance,
> >but they are sometimes required during coding.  So what?  There is no
> >way to write code that never requires code transformations during
> >maintenance, and trying to do so just makes the code harder to
> >understand and ultimately increases maintenance cost.  Far better is
> >to endevour to reach 0 bugs so that maintenance is never required.
> >Not easy, perhaps, but it is getting closer and closer every day.  I
> >personally am running somewhere around 0.0001 and 0.0002 errors
> >per line of code --  prior to quality assurance getting the code.

Mike, I wish I'd written this...

> Reaching zero bugs may not have that big an impact on maintenance, since
> much of maintenance has to do with changes to the requirements.

Granted.

> In any case, I note that in this thread nearly every article that advocates
> multiple exits evokes either readability, complexity, or naturalness as the
> justification.  I contend that these are highly subjective things, that are
> not shared by all programmers alike.  Indeed, what is readable, natural and
> simple to me, may be opaque and convoluted to you.  I also contend that
> these issues are somewhat emotional, as evidenced by the terms such as
> "twist", "warp", "bend", "religious argument", etc. that have also been used
> in this thread.

Emotional arguments have been made on both sides. It is unfortunate since it
obfuscates the discussion. I suggest that from here on out we eschew
obfuscation.

> Finally, I contend that the factors in favor of using a
> single-entry/single-exit style are, on the other hand, quite concrete and
> demonstrable.  It has been shown that adhering to a structured style
> facilitates both resource management and error processing.   It has also
> been shown that a multiple exit style is vulnerable to redundant code, and
> code for recovery of state.

It has also been shown that in some circumstances SE/SE can introduce
redundant code and that it also requires code for maintenance of state. In
general these problems are less pronounced with SE/SE and most often the
benefits outweigh the costs. Sometimes, however, it's really best to do
what's easiest until you run into a compelling reason not to.

> So, it seems what we have here is "gut feelings" warring against empirical
> data.  I can understand why the gut reaction is so strong; multiple exits
> are *eaiser* to write; and are, for some, easier to read.  But those are not
> the only, or even the most important, criteria for evaluating the quality of
> a design.  Maintainability is an issue too, and sometimes an overriding one.

I think that you're overstating the case. It only makes sense to design code
to be amenable to a particular kind of change if there is some reason to
think that changes of that kind will actually occur.

> In the end, the decision to use a structured style is a tradeoff.  There are
> benefits, and there are costs.  And there are certainly situations in which
> the costs outweight the benefits (e.g. quick an dirty programs that have
> short lifetimes and require little maintenance during their life).  It is
> also true, however, that for a very large set of circumstances, the benefits
> outweigh the costs.

Now, that I agree with, wholeheartedly. I just want to avoid incurring a cost
for a benifit that I will never actually use.

Phil

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                         ` Richard D Riehle
  1998-09-01  0:00                                           ` Simon Wright
@ 1998-09-02  0:00                                           ` adam
  1 sibling, 0 replies; 510+ messages in thread
From: adam @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6set0b$oa@sjx-ixn3.ix.netcom.com>,
  Richard D Riehle <laoXhai@ix.netcom.com> wrote:

> The talk about spaghetti code is colorful but unproductive.  By this
> analogy, perhaps we should call the modular code, "ravioli code."
> Now we have this little plate of raviolis, each representing a software
> module.  Oh, and then we could thread them together with one long strand of
> spaghetti. Yes, I do know what that implies.

Actually, I like this metaphor.  Ravoili has all this good stuff hidden
inside the pasta where you can't see it, which fits nicely with the "black
box" theory of programming, in which the parts of the program outside the
module can see just the parts of the module that it needs to see, i.e. the
pasta part, while it doesn't have to know anything about the inside part
except that it tastes good when you bite into it.

However, there aren't any holes in ravioli, which makes it hard to thread
them together with spaghetti.  Therefore, I'd like to suggest an alternative
metaphor, mostaccioli code, which I think also fits nicely.  Mostaccioli
comes in nice firm parts, so that it can't wind up all around itself the way
spaghetti code can.  Also, mostaccioli has one entry hole and one exit hole,
suggesting the desirability of writing code with a single entry point and a
single exit point, as well as providing a way for a lot of mostaccioli to be
strung together on a piece of spaghetti (although I have never tried to cook
it this way). Macaroni also has one entry hole and one exit hole, but
mostaccioli is nice and straight, suggesting straightforward code that's easy
to understand, while macaroni tends to be bent, except for those little salad
macaroni things, which might be a good metaphor for a very short one-line
procedure.

My motivation here is, of course, to make sure all the other forms of pasta
don't feel left out of the discussion.	I'm working on figuring out
appropriate meanings for "rotelle code", "lasagne code", and "farfalle code",
and will follow up when I figure out something good.  But I have to quit now,
because I'm hungry.

				-- Adam

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                           ` mfinney
  1998-09-02  0:00                                             ` Ell
  1998-09-02  0:00                                             ` Ell
@ 1998-09-02  0:00                                             ` john-clonts
  1998-09-03  0:00                                               ` mfinney
  1998-09-02  0:00                                             ` Robert Martin
  3 siblings, 1 reply; 510+ messages in thread
From: john-clonts @ 1998-09-02  0:00 UTC (permalink / raw)


In article <Oi4H1.219$qj1.315418@newsread.com>,
  mfinney@lynchburg.net wrote:
> In <6sh3qn$9p2$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> writes:
>
> >However, multiple exits to a single destination represent a problem.  The
> >two exits come from two different states within the algorithm.  If the
> >single destination must do some work that depends upon that state (or if in
> >the future, that single destination must be modified to do work that depends
> >upon that state), then the code in the single destination is going to get
> >pretty ugly.
>
> I have been following this thread for a while (or at least part of the
thread),
> and it seems to me that the basic argument is between the use of structured
> programming which requires a single entry and single exit and of tree-
> structured programming which allows multiple-level breaks/continues, but
> not arbitrary jumps into blocks.
>
> It turns out that tree-structured programming covers almost all of the flow
> graphs actually encountered by compilers which are not undecomposable
> and provides the necessary flow graph assurances for optimization (I do
> have a reference on that, but have just finished moving and everything
> is in boxes, so regrettably I can't provide it at this time).  Multiple exits
>
> [snip]
>
> Michael Lee Finney
>
>

What do you mean by 'tree-structured' programming?  A simple example perhaps?

THanks,
John

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` Robert Martin
@ 1998-09-02  0:00                                                     ` Richard MacDonald (dogmat)
  1998-09-03  0:00                                                       ` Matthew Heaney
  1998-09-02  0:00                                                     ` Richard Melvin
                                                                       ` (4 subsequent siblings)
  5 siblings, 1 reply; 510+ messages in thread
From: Richard MacDonald (dogmat) @ 1998-09-02  0:00 UTC (permalink / raw)


Robert Martin wrote in message <6siijm$h1m$1@hirame.wwa.com>...

>Lets just say, for grins, that I must make a change to the loop.  For some
>odd reason I must count the number of times that the loop body completes.
>Where do I put the code that does this counting?  I'd like to make it the
>last line of the loop.  But if there are early exits, then I must find each
>and every early exit and add the code just before they exit.
>
>Of course, later, someone else will make a change that forces yet another
>early exit.  They find where to add the early exit, but they must remember
>to bump the counter before they exit.

Solved by putting the counter at the start of the loop. That seems to be the
"right" place to put it, surely.

>Of course later on, someone asks us to sieze and release a mutex for each
>iteration of the loop.  We'd like to put the seize as the first line of the
>loop body, and the release as the last line of the loop body.  But if there
>are early exits, then we must put a release before every exit.
>
>Of course later on someone adds yet another early exit to the loop, and
must
>remember to bump the counter and release the mutex.
>
Better example. However, my solution for this would be to have a simple loop
with three lines: (1) Seize the mutex. (2) Call a subroutine to do whatever
(with one entry and one or more exits). (3) Release the mutex.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                       ` Robert Martin
  1998-09-02  0:00                                                         ` Richard Melvin
@ 1998-09-02  0:00                                                         ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-02  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> >So no, you don't have to worry about bailing out early.  There is no
> >maintenance penalty for an early return from the loop.
> 
> This is true if:
> 
> 1. Your language has controlled types.

Agreed.  But C++ does have the equivalent of Ada95 controlled types.

It may be that you have a philosophical problem with using
deconstructors for dealing with resource management issues that can be
handled via traditional techniques - like a single point of exit from a
loop.  

Fair enough.  But I argue that in a language with exception propagation,
you're going to have to be thinking about resource management anyway,
even if you're not writing a loop.

So I think the resource management argument is a bit of a red herring.

> 2. The cleanup that needs to be done can be done from the finalizer.   For
> example, in C++ the equivalent scheme is to use a destructor.  However the
> destructor is in a completely different scope.  So extraordinary means may
> need to be used to allow the destructor access to the variables that need
> finalization.
> 
> Consider the case of a complex data structure.  You are in the midst of
> changing a set of variables within it.  Suddenly you realize that you must
> exit early.  Before you can exit, you have to put the data structure back
> the way it was.  In C++, getting a destructor to do this can be horrific.

I don't see this as a hard problem.  Let the object cache the new
settings until a Commit operation is invoked.  If you bail out early,
then Commit doesn't get called, and the data structure retains its
original value.

> Btw, in essense a controlled type is simply a way to enforce that a scope
> has a single exit.  By using single-entry/single-exit style, *all* your
> variables are controlled -- albeit manually.  (excluding exceptions).

But resource management in the presence of exceptions is precisely my
point.  Your parenthetical disclaimer is a little like saying, "All
objects can levitate.  (excluding gravitation)."





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Robert Oliver
  1998-09-02  0:00                                                 ` Ell
@ 1998-09-02  0:00                                                 ` Matthew Heaney
  1998-09-02  0:00                                                 ` john-clonts
  2 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-02  0:00 UTC (permalink / raw)


Robert Oliver <oliverb@hfl.tc.faa.gov> writes:

> Edward Yourdan, in his book Techniques of Program Structure and Design
> discusses this article:
> 
> C. Bohm and G. Jacopini, "Flow Diagrams, Turing Machines, and Languages
> with Only two Formation Rules", Communications of the ACM, May 1996, 
> pages 366-371.

The year was 1966.
 
> (Is this not *the* foundational article for structured programming?)

Be aware that Bohm and Jacopini showed only what the minimal set of
control flow primitive are.  But don't take this to mean that those
are the only control flow statements you should use.  

Control flow constructs in a language should be chosen for their
expressive power.  What's the most natural way to do the iteration for a
certain class of problems?

Ed Yourdon edited a pair of books that have all the major papers on the
goto issue, including those by George Miller, Bohm & Jacopini, and
Knuth.

Classics in Software Engineering
Writings of the Revolution




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <m3zpck79xp.fsf@mheaney.ni.net>
@ 1998-09-02  0:00             ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-02  0:00 UTC (permalink / raw)


In article <m3zpck79xp.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>
>Loryn Jenkins <loryn@s054.aone.net.au> writes:
>
>>  equal (l,r: LIST): BOOLEAN is
>>        require
>>                l /= Void and r /= Void
>>        do
>>                Result := l.count /= r.count
>>                if Result then
>>                        from
>>                                l.start; r.start
>>                        until
>>                                not Result or l.off
>>                        loop
>>                                Result := l.item /= r.item
>>                                l.forth; r.forth
>>                        end
>>                end
>>        end
>
> [...]
>
>No, no, not the same here.
>
>If the test l.count /= r.count returns False, then you know immediately
>what the return value of the function is, so why not deliver that
>information right away?  That way you can remove the test of result
>(reducing the level of nesting), and simplify the predicate,

No, if the test returns False then the *computer* knows immediately
what the return value of the function is.  But remember that it's
the reader of the code that is important; he's the one that must
know what's going on.

I can tell by the line "until not Result or l.off" that either we'll
go the the end of the loop or else we'll quit early if Result becomes
false.  I don't have to mentally single-step the code to find that
out; it's right there in the "until" clause.

>(By way of analogy, if you've found the house, then you can park in the
>driveway right way, instead of driving to the end of the block to
>announce that you found the house.)

Right, this would be the best idea if, in the analogy, the programmer
were the driver.  However, it's the computer that's the driver here.
The programmer is the one who told the driver to find the house.
(At this point, the analogy becomes strained beyond all recognition... :-)

>Let's once again compare the decision tables.  If we re-write the code,
>to put it into Matt-like (because Matt likes it) syntax:
>
>
>equal (l,r: LIST): BOOLEAN is
>      require
>              l /= Void and r /= Void
>      do
>              if l.count /= r.count then
>                 return False
>              end
>              
>              from
>                 l.start; r.start
>              until
>                 l.off
>              loop
>                 if l.item /= r.item then
>                    return False
>                 end
>
>                 l.forth; r.forth
>              end
>
>              return True
>      end
>
>
>This version has only two rules in the decision table for the loop predicate:
>
>       1  2
>l.off  T  F

Right, so you've just made it really easy for the computer to execute
the loop.  But now I have to mentally single-step the entire body
of the function to understand it.  Particularly, I have to read
every line in the loop body to understand what conditions will hold
upon loop/routine termination.  In Loryn's version, this information
appears in one place, so it's much easier to verify that the loop
does what it's supposed to do.  After all, the whole point of a
loop like this one is to cause certain conditions to hold when
the loop terminates, right?

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Ell
  1998-09-02  0:00                                                 ` Rick Smith
  1998-09-02  0:00                                                 ` Patrick Doyle
@ 1998-09-02  0:00                                                 ` adam
  1998-09-02  0:00                                                 ` Robert Martin
  3 siblings, 0 replies; 510+ messages in thread
From: adam @ 1998-09-02  0:00 UTC (permalink / raw)


In article <35eeea9b.2174586@news.erols.com>,
  ell@access.digex.net wrote:
>
> This may be true, though I don't thinks so, but adherence to the dogma
> you made up about "single entry and single exit" doesn't make things
> clearer as most see it in this case.

This is not a comment about whether "single entry and single exit" is
desirable or not, but . . . the theory about single-entry and single-exit is
something I've heard about since the early 1980's or so, which was *long*
before I ever heard of Robert Martin.  So I seriously doubt this is something
he "made up".

				-- Adam

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Robert Martin
@ 1998-09-02  0:00                                                 ` sureshvv
  1998-09-02  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                   ` Robert Martin
  0 siblings, 2 replies; 510+ messages in thread
From: sureshvv @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6shhcq$lid$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> sureshvv@hotmail.com wrote in message <6sh6ic$o8p$1@nnrp1.dejanews.com>...
>
> >1. Early returns aid in limiting the amount of code that has to be
> processed
> >and understood.
>
> I disagree.  It only limits the amount of code to read for one particular
> iteration of the loop.  But to understand the loop you have to read it all.
> >

I do not think that number of iterations a loop makes is of primary importance
while examining an unfamiliar piece of code. In the example we have been
discussing, the early return indicates that if the stacks are of different
length the stacks are different and examining the items in the stack is
unnecessary. This logic is immediately apparent with the early return
than with the flags that you added in order to conform to the se/se principle.

> >2. Understandability is the most important criterion for maintainability.
>
> I disagree again.  An easily modifiable structure is much more important
> than understandability.  *Any* structure built by a human can be understood
> by most other humans.  Once understood, the work is over.  But a structure
> that is hard to maintain, remains hard to maintain until you redesign it.

Maintenance is redesign. It is more important that your methods be small and
focussed enough that they can be rewritten relatively quickly in the face of
new requirements than being harder to read (with various flags to help
conform to the single entry-exit principle) just so they give you space to
squeeze in some new code.

> There are many structures that are easy to understand but hard to maintain.

But maintain against what kind of changes? Your examples were all about using
some resource that needs to be finalized, and will be properly handled by
using the Resource acquisition is initialization (RAI, to be Ellesque) idiom.

> >Making the code as simple as possible in order to solve the problem at hand
> >is more important than trying to make it easier to change against some
> >imaginary future changes.
>
> I disagree one last time.  Two digit dates are much easier to deal with than
> four digit dates.  Until the century changes...

Y2K, the last resort of usenet arguments. INMO, 2 digit dates were
an engineering tradeoff, that made sense when they were written
just like 4 digit dates do now (which will break after the year 9999).


> The engineer who does not
> design for maintainability, is doing a disservice to himself, his fellow
> engineers, and his employer.

More bs. The argument is if using flags to conform to the se/se principle,
makes the code more maintainable.

The engineer who spends his time making his code more complex to protect
against a certain kind of changes (which are better handled using techniques,
such as Resource acquisition is initialization) is wasting the time of his
fellow engineers and the resources of his employer.

suresh

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Matthew Heaney
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-02  0:00                                                     ` Patrick Logan
  1998-09-03  0:00                                                       ` Matthew Heaney
  1998-09-03  0:00                                                       ` Ole-Hjalmar Kristensen
  1 sibling, 2 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Matthew Heaney <matthew_heaney@acm.org> wrote:
: "Robert Martin" <rmartin@oma.com> writes:

: > >So it's the structured approach which causes the redundancy, becuase Get
: > >must be called twice.
: > 
: > Consider:
: > 
: >    do {
: >       Get(N);
: >       if (N)
: >         <process N>
: >    } while (N);
: > 
: > Structured programming allows the loop condition to be either at the top or
: > the bottom.

: The thing I dislike about the above code fragment is that N gets tested
: twice.

If you memoize the result of the first test, then the second test is
about as fast as can be...

  boolean test;
  ...
  do {
    ...
    test = N;
    if (test)
      ...
  } while (test);

This does not add a new state to a decision table. It provides a
mnemonic for the test condition. The redundant test is minimal
compared to the other work in the loop, not to mention the rest of the
application. If you are writing small methods anyway, then it is very
clear what is occurring.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <6sjms6$7c4$1@hirame.wwa.com>
@ 1998-09-02  0:00             ` Patrick Doyle
  1998-09-02  0:00               ` Patrick Logan
                                 ` (3 more replies)
  0 siblings, 4 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6sjms6$7c4$1@hirame.wwa.com>,
Robert Martin <rmartin@oma.com> wrote:
>
>1. They are indeterminate.  When you throw an exception, you have no idea
>where control will wind up.  It is not simply an exit from the current
>scope, or even from the current function.

By this logic, polymorphism is indeterminate too.  When you call a
polymorphic function, you have no idea where control will
wind up.  This is a Good Thing.  It's what makes polymorphism
powerful: the fact that you're giving someone else some control
over the situation makes your code flexible.

The same holds for exceptions.

Having said that, I just used an exception for the first time
yesterday.  I (almost) never use them, and I don't even know
why.  But the nondeterminism isn't it.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Jim Cochrane
@ 1998-09-02  0:00                                                 ` Richard Melvin
  1998-09-02  0:00                                                   ` Jim Cochrane
  0 siblings, 1 reply; 510+ messages in thread
From: Richard Melvin @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6silt4$gb0@flatland.dimensional.com>, Jim Cochrane
<jtc@dimensional.com> writes
>
>It appears that this routine has an implied pre-condition:
>l.size() == r.size()
>
snip..
>
>I think, more appropriately, it argues for the "Document routine
>pre/post-conditions (as well as use assertions as documentation of
>program state, where appropriate)" camp.

I hardly think so, given that this was a comparison operator for a stack
- a stack, pretty much by definition, is variable-length (perhaps with a
fixed maximum length, but that's not relevant).

Just throwing in extra preconditions to cover bugs in the implementation
is not my interpretation of design-by-contract.

Otherwise I can revolutionise the world of fast sort algorithms:

void 
sortInLinearTime(Vector & v)
{
        PRE (v.length() < 2);
        return;
}

(assuming PRE is counted as an externally-documented precondition, not
an assertion).
-- 
Richard Melvin




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Rick Smith
@ 1998-09-02  0:00                                                   ` Robert I. Eachus
  1998-09-02  0:00                                                     ` Patrick Logan
  0 siblings, 1 reply; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-02  0:00 UTC (permalink / raw)


In article <VFaH1.226$I%.386253@news1.atlantic.net> "Rick Smith" <ricksmith@aiservices.com> writes:

 > Edward Yourdon, "Techniques of Program Structure and Design",
 > Prentice-Hall, 1975, pg 145.

 > "In order to test the entire program...  This in turn strongly
 >  suggests that each submodule should be
 >  designed with a single entry point and a single exit; in turn, the entire
 >  program can be described as a set of nested modules, each of which
 >  has one entry and one exit."
    ...
 > " 1. Procedure calls, subroutine calls, function invocation -- any legal
 > call to a closed subroutine with one entry and one exit. ...

    Nice quotes, but you have to understand them.  In the sense of
these quotes it is not possible to have multiple entries or exits to
subroutines in most modern languages.  The multiple exits in this
sense are what you get with longjumps in C--the subroutine returns to
a place other than the one it was called from.  The multiple entries
were common in PL/I, where depending on the name in the call you would
enter the same code at different points.  Typical in fact was to have
multiple profiles where the procedure had three or four different
parameter profiles, and you called the correct one for the parameters
you wanted to supply.

    All subprograms in most modern languages are closed subroutines in
the sense of this quote--they have a single entry, and the returns all
go to the same place.  (Absent exceptions, Unix signals, and the like.)

   To put it more bluntly, "You young whipersnappers have no idea what
programming was like in the old days.  The languages we used had no
concept of a subroutine, we had to simulate it with gotos.  And some
idiots would write subroutines that didn't return to the place they
were called from.  Made debugging almost impossible, I tell you."

   Seriously, at the time that Yourdon wrote those words, there were
languages that had call stacks and closed subroutines, but a lot of
code was still written in versions of Fortran and Cobol where
reentrant subroutines were not supported.  In really was a very
different world back then.  In fact significantly more than half of
the new code that year was written in assembler of one form or
another, but mostly for the IBM 360.  The most modern language use
(extensively) in this country was PL/I, and that allowed multiple
entry, multiple exit subroutines.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00             ` Patrick Doyle
@ 1998-09-02  0:00               ` Patrick Logan
  1998-09-02  0:00                 ` Patrick Doyle
  1998-09-02  0:00               ` Robert Martin
                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 510+ messages in thread
From: Patrick Logan @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Patrick Doyle <doylep@ecf.toronto.edu> wrote:

: By this logic, polymorphism is indeterminate too.  When you call a
: polymorphic function, you have no idea where control will
: wind up.  This is a Good Thing.  It's what makes polymorphism
: powerful: the fact that you're giving someone else some control
: over the situation makes your code flexible.

These are apples and oranges. Why the comparison?

If your method performs polymorphic message sends to multiple objects,
there is a contract each object has to uphold.

If your method throws an exception, there is a contract it has to
uphold, but beyond that, its work is done. There is a contract the
caller has to uphold, but that is of no concern to your method. You're
done.

If your method has allocated some resources and your method throws an
exception, your method has to put those resources into whatever state
is specified by your contract. If your method has specified no
contract about those resources, then it does not have to do anything
in particular with them. Common sense may dictate that they be
deallocated so the state of the world is as much like the state of the
world before your method was called.

But if commons sense dictates this, then I would argue so should your
method's contract, explicitly!

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Robert I. Eachus
@ 1998-09-02  0:00                                                     ` Patrick Logan
  1998-09-03  0:00                                                       ` Robert I. Eachus
  0 siblings, 1 reply; 510+ messages in thread
From: Patrick Logan @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Robert I. Eachus <eachus@spectre.mitre.org> wrote:

:     Nice quotes, but you have to understand them.  In the sense of
: these quotes it is not possible to have multiple entries or exits to
: subroutines in most modern languages.  The multiple exits in this
: sense are what you get with longjumps in C--the subroutine returns to
: a place other than the one it was called from.  

The C, C++, Java, Smalltalk, and Common Lisp languages all allow a
form of a "return" statement to appear anywhere within a block of
statements. Some of these languages have a form of GOTO that allow
multiple exits from loops. I would think these languages make up "most
modern languages".

: The multiple entries were common in PL/I, where depending on the
: name in the call you would enter the same code at different points.
: Typical in fact was to have multiple profiles where the procedure
: had three or four different parameter profiles, and you called the
: correct one for the parameters you wanted to supply.

I remember some FORTRAN code to do printed circuit board layout
implementing all of its loops using GOTOs. Some of these loops had
GOTOs at the top that jumped into the middle of the "loop"!

:     All subprograms in most modern languages are closed subroutines in
: the sense of this quote--they have a single entry, and the returns all
: go to the same place.  (Absent exceptions, Unix signals, and the like.)

This may or may not be the case. I'd have to read the entire text to
judge for myself. In any case, I'd say the principle applies to
subroutine exits as well as loop entrances and exits.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                     ` Richard MacDonald (dogmat)
@ 1998-09-02  0:00                                                     ` Richard Melvin
  1998-09-02  0:00                                                     ` dennison
                                                                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 510+ messages in thread
From: Richard Melvin @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6siijm$h1m$1@hirame.wwa.com>, Robert Martin
<rmartin@oma.com> writes
>
>Lets just say, for grins, that I must make a change to the loop.  For some
>odd reason I must count the number of times that the loop body completes.

I'm sorry, this really is an invalid argument. 
Any change case must be based on functionality, not on the existing
structure of the code.

Otherwise I can blow any of your dependency management principles out of
the water with a change case carefully designed to cause maximum pain
and distress (e.g. 'all Visitors must be re-written to be case
statements').

You wouldn't really agree that the above proved case statements were
better, would you?

Just because you're the only one using change-case based arguments,
doesn't mean you're the only one thinking about design for
maintainability.

It'd be interesting to do a proper change-case comparison.
I guess that would need a set of 5 or 6 reasonable, functionality-based
changes to a function written in 'pure-structured' and 'tree-structured'
styles. 
Changes that require restructuring count against, changes made correctly
first time count for.
As a control, you could throw in a true spaghetti implementation - if
the analysis didn't show this was worse, then there's something wrong
with the analysis.

As a starter, try extending a fixed-length array comparison function to
be a stack comparison :-) 

-- 
Richard Melvin




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Robert Oliver
  1998-09-02  0:00                                                 ` Ell
  1998-09-02  0:00                                                 ` Matthew Heaney
@ 1998-09-02  0:00                                                 ` john-clonts
  1998-09-02  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                   ` Darren New
  2 siblings, 2 replies; 510+ messages in thread
From: john-clonts @ 1998-09-02  0:00 UTC (permalink / raw)


In article <35ED7082.1889@hfl.tc.faa.gov>,
  Robert Oliver <oliverb@hfl.tc.faa.gov> wrote:
> Ell wrote:
>
> > The assertion that "single entry, single exit" is a required, or even
> > desirable, maxim of structured programming is a myth.
> >
> > No one (including RCM) can show that this maxim is in fact a coding
> > heuristic put forward by any of the founders of the structured
> > paradigm. [Check past posts in this thread.]
>
> Edward Yourdan, in his book Techniques of Program Structure and Design
> discusses this article:
>
> C. Bohm and G. Jacopini, "Flow Diagrams, Turing Machines, and Languages
> with Only two Formation Rules", Communications of the ACM, May 1996,
> pages 366-371.
>
> (Is this not *the* foundational article for structured programming?)
>
> Yourdan says:
>
> "According to Bohm and Jacopini, we need three basic building blocks in
> order to construct a program:
>
> 	1. A process box.
> 	2. A generalized loop mechanism.
> 	3. A binary-decision mechanism.
>
> The process box, shown in Fig. 4.1, may be thought of as a single
> computational statement (or machine language instruction) *or as any
> other proper conputational sequence with only one entry and one exit* -
> such as a subtoutine."
>
> The emphasis between *...* above is his (shown in italics) not mine.
>
> In the next paragraph he says:
>
> "Note that the constructs shown in Fig. 4.2(a) and 4.2(b) {the decision
> and
> loop control structures} can themselves be thought of as a process box
> since they have only one entry and one exit.  Thus we can define a
> transformation from a looping operation to a process box ..."
>
> I added the part between braces {}.
>
> I do not have the Bohm and Jacopini article.  All I have is Yourdans
> description of it.
>
> However, it seems clear from his description that the "single entry -
> single exit" principle is fundamental to structured programming.
> Yourdan
> goes on to discuss some practical implementations such as various loop
> constructs and the case statement.  During this discussion, he uses the
> "single entry - single exit" principle repeatedly and refers to it as
> part of the "black-box principle".
>
> Bob Oliver
>

But wait:

...
  statementA;
  statementB;
  subroutine1();
  statementC;

Doesn't subroutine1() here qualify as having a single entrance/exit
*regardless* how many "return" statements happen to be coded within it?

Or does it even bear upon the discussion?

John

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Robert Martin
  1998-09-02  0:00                                               ` Phil Goodwin
  1998-09-02  0:00                                               ` adam
@ 1998-09-02  0:00                                               ` adam
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-06  0:00                                                 ` Charles Hixson
  1998-09-02  0:00                                               ` Matthew Heaney
                                                                 ` (3 subsequent siblings)
  6 siblings, 2 replies; 510+ messages in thread
From: adam @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6simjo$jnh$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:

> In any case, I note that in this thread nearly every article that advocates
> multiple exits evokes either readability, complexity, or naturalness as the
> justification.  I contend that these are highly subjective things, that are
> not shared by all programmers alike.  Indeed, what is readable, natural and
> simple to me, may be opaque and convoluted to you.  I also contend that
> these issues are somewhat emotional, as evidenced by the terms such as
> "twist", "warp", "bend", "religious argument", etc. that have also been used
> in this thread.
>
> Finally, I contend that the factors in favor of using a
> single-entry/single-exit style are, on the other hand, quite concrete and
> demonstrable.  It has been shown that adhering to a structured style
> facilitates both resource management and error processing.   It has also
> been shown that a multiple exit style is vulnerable to redundant code, and
> code for recovery of state.
>
> So, it seems what we have here is "gut feelings" warring against empirical
> data.

I agree with the first quoted paragraph, but I wonder about the
"empirical data" part.  So far, on this thread, I haven't seen any
empirical data at all, aside from the one study Matthew quoted.
Instead, I've seen lots of theories and explanations for why style X
is better than style Y.  Some have sounded pretty logical, and others
seem to have no connection to reality.  Even so, all of them seem to
be little more than speculation.  Someone might say, "Putting all the
predicate information at the top of the loop leads to better code",
but where's the empirical evidence that this is the case?  I mean, we
could come up with all sorts of logic about why doing this should be
better, but without some sort of study, our logic is based on
assumptions about what *seems* like it should be more maintainable,
assumptions that may or may not hold water.

At best, these assumptions may reflect the poster's personal
experience; but since not everyone thinks the same way, an assertion
based on someone's experience may not be all that useful.  One person
may find code style X easier to deal with than Y, but another might
find X to be more difficult.  I've noticed this in some of the short
examples posted, where one person posts something they think is quite
clear, but I've had to stare at it for a long time to figure out what
the code was supposed to do.  This may be because all of us
programmers have had difference experiences working with different
kinds of code, so that a programming idiom that one programmer is
intimately familiar with may take some effort for a different
programmer to figure out.  Anyway, as someone who has been pounding
keyboards for 20+ years, I've had a lot of experience at noticing what
kinds of coding techniques lead to more or fewer problems later when I
try to maintain my code, and what techniques in other peoples'
programs make them easier or more difficult to work with; still, I
wouldn't call my own conclusions more than "gut feelings".  Certainly,
I haven't come close to the standards required to ensure that my
conclusions are controlled for other factors, free from personal bias,
etc., that would enable me to call my experiences "empirical data".

At worst, the assumptions behind arguments for style X or Y are based
on abstract ideas that we have no reason to believe has any actual
correlation with maintainability.  This was my original complaint
about some of the arguments against GOTO, but it applies equally to
the other arguments about "multiple exits", "continue" statements,
etc.  Some of these arguments strike me as someone struggling to come
up with reasoning that supports a viewpoint that they believe in but
don't have clear logical reasons for---i.e. a viewpoint they have no
more than a gut feeling about.  It's no wonder some of us look at
these arguments as "religious wars".

So, rather than gut feelings warring against empirical data, the whole
thread appears to me to be gut feelings warring against other gut
feelings.


> I can understand why the gut reaction is so strong; multiple exits
> are *eaiser* to write; and are, for some, easier to read.  But those are not
> the only, or even the most important, criteria for evaluating the quality of
> a design.  Maintainability is an issue too, and sometimes an overriding one.

I agree that ease of writing doesn't correlate well with
maintainability, but ease of reading seems to be a very important
factor.  I don't see how code can be maintainable if it's not easy to
understand.  If it's relatively difficult for someone to understand
what's going on, it has to be relatively easier (it seems to me) to
modify the code in a way that screws things up.

For example, it seemed that one of your arguments about why fractional
loops are worse is that you could add statements to the end of the
loop and be assured that they would be executed every time.  I don't
see this.  It seems to imply that a programmer should be able to just
stick statements at the end of the loop, without understanding what
the whole loop does, and be assured that they will be executed every
time (how could this argument possibly make sense if the programmer
fully understands the loop's control structure?).  But my experience
is that if I try to add code to the end of a loop without completely
understanding what's going on, I'm just as likely to add bad code to a
loop without multiple exits than to a loop with them.  I think this
argues that ease of reading is, in essence, the most important
criteria, since it can't be separated from maintainability.

Finally, a lot of people on this thread have tried to explain why they
find multiple exits easier to read and understand, but you seem to be
implying that they're doing this just to justify writing code that's
easier to *write*.  I don't see this at all, and I think it's an
unwarranted insult.


> In the end, the decision to use a structured style is a tradeoff.  There are
> benefits, and there are costs.  And there are certainly situations in which
> the costs outweight the benefits (e.g. quick an dirty programs that have
> short lifetimes and require little maintenance during their life).  It is
> also true, however, that for a very large set of circumstances, the benefits
> outweigh the costs.

I agree, as long as "structured style" is loosely defined.  Code that
has any structure at all is easier to read than code that doesn't.
And sometimes it's faster and easier to write unstructured or
carelessly-structured code, but this should be avoided when possible.
My own feeling is that once a programmer makes readability a priority,
and follows certain general principles we can all agree with (e.g.
break the code down into relatively small segments that have a clearly
defined purpose, and use comments), the programmer will write code
that's more maintainable.  The programmer has to rely on judgment to
decide what the best style is in a particular case, and of course more
experience produces better judgment.  But I just haven't seen any
compelling evidence that, for a programmer who understands the
importance of readability and has good judgment, any particular style
will be preferable to any other particular style (occasional GOTO's
vs. avoiding them like the plague, single-exit vs.  multiple-exit,
using return's in the middle of your procedures, etc.).  I just don't
see that we have enough empirical evidence to support any such
conclusion.

                                -- Adam

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
@ 1998-09-02  0:00                                                   ` dennison
  1998-09-02  0:00                                                   ` Dan Higdon
  1998-09-02  0:00                                                   ` Matthew Heaney
  2 siblings, 0 replies; 510+ messages in thread
From: dennison @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6sjk3p$4tc$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Matthew Heaney wrote in message ...
>
> >Without being able to exit from the middle of a loop, I'd have to do
> >this to terminate a read sequence:
> >
> >  Get (N);
> >
> >  while N /= 0 loop
> >
> >      <process N>
> >
> >      Get (N);
> >
> >  end loop;
> >
> >So it's the structured approach which causes the redundancy, becuase Get
> >must be called twice.
>
> Consider:
>
>    do {
>       Get(N);
>       if (N)
>         <process N>
>    } while (N);
>
> Structured programming allows the loop condition to be either at the top or
> the bottom.


In Ada (which is what it looks like Matthew was writing in) there is no
"do-while" loop construct. It has to be simulated with the "exit" statement as
follows:

(sorry if the nesting isn't there. DejaNews' posting software has problems
with leading spaces)

   loop
      Get(N);
      if N then
        <process N>
      end if;
      exit when not N;
   end loop;

which looks pretty awkward (and performs twice as many comparisons) compared
to:

   loop
      Get(N);
      exit when not N;
      <process N>
   end loop;

Anyway, if you think middle-exits are bad from a maintenence perspective, then
in Ada you should probably stick to while and for. In your example there is
nothing stopping a later maintainence person from inserting a line between the
"exit" and the "end loop".

--
T.E.D.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                       ` Robert Martin
@ 1998-09-02  0:00                                                         ` Richard Melvin
  1998-09-02  0:00                                                           ` Tim Ottinger
  1998-09-02  0:00                                                         ` Matthew Heaney
  1 sibling, 1 reply; 510+ messages in thread
From: Richard Melvin @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6sjl6v$5qh$1@hirame.wwa.com>, Robert Martin
<rmartin@oma.com> writes
>
>Consider the case of a complex data structure.  You are in the midst of
>changing a set of variables within it.  Suddenly you realize that you must
>exit early.  Before you can exit, you have to put the data structure back
>the way it was.  In C++, getting a destructor to do this can be horrific.

This seems a weak argument, as there can easily be no way whatsoever to
put things back the way they were - the most obvious example is a sort
function.

(Unless you copy the initial state of the array before sorting, which
can be done just as easily in a little stack-based transaction object.) 

-- 
Richard Melvin




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Ell
@ 1998-09-02  0:00                                                   ` Robert Oliver
  1998-09-02  0:00                                                     ` Robert Martin
  1998-09-03  0:00                                                     ` Ell
  0 siblings, 2 replies; 510+ messages in thread
From: Robert Oliver @ 1998-09-02  0:00 UTC (permalink / raw)


Ell wrote:
> 
> In comp.object Robert Oliver <oliverb@hfl.tc.faa.gov> wrote:
> : Ell wrote:
> 
> :> The assertion that "single entry, single exit" is a required, or even
> :> desirable, maxim of structured programming is a myth.
> :>
> :> No one (including RCM) can show that this maxim is in fact a coding
> :> heuristic put forward by any of the founders of the structured
> :> paradigm. [Check past posts in this thread.]
> 
> : Edward Yourdan, in his book Techniques of Program Structure and Design
> : discusses this article:
> 
> : C. Bohm and G. Jacopini, "Flow Diagrams, Turing Machines, and Languages
> : with Only two Formation Rules", Communications of the ACM, May 1996,
> : pages 366-371.
> 
> : (Is this not *the* foundational article for structured programming?)
> 
> How can an artile written in '96 be *the* foundational article for
> the structured programming paradigm which gained currency in the late
> '70's?

Clearly it can't be.  It should have read 1966.  My typo.

> 
> : Yourdan says:
> 
> : "According to Bohm and Jacopini, we need three basic building blocks in
> : order to construct a program:
> 
> :       1. A process box.
> :       2. A generalized loop mechanism.
> :       3. A binary-decision mechanism.
> 
> : The process box, shown in Fig. 4.1, may be thought of as a single
> : computational statement (or machine language instruction) *or as any
> : other proper conputational sequence with only one entry and one exit* -
> : such as a subtoutine."
> 
> Where is the proof that this underlays the structured paradigm and an
> assertion that something is "proper" doesn't make it so. What structured
> programming avoided was unstructured flow control. It encouraged the use
> of procedure/routine calls over 'goto'.  

Yes, but there is more to it.  Unstructured flow control was replaced by
one
or more of the previously mentioned programming constructs, process,
loop,
or decision.  This was to be accomplished at all levels of code from
main()
to individual instructions.  Bohm and Jacopini proved that one could
write
any realistic (proper) program using only these constructs.  Sequences
of
instructions (or other process boxes) could be transformed into a
process
box with a single entry and single exit.  Loops and decision mechanisms 
could be similarly transformed.  In fact, using only these constructs
ones code must be decomposable into blocks with only a single entry and
exit.

So, the point I wanted to make is that early on (Yourdon's book was
published
in 1975) was known as a common characteristic of structured programming.

> Along with entry into a procedure
> via a call, the use of 'return' is structured flow control; 'return' can
> only go back to the calling procedure, unlike 'goto' which can branch to a
> label anywhere.

It's interesting that you use the fact that return always returns the
program
to a single exit point (the calling procedure) as an argument that this
technique is structured.  Indeed, it is at the procedure level.  (Just,
curious.  Would you allow goto's if they could not leave the scope of
the
procedure?  Probably not.)

I am not arguing against all use of multiple returns in a procedure or
function.  I often write a function like this:

void AFunction(...)
{
  if (SomeCondition) return;
  if (AnotherCondition) return;
  if (AThirdCondition) return;

  // now do the real work...

  return;
}

I think this makes sense when AFunction is called from many places and
the
conditions need to be tested each time.  I can look at the beginning of
the
function and know that there will be nothing done in these three
circumstances.
It's not without danger as RCM has pointed out, but I often choose to
live
with the risk.

Of course, it could also be written as:

void AFunction(...)
{
  if not (SomeCondition)    and
     not (AnotherCondition) and
     not (AThirdCondition)  then

  // now do the real work...

  endif
  return;
}

Bob Oliver




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00             ` Patrick Doyle
  1998-09-02  0:00               ` Patrick Logan
@ 1998-09-02  0:00               ` Robert Martin
  1998-09-02  0:00                 ` Patrick Logan
  1998-09-03  0:00               ` mfinney
  1998-09-03  0:00               ` Matthew Heaney
  3 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Patrick Doyle wrote in message ...
>In article <6sjms6$7c4$1@hirame.wwa.com>,
>Robert Martin <rmartin@oma.com> wrote:
>>
>>1. They are indeterminate.  When you throw an exception, you have no idea
>>where control will wind up.  It is not simply an exit from the current
>>scope, or even from the current function.
>
>By this logic, polymorphism is indeterminate too.  When you call a
>polymorphic function, you have no idea where control will
>wind up.  This is a Good Thing.  It's what makes polymorphism
>powerful: the fact that you're giving someone else some control
>over the situation makes your code flexible.

Granted.

>The same holds for exceptions.

But there is a difference.  With polymorphism, though you may not know what
function is actually being called, you do know that it will return to you.
Thus, there is a postcondition that you can depend upon.   But once you
throw an exception, there is very little you can say about what happens
next.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` sureshvv
@ 1998-09-02  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                   ` Robert Martin
  1 sibling, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



sureshvv@hotmail.com wrote in message <6sk59r$8e6$1@nnrp1.dejanews.com>...
>
>Y2K, the last resort of usenet arguments.

No -- Hitler is the last resort of usenet arguments.  (oops, thread over, I
lose.)


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Robert Martin
  1998-09-02  0:00                                               ` Phil Goodwin
@ 1998-09-02  0:00                                               ` adam
  1998-09-02  0:00                                               ` adam
                                                                 ` (4 subsequent siblings)
  6 siblings, 0 replies; 510+ messages in thread
From: adam @ 1998-09-02  0:00 UTC (permalink / raw)


A further thought on this:

In article <6simjo$jnh$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:

> In any case, I note that in this thread nearly every article that advocates
> multiple exits evokes either readability, complexity, or naturalness as the
> justification.  I contend that these are highly subjective things, that are
> not shared by all programmers alike.  Indeed, what is readable, natural and
> simple to me, may be opaque and convoluted to you.

I agree with the truth of this, but not with the implication that this makes
the arguments invalid.  It makes sense to me that code that is more readable,
less complex, and more natural (to me) is code that is more maintainable (by
me).  If this is correct, then it follows that there is no one coding style
that will be the most maintainable for *all* programmers who have to read the
code.  So arguments about whether this or that style is better may well be
pointless.

If that's the case, then the only real basis for arguing is that we should
program in the way that will have the best chance of being maintainable by
the greatest number of programmers who might be maintaining the code.  This
would indicate that the only arguments that are useful are those that are
based on empirical studies of what people consider more "natural"---something
like an opinion poll, I guess.	That would mean that all the theoretical
arguments about "loss of state information" or "goto's going to an undefined
place" or "fractional loop iterations" or whatever  are irrelevant.  However,
in this thread, we've had lots of attempts at logic and theory to demonstrate
why one style is better than the other, and just one reference to any
empirical study.

				-- Adam




-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` sureshvv
  1998-09-02  0:00                                                   ` Robert Martin
@ 1998-09-02  0:00                                                   ` Robert Martin
  1998-09-03  0:00                                                     ` Charles Hixson
  1998-09-04  0:00                                                     ` Rick Smith
  1 sibling, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



sureshvv@hotmail.com wrote in message <6sk59r$8e6$1@nnrp1.dejanews.com>...
>In article <6shhcq$lid$1@hirame.wwa.com>,
>  "Robert Martin" <rmartin@oma.com> wrote:
>>
>> sureshvv@hotmail.com wrote in message
<6sh6ic$o8p$1@nnrp1.dejanews.com>...

>> >Making the code as simple as possible in order to solve the problem at
hand
>> >is more important than trying to make it easier to change against some
>> >imaginary future changes.
>>
>> I disagree one last time.  Two digit dates are much easier to deal with
than
>> four digit dates.  Until the century changes...
>
>INMO, 2 digit dates were
>an engineering tradeoff, that made sense when they were written
>just like 4 digit dates do now (which will break after the year 9999).

If only it were so.  But of course many of the Y2K problems are not being
solved by expanding the field to four digits.  Rather they are adding *code*
not *space*.  The technique is called windowing.  Whenver date subtractions
or comparisons are done in the code, they interpreted as follows:

   if date > X assume 1900 else assume 2000

If X is 50 then any date larger than 50 is assumed to be in the 20th
century.  Otherwise the data is assumed to be in the 21st century.

This, of course, means that there will be a Y2050 crisis.  Ah, but no.
Because X is not universally agreed upon.  Some applications use 60, some
use 40.  So what we really have is a smearing of the crisis over the next
several decades.

Of course none of those old COBOL programs will still be running then...

The choice to use windowing rather than 4 digit dates is also an engineering
trade off.

>> The engineer who does not
>> design for maintainability, is doing a disservice to himself, his fellow
>> engineers, and his employer.
>
>More bs. The argument is if using flags to conform to the se/se principle,
>makes the code more maintainable.

>The engineer who spends his time making his code more complex to protect
>against a certain kind of changes (which are better handled using
techniques,
>such as Resource acquisition is initialization) is wasting the time of his
>fellow engineers and the resources of his employer.


Granted.

Now, what takes longer.  Creating new classes and managing resources in
their constructors and destructors; or maintaining single-entry/single-exit
style?

RAI is a very nice technique, and I am happy to use it for certain kinds of
exception protection.  Expecially when the classes have already been built
(e.g. auto_ptr).  On the other hand, there are resources that don't lend
well to management from destructors.  And for those, I prefer to use se/se
as an aid to their management.

In the final analysis, we are not talking about a huge investment.  se/se
functions are not horribly more complex, or terribly difficult to read.
They are software, like any other.  Their structure is more conducive to
certain kinds of maintenance.  The cost of building se/se is reasonably low.

These are data points for making engineering trade offs.  If you have a
function that can be managed with RAI, and you are reasonably sure that this
will be the case for the forseeable future, and you really need a few extra
minutes, then by all means use multiple exits.  On the other hand, if you
think its possible that RAI will be insufficient to handle the resource
needs of your functions in the forseeable future, and you can spare a few
extra minutes to work out the se/se structure, you are probably better off
doing so.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00               ` Robert Martin
@ 1998-09-02  0:00                 ` Patrick Logan
  1998-09-02  0:00                   ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Patrick Logan @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: But there is a difference.  With polymorphism, though you may not know what
: function is actually being called, you do know that it will return to you.
: Thus, there is a postcondition that you can depend upon.   But once you
: throw an exception, there is very little you can say about what happens
: next.

But you (the method developer whose method is throwing an exception)
don't care what happens next. You only care that your method has held
up its end of the bargain.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Phil Goodwin
@ 1998-09-02  0:00                                                   ` Robert Martin
  1998-09-03  0:00                                                     ` Phil Goodwin
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Phil Goodwin wrote in message <6sk01j$1qn$1@nnrp1.dejanews.com>...
>
>I would posit that if you are changing the function at all you must do a
>complete regression test on it. I grant you that the more you change the
>routine the more likely you are to introduce bugs and that is an important
>consideration. However, what we are doing here is deffering the risk of
>creating a more complicated algorithm to the point in time where we know
that
>the risk is worthwhile.

Unfortunately, by the time you know that the structure is wrong, it is often
difficult to justify making it right.  It is almost always easier to find a
clever fix than it is to restructure so that the clever fix isn't necessary.
(witness the windowing technique for fixing Y2K bugs).  Now, you might
suggest that once faced with the choice of clever fix or refactoring, one
should always choose refactoring.  But I will respond to that with two
points.

1. Your premise is that you shouldn't pay for a risk you aren't sure will
materialize.  Since you don't know that you'll need another clever fix, your
premise will lead you to simply make the current clever fix.

2. Multiple returns *were* the first clever fix.

If you look at these two statements carefully you will realize that they
form the essense of inductive reasoning; leading to the conclusion that true
refactoring will never happen.

I take slightly different view.  If the cost of protecting myself from risk
is low, and if the cost of the risk materializing is high, then I will pay
for the risk up front.  It's like buying insurance.

>The only other option is to assume that the risk will
>always turn out to be worthwhile and code the more complicated algorithm in
>every case.

Again, if cost of the more complex algorithm is low, and if the cost of the
risk is high, then this may not be a bad decision.

>My position is not that strict structured programming has no benefit, it is
>that it has a cost and that the cost is not justified unless the benefit is
>recieved.

Is the cost of your medical insurance, or your auto insurance, or your life
insurance justified?
Of course it is!  (and you should see my health insurance rates!)  The
reason it is justified is that the potential downside is enormous.

So the justificaton of a maintainable approach must be that the downside
potential is high enough to get us to gladly pay the up front costs of
protection.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Matthew Heaney
@ 1998-09-02  0:00                                                     ` Robert Martin
  1998-09-03  0:00                                                       ` Matthew Heaney
  1998-09-02  0:00                                                     ` Patrick Logan
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...
>"Robert Martin" <rmartin@oma.com> writes:
>
>> >So it's the structured approach which causes the redundancy, becuase Get
>> >must be called twice.
>>
>> Consider:
>>
>>    do {
>>       Get(N);
>>       if (N)
>>         <process N>
>>    } while (N);
>>
>> Structured programming allows the loop condition to be either at the top
or
>> the bottom.
>
>The thing I dislike about the above code fragment is that N gets tested
>twice.

For good reason.  There are two independent program states that depend upon
N.  One is whether or not we call process, and the other is whether or not
the loop exits.

Now, we could combine them as:

    for(;;)
    {
       Get(N);
       if (N)
         <process N>
       else
         break;
    }

This is certainly more efficient; and if efficiency is what you need then
you'd better do this.

However, the efficiency costs us something.  It couples the two independent
program states.  This increased coupling makes it difficult to make changes
that are independent of N.

For example, suppose I need to flush some buffers at the end of each
iteration.  I do this by calling 'flush'.   I must write this as:

    for(;;)
    {
       Get(N);
       if (N)

         <process N>
         flush();
       }
       else {
         break;
         flush();
       }
    }

Whereas if I had lived with the double test:

    do {
       Get(N);
       if (N) {
         <process N>
       }
       flush();
    } while (N);


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Richard Melvin
@ 1998-09-02  0:00                                                   ` Jim Cochrane
  1998-09-03  0:00                                                     ` Matthew Heaney
  0 siblings, 1 reply; 510+ messages in thread
From: Jim Cochrane @ 1998-09-02  0:00 UTC (permalink / raw)


In article <9qnQhDAAvZ71EwAx@radm.demon.co.uk>,
Richard Melvin  <rmelvin@radm.demon.co.uk> wrote:
>In article <6silt4$gb0@flatland.dimensional.com>, Jim Cochrane
><jtc@dimensional.com> writes
>>
>>It appears that this routine has an implied pre-condition:
>>l.size() == r.size()
>>
>snip..
>>
>>I think, more appropriately, it argues for the "Document routine
>>pre/post-conditions (as well as use assertions as documentation of
>>program state, where appropriate)" camp.
>
>I hardly think so, given that this was a comparison operator for a stack
>- a stack, pretty much by definition, is variable-length (perhaps with a
>fixed maximum length, but that's not relevant).
>
>Just throwing in extra preconditions to cover bugs in the implementation
>is not my interpretation of design-by-contract.

You are correct.  My premise was a bit off.  A better one would be:
Before implementing a routine, it is necessary to determine what the
routine must accomplish.  A very effective method of doing this is to
document the specification for the routine in the form of pre- and
post-conditions.  Once this is done, the routine can be coded such that it
meets the post-condition based on the pre-condition.

In the quoted example, documenting the pre-condition would have helped to
uncover the fact that containers of different sizes would need to be dealt
with.  It would become obvious that a pre-condition of l.size = r.size
would not be appropriate and thus that the negation of this condition would
need to be dealt with in the implementation.

>
>Otherwise I can revolutionise the world of fast sort algorithms:
>
>void 
>sortInLinearTime(Vector & v)
>{
>        PRE (v.length() < 2);
>        return;
>}
>
>(assuming PRE is counted as an externally-documented precondition, not
>an assertion).
>-- 
>Richard Melvin


-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                     ` John Volan
  1998-09-01  0:00                                                       ` Robert Martin
  1998-09-02  0:00                                                       ` Nick Leaton
@ 1998-09-02  0:00                                                       ` Chris Saunders
  2 siblings, 0 replies; 510+ messages in thread
From: Chris Saunders @ 1998-09-02  0:00 UTC (permalink / raw)


>There are situations where extraneous calls in the final loop iteration
>would not be so harmless.  For instance, suppose you wished to implement
>an 'out' function for a LIST class that generated strings of the form:
>
> "{}"    for an empty list
> "{A}"   for a list with one element "A"
> "{A, B}" for a list with two elements "A" and "B"
>        etc...
>
>In other words, separate the elements by commas, but only if there is
>more than one element.  Here's a first attempt at a solution:
>
>out: STRING is
>    do
>        Result := "{";
>        from
>            start
>        until
>            after
>        loop
>                Result.append (item.out)
>                Result.append (", ");
>                forth
>            end loop
>        end
>        Result.append ("}");
>    end
>
>Unfortunately, this is incorrect, because it places an extraneous comma
>after the last element.  To correct this, we could add a test within the
>body:


My suggestion:

out: STRING is
    do
        Result := "{";
        from
            start
        until
            after
        loop
                Result.append (item.out)
                Result.append (", ");
                forth
            end loop
        end
        Result.prune_all_trailing (',')
        Result.append ("}");
    end

In place of prune_all_trailing you could also use head (Result.count - 1)
Costs very little overhead and leaves you with a nice looking loop.

Regards
Chris Saunders
saunders@wchat.on.ca






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                         ` Robert Martin
  1998-09-01  0:00                                           ` Gerry Quinn
  1998-09-01  0:00                                           ` Mike Spille
@ 1998-09-02  0:00                                           ` mfinney
  1998-09-02  0:00                                             ` Ell
                                                               ` (3 more replies)
  1998-09-02  0:00                                           ` Gene Gajewski
  3 siblings, 4 replies; 510+ messages in thread
From: mfinney @ 1998-09-02  0:00 UTC (permalink / raw)


In <6sh3qn$9p2$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> writes:

>However, multiple exits to a single destination represent a problem.  The
>two exits come from two different states within the algorithm.  If the
>single destination must do some work that depends upon that state (or if in
>the future, that single destination must be modified to do work that depends
>upon that state), then the code in the single destination is going to get
>pretty ugly.

I have been following this thread for a while (or at least part of the thread),
and it seems to me that the basic argument is between the use of structured
programming which requires a single entry and single exit and of tree-
structured programming which allows multiple-level breaks/continues, but
not arbitrary jumps into blocks.

It turns out that tree-structured programming covers almost all of the flow
graphs actually encountered by compilers which are not undecomposable 
and provides the necessary flow graph assurances for optimization (I do
have a reference on that, but have just finished moving and everything
is in boxes, so regrettably I can't provide it at this time).  Multiple exits from
a block do require the compiler to add extra control flow paths to a single
exit point for some algorithms, but that is trivial control flow transformation
by the compiler -- but not for the programmer because modern languages do
not generally provide adequate control structures (other than goto) to
represent the extra control flow paths.

I personally feel that structured programming is a very good idea, but like
most things is an extreme which is better with a little compromise.  I see
tree-structured programming as that compromise.  It is true that multiple
exits arrive from different states -- but presumably they all satisify the
exit postcondition, and that is what should be used for subsequent
programming (assuming that the exit postcondition is clearly stated).  In
a routine such as the one being used for an example, it seems clear that
multiple exits do not harm and actually improve code readability.

It has been suggested that the need for maintenance is a reason to twist
the code unnaturally -- but that is where using a multiple level exit
instead of returns would solve the problem (true, C/C++ does not directly
provide multiple level exits, but they can be "faked").

It has been suggested that mid-loop exits (which can still be considered
structured code because they have a single entry and a single exit, even
if the exit is not at the top or bottom of the loop) are not good because
the loop is not executed an integral number of times.  On the contrary,
that is the best possible reason to use a mid-loop exit because many
programs do not naturally map to an integral number of iterations.  It is
always better to allow the control structure map as closely as possible
to the problem.  So "twisting" a mid-loop exit to make it a top or bottom
exit, and possibly duplicating code will make code readability harder.

It has also been stated that when multiple exits are allowed, it is
necessary for the programmer to actually *read* the code to be able
to understand it!  Well surprise -- do you really want somebody
modifying your code *without* reading it?  Sorry, but I don't think so!

It also seems to me that this argument has no resolution.  Those who
are strictly in favor of the orginal, unadulterated structured programming
aren't going to give ground to those who favor a more relaxed view of
structured programming.

And, as far as maintainability is concerned, I strictly use tree-structured
programming and have *never* found it to be a maintenance problem.
Sure, sometimes code transformations are required during maintenance,
but they are sometimes required during coding.  So what?  There is no
way to write code that never requires code transformations during
maintenance, and trying to do so just makes the code harder to
understand and ultimately increases maintenance cost.  Far better is
to endevour to reach 0 bugs so that maintenance is never required.
Not easy, perhaps, but it is getting closer and closer every day.  I 
personally am running somewhere around 0.0001 and 0.0002 errors
per line of code --  prior to quality assurance getting the code.


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <6shhg4$llp$1@hirame.wwa.com>
@ 1998-09-02  0:00             ` Jim Cochrane
  0 siblings, 0 replies; 510+ messages in thread
From: Jim Cochrane @ 1998-09-02  0:00 UTC (permalink / raw)


In addition to what Robert points out, the potential problem can easily be
eliminated by changing "equal == true" to simply "equal".  [Or you can
simply switch to Eiffel where the equivalent typo "equal = true" -> "equal
:= true" would not compile. :-)]

I think the problem here is not the proposed algorithm, but is simply a C++
syntax anomoly that causes a potential hazard, which can occur within any
algorithm implementation.

[Besides, why would anyone want to change a piece of code like this that is
already written?  You do have a rule in your org., don't you, that
disallows copying and pasting? :-)]

In article <6shhg4$llp$1@hirame.wwa.com>,
Robert Martin <rmartin@oma.com> wrote:
>
>Chris Brand wrote in message <35EC3440.9FA81BF1@west.raytheon.com>...
>>Robert Martin wrote:
>>>
>>> bool operator==(Stack& l, Stack& r)
>>> {
>>>   bool equal = true;
>>>   for (int index = 1; index < l.top() && equal == true; index++)
>>>   {
>>>     if (l[index] != r[index])
>>>       equal = false;
>>>   }
>>>   return equal;
>>> }
>>>
>>> If this is more complex (something that is arguable) it is not *much*
>more
>>> complex.  On the other hand, it is easier to maintain.
>>
>>It is open to (maintenance) errors such as
>>   for (int index = 1; index < l.top() && equal = true; index++)
>>which the multiple-return version isn't, so the "easier to maintain"
>>argument is far from clear-cut.
>
>
>I think *all* structures are vulnerable to typos.  The code above is no more
>vulnerable than any other code is.
>
>
>Robert C. Martin    | Design Consulting   | Training courses offered:
>Object Mentor       | rmartin@oma.com     |   Object Oriented Design
>14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
>Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
>
>"One of the great commandments of science is:
>    'Mistrust arguments from authority.'" -- Carl Sagan
>
>
>


-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Richard Melvin
  1998-09-01  0:00                                               ` Robert Martin
@ 1998-09-02  0:00                                               ` Jim Cochrane
  1998-09-02  0:00                                                 ` Richard Melvin
  1 sibling, 1 reply; 510+ messages in thread
From: Jim Cochrane @ 1998-09-02  0:00 UTC (permalink / raw)


In article <LpVjTBAegG71EwXH@radm.demon.co.uk>,
Richard Melvin  <rmelvin@radm.demon.co.uk> wrote:
>In article <6sf87j$47n$1@hirame.wwa.com>, Robert Martin
><rmartin@oma.com> writes
>>bool operator==(Stack& l, Stack& r)
>>{
>>  bool equal = true;
>>  for (int index = 1; index < l.top() && equal == true; index++)
>>  {
>>    if (l[index] != r[index])
>>      equal = false;
>>  }
>>  return equal;
>>}
>
>Now, following convoluted conditionals[1] like the above always makes my
>head spin, but it looks to me like the above code would always return
>true when comparing against an empty stack.

It appears that this routine has an implied pre-condition:
l.size() == r.size()

In this case, if l is empty, r is also empty.  I think you can easily
define equality as including the case where both stacks are empty.  I
suppose you could say that the problem is an undocumented pre-condition.

>
>Given that this is a trivial piece of code, written by an expert, read
>by half of usenet, and nobody seems to have spotted the problem, I think
>this has to count as a significant data point on the side of the
>multiple returns camp.

I think, more appropriately, it argues for the "Document routine
pre/post-conditions (as well as use assertions as documentation of
program state, where appropriate)" camp.

>
>Richard
>
>[1] It's not particularly complicated, but it does combine into one
>expression two tests with completely different purposes, which I think
>is always a source of confusion. Of course, the 1-based indexing doesn't
>help, with 0-based being more usual in C++ - this is probably a second
>bug, but I'd have to see the specification of top and operator[] to find
>out.
> 
>-- 
>Richard Melvin


-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                           ` mfinney
                                                               ` (2 preceding siblings ...)
  1998-09-02  0:00                                             ` john-clonts
@ 1998-09-02  0:00                                             ` Robert Martin
  1998-09-02  0:00                                               ` Phil Goodwin
                                                                 ` (6 more replies)
  3 siblings, 7 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



mfinney@lynchburg.net wrote in message ...

>And, as far as maintainability is concerned, I strictly use tree-structured
>programming and have *never* found it to be a maintenance problem.
>Sure, sometimes code transformations are required during maintenance,
>but they are sometimes required during coding.  So what?  There is no
>way to write code that never requires code transformations during
>maintenance, and trying to do so just makes the code harder to
>understand and ultimately increases maintenance cost.  Far better is
>to endevour to reach 0 bugs so that maintenance is never required.
>Not easy, perhaps, but it is getting closer and closer every day.  I
>personally am running somewhere around 0.0001 and 0.0002 errors
>per line of code --  prior to quality assurance getting the code.


Reaching zero bugs may not have that big an impact on maintenance, since
much of maintenance has to do with changes to the requirements.

In any case, I note that in this thread nearly every article that advocates
multiple exits evokes either readability, complexity, or naturalness as the
justification.  I contend that these are highly subjective things, that are
not shared by all programmers alike.  Indeed, what is readable, natural and
simple to me, may be opaque and convoluted to you.  I also contend that
these issues are somewhat emotional, as evidenced by the terms such as
"twist", "warp", "bend", "religious argument", etc. that have also been used
in this thread.

Finally, I contend that the factors in favor of using a
single-entry/single-exit style are, on the other hand, quite concrete and
demonstrable.  It has been shown that adhering to a structured style
facilitates both resource management and error processing.   It has also
been shown that a multiple exit style is vulnerable to redundant code, and
code for recovery of state.

So, it seems what we have here is "gut feelings" warring against empirical
data.  I can understand why the gut reaction is so strong; multiple exits
are *eaiser* to write; and are, for some, easier to read.  But those are not
the only, or even the most important, criteria for evaluating the quality of
a design.  Maintainability is an issue too, and sometimes an overriding one.

In the end, the decision to use a structured style is a tradeoff.  There are
benefits, and there are costs.  And there are certainly situations in which
the costs outweight the benefits (e.g. quick an dirty programs that have
short lifetimes and require little maintenance during their life).  It is
also true, however, that for a very large set of circumstances, the benefits
outweigh the costs.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan




Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                           ` mfinney
@ 1998-09-02  0:00                                             ` Ell
  1998-09-02  0:00                                               ` Robert Oliver
                                                                 ` (2 more replies)
  1998-09-02  0:00                                             ` Ell
                                                               ` (2 subsequent siblings)
  3 siblings, 3 replies; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


On Wed, 02 Sep 1998 05:01:34 GMT, mfinney@lynchburg.net wrote:

>In <6sh3qn$9p2$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> writes:
>
>>However, multiple exits to a single destination represent a problem.  The
>>two exits come from two different states within the algorithm.  If the
>>single destination must do some work that depends upon that state (or if in
>>the future, that single destination must be modified to do work that depends
>>upon that state), then the code in the single destination is going to get
>>pretty ugly.

>I have been following this thread for a while (or at least part of the thread),
>and it seems to me that the basic argument is between the use of structured
>programming which requires a single entry and single exit

The assertion that "single entry, single exit" is a required, or even
desirable, maxim of structured programming is a myth.

No one (including RCM) can show that this maxim is in fact a coding
heuristic put forward by any of the founders of the structured
paradigm. [Check past posts in this thread.]

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                           ` mfinney
  1998-09-02  0:00                                             ` Ell
@ 1998-09-02  0:00                                             ` Ell
  1998-09-02  0:00                                             ` john-clonts
  1998-09-02  0:00                                             ` Robert Martin
  3 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


On Wed, 02 Sep 1998 05:01:34 GMT, mfinney@lynchburg.net wrote:

>It is true that multiple exits arrive from different states

Not at least significantly in this case.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Loryn Jenkins
                                                                       ` (2 preceding siblings ...)
  1998-09-01  0:00                                                     ` Darren New
@ 1998-09-02  0:00                                                     ` Matthew Heaney
  1998-09-02  0:00                                                       ` Loryn Jenkins
                                                                         ` (2 more replies)
  3 siblings, 3 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-02  0:00 UTC (permalink / raw)


Loryn Jenkins <loryn@s054.aone.net.au> writes:

> Now, someone else was kind enough to show me an even simpler way of
> doing this ... albeit marginally less efficient (and again, I don't care
> about this criteria, unless my application beforms below specification
> and my profiler shows me that this is a hot spot).
> 
> equal (l,r: LIST): BOOLEAN is
>       require
>           l /= Void and r /= Void
>       do
>           from
>               Result := (l.count = r.count)
>               l.start; r.start
>           until
>               not Result or l.off
>           loop
>               Result := (l.item = r.item)
>               l.forth; r.forth
>           end
>       end
> 
> This, at least, loses your nesting objection. In fact, it has less
> nesting than your original example. However, it might mislead unless the
> reader was aware of this sort of idiom. (It does simplify things though;
> so I think I'll be using this style, where appropriate.)

I like that there's less nesting, but still have a couple of issues with
it:

1) The decision table for the predicate still has 4 rules instead of 2.

2) It still bothers me a little that once you calculate the value of
Result (the second time, when comparing items), you still do some work
after (to increment the iterators), even though the result may already
be False.

The latter point is only a nit.  It's the first point that puts a bee in
my bonnet.  It may not seem like much in this example, because we're
"only" going from 2 rules to 4.  But things get scary really fast when
going 4 to 8.

This was my experience trying to decipher someone else's post, in which
a flag was added to a decision table with 4 rules, doubling the size to
8.  I wouldn't have been able to figure things out without using a
decision table.  (I haven't caught on to K-maps yet, but decision tables
are my best friend.)

BTW: Treat minimizing nesting levels seriously.  Whereas Miller's limit
was 7 plus or minus 2, for a linear sequence of items, the limit is even
lower (around 3) for nested relationships.  (This info I read in
Structured Design, by Constantine & Yourdon.)










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                       ` Loryn Jenkins
@ 1998-09-02  0:00                                                         ` Matthew Heaney
  1998-09-02  0:00                                                           ` Loryn Jenkins
  0 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-02  0:00 UTC (permalink / raw)


Loryn Jenkins <loryn@s054.aone.net.au> writes:

> Do you still disagree, Matthew? Given that the complexity is pretty
> similar---perhaps with some complexity shifted from the flowgraph to the
> decision table---with the resulting complexity being equivalent. And, I
> think, all your other points have been addressed by this example ...
> excepting the 'performance' issue.

I like what you did, but still prefer to bail out immediately, once I
know that the answer is false.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00               ` Matthew Heaney
@ 1998-09-02  0:00                 ` Jim Cochrane
  1998-09-02  0:00                   ` Richard Melvin
  1998-09-03  0:00                   ` Robert I. Eachus
  0 siblings, 2 replies; 510+ messages in thread
From: Jim Cochrane @ 1998-09-02  0:00 UTC (permalink / raw)


In article <m3af4kpyr9.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>jtc@dimensional.com (Jim Cochrane) writes:
>
>> class STACK [G] ...
>> is_equal (other: STACK [G]): BOOLEAN is
>>... (See below for entire original article.)

You have provided a good, thorough analysis supporting the argument that my
version is more complex, and I think you've convinced me.  It is difficult
to determine what the loop is doing when the exit condition is so complex.
Also, I agree with your argument for separating the test of the two stack
sizes being unequal into a separate statement from the loop body, since
this does make the code easier to understand, as well as more efficient.

I would like to now propose an algorithm that separates the equality check
from the loop and that also returns only at the end of the function.  I
will include a loop invariant in the code, and I'll then copy your
algorithm, inserting a loop invariant.  The point of this exercise will be
to see if how each idiom affects the traditional technique of analyzing a
loop by means of the loop invariant.  (In my version I have changed the
type from STACK to ARRAY, since this operation is not really compatible
with the STACK abstraction and because it makes expressing the loop
invariant easier - using indexes instead of iterators.  [Of course, a stack
internally implemented as an array will be able to use this algorithm.])

My new version:

class ARRAY [G] ...
is_equal (other: ARRAY [G]): BOOLEAN is
    require
        arg_not_void: other /= Void
    local
        i: INTEGER
    do
        if count /= other.count then
            Result := false
        else
            from
                i := 1
            invariant
                -- for_all j member_of {1..i - 1} it_holds
                --   Current @ j = other @ j
            until
                i > count or Current @ i /= other @ i
            loop
                i := i + 1
            end
            check
                (i - 1 /= count) implies (Current @ i /= other @ i)
                count = other.count
            end
            Result := i - 1 = count
        end
    ensure
        -- Result = (count = other.count and for_all j member_of
        --                 {1..count} it_holds Current @ j = other @ j)
    end

Your version:

function "=" (L, R : Stack_Type) return Boolean is
begin

   if L.Top /= R.Top then
      return False;
   end if;

   for Index in Positive range 1 .. L.Top loop
		-- INV: for_all j member_of {1..Index - 1} it_holds
		--   L.Items (j) = R.items (j)
      if L.Items (Index) /= R.Items (Index) then
		 -- not (Index - 1 = L.Top)
         return False;
      end if;
   end loop;
   -- L.Top = R.Top and Index - 1 = L.Top

   return True;

   -- Postcondition: Result = (L.Top = R.Top and for_all j member_of
   -- 				{1..L.Top} it_holds Current @ j = other @ j)

end "=";


When we compare these two implementations, your earlier comments (comparing
your implementation with an implementation someone else proposed [I believe
it was Loryn] that is very similar to mine) mostly still apply - especially
the point that your loop termination condition is simpler than mine.  But
since you include what is in essence a hidden loop termination condition
[L.Items (Index) /= R.Items (Index)], as someone else pointed out, the
complexity of two termination conditions is still there.  My routine does
nest the loop within an else statement; but yours nests an if within a
loop.  Which is better?  I don't know - I'm not sure it matters that much.

In addition to the loop invariant, I have added a postcondition to both
routines (which is the same for both routines; also, the loop invariant is
the same for both routines).  I have also added a couple other assertions
to document program state at those points.

Looking at my routine, you can easily determine that the loop invariant is
correct and that, as a result, if i - 1 /= count then (although the loop
invariant is true), Current @ i /= other @ i and the result will be false;
otherwise, the result will be true.  The postcondition of the routine
follows straightforwardly from that.

Looking at your routine, you need to check 3 different places to check that
the postcondition is upheld, the 3 return statements:  In the first if
statement, in the second if statement in the middle of the loop, and at the
end of the routine.  This is a pretty straightforward process, but I think
it makes it a little more difficult in that you need to check 3 separate
locations, including in the middle of the loop.

My conclusion at this point is that I don't see a noticable advantage to
either idiom.  I prefer the one that only exits at the end of the routine,
but I don't think I would object to seeing your version in a code
inspection.  (Of course, if the code was written in Eiffel, your version
would not be possible.)  The one remaining question I have is:  How will
the two idioms compare with a more complex algorithm?  I have a suspicion
that having multiple return points with a more complex algorithm will make
the routine postcondition and the loop invariant harder to verify than with
the return-at-the-end idiom.  Of course, I can't confirm that until I
examine some examples.

I think this has been a good discussion and (contrary to another poster's
implication that this is simply a loop structuring war) I (and I would hope
others) have learned from it.

For comparison, here is my original version with loop invariant and
postcondition added (and using indexes instead of iterators) (I also
changed the "or else" term to "or", since they are semantically equivalent
and the latter is easier to understand for those who don't know Eiffel
well):

class ARRAY [G] ...
is_equal (other: ARRAY [G]): BOOLEAN is
    require
        arg_not_void: other /= Void
    local
        i: INTEGER
    do
        from
            i := 1
        invariant
            -- for_all j member_of {1..i - 1} it_holds Current @ j = other @ j
        until
            i > count or i > other.count or Current @ i /= other @ i
        loop
            i := i + 1
        end
        check
            i - 1 = count and i - 1 = other.count or count /= other.count or
                Current @ i /= other @ i
        end
        Result := i - 1 = count and i - 1 = other.count
    ensure
        -- Result = (count = other.count and for_all j member_of
        --                 {1..count} it_holds Current @ j = other @ j)
    end

In article <m3af4kpyr9.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>jtc@dimensional.com (Jim Cochrane) writes:
>
>> class STACK [G] ...
>> is_equal (other: STACK [G]): BOOLEAN is
>>         -- Are all items in Current equal to all item in other?
>>     require
>>         other /= Void
>>     local
>>         i1, i2: STACK_ITERATOR
>>     do
>>         !!i1.make (Current); !!i2.make (other)
>>         from
>>             i1.start; i2.start
>>         until
>>             i1.after or i2.after or else i1.item /= i2.item
>>         loop
>>             i1.forth; i2.forth
>>         end
>>         Result := i1.after and i2.after
>>     end
>> 
>> I don't think this is particularly hard to understand or maintain,
>> plus it is simpler than the algorithm below - it eliminates the if
>> statement at the beginning.  (STACK_ITERATOR behavior is, hopefully,
>> obvious - i.item means the value of item at the current cursor
>> position of i.)  I threw this together just for this post, so
>> apologies if there are any bugs (and bonus points to those that find
>> them :-) ).
>
>I think this is a real brain teaser.  Let me show you how I try to
>unravel it.
>
>Let's start by making a decision table for the loop predicate:
>
>                    1  2  3  4  5  6  7  8
>i1.after            T  T  T  T  F  F  F  F
>
>i2.after            T  T  F  F  T  T  F  F
>
>i1.item /= i2.item  T  F  T  F  T  F  T  F
>
>As you can see, there are 8 rules, which just exceeded the cognitive
>limits of most of human population.  Already, we're in trouble.  But
>there's more trouble ahead.
>
>The last part of the predicate uses a short-circuit form, so we're going
>to have to prune the table, by removing the rules in which i1.after and
>i2.after are both false.  
>
>Or is it both true???  As I'm writing this post, I've already spent
>several minutes trying to figure out when the last part of the predicate
>actually gets executed.
>
>And I don't even know what the evaluation order rules are in Eiffel.
>Does 
>
>  i1.after or i2.after or else i1.item /= i2.item
>
>mean
>
>  (i1.after or i2.after) or else i1.item /= i2.item
>
>or 
>
>   i1.after or (i2.after or else i1.item /= i2.item)
>
>Hmmm?  Maybe these expressions both have the same value.  I don't know,
>but I'm obligated to find out.  This is mental work I shouldn't have to
>do, and I'll probably get it wrong.
>
>So I gotta ask: Is this a program, or an IQ test?
>
>I'll just use my little decision table friend again, to help me crack
>the secret of what result the predicate acually delivers.
>
>                    1  2  3  4  5  6  7  8
>i1.after            T  T  T  T  F  F  F  F
>
>i2.after            T  T  F  F  T  T  F  F
>
>i1.item /= i2.item  -  -  -  -  -  -  T  F
>
>The dash (-) means "does not matter."
>
>So the item test only influences the result (I think) when i1.after and
>i2.after are both false.  (Gee, that's what I originally thought.  A
>miracle happened, and I guessed right!  But how many other times will I
>be this lucky?)
>
>Now I have to actually figure out what the result of the predicate is:
>
>                    1  2  3  4  5  6  7  8
>i1.after            T  T  T  T  F  F  F  F
>
>i2.after            T  T  F  F  T  T  F  F
>
>i1.item /= i2.item  -  -  -  -  -  -  T  F
>
>predicate has value T  T  T  T  T  T  T  F
>
>Ah, so that's the secret!  The loop teriminates (I think) when all
>sub-predicates yield false.
>
>Revealed at last, after several minutes of careful analysis, which I
>probably screwed up.
>
>But wait, I did screw up!  Loop termination in Eiffel has opposite the
>traditional sense, which is to terminate when the predicate is false.
>So the loop terminates when the predicate is true.  Whew!
>
>How many programmers do you think will take the time to figure all this
>out?  How many programmers even know how to use a decision table?
>
>One more issue with this example.  Following termination, calculating
>the result, 
>
>   Result := i1.after and i2.after
>
>means i1.after and i2.after get tested again.  Why?  They were tested
>already, in the loop.  Why test them twice?
>
>Maybe I get bonus points for being able to decipher this, but is that
>how we should write software?  Be rewarding those who perform mental
>gymnastics?
>
>I hope not.


-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Robert Martin
                                                                 ` (3 preceding siblings ...)
  1998-09-02  0:00                                               ` Matthew Heaney
@ 1998-09-02  0:00                                               ` Ell
  1998-09-02  0:00                                                 ` Rick Smith
                                                                   ` (3 more replies)
       [not found]                                               ` <gio+van+no+ni+8-0309982311220001@dialup62.tlh.talstar.com>
  1998-09-03  0:00                                               ` mfinney
  6 siblings, 4 replies; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


On Wed, 2 Sep 1998 00:44:08 -0500, "Robert Martin" <rmartin@oma.com>
wrote:


>In any case, I note that in this thread nearly every article that advocates
>multiple exits evokes either readability, complexity, or naturalness as the
>justification.  I contend that these are highly subjective things,

This may be true, though I don't thinks so, but adherence to the dogma
you made up about "single entry and single exit" doesn't make things
clearer as most see it in this case.

>Finally, I contend that the factors in favor of using a
>single-entry/single-exit style are, on the other hand, quite concrete and
>demonstrable.  It has been shown that adhering to a structured style

You have not shown at all that "single entry, single exit" is a
general coding maxim of structured programming. 

And you should be ashamed of yourself for asserting that it is when
after recently being challenged on it, you failed to prove that it was
a general coding heuristic of structured programming.  Why do you
think you have a right to lie, and make false assertions contrary ti
the facts?

>facilitates both resource management and error processing.   It has also
>been shown that a multiple exit style is vulnerable to redundant code,
>code for recovery of state.

Not at all.  It has been shown that in this and many other cases the
difference in state at each exit point matters little.

>So, it seems what we have here is "gut feelings" warring against empirical
>data.

It seems we have a masochistic task master adhering to his own
unnecessary dogma trying to make others suffer as well by palming his
dogma off as some kind of officialdom.  Further, he can't prove it as
officialdom and it wouldn't matter if it was because the
appropriateness of all heuristics depends on specific concrete
circumstances.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` Robert Martin
                                                                       ` (2 preceding siblings ...)
  1998-09-02  0:00                                                     ` dennison
@ 1998-09-02  0:00                                                     ` Matthew Heaney
  1998-09-02  0:00                                                       ` Robert Martin
  1998-09-03  0:00                                                     ` mfinney
       [not found]                                                     ` <gio+van+no+ni+8-0309982244140001@dialup62.tlh.talstar.com>
  5 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-02  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> Of course later on, someone asks us to sieze and release a mutex for each
> iteration of the loop.  We'd like to put the seize as the first line of the
> loop body, and the release as the last line of the loop body.  But if there
> are early exits, then we must put a release before every exit.

No.  Use a controlled type (construction/deconstruction) to
automatically seize and release:

loop
   declare
      Lock : Mutex_Lock (Mutex'Access);
   begin
      <use the resource controlled by Mutex>
   end;
end loop;


When you enter the loop, the Lock object elaborates, and during its
initialization, it automatically calls the Seize operation of Mutex.

When you leave the loop - via a return, or an exit, or an exception, or
whatever - the Lock object is Finalized, during which time it
automatically calls the Release operation of Mutex.

So no, you don't have to worry about bailing out early.  There is no
maintenance penalty for an early return from the loop.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Robert Martin
                                                                 ` (2 preceding siblings ...)
  1998-09-02  0:00                                               ` adam
@ 1998-09-02  0:00                                               ` Matthew Heaney
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                               ` Ell
                                                                 ` (2 subsequent siblings)
  6 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-02  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> Finally, I contend that the factors in favor of using a
> single-entry/single-exit style are, on the other hand, quite concrete
> and demonstrable.

I contend that the factors in favor of using multiple returns are quite
concrete and demonstrable.

My argument concerns the complexity of the decision table for the loop
predicate.  Adding a flag doubles the number of states.

> It has been shown that adhering to a structured style facilitates both
> resource management and error processing.

It has been shown that this is a specious argument.  Automatic
finalization of a controlled object guarantees that resources get
released, no matter how or when the subprogram or loop terminates.

> It has also been shown that a multiple exit style is vulnerable to
> redundant code, and code for recovery of state.

Without being able to exit from the middle of a loop, I'd have to do
this to terminate a read sequence:

  Get (N);
 
  while N /= 0 loop

      <process N>

      Get (N);

  end loop;

So it's the structured approach which causes the redundancy, becuase Get
must be called twice.  

Using the an exit from the middle:

   loop

      Get (N);

      exit when N = 0;

      <process N>

   end loop;

eliminates the redundancy.

> So, it seems what we have here is "gut feelings" warring against
> empirical data.  I can understand why the gut reaction is so strong;
> multiple exits are *eaiser* to write; and are, for some, easier to
> read.  But those are not the only, or even the most important,
> criteria for evaluating the quality of a design.  Maintainability is
> an issue too, and sometimes an overriding one.

But Robert, this isn't just "gut reaction."  Researchers empirically
demonstrated that programmers using an exit from the middle produced
fewer errors:

Cognitive Strategies and Looping Constructs: An Empirical Study
Soloway, Bonar, Ehrlich
CACM, Nov 83, Vol 26, No 11, p853-860

Yes, indeed, multiple exits are easier to write, because that construct
has a better cognitive fit.

I don't find your maintenance argument convincing.  You seem to be
arguing that we should all wear six-fingered gloves, because some day we
might grow another finger.

I have provided examples that mitigate any resource management issues
that would arise because of early termination.  These are techniques
you'll have to use anyway, because of unhandled exceptions.

> In the end, the decision to use a structured style is a tradeoff.  There are
> benefits, and there are costs.  And there are certainly situations in which
> the costs outweight the benefits (e.g. quick an dirty programs that have
> short lifetimes and require little maintenance during their life).  It is
> also true, however, that for a very large set of circumstances, the benefits
> outweigh the costs.

I am not convinced by your argument about higher maintenance costs.

I am convinced by real data that shows real programmers made more real
mistakes when using the approach you advocate.

Here's the reference one more time:

Cognitive Strategies and Looping Constructs: An Empirical Study
Soloway, Bonar, Ehrlich
CACM, Nov 83, Vol 26, No 11, p853-860





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                     ` John Volan
  1998-09-01  0:00                                                       ` Robert Martin
@ 1998-09-02  0:00                                                       ` Nick Leaton
  1998-09-02  0:00                                                       ` Chris Saunders
  2 siblings, 0 replies; 510+ messages in thread
From: Nick Leaton @ 1998-09-02  0:00 UTC (permalink / raw)


John Volan wrote:
> 
> Loryn Jenkins wrote:
> >
> > equal (l,r: LIST): BOOLEAN is
> >       require
> >           l /= Void and r /= Void
> >       do
> >           from
> >               Result := (l.count = r.count)
> >               l.start; r.start
> >           until
> >               not Result or l.off
> >           loop
> >               Result := (l.item = r.item)
> >               l.forth; r.forth
> >           end
> >       end
> 
> This has a certain elegance, but note that:
> 
> (1) If Result is False after the first assignment, then the 'start'
> calls are executed unnecessarily.
> 
> (2) If Result is False after the second assignment (in the body of the
> loop), then the 'forth' calls and the 'off' test are executed
> unnessarily.

If the until clause is changed to

	not Result or else l.off

Then if Result is false l.off is not evaluated. 'or else' and 'and then'
are semi-strict boolean operators and only evaluate the right hand side
if necessary.



-- 

Nick




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                     ` Mike Spille
@ 1998-09-02  0:00                                                       ` Nick Leaton
  0 siblings, 0 replies; 510+ messages in thread
From: Nick Leaton @ 1998-09-02  0:00 UTC (permalink / raw)


Mike Spille wrote:

> 
> Would your average programmer ask the question "Where will the loop
> terminate?", or "What does the function do?".  I think the latter
> question is alot more important.  I personally subscribe to
> the technique of "bailing-out" as soon as possible in a function.
> 
> This has two effects: nesting later on is greatly reduced (I find
> if-else nesting affects readability), and the early-bailouts give
> me guarantees later in the code that I don't need to check for.
> 

This doesn't tend to happen in Eiffel, all because of preconditions. The
preconditions and postconditions, name of the routine and a comment tell
you what the routine does.

Early bailout is usually implements checks on arguments passed in, and
if they are not consistent, then exits with an error. In Eiffel, this is
removed because of the support for DBC. As such, you don't get much
nesting, and as has been posted, you can solve the compare two stacks
without the loop in an if-then statement. The nesting of the loop in the
if then statement is a optimisation, which with a decent compiler, would
be optimised out anyway.

-- 

Nick




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Robert Martin
@ 1998-09-02  0:00                                               ` Gerry Quinn
  1998-09-02  0:00                                                 ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Gerry Quinn @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6shhq7$lut$1@hirame.wwa.com>, "Robert Martin" 
<rmartin@oma.com> wrote:
>Gerry Quinn wrote in message <6shbca$66c$1@news.indigo.ie>...
>>In article <6sh3qn$9p2$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com>
>wrote:
>>>Gerry Quinn wrote in message <6sgror$je8$3@news.indigo.ie>...
>>>
>>>>Multiple exits to a single destination are not spaghetti.
>>>
>>>Spaghetti is not a well defined term.
>>>
>>How strange, then, that such sloppy language is endemic among those
>>who believe they hold the line against sloppy coding...
>
>It's not strange at all.  The common definition of Spaghetti is: "I don't
>like it.".
>

Spaghetti does have a meaning - it is a metaphor for code in which 
multiple goto statements jump to multiple labels, forward and 
backwards.  It describes such code very well (it also well describes 
threads on Usenet...).  It does not describe what we have been talking 
about here.

Thirty years ago, primitive versions of Basic may indeed have lent 
themselves to such code due to an absence of proper control 
structures.  And of course assembler is typically full of spaghetti 
for the same reason.

>Please note that in this thread I have not characterized anyone elses
>examples as spaghetti.  I have tried to stick to more substantive
>complaints.  I think this is important.  Spaghetti is a subjective term that
>accomplishes little as a description.

I would say rather that it is an objective term, nowadays used 
incorrectly as a term of abuse by those who do not actually understand 
the meaning of the word.

[--]

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Ell
@ 1998-09-02  0:00                                                 ` Rick Smith
  1998-09-02  0:00                                                   ` Robert I. Eachus
  1998-09-02  0:00                                                 ` Patrick Doyle
                                                                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 510+ messages in thread
From: Rick Smith @ 1998-09-02  0:00 UTC (permalink / raw)



Ell wrote in message <35eeea9b.2174586@news.erols.com>...
>On Wed, 2 Sep 1998 00:44:08 -0500, "Robert Martin" <rmartin@oma.com>
>wrote:
>
>
>>In any case, I note that in this thread nearly every article that
advocates
>>multiple exits evokes either readability, complexity, or naturalness as
the
>>justification.  I contend that these are highly subjective things,
>
>This may be true, though I don't thinks so, but adherence to the dogma
>you made up about "single entry and single exit" doesn't make things
>clearer as most see it in this case.
>
>>Finally, I contend that the factors in favor of using a
>>single-entry/single-exit style are, on the other hand, quite concrete and
>>demonstrable.  It has been shown that adhering to a structured style
>
>You have not shown at all that "single entry, single exit" is a
>general coding maxim of structured programming.
>
Edward Yourdon, "Techniques of Program Structure and Design",
Prentice-Hall, 1975, pg 145.

"In order to test the entire program, it is important to be able to define
the behavior of submodules at the k-th level independently of the context
in which they occur. This allows us to prove the correctness of the
submodules at the (k + 1)th level independent of their context in the k-th
step. This in turn strongly suggests that each submodule should be
designed with a single entry point and a single exit; in turn, the entire
program can be described as a set of nested modules, each of which
has one entry and one exit."

-----------, pg 148.

"The theoretical basis of structured programming lends itself to
implementation in many of the current programming languages. The
rules are quite simple: All processing in the program must consist of
straight-line statements (e.g., ordinary computational statements) or
one of the following three control statements:

" 1. Procedure calls, subroutine calls, function invocation -- any legal
call to a closed subroutine with one entry and one exit. ...

" 2. IF-THEN-ELSE statements nested to any depth.

" 3. Some looping constructs. ..."
-------------------------------
Rick Smith
e-mail: < ricksmith@aiservices.com >






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                     ` Richard MacDonald (dogmat)
  1998-09-02  0:00                                                     ` Richard Melvin
@ 1998-09-02  0:00                                                     ` dennison
  1998-09-02  0:00                                                     ` Matthew Heaney
                                                                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 510+ messages in thread
From: dennison @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6siijm$h1m$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Of course later on, someone asks us to sieze and release a mutex for each
> iteration of the loop.  We'd like to put the seize as the first line of the
> loop body, and the release as the last line of the loop body.  But if there
> are early exits, then we must put a release before every exit.
>
> Of course later on someone adds yet another early exit to the loop, and must
> remember to bump the counter and release the mutex.
>
> ....  Has anybody out there ever had an experience like this?

In my experience it is more likely that I'm going to have to either add code
to one of the branches that doesn't always get executed, or create a new
(non-exiting) if-conditional inside the loop. In both cases my cause is
helped greatly by not having a lot of extra conditional code already in the
loop. But if the loop is naturally middle-exiting, then you will HAVE to have
that coditional code in the loop (or have one copy of it outside the loop,
which is a problem as well).

Part of my problem is that a conditional in a loop tells me "this code can
execute some iterations and not others". I have to go figure out exactly when
by examining the entire loop to see what affects the conditional, and all the
preceeding code to figure out its initial condition. I have to do a *lot* of
digging just to figure out that it once it is false, it will never be true
again. Using an "exit" or "return" tells me that information up front. I'm
inclined to believe that the construct that conveys the most information
about what I am doing is going to be the one that makes reading and
maintainence easiest.

Now I will freely admit that someone could embed lots of returns and exits
within different levels of if statements and inner loops, and make a
completely confusing mess. In that case, yes switching to flags would
probably be better. But as long as the overall structure of the loop is
simpler with the early exit construct, I don't see why it shouldn't be used.

--
T.E.D.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                         ` Robert Martin
@ 1998-09-02  0:00                                                           ` dennison
  0 siblings, 0 replies; 510+ messages in thread
From: dennison @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6sidsq$e6c$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Correct.  More specifically, I can guarantee that if I put a line of code
> just above the endloop statement (closing brace in my case) it will be
> executed in every iteration.

Well, if this loop is an implementation of middle-exited loop algorithm
(remember what started this thread), then that line will get executed one
extra iteration.

Is that what you want? Maybee, maybee not. You have to stop and think about
it. Just because you rephrased the middle-exited loop as a
multiple-conditional "while" with conditional code in the body doesn't
magically give you the ability to blindly throw code at the end of the loop
and expect it to behave the way you want it to.


--
T.E.D.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Robert Martin
  1998-09-01  0:00                                                 ` Robert I. Eachus
@ 1998-09-02  0:00                                                 ` Mattias Lundstr�m
  1998-09-02  0:00                                                   ` Robert Martin
  1998-09-02  0:00                                                 ` Mattias Lundstr�m
  2 siblings, 1 reply; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-09-02  0:00 UTC (permalink / raw)


Aggresive cuttings below.

Robert Martin wrote:
> 
[...]
> This is roughly equivalent to the 'finally' solution in another post.  And
> I'll use the same argument.
[...]
[Loop that sets return value 'retval' and does 'goto error_exit' on
error]
> error_exit:
>   if (p) free(p);
>   if (f) fclose(f);
return retval;
// The point is that this is code that is ALWAYS executed.
// The only "multi-exit" issue here is the multiple exit
// points from the loop. The function has only this exit.

Your problem with this is (as I understand you) is the use of flags 
(or other method of tracking) to be able to say 

if( resource1 allocated ) deallocate( resource1 );
if( resource2 allocated ) deallocate( resource2 );
...
if( resourceN allocated ) deallocate( resourceN );

How do you mean that you could avoid this by a single-exit
solution ?

> 
> The redundant resource cleanup, and the checks made in the error_exit
> section are pretty ugly.  And this ugliness will only grow and become more

Perhaps. But I do think they are unavoidable. You may break them up
over multiple functions when and if they become too complex, but this
has really nothing to do with the single/multi-exit issue.

> contorted over time.  Also, it is not guaranteed that all resources will
> have check functions, forcing the use of flags (which is all p and f are
> used for in error_exit) in order to determine when it is safe to release
> such a resource.
> 
> Single-entry/single-exit (se/se) structures always have appropriate places
> for acuiring and freeing resources.  The state of the algorithm is encoded
> into the structure.  Multiple exits, gotos, finally clauses, destructures,
> etc, all *lose* state information.  Once they are invoked, the previous
> state of the algorithm can only be recaptured by investigating the data and
> within the algorithm.  This means flags that cover the entire scope of the
> algorithm must be maintained so that the error recovery code can determine
> what to do.

The whole point of having resource deallocation at the end of the
loop is that you do not want to distribute this into many places.
Are you (I hope not) proposing something like

while( loop should continue )
{
  ...
  if( error 1 )
  {
    do some deallocation
    set flag(s) not to continue
  }
  ...
  if( error 2 )
  {
    do some oother (possibly overlapping) deallocation
    set flag(s) not to continue
  }
...
}

> The decision to use multiple exists (other than exceptions) is a short term
> decision that will probably yeild short term benefits.  But in the long term
> the decision has the potential to cause significant pain.  Personally, I
> have experienced enough of that sort of pain, so I am pretty careful about
> se/se.

As can be deduced from the above I do not agree with you ;-)

Btw. Why, in your opinion, are exceptions different?

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Robert Martin
  1998-09-01  0:00                                                 ` Robert I. Eachus
  1998-09-02  0:00                                                 ` Mattias Lundstr�m
@ 1998-09-02  0:00                                                 ` Mattias Lundstr�m
  2 siblings, 0 replies; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-09-02  0:00 UTC (permalink / raw)


Aggresive cuttings below.

Robert Martin wrote:
> 
[...]
> This is roughly equivalent to the 'finally' solution in another post.  And
> I'll use the same argument.
[...]
[Loop that sets return value 'retval' and does 'goto error_exit' on
error]
> error_exit:
>   if (p) free(p);
>   if (f) fclose(f);
return retval;
// The point is that this is code that is ALWAYS executed.
// The only "multi-exit" issue here is the multiple exit
// points from the loop. The function has only this exit.

Your problem with this is (as I understand you) is the use of flags 
(or other method of tracking) to be able to say 

if( resource1 allocated ) deallocate( resource1 );
if( resource2 allocated ) deallocate( resource2 );
...
if( resourceN allocated ) deallocate( resourceN );

How do you mean that you could avoid this by a single-exit
solution ?

> 
> The redundant resource cleanup, and the checks made in the error_exit
> section are pretty ugly.  And this ugliness will only grow and become more

Perhaps. But I do think they are unavoidable. You may break them up
over multiple functions when and if they become too complex, but this
has really nothing to do with the single/multi-exit issue.

> contorted over time.  Also, it is not guaranteed that all resources will
> have check functions, forcing the use of flags (which is all p and f are
> used for in error_exit) in order to determine when it is safe to release
> such a resource.
> 
> Single-entry/single-exit (se/se) structures always have appropriate places
> for acuiring and freeing resources.  The state of the algorithm is encoded
> into the structure.  Multiple exits, gotos, finally clauses, destructures,
> etc, all *lose* state information.  Once they are invoked, the previous
> state of the algorithm can only be recaptured by investigating the data and
> within the algorithm.  This means flags that cover the entire scope of the
> algorithm must be maintained so that the error recovery code can determine
> what to do.

The whole point of having resource deallocation at the end of the
loop is that you do not want to distribute this into many places.
Are you (I hope not) proposing something like

while( loop should continue )
{
  ...
  if( error 1 )
  {
    do some deallocation
    set flag(s) not to continue
  }
  ...
  if( error 2 )
  {
    do some oother (possibly overlapping) deallocation
    set flag(s) not to continue
  }
...
}

> The decision to use multiple exists (other than exceptions) is a short term
> decision that will probably yeild short term benefits.  But in the long term
> the decision has the potential to cause significant pain.  Personally, I
> have experienced enough of that sort of pain, so I am pretty careful about
> se/se.

As can be deduced from the above I do not agree with you ;-)

Btw. Why, in your opinion, are exceptions different?

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Gerry Quinn
@ 1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` Ell
  1998-09-02  0:00                                                   ` Gerry Quinn
  0 siblings, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Gerry Quinn wrote in message <6sjbso$1lk$2@news.indigo.ie>...

>I would say rather that [spaghetti] is an objective term, nowadays used
>incorrectly as a term of abuse by those who do not actually understand
>the meaning of the word.


FYI, here is the entry in the Hacker Jargon Dictionary:

spaghetti code /n./ Code with a complex and tangled control structure, esp.
one using many GOTOs, exceptions, or other `unstructured' branching
constructs. Pejorative. The synonym `kangaroo code' has been reported,
doubtless because such code has so many jumps in it.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Ell
                                                                   ` (2 preceding siblings ...)
  1998-09-02  0:00                                                 ` adam
@ 1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` Ell
  1998-09-02  0:00                                                   ` Ell
  3 siblings, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Ell wrote in message <35eeea9b.2174586@news.erols.com>...
>On Wed, 2 Sep 1998 00:44:08 -0500, "Robert Martin" <rmartin@oma.com>
>wrote:
>
>
>>In any case, I note that in this thread nearly every article that
advocates
>>multiple exits evokes either readability, complexity, or naturalness as
the
>>justification.  I contend that these are highly subjective things,
>
>This may be true, though I don't thinks so, but adherence to the dogma
>you made up about "single entry and single exit" doesn't make things
>clearer as most see it in this case.

"clearer", again, is subjective IMHO.  In any case, I have not been
recommending aherence to dogma. Rather I have been describing a cost/benfit
trade-off.  On at least two occasions, in this thread, I have said that
there is a time and place for multiple returns; but that such times and
places need to be chosen well based on a real assesment of the costs; an not
a subjective evaluation of what "feels good".
>
>>Finally, I contend that the factors in favor of using a
>>single-entry/single-exit style are, on the other hand, quite concrete and
>>demonstrable.  It has been shown that adhering to a structured style
>
>You have not shown at all that "single entry, single exit" is a
>general coding maxim of structured programming.

Well, that's your opinion.  But I have cited the section of Dijkstra's book
"Structured Programming" that talks about this; and have quoted the page
where it is elaborated; and have summarized the discussion.  It's quite
difficult for me to understand how anyone could read the cited section and
not agree that single-entry/single-exit is a core concept of structured
programming.  I also note that no one else has challenged that assertion.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Richard Jones
@ 1998-09-02  0:00                                               ` Mattias Lundstr�m
  1998-09-02  0:00                                                 ` Patrick Logan
  1998-09-02  0:00                                               ` Mattias Lundstr�m
                                                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-09-02  0:00 UTC (permalink / raw)


Richard Jones wrote:
> Both of you miss the point that exceptions solve this problem
> neatly and naturally, i.e. in some sort of bastardized
> Java/C++ hybrid you might write:
> 
>     File f ("name", File::OpenReadOnly);
>     while (...) {
> 
>       if (error_condition) throw new ErrorException;
>     }
>     return;
> 
> Rich.

Not so. This is equivalent (if only function scope is
considered here):

    File f ("name", File::OpenReadOnly);
    while (...) {
      if (error_condition) return NOT_OK;
    }
    return OK;

which depends on the File object to do the cleanup in
its destructor. This is one way to solve the problem, but
it has nothing to do with the whole exception vs return
code discussion.

Note also that in the case of Java this kind of resource
cleanup may not be satisfactory since we can not know when
the finalization (cleanup) is actually done.

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Richard Jones
  1998-09-02  0:00                                               ` Mattias Lundstr�m
  1998-09-02  0:00                                               ` Mattias Lundstr�m
@ 1998-09-02  0:00                                               ` Mattias Lundstr�m
  1998-09-02  0:00                                               ` Mattias Lundstr�m
  3 siblings, 0 replies; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-09-02  0:00 UTC (permalink / raw)


Richard Jones wrote:
> Both of you miss the point that exceptions solve this problem
> neatly and naturally, i.e. in some sort of bastardized
> Java/C++ hybrid you might write:
> 
>     File f ("name", File::OpenReadOnly);
>     while (...) {
> 
>       if (error_condition) throw new ErrorException;
>     }
>     return;
> 
> Rich.

Not so. This is equivalent (if only function scope is
considered here):

    File f ("name", File::OpenReadOnly);
    while (...) {
      if (error_condition) return NOT_OK;
    }
    return OK;

which depends on the File object to do the cleanup in
its destructor. This is one way to solve the problem, but
it has nothing to do with the whole exception vs return
code discussion.

Note also that in the case of Java this kind of resource
cleanup may not be satisfactory since we can not know when
the finalization (cleanup) is actually done.

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Richard Jones
  1998-09-02  0:00                                               ` Mattias Lundstr�m
@ 1998-09-02  0:00                                               ` Mattias Lundstr�m
  1998-09-02  0:00                                               ` Mattias Lundstr�m
  1998-09-02  0:00                                               ` Mattias Lundstr�m
  3 siblings, 0 replies; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-09-02  0:00 UTC (permalink / raw)


Richard Jones wrote:
> Both of you miss the point that exceptions solve this problem
> neatly and naturally, i.e. in some sort of bastardized
> Java/C++ hybrid you might write:
> 
>     File f ("name", File::OpenReadOnly);
>     while (...) {
> 
>       if (error_condition) throw new ErrorException;
>     }
>     return;
> 
> Rich.

Not so. This is equivalent (if only function scope is
considered here):

    File f ("name", File::OpenReadOnly);
    while (...) {
      if (error_condition) return NOT_OK;
    }
    return OK;

which depends on the File object to do the cleanup in
its destructor. This is one way to solve the problem, but
it has nothing to do with the whole exception vs return
code discussion.

Note also that in the case of Java this kind of resource
cleanup may not be satisfactory since we can not know when
the finalization (cleanup) is actually done.

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Richard Jones
                                                                 ` (2 preceding siblings ...)
  1998-09-02  0:00                                               ` Mattias Lundstr�m
@ 1998-09-02  0:00                                               ` Mattias Lundstr�m
  3 siblings, 0 replies; 510+ messages in thread
From: Mattias Lundstr�m @ 1998-09-02  0:00 UTC (permalink / raw)


Richard Jones wrote:
> Both of you miss the point that exceptions solve this problem
> neatly and naturally, i.e. in some sort of bastardized
> Java/C++ hybrid you might write:
> 
>     File f ("name", File::OpenReadOnly);
>     while (...) {
> 
>       if (error_condition) throw new ErrorException;
>     }
>     return;
> 
> Rich.

Not so. This is equivalent (if only function scope is
considered here):

    File f ("name", File::OpenReadOnly);
    while (...) {
      if (error_condition) return NOT_OK;
    }
    return OK;

which depends on the File object to do the cleanup in
its destructor. This is one way to solve the problem, but
it has nothing to do with the whole exception vs return
code discussion.

Note also that in the case of Java this kind of resource
cleanup may not be satisfactory since we can not know when
the finalization (cleanup) is actually done.

- Mattias




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Matthew Heaney
@ 1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` dennison
                                                                     ` (2 more replies)
  0 siblings, 3 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...

>Without being able to exit from the middle of a loop, I'd have to do
>this to terminate a read sequence:
>
>  Get (N);
>
>  while N /= 0 loop
>
>      <process N>
>
>      Get (N);
>
>  end loop;
>
>So it's the structured approach which causes the redundancy, becuase Get
>must be called twice.

Consider:

   do {
      Get(N);
      if (N)
        <process N>
   } while (N);

Structured programming allows the loop condition to be either at the top or
the bottom.
>
>But Robert, this isn't just "gut reaction."  Researchers empirically
>demonstrated that programmers using an exit from the middle produced
>fewer errors:
>
>Cognitive Strategies and Looping Constructs: An Empirical Study
>Soloway, Bonar, Ehrlich
>CACM, Nov 83, Vol 26, No 11, p853-860

Granted.  I accept that as input to the cost side.  However, as far as I
know the study does not take into account the long term benefits of
structured programming; which has been the major thrust of my argument.
Indeed, my argument has taken as given the assertion that multiple exits are
easier to write and read (for some).  My argument says that there are other
concerns, such as maintenance, that also must be taken into account.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
@ 1998-09-02  0:00                                                   ` Ell
  1998-09-04  0:00                                                     ` Andre Tibben
  1998-09-02  0:00                                                   ` Gerry Quinn
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


On Wed, 2 Sep 1998 08:41:47 -0500, "Robert Martin" <rmartin@oma.com>
wrote:

>Gerry Quinn wrote in message <6sjbso$1lk$2@news.indigo.ie>...
>
>>I would say rather that [spaghetti] is an objective term, nowadays used
>>incorrectly as a term of abuse by those who do not actually understand
>>the meaning of the word.

>FYI, here is the entry in the Hacker Jargon Dictionary:
>
>spaghetti code /n./ Code with a complex and tangled control structure, esp.
>one using many GOTOs, exceptions, or other `unstructured' branching
>constructs. Pejorative. The synonym `kangaroo code' has been reported,
>doubtless because such code has so many jumps in it.

'exit', and 'return' are not "unstructured" branching as I see it.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` Ell
@ 1998-09-02  0:00                                                   ` Ell
  1998-09-02  0:00                                                     ` Robert Martin
                                                                       ` (2 more replies)
  1 sibling, 3 replies; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


On Wed, 2 Sep 1998 08:52:36 -0500, "Robert Martin" <rmartin@oma.com>
wrote:

>
>Ell wrote in message <35eeea9b.2174586@news.erols.com>...
>>
>>You have not shown at all that "single entry, single exit" is a
>>general coding maxim of structured programming.

>Well, that's your opinion.

It's a *fact*!

>But I have cited the section of Dijkstra's book
>"Structured Programming" that talks about this;  
>and have quoted the page where it is elaborated;

That single fragment of a sentence, or at most single sentence, about
*flowcharting* in no way made the case that *coding* in the structured
paradigm should generally adhere to "single entry and single exit".

You are being ultra disengenuous to support your fantasies about
structured programming.

>I also note that no one else has challenged that assertion.

Because no one else is confident enough to challenge you on the point
doesn't ipso factso mean that you are right.  What kind of logic is
that?

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` Mattias Lundstr�m
@ 1998-09-02  0:00                                                 ` Patrick Logan
  1998-09-02  0:00                                                   ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Patrick Logan @ 1998-09-02  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=US-ASCII, Size: 619 bytes --]

In comp.object Mattias Lundstr�m <ehsmalu@ehpt.com> wrote:

: Note also that in the case of Java this kind of resource
: cleanup may not be satisfactory since we can not know when
: the finalization (cleanup) is actually done.

In Java you should always explicitly handle resource deallocation for
all resources that are in any way "precious". Use...

  try {} finally { deallocation }

to ensure that deallocation will occur no later than the exit of the
"try" body.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
@ 1998-09-02  0:00                                                   ` Ell
  1998-09-03  0:00                                                     ` Ole-Hjalmar Kristensen
  1998-09-02  0:00                                                   ` Ell
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

>Ell wrote in message <35eeea9b.2174586@news.erols.com>...
>>
>>"Robert Martin" <rmartin@oma.com> wrote:
>>>
>>>In any case, I note that in this thread nearly every article that
>>>advocates
>>>multiple exits evokes either readability, complexity, or naturalness as
>>>the
>>>justification.  I contend that these are highly subjective things,

>>This may be true, though I don't think[] so, but adherence to the dogma
>>you made up about "single entry and single exit" doesn't make things
>>clearer as most see it in this case.

>"clearer", again, is subjective IMHO.

Quite often the majority or a plurality of programmers is quite
capable of agreeing on what is readable and more easily maintained.
That isn't some kind of wild, unsubstantiated idea.  Programmers have
agreed on that for years.  Geez, loosen up.

>In any case, I have not been
>recommending aherence to dogma.

Yes you have.  You have been citing your imaginary heuristic of
structured programming - single entry, single exit - more than a call
girl shouts for Johns at night.  And as I said:

[You've been palming your "single entry, single exit"]
>dogma off as some kind of officialdom.  Further, he can't prove it as
>officialdom and it wouldn't matter if it was because the
>appropriateness of all heuristics depends on specific concrete
>circumstances.

>Rather I have been describing a cost/benfit trade-off.

And you haven't made your case on this as I see it.

>On at least two occasions, in this thread, I have said that
>there is a time and place for multiple returns; but that such times and
>places need to be chosen well based on a real assesment of the costs; an not
>a subjective evaluation of what "feels good".

In that you haven't proven your cost/benefit assertions, what you say
is what's "gut", and "feels good" to you.

>>>Finally, I contend that the factors in favor of using a
>>>single-entry/single-exit style are, on the other hand, quite concrete and
>>>demonstrable.  It has been shown that adhering to a structured style
>>
>>You have not shown at all that "single entry, single exit" is a
>>general coding maxim of structured programming.
>
>Well, that's your opinion.  But I have cited the section of Dijkstra's book
>"Structured Programming" that talks about this; and have quoted the page
>where it is elaborated; and have summarized the discussion.  It's quite
>difficult for me to understand how anyone could read the cited section and
>not agree that single-entry/single-exit is a core concept of structured
>programming.  I also note that no one else has challenged that assertion.
>
>
>Robert C. Martin    | Design Consulting   | Training courses offered:
>Object Mentor       | rmartin@oma.com     |   Object Oriented Design
>14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
>Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
>
>"One of the great commandments of science is:
>    'Mistrust arguments from authority.'" -- Carl Sagan
>
>





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Matthew Heaney
@ 1998-09-02  0:00                                                       ` Robert Martin
  1998-09-02  0:00                                                         ` Richard Melvin
  1998-09-02  0:00                                                         ` Matthew Heaney
  0 siblings, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...
>"Robert Martin" <rmartin@oma.com> writes:
>
>> Of course later on, someone asks us to sieze and release a mutex for each
>> iteration of the loop.  We'd like to put the seize as the first line of
the
>> loop body, and the release as the last line of the loop body.  But if
there
>> are early exits, then we must put a release before every exit.
>
>No.  Use a controlled type (construction/deconstruction) to
>automatically seize and release:
>
>loop
>   declare
>      Lock : Mutex_Lock (Mutex'Access);
>   begin
>      <use the resource controlled by Mutex>
>   end;
>end loop;
>
>
>When you enter the loop, the Lock object elaborates, and during its
>initialization, it automatically calls the Seize operation of Mutex.
>
>When you leave the loop - via a return, or an exit, or an exception, or
>whatever - the Lock object is Finalized, during which time it
>automatically calls the Release operation of Mutex.
>
>So no, you don't have to worry about bailing out early.  There is no
>maintenance penalty for an early return from the loop.

This is true if:

1. Your language has controlled types.
2. The cleanup that needs to be done can be done from the finalizer.   For
example, in C++ the equivalent scheme is to use a destructor.  However the
destructor is in a completely different scope.  So extraordinary means may
need to be used to allow the destructor access to the variables that need
finalization.

Consider the case of a complex data structure.  You are in the midst of
changing a set of variables within it.  Suddenly you realize that you must
exit early.  Before you can exit, you have to put the data structure back
the way it was.  In C++, getting a destructor to do this can be horrific.

The point is that controlled types are not a generally applicable solution,
since not all languages have them, and not all languages implement them
well.

BTW, in essense a controlled type is simply a way to enforce that a scope
has a single exit.  By using single-entry/single-exit style, *all* your
variables are controlled -- albeit manually.  (excluding exceptions).



Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Mattias Lundstr�m
@ 1998-09-02  0:00                                                   ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-02  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2379 bytes --]


Mattias Lundstr�m wrote in message <35ED4937.1D01ED67@ehpt.com>...
>Aggresive cuttings below.
>
>Robert Martin wrote:
>>
>[...]
>> This is roughly equivalent to the 'finally' solution in another post.
And
>> I'll use the same argument.
>[...]
>[Loop that sets return value 'retval' and does 'goto error_exit' on
>error]
>> error_exit:
>>   if (p) free(p);
>>   if (f) fclose(f);
>return retval;
>// The point is that this is code that is ALWAYS executed.
>// The only "multi-exit" issue here is the multiple exit
>// points from the loop. The function has only this exit.
>
>Your problem with this is (as I understand you) is the use of flags
>(or other method of tracking) to be able to say
>
>if( resource1 allocated ) deallocate( resource1 );
>if( resource2 allocated ) deallocate( resource2 );
>...
>if( resourceN allocated ) deallocate( resourceN );
>
>How do you mean that you could avoid this by a single-exit
>solution ?

Here is the solution I posted a few article back in this thread...

int f()
{
  int retval = 0;
  if (char* p = malloc(80))
  {
    if (File* f = fopen("myFile", "r");
    {
      fread(f, p, 80);
      ...
      fclose(f);
    }
    else // fopen failure
    {
      retval = 2;
    }
    free(p);
  }
  else // malloc failure
  {
    retval = 1;
  }
  return retval;
}

No tests necessary, structure preserved.


>Btw. Why, in your opinion, are exceptions different?

1. They are indeterminate.  When you throw an exception, you have no idea
where control will wind up.  It is not simply an exit from the current
scope, or even from the current function.

2. As I prefer to use them, they are for extraordinary conditions.  They are
used when things go so wrong that there is no point in continuing, and also
no point in maintaining any concern for efficiency.  They are expensive.

Finally, in the end, I still try to force a kind of single-exit mechanism on
exceptions by using:

      catch(...){
        cleanup();
        throw;
      }

(akin to Java's 'finally' clause).


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                     ` Robert Martin
@ 1998-09-02  0:00                                                       ` Andrew Reilly
  1998-09-01  0:00                                                         ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Andrew Reilly @ 1998-09-02  0:00 UTC (permalink / raw)


In article <6sh4o4$afu$1@hirame.wwa.com>,
	"Robert Martin" <rmartin@oma.com> writes:
> 
> dennison@telepath.com wrote in message <6sh30l$k4i$1@nnrp1.dejanews.com>...
>>In article <6sfqul$ggg$1@hirame.wwa.com>,
>>  "Robert Martin" <rmartin@oma.com> wrote:
>>> iteration is the last or not.  Also, a programmer must be aware that the
>>> last statement in the loop body will not be executed on the last iteration.
>>
>>Yes, but if that's what the algorithm is *supposed* to do, rephrasing it with
>>flags and if statements won't change that.
> 
> On the contrary, it is possible to create a loop body with a single
> invariant, and whose last line will be executed in every iteration.

How can you say this?

Or are you counting the endloop statement as the last line?

If the algorithm requires middle exit, and you achieve that with
a flag and an if..endif section around the second half of the loop,
then the second part doesn't execute on the last iteration, exactly
like a break.

-- 
Andrew Reilly                     Reilly@zeta.org.au




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Robert Martin
@ 1998-09-02  0:00                                                 ` Ell
  1998-09-01  0:00                                                   ` Robert Martin
       [not found]                                                 ` <gio+van+no+ni+8-0309982225160001@dialup62.tlh.talstar.com>
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-02  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: Phil Goodwin wrote in message <6shp40$ec8$1@nnrp1.dejanews.com>...
:>In article <6sfcft$70p$1@hirame.wwa.com>,
:>  "Robert Martin" <rmartin@oma.com> wrote:
:>>
:>> Stephen Leake wrote in message ...
:>> >One entry, one exit. Perfectly clear. There's nothing magic about
:>> >putting the exit statement at the top or the bottom!
:>>
:>> In fact there is.  If the exit condition is at the top or the bottom,
: then
:>> the body of the loop will always be excuted an exact integral number of
:>> times.  However if the loop condition is in the middle, then the loop
: body
:>> will be executed a fractional number of times.
:>
:>So what?


: So...  I can guarantee that any line of code placed at the end of the loop
: body will be executed for each iteration of the loop.

Maybe, juuussst maybe, you like many of the rest of us might be able to
design the loop so that "any line of code placed at the end of loop" 
doesn't matter if the exit/return occurs before the end of the loop?

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                         ` Matthew Heaney
@ 1998-09-02  0:00                                                           ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-02  0:00 UTC (permalink / raw)


Matthew Heaney wrote:
> 
> Loryn Jenkins <loryn@s054.aone.net.au> writes:
> 
> > Do you still disagree, Matthew? Given that the complexity is pretty
> > similar---perhaps with some complexity shifted from the flowgraph to the
> > decision table---with the resulting complexity being equivalent. And, I
> > think, all your other points have been addressed by this example ...
> > excepting the 'performance' issue.
> 
> I like what you did, but still prefer to bail out immediately, once I
> know that the answer is false.

Thanks. That is your right.

Thank you for helping facilitate / participating in the most useful
(educational) thread I've read for a *long* time.

I certainly have come to a better appreciation of 'tree-structured'
programming; and although I won't be using it myself, now understand it
ain't all bad ... and, if looked at in a certain way, has its
advantages.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Matthew Heaney
@ 1998-09-02  0:00                                                       ` Loryn Jenkins
  1998-09-02  0:00                                                       ` Tim McDermott
  1998-09-03  0:00                                                       ` Joe Gamache
  2 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-02  0:00 UTC (permalink / raw)


> BTW: Treat minimizing nesting levels seriously.  Whereas Miller's limit
> was 7 plus or minus 2, for a linear sequence of items, the limit is even
> lower (around 3) for nested relationships.  (This info I read in
> Structured Design, by Constantine & Yourdon.)

Thanks for the advice. I will do so, as I have done here.

By the way, your function exhibits more nesting than mine***. Can you
eliminate any?

*** My reading of it is that it always had *at least* as much nesting,
and now certainly has more.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` sureshvv
@ 1998-09-03  0:00                                                         ` Patrick Logan
  1998-09-04  0:00                                                           ` Matthew Heaney
  1998-09-03  0:00                                                         ` Robert Martin
  1 sibling, 1 reply; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object sureshvv@hotmail.com wrote:

: I would like to find out the costs that are associated with the se/se
: structure of functions.

: 1. Increases level of nesting in code, making it potentially more complex.

You should procedures or methods to make loops more abstract and smaller.

: 2. Requires adding flag variables which have to be tracked, making it
: more complex.

A flag variable can actually make a complex condition more readable by
providing it with a meaningful name.

: 3. Special conditions can become embedded in code rather than being readily
: apparent.

I'd have to see an example of this in either style in order to
understand it. Nothing should be *too* hidden if the loop text is kept
to a manageable size. Size is (almost) everything. Beyond that names,
comments, and good, nested, formatting should make a loop's control
flow and special cases apparent.

Please throw your worst one at us, so we can all refactor it to our
liking!

(Reminds me of the revived GOTO controversy, in what? The
Communications of the ACM about ten years ago or so.)

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00             ` Patrick Doyle
@ 1998-09-03  0:00               ` Martin Tom Brown
  1998-09-03  0:00               ` Tim McDermott
  1 sibling, 0 replies; 510+ messages in thread
From: Martin Tom Brown @ 1998-09-03  0:00 UTC (permalink / raw)


On Thursday, in article <EypnAz.L66@ecf.toronto.edu>
     doylep@ecf.toronto.edu "Patrick Doyle" wrote:

> In article <35EDC648.76F03F32@draper.com>,
> Tim McDermott  <mcdermott@draper.com> wrote:
> >
> >This seems a little extreme to me.  While I have great respect for
> >combinatorial explosion, you are talking about a 3-term boolean expression.
> >There are only 6 ways to put one of those together, and I have no trouble
> >evaluating any of the forms.  I know because I just listed them all, and ran
> >through their evaluation with no problem.

> Could you explain how you got the 6?

> Maybe what you're talking about is these?...
> 
>  A + B + C
>  A & B + C
>  A &(B + C)
>  A + B & C
> (A + B)& C
>  A & B & C
> 
> However, these aren't really 6 distinct expressions.  The third
> and fifth are the same, as are the second and fourth.

Are your sure about that ??

And what did 

  B + A & C
  B &(A + C)

Do to deserve being missed out ?  

And when you allow for the shortcircuiting that some compilers 
do in code generation to avoid evaluting terms which cannot 
affect the result even things like A + B + C vs B + A + C
could be distinct if there were side effects in A,B or C.

I know they should not be, but people do these things.

Regards, 
-- 
Martin Brown  <martin@nezumi.demon.co.uk>     __                CIS: 71651,470
Scientific Software Consultancy             /^,,)__/





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` sureshvv
@ 1998-09-03  0:00                                                         ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object sureshvv@hotmail.com wrote:

: > >void AFunction(...)
: > >{
: > >  if not (SomeCondition)    and
: > >     not (AnotherCondition) and
: > >     not (AThirdCondition)  then
: > >
: > >  // now do the real work...
: > >
: > >  endif
: > >  return;
: > >}

: Note that this has added a level of nesting to the real work (tm). Now also
: consider the case where you might have to return different error conditions
: to the calling routine. And/Or you have to output some message to a log file
: for each of the conditions.

If I have to do something like this, I usually put the body in its own
method that does not have these checks at all, something like this...

void AFunction(...)
{
  if (someCondition) {
    throw ...
  } else if (anotherCondition) {
    throw ...
  } else if (aThirdCondition) {
    throw ...
  } else if (...) {
    throw ...
  } else {
    AFunctionWithGoodStanding(...)
  }
}

void AFunctionWithGoodStanding(...)
{
  ...do the real stuff...
}

Then it is clear the first function's purpose is to get all the issues
out of the way and the second function's purpose is to do the work.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` sureshvv
  1998-09-03  0:00                                                         ` Patrick Logan
@ 1998-09-03  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                           ` Mike Spille
  1998-09-06  0:00                                                           ` Charles Hixson
  1 sibling, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



sureshvv@hotmail.com wrote in message <6smmhv$1kp$1@nnrp1.dejanews.com>...
>In article <6skqf3$9g0$1@hirame.wwa.com>,
>  "Robert Martin" <rmartin@oma.com> wrote:
>
>>  Knowledge of the benefits and costs of
>> single-entry/single-exit functions should be firmly ingrained in all
>> software engineers.
>
>I would like to find out the costs that are associated with the se/se
>structure of functions.
>
>1. Increases level of nesting in code, making it potentially more complex.
>2. Requires adding flag variables which have to be tracked, making it
>more complex.
>3. Special conditions can become embedded in code rather than being readily
>apparent.


1 and 2 are certainly costs; although perhaps overstated.  I don't
understand 3.

As for 1, nesting level becomes explicit, whereas early returns hide the
true nesting level.  Consider:


void f()
{
  if (condition.1) return;
  if (condition.2) return;
  do something useful
  return;
}

This is equivalent to:

void f()
{
  if (condition.1) return;
  else if (condition.2) return;
  else do something useful;
  return;
};

Which, in reality, is:

void f()
{
  if (condition.1) return;
  else{
    if (condition.2) return;
    else {
      do something useful;
    }
  }
};

So, early returns do not actually reduce nesting; they just appear to.  The
problem is that subsequent changes to the function may force you to separate
the flows that multiple exits have combined.

So, the benefit of multiple returns is not a reduction in nesting, but just
an *apparent* reduction in nesting.  The cost, on the other hand, is that
the nesting will have to be unhidden later.

Point 2 is certainly a cost.  The creation of mutable state is always
annoying.  On the other hand, the loss of control flow state is also
annoying.  Both have their own benefits and costs.  The cost of capturing
state in se/se is paid once when you write the module, and once for every
person who must understand it.  The cost of rederiving state lost by merging
control flows is paid every time the function changes in such a way that the
state must be rederived.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00             ` Patrick Doyle
  1998-09-03  0:00               ` Martin Tom Brown
@ 1998-09-03  0:00               ` Tim McDermott
  1998-09-04  0:00                 ` Patrick Doyle
  1998-09-04  0:00                 ` Matthew Heaney
  1 sibling, 2 replies; 510+ messages in thread
From: Tim McDermott @ 1998-09-03  0:00 UTC (permalink / raw)




Patrick Doyle wrote:
snip

> >you are talking about a 3-term boolean expression. There are only 6 ways to
> put one of those together, and I have no trouble
> >evaluating any of the forms.  I know because I just listed them all, and ran
> >through their evaluation with no problem.
>
> Could you explain how you got the 6?

I was wearing my bithead, thinking about the textual form of a predicate.  I did
neglect negation.

> If you want to talk about how many possible boolean expressions there
> are with n terms, that's 2^(2^n).  There are 2^n assignments for the
> variables, and any combination of those assignments could make
> the expression true.

There are 4 possible 1-term boolean expressions?  Could you list them?Perhaps
this is a terminology problem.  By 3-term, I don't mean 3 variables used as often
as you like, I mean 3 occurances of any variable and 2 operators (again
neglecting negation).
I am counting "A & (!A)" as a 2-term expression.

> If you're just talking about how many disjunctions there are, even
> that is 2^n because any combination of terms can be negated.
>
> Maybe what you're talking about is these?...

Yep, the very beasts.

>  A + B + C
>  A & B + C
>  A &(B + C)
>  A + B & C
> (A + B)& C
>  A & B & C
>
> However, these aren't really 6 distinct expressions.  The third
> and fifth are the same, as are the second and fourth.

Hmmm.  With A and B false and C true, the second expresion is true, while the
fourth is false.  The third and fifth expressions differ when A is false and B
and C are true.  (assuming '&' has higher precedence than '+')

I guess the moral of the story is that this stuff really is hard, even at 3
terms.


Tim






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                         ` Robert Martin
@ 1998-09-03  0:00                                                           ` Mike Spille
  1998-09-03  0:00                                                             ` Robert Martin
  1998-09-06  0:00                                                           ` Charles Hixson
  1 sibling, 1 reply; 510+ messages in thread
From: Mike Spille @ 1998-09-03  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> sureshvv@hotmail.com wrote in message <6smmhv$1kp$1@nnrp1.dejanews.com>...
> >In article <6skqf3$9g0$1@hirame.wwa.com>,
> >  "Robert Martin" <rmartin@oma.com> wrote:
> >
> >>  Knowledge of the benefits and costs of
> >> single-entry/single-exit functions should be firmly ingrained in all
> >> software engineers.
> >
> >I would like to find out the costs that are associated with the se/se
> >structure of functions.
> >
> >1. Increases level of nesting in code, making it potentially more complex.
> >2. Requires adding flag variables which have to be tracked, making it
> >more complex.
> >3. Special conditions can become embedded in code rather than being readily
> >apparent.
> 
> 1 and 2 are certainly costs; although perhaps overstated.  I don't
> understand 3.
> 
> As for 1, nesting level becomes explicit, whereas early returns hide the
> true nesting level.  Consider:
> 

"True nesting level"?  Sounds metaphysical.  In a C-like language I define
nesting level as "how many open braces have I got"?  (oh, this works for me
'cause I always brace-ify if/do/while/for/etc statements, even for one liners).

> void f()
> {
>   if (condition.1) return;
>   if (condition.2) return;
>   do something useful
>   return;
> }
> 
> This is equivalent to:
> 
> void f()
> {
>   if (condition.1) return;
>   else if (condition.2) return;
>   else do something useful;
>   return;
> };
> 
> Which, in reality, is:
> 
> void f()
> {
>   if (condition.1) return;
>   else{
>     if (condition.2) return;
>     else {
>       do something useful;
>     }
>   }
> };
> 
> So, early returns do not actually reduce nesting; they just appear to.  The
> problem is that subsequent changes to the function may force you to separate
> the flows that multiple exits have combined.
> 

Nesting is as nesting does.  Your first example does not have any "hidden"
nesting; it avoids nesting by using multiple-returns.  Period.  You may
introduce nesting later on but that doesn't mean the nesting was hidden
in the function, struggling to get out :-)

I've seen the style you've shown above in example 3 in code before.  It
invariably was written by someone who religiously followed the 1 entrance/
1 exit philosophy.  The reality of reading such code was that the meat of
function, the code that actually did "work" within the function, was buried under
a pile of ifs, and forced the reader seperate the wheat from the chaff in
a painful manner.  In the first example above, it's immediately obvious
where the "meat" is.

To put it another way, example 1 puts emphasis on the "do something useful"
section.  Example 3 hides "do something useful", and emphasizes the
condition checking instead.

[snip]

> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

	-Mike




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Phil Goodwin
@ 1998-09-03  0:00                                                       ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Phil Goodwin wrote in message <6smrvi$86c$1@nnrp1.dejanews.com>...
>
>The message that I'm interested in conveying is not that the rule is bad
and
>should be thrown out, but rather that it shouldn't be rigidly applied in
every
>circumstance. Knowing why the rule exists at all and what benefit following
it
>confers is IMHO far more important than always following it to the letter
>because it's a Good Thing.


Then we are in agreement.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                           ` Mike Spille
@ 1998-09-03  0:00                                                             ` Robert Martin
  1998-09-03  0:00                                                               ` Mike Spille
                                                                                 ` (3 more replies)
  0 siblings, 4 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Mike Spille wrote in message <35EEBA15.30C3CC76@tisny.com>...
>Robert Martin wrote:

>
>> void f()
>> {
>>   if (condition.1) return;
>>   if (condition.2) return;
>>   do something useful
>>   return;
>> }
>>
>> This is equivalent to:
>>
>> void f()
>> {
>>   if (condition.1) return;
>>   else if (condition.2) return;
>>   else do something useful;
>>   return;
>> };
>>
>> Which, in reality, is:
>>
>> void f()
>> {
>>   if (condition.1) return;
>>   else{
>>     if (condition.2) return;
>>     else {
>>       do something useful;
>>     }
>>   }
>> };
>>
>
>Nesting is as nesting does.  Your first example does not have any "hidden"
>nesting; it avoids nesting by using multiple-returns.  Period.  You may
>introduce nesting later on but that doesn't mean the nesting was hidden
>in the function, struggling to get out :-)

Draw the flowcharts of the three snippets above.  You will find that they
are identical.  Now ask yourself whether or not nesting is a semantic
quality, or just a comment.  If nesting is a semantic quality, then how can
three identical flowcharts have different nesting?  On the other hand, if
nesting has no semantic content, then why do we do it?

Indentation is one of the ways we represent nesting.  The three functions
shown above use different indentation schemes.  Nesting, on the other hand,
occurs when control flow splits.  The branches below the split are nested.

>I've seen the style you've shown above in example 3 in code before.  It
>invariably was written by someone who religiously followed the 1 entrance/
>1 exit philosophy.

All of the snippets above violate se/se; so anybody who religiously followed
se/se would not use any of them.

Also, I would advise that religiously following se/se, or any other
paradigm, is foolish.

>The reality of reading such code was that the meat of
>function, the code that actually did "work" within the function, was buried
under
>a pile of ifs, and forced the reader seperate the wheat from the chaff in
>a painful manner.  In the first example above, it's immediately obvious
>where the "meat" is.

It seems to me that in all of the styles above, the work is buried under a
pile of ifs.  And the flowchart of the three shows this to be true as well.
I think you are really saying that the second and third show the work to be
indented to the right of a pile of ifs.

Now, in a real se/se function that checks a few things before doing the real
work, the real work will be the most indented part of the function.  People
who train themselves to know that the real work is the stuff that is most
indented, have little trouble finding it.

>
>To put it another way, example 1 puts emphasis on the "do something useful"
>section.  Example 3 hides "do something useful", and emphasizes the
>condition checking instead.


It's odd, but that's exactly the statement I'd make about se/se.

It seems to me that:

 if (A is right)
   if (B is right)
     if (C is right)
        then do the work.

emphasizes the work more than:

if (A is wrong) then return;
if (B is wrong) then return;
if (C is wrong) then return;
do the work;

So, I think the notion of "emphasis" is somewhat subjective.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                 ` Jim Cochrane
  1998-09-02  0:00                   ` Richard Melvin
@ 1998-09-03  0:00                   ` Robert I. Eachus
  1 sibling, 0 replies; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6siqo0$hiv@flatland.dimensional.com> jtc@dimensional.com (Jim Cochrane) writes:

 > Looking at your routine, you need to check 3 different places to check that
 > the postcondition is upheld, the 3 return statements:  In the first if
 > statement, in the second if statement in the middle of the loop, and at the
 > end of the routine.  This is a pretty straightforward process, but I think
 > it makes it a little more difficult in that you need to check 3 separate
 > locations, including in the middle of the loop.

     But this is irrelevant to the way the code was written, and to
the way it should be understood.  The code flows from this problem
statement:  "Two lists are equal if they are the same length and each
element in the first list is equal to the corresponding element in the
second list."

     Now the postconditions corresponding to the three exits are:

     Lengths not equal, lists not equal.
     Element L.Items(Index) /= R.Items(Index), lists not equal.
     Lengths and all elements equal, lists are equal.

     Before you jump all over me, realize that this is a DIFFERENT way
of treating postconditions, factoring the full statement of the
postcondition into separate cases, and having an exit/return for each
case.  There are many cases where it results in the best code, there
are others where it is not the method of choice, but if you are
willing to accept multiple returns, then you should add this approach
to your bag of tricks.

     (Notice that it works best when you can linearize the cases as
you can here.)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Patrick Logan
@ 1998-09-03  0:00                                                       ` Robert I. Eachus
  0 siblings, 0 replies; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-03  0:00 UTC (permalink / raw)


In article <xChH1.6534$f01.4705828@news.teleport.com> Patrick Logan <plogan@user2.teleport.com> writes:

  > The C, C++, Java, Smalltalk, and Common Lisp languages all allow a
  > form of a "return" statement to appear anywhere within a block of
  > statements. Some of these languages have a form of GOTO that allow
  > multiple exits from loops. I would think these languages make up
  > "most modern languages".

  I could add more to the list, but you are missing the point.  All of
these languages have exceptional ways of returning to some other point
in the code, but the return statements all go to the point of the call
(unless you fiddle with the stack).  In ancient days the return stack
was under programmer control, so you often saw code that changed the
return address.  (I remember once wanting to throw one of those 4"
thick binders of listings across the room because I finally tracked
down an obscure bug to a pair of lines that read:

    RETURN = IS TBD
  C SET RETURN VALUE

  (Yes, FORTRAN 66 didn't hiccup.  The careful leading I made that TBD
an integer, and once I found it, that blasted comment gave no clue as
to what that value should be changed to!  Oh, yes, the space was
non-significant, so that variable was named ISTBD.)

  > I remember some FORTRAN code to do printed circuit board layout
  > implementing all of its loops using GOTOs. Some of these loops had
  > GOTOs at the top that jumped into the middle of the "loop"!

  Of course, that was the "normal" way to do an N and a half loop in
FORTRAN.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                               ` mfinney
@ 1998-09-03  0:00                                                 ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



mfinney@lynchburg.net wrote in message ...

>Reaching zero bugs means that changes are made by development
>rather than maintenance.  That distinction is, of course, a matter of
>definition.

Yes, and apparently our definitions differ.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                         ` Robert Martin
@ 1998-09-03  0:00                                                           ` Joe Gwinn
  1998-09-03  0:00                                                             ` Robert Martin
  1998-09-06  0:00                                                             ` Charles Hixson
  0 siblings, 2 replies; 510+ messages in thread
From: Joe Gwinn @ 1998-09-03  0:00 UTC (permalink / raw)


It seems to me that there is an unspoken assumption in the long debate
about GOTOs and spaghetti code:  It doesn't follow that presence of GOTOs
makes code spaghetti, or that code without GOTOs is always clear and easy
to understand, write, and maintain.  

The issues are in my experience quite independent.  I have seen lots of
spaghetti code with nary a GOTO, and perfectly clear code with many GOTOs.

I would submit that good programmers write clear, simple code, regardless
of the nature of the language or language constructs used.  (With the
possible exception of APL, which was known as the write-only language.)  I
have seen the same effect in the design of digital hardware.  The key
issue is clarity of thought; lost-puppy engineers will do the oddest
things, at length.  It can be painful to watch, and hard on the engineer.

So, the whole 1970s debate about structured programming (and thus GOTOs)
reduced to the fond hope that if we tied the hands of those lost-puppy
programmers, they would no longer be lost, and would then think ahead and
write good code.

By that same token, if we take a hard-to-use tool away from a rough
carpenter, he will suddenly become a cabinetmaker.


Joe Gwinn




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                             ` Robert Martin
@ 1998-09-03  0:00                                                               ` Mike Spille
  1998-09-03  0:00                                                                 ` Robert Martin
  1998-09-04  0:00                                                                 ` sureshvv
  1998-09-04  0:00                                                               ` Ray Blaak
                                                                                 ` (2 subsequent siblings)
  3 siblings, 2 replies; 510+ messages in thread
From: Mike Spille @ 1998-09-03  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Mike Spille wrote in message <35EEBA15.30C3CC76@tisny.com>...
> >Robert Martin wrote:
> 
> >
> >> void f()
> >> {
> >>   if (condition.1) return;
> >>   if (condition.2) return;
> >>   do something useful
> >>   return;
> >> }
> >>
> >> This is equivalent to:
> >>
> >> void f()
> >> {
> >>   if (condition.1) return;
> >>   else if (condition.2) return;
> >>   else do something useful;
> >>   return;
> >> };
> >>
> >> Which, in reality, is:
> >>
> >> void f()
> >> {
> >>   if (condition.1) return;
> >>   else{
> >>     if (condition.2) return;
> >>     else {
> >>       do something useful;
> >>     }
> >>   }
> >> };
> >>
> >
> >Nesting is as nesting does.  Your first example does not have any "hidden"
> >nesting; it avoids nesting by using multiple-returns.  Period.  You may
> >introduce nesting later on but that doesn't mean the nesting was hidden
> >in the function, struggling to get out :-)
> 
> Draw the flowcharts of the three snippets above.  You will find that they
> are identical.  Now ask yourself whether or not nesting is a semantic
> quality, or just a comment.  If nesting is a semantic quality, then how can
> three identical flowcharts have different nesting?  On the other hand, if
> nesting has no semantic content, then why do we do it?
> 

Well, I can make a semantically equivalent program out of gotos - so what?
I thought the point was readability and maintainability.

Your second and third examples add a bunch of extra tokens a reader of
the code has to scan.  Turning this into single/entry, single/exit will
do the same or add even more tokens.  This enhanes maintainablility?

> Indentation is one of the ways we represent nesting.  The three functions
> shown above use different indentation schemes.  Nesting, on the other hand,
> occurs when control flow splits.  The branches below the split are nested.
> 
> >I've seen the style you've shown above in example 3 in code before.  It
> >invariably was written by someone who religiously followed the 1 entrance/
> >1 exit philosophy.
> 
> All of the snippets above violate se/se; so anybody who religiously followed
> se/se would not use any of them.
> 

Whoops - my eyes failed me on that one.  Mea culpa.

> Also, I would advise that religiously following se/se, or any other
> paradigm, is foolish.
> 
> >The reality of reading such code was that the meat of
> >function, the code that actually did "work" within the function, was buried
> under
> >a pile of ifs, and forced the reader seperate the wheat from the chaff in
> >a painful manner.  In the first example above, it's immediately obvious
> >where the "meat" is.
> 
> It seems to me that in all of the styles above, the work is buried under a
> pile of ifs.  And the flowchart of the three shows this to be true as well.
> I think you are really saying that the second and third show the work to be
> indented to the right of a pile of ifs.
> 

What my brain sees in case one is a bunch of constraint-type checks that
"abort" if they fail.  Following that is un-nested, unindented code which
can rely on the guarantees made at the top of the function.

The third case isn't as clear cut in my eyes.  The meat of the code is
physically contained within the constraint checks.  In addition, if this
code takes up more than a page, I have to worry about an else possibly
being hung on to the end.

> Now, in a real se/se function that checks a few things before doing the real
> work, the real work will be the most indented part of the function.  People
> who train themselves to know that the real work is the stuff that is most
> indented, have little trouble finding it.
> 

I avoid syntax-level nesting (e.g. open curlies and indenting for C-based
stuff) when I can, because I find nesting negatively impacts readability.
This is highly subjective of course.  

> >
> >To put it another way, example 1 puts emphasis on the "do something useful"
> >section.  Example 3 hides "do something useful", and emphasizes the
> >condition checking instead.
> 
> It's odd, but that's exactly the statement I'd make about se/se.
> 
> It seems to me that:
> 
>  if (A is right)
>    if (B is right)
>      if (C is right)
>         then do the work.
> 
> emphasizes the work more than:
> 
> if (A is wrong) then return;
> if (B is wrong) then return;
> if (C is wrong) then return;
> do the work;
> 
> So, I think the notion of "emphasis" is somewhat subjective.
> 

Defintely so - I find having the most important code stuck in column X (where
X can vary, depending on how many checks and the nesting level) very hard
to follow over large programs.  Having the important stuff at the zero
indentation level seems much more natural.

> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

	-Mike




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                         ` Ell
@ 1998-09-03  0:00                                                           ` Robert Martin
  1998-09-04  0:00                                                             ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Ell wrote in message <35f23ce2.7649859@news.erols.com>...

>
>Think "avoid unstructured control flow", and not "avoid [creating code
>which has multiple exits]".

You had best define 'unstructured' in this context.  Dijkstra's definition
of 'unstructured control flow' is control flow that does not conform
precisely to the four standard sequencing elements {sequence, selection, top
exit loop, bottom exit loop}, all of which have a single entry and a single
exit.

>That's the true spirit of one aspect of the structured paradigm as I
>see it.  The other being that we should use abstractions to design
>code and to model functional domain processes.
>
>It was Dijkstra who said he thinks of *abstraction* when someone
>mentions "structured programming".

Indeed, Dijkstra talks about abstraction quite a bit in the book "Structured
programming".  One of his uses of the term is that the four sequencing
elements he recommends can all be considered to be units whose internals
can, at times, be ignored (i.e. abstracted away) because they have a single
entry and a single exit.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                               ` Mike Spille
@ 1998-09-03  0:00                                                                 ` Robert Martin
  1998-09-04  0:00                                                                 ` sureshvv
  1 sibling, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Mike Spille wrote in message <35EEF0D1.939F1907@tisny.com>...
>Robert Martin wrote:
>>
>> Mike Spille wrote in message <35EEBA15.30C3CC76@tisny.com>...
>> >Robert Martin wrote:
>>
>> >
>> >> void f()
>> >> {
>> >>   if (condition.1) return;
>> >>   if (condition.2) return;
>> >>   do something useful
>> >>   return;
>> >> }
>> >>
>> >> This is equivalent to:
>> >>
>> >> void f()
>> >> {
>> >>   if (condition.1) return;
>> >>   else if (condition.2) return;
>> >>   else do something useful;
>> >>   return;
>> >> };
>> >>
>> >> Which, in reality, is:
>> >>
>> >> void f()
>> >> {
>> >>   if (condition.1) return;
>> >>   else{
>> >>     if (condition.2) return;
>> >>     else {
>> >>       do something useful;
>> >>     }
>> >>   }
>> >> };
>> >>
>> >
>> >Nesting is as nesting does.  Your first example does not have any
"hidden"
>> >nesting; it avoids nesting by using multiple-returns.  Period.  You may
>> >introduce nesting later on but that doesn't mean the nesting was hidden
>> >in the function, struggling to get out :-)
>>
>> Draw the flowcharts of the three snippets above.  You will find that they
>> are identical.  Now ask yourself whether or not nesting is a semantic
>> quality, or just a comment.  If nesting is a semantic quality, then how
can
>> three identical flowcharts have different nesting?  On the other hand, if
>> nesting has no semantic content, then why do we do it?
>>
>Well, I can make a semantically equivalent program out of gotos - so what?
>I thought the point was readability and maintainability.

It is.  And I agree with you that, for most people at least, the first
snippet is more readable than the other two simply because it has fewer
tokens.

>Your second and third examples add a bunch of extra tokens a reader of
>the code has to scan.

Correct, and I do not recommend them; the added tokens serve no extra
purpose.  I was just demonstrating that the first example was just as nested
as the others (if not as indented).

>Turning this into single/entry, single/exit will
>do the same or add even more tokens.  This enhanes maintainablility?

It can.  Yes, more tokens may be added.  But in an se/se structure, each
added token serves a purpose.  It serves to expose a control flow that would
otherwise be hidden, or to separate a control flow that would otherwise have
been merged.  Does this benefit offset the additional tokens?  That depends
up the kinds of changes that the function faces in the future.  My own
personal view is that the cost of the extra tokens is low, whereas the cost
if separating control flows in the future is high, so I usually prefer to
keep the control flows separate.



Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                               ` <gio+van+no+ni+8-0309982311220001@dialup62.tlh.talstar.com>
@ 1998-09-03  0:00                                                 ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Giovanni 8 wrote in message ...
>> Robert Martin wrote:
>
>> Finally, I contend that the factors in favor of using a
>> single-entry/single-exit style are, on the other hand, quite
>> concrete and demonstrable.  It has been shown that adhering
>> to a structured style facilitates both resource management and
>> error processing.
>
>Non sequitur.  It hasn't been concretely shown that single
>exits at the bottom of a loop facilitates resource management,
>and I know it makes error processing more difficult because
>the erroneous state is retained while slogging through
>irrelevant code to the bottom of the loop.  It's a kludge.

If the loop, or function, is properly structured, then upon detection of the
error, no further code is executed except the code that must be executed to
complete the loop.

while (some condition)
{
  if (vetting condition)
    do something interesting
  else
    report error
}

No slogging through irrelevant code, no retention of erroneous state.  And,
the extra benefit that the loop body is completely self contained.  For
example, I can put X and UNX calls at the top and bottom of the loop body,
and guarantee that every X and UNX will be paired.

while (some condition)
{
  X();
  if (vetting condition)
    do something interesting
  else
    report error
  UNX();
}

>Multiple exits, OTOH, are elegant.

They can be, but they also have costs:

while (some condition)
{
  if (!vetting condition) {
    report error;
    continue;
  }
  do something interesting;
}

Why this is any more elegant than the se/se version above, I can't say;
though some folks do like to focus on the negative aspects of the invariants
first.  However, this code no longer has the nice self contained property.
I can no longer add the X and UNX pair conveniently.  Rather I must add UNX
in two places:

while (some condition)
{
  X();
  if (!vetting condition) {
    report error;
    UNX();
    continue;
  }
  do something interesting;
  UNX();
}

This is a concrete benefit of se/se.  It is not an appeal to elegance or
readability.  It is not an appeal to prettiness or common sense.  It is an
ability that se/se code has, that is lost if the se/se style is not
conformed to.

Does that mean that se/se should be *always* be used?  No, it's just a
concrete, demonstrable, benefit.



>
>> It has also been shown that a multiple exit style is
>> vulnerable to redundant code, and code for recovery of
>> state...
>
>No, that has not been shown,

I presume that the above is sufficient proof?  Note the reduntant UNX() call
in the second case.

>& I contend that it is the
>exit only from the bottom of a loop style that creates
>a need for redundant or extraneous code, while multiple
>exits eliminates it.

Can you provide a case in point like the one above?

>Multiple exits promote
>Readability: The code follows the algorithm without any
>  extraneous matter.
>Complexity: No extraneous matter.  No multiple checks of
>  a condition or state.  No flags.
>Naturalness: The exit happens when the prescribed condition
>  is satisfied, not before, and not after.

I think the above is rather subjective as the following rebuttal points out.
se/se promotes:

Readability: every control flow is explicit.
Complexity management: since all control flows are explicit, adding new
statement to existing control flows is trivial.
Natrualness: the function happens when all the vetting conditions pass, all
error recovery is at the end, and each is in its own specific control flow,
so that specific error recovery is trivial.

>"[I]n the early 1980s, a survey [1980 _Software Maintenance
> Management_ pp 151-157 & 492-497] by [B.] Lientz & [E.] Swanson
> of 487 data processing organizations showed that only 20% of
> the maintenance effort was spent on corrective maintenance.
> [And 42% on user requested enhancements.]" --- Carma McClure
> 1992 _The 3 Rs of Software Automation_ pp 15-17


Precisely!  Programs need changing a lot more than then need fixing.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                           ` Joe Gwinn
@ 1998-09-03  0:00                                                             ` Robert Martin
  1998-09-04  0:00                                                               ` sureshvv
  1998-09-04  0:00                                                               ` Ell
  1998-09-06  0:00                                                             ` Charles Hixson
  1 sibling, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Joe Gwinn wrote in message ...

>I would submit that good programmers write clear, simple code, regardless
>of the nature of the language or language constructs used.  (With the
>possible exception of APL, which was known as the write-only language.)  I
>have seen the same effect in the design of digital hardware.  The key
>issue is clarity of thought; lost-puppy engineers will do the oddest
>things, at length.  It can be painful to watch, and hard on the engineer.

Hardware engineers have their own intresting set of principles that they
need to adhere to.  Woe to the hardware engineer who does not use bypass
capacitors.  Woe to the hardware engineer who runs HF digital lines next to
analog feedback lines.  etc, etc..  In other words, there are things that
the experienced hardware engineer knows that "you just don't do".


>So, the whole 1970s debate about structured programming (and thus GOTOs)
>reduced to the fond hope that if we tied the hands of those lost-puppy
>programmers, they would no longer be lost, and would then think ahead and
>write good code.

Negative.  That is not the point, nor ever was the point.  The point of
structured programming was not the elimination of GOTO.  Indeed, you can
write perfectly structured programs with GOTO.  The point of structured
programming was to recusively form the structure of an algorithm using units
that have a single-entry and a single exit.  And this structure has some
concrete and well understood benefits.

Even now, any programming standard that forces engineers to follow this
scheme is probably broken.  It is more important the engineer understand the
costs and benefits of structured programming; then force them to blindly
follow it.

It was not Dijkstra's hope that we could tie the hands of the young puppies
and thereby make good engineers out of them.  Rather, I think it was his
hope that experienced engineers would understand his suggestions and find
that they had value in at least some contexts.



Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                   ` Patrick Doyle
@ 1998-09-03  0:00                                                     ` Charles Hixson
  1998-09-03  0:00                                                       ` John G. Volan
  0 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-03  0:00 UTC (permalink / raw)


In order for that to be an equivalently obvious form one would need to
adopt an indentation convention that caused the exit test to stand-out
as well as the top and the bottom of the loop do.  Probably not hard,
especially with colored-syntax editors (environments?), but not a
current standard. (Well, at least not one that I know.)

Patrick Doyle wrote:
...
> How would you feel about a loop...exit_when...end_loop structure?
> It has only one exit point.  You could still add something to
> the end of every iteration by putting it before the exit_when.
> 
> This seems pretty safe to me.  Do you see any reason this would
> be less manageable than a top- or bottom-exit loop?
> 
>  -PD
> 
> --
> --
> Patrick Doyle
> doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Robert Martin
@ 1998-09-03  0:00                                                     ` Charles Hixson
  1998-09-04  0:00                                                       ` adam
  1998-09-04  0:00                                                       ` Patrick Logan
  1998-09-04  0:00                                                     ` Rick Smith
  1 sibling, 2 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-03  0:00 UTC (permalink / raw)


Robert Martin wrote:
... 
> If only it were so.  But of course many of the Y2K problems are not being
> solved by expanding the field to four digits.  Rather they are adding *code*
> not *space*.  The technique is called windowing.  Whenver date subtractions
> or comparisons are done in the code, they interpreted as follows:
> 
>    if date > X assume 1900 else assume 2000
> 
> If X is 50 then any date larger than 50 is assumed to be in the 20th
> century.  Otherwise the data is assumed to be in the 21st century.
> 
> This, of course, means that there will be a Y2050 crisis.  Ah, but no.
> Because X is not universally agreed upon.  Some applications use 60, some
> use 40.  So what we really have is a smearing of the crisis over the next
> several decades.
> 
> Of course none of those old COBOL programs will still be running then...
> 
> The choice to use windowing rather than 4 digit dates is also an engineering
> trade off.
> 
... 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

I hope that you are wrong about what they are doing.  I fear that you
aren't.  Windowing is a good solution for recovering the data before
saving it into a new format.  It's a very bad permanent "solution". 
Usually.

Sometimes one can define a window based around the current date that
will work in a permanent manner (data only kept for so long, e.g.).  And
in such cases one would always be able to recalculate the data to the
expanded format whenever needed. (This is why there should never be a
9999 crisis).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Charles Hixson
@ 1998-09-03  0:00                                                       ` John G. Volan
  0 siblings, 0 replies; 510+ messages in thread
From: John G. Volan @ 1998-09-03  0:00 UTC (permalink / raw)


Charles Hixson wrote:
> 
> In order for that to be an equivalently obvious form one would need to
> adopt an indentation convention that caused the exit test to stand-out
> as well as the top and the bottom of the loop do. 

Sure, why not?  See my post on another branch of this thread (gads, such
metaphor mixing!), describing a possible Eiffel extension that would
satisfy your criterion ("Mid-Loop 'Until' Proposal").

> Probably not hard,
> especially with colored-syntax editors (environments?), but not a
> current standard. (Well, at least not one that I know.)
> 
> Patrick Doyle wrote:
> ...
> > How would you feel about a loop...exit_when...end_loop structure?
> > It has only one exit point.  You could still add something to
> > the end of every iteration by putting it before the exit_when.
> >
> > This seems pretty safe to me.  Do you see any reason this would
> > be less manageable than a top- or bottom-exit loop?

I think the key question is whether one can devise a reasonable
semantics for such a construct such that important principles like
Design By Contract are upheld.  (Again, cf. my "Mid-Loop 'Until'
Proposal" post.)

-- 
indexing
   description: "Signatures for John G. Volan"
   self_plug: "Ex Ada guru", "Java 1.1 Certified", "Eiffelist wannabe"
   two_cents: "Java would be even cooler with Eiffel's assertions/DBC, %
              %generics, true MI, feature adaptation, selective export, %
              %uniform access, expanded types, etc., etc..."
class JOHN_VOLAN_SIGNATURE inherit SIGNATURE invariant
   disclaimer: not (opinion implies employer.opinion)
end -- class JOHN_VOLAN_SIGNATURE




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                                   ` Robert Martin
                                                                       ` (3 preceding siblings ...)
  1998-09-02  0:00                                                     ` Matthew Heaney
@ 1998-09-03  0:00                                                     ` mfinney
       [not found]                                                     ` <gio+van+no+ni+8-0309982244140001@dialup62.tlh.talstar.com>
  5 siblings, 0 replies; 510+ messages in thread
From: mfinney @ 1998-09-03  0:00 UTC (permalink / raw)


In <6siijm$h1m$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> writes:

>Lets just say, for grins, that I must make a change to the loop.  For some
>odd reason I must count the number of times that the loop body completes.
>Where do I put the code that does this counting?  I'd like to make it the
>last line of the loop.  But if there are early exits, then I must find each
>and every early exit and add the code just before they exit.

>Of course, later, someone else will make a change that forces yet another
>early exit.  They find where to add the early exit, but they must remember
>to bump the counter before they exit.

>Of course later on, someone asks us to sieze and release a mutex for each
>iteration of the loop.  We'd like to put the seize as the first line of the
>loop body, and the release as the last line of the loop body.  But if there
>are early exits, then we must put a release before every exit.

>Of course later on someone adds yet another early exit to the loop, and must
>remember to bump the counter and release the mutex.

>.....  Has anybody out there ever had an experience like this?

Not a problem...I would simply double click the opening {, hit tab to shift
the block right, alt-{ to create a new block, a search and replace for
"return" in the high-lighted block to use a different multi-level exit
control structure (probably a goto to a name at the end of the block
in C/C++) and add a wrapper the top of the block -- a

	do {/*code*/} while (false); multiLevelExitName:

would do the trick nicely.  My code is still tree structured, and I can now
add new code just before or after the do..while to satisify your
requirements.  Also, the above took about 10 or 15 seconds, perhaps 30
with the search and replace.  If the return has a value, then I might
need to add a block variable to contain the return value and my edit
for the return would be slightly more complex -- but even so, the
edit cost is trivial compared to understanding the needed changes.

Now...if I were still using a card punch, I would... (well, I guess that nobody
cares about that anymore <g>)


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00             ` Patrick Doyle
  1998-09-02  0:00               ` Patrick Logan
  1998-09-02  0:00               ` Robert Martin
@ 1998-09-03  0:00               ` mfinney
  1998-09-03  0:00                 ` Patrick Doyle
  1998-09-03  0:00               ` Matthew Heaney
  3 siblings, 1 reply; 510+ messages in thread
From: mfinney @ 1998-09-03  0:00 UTC (permalink / raw)


In <EynyFt.Mwz@ecf.toronto.edu>, doylep@ecf.toronto.edu (Patrick Doyle) writes:

>In article <6sjms6$7c4$1@hirame.wwa.com>,
>Robert Martin <rmartin@oma.com> wrote:

>>1. They are indeterminate.  When you throw an exception, you have no idea
>>where control will wind up.  It is not simply an exit from the current
>>scope, or even from the current function.

>By this logic, polymorphism is indeterminate too.  When you call a
>polymorphic function, you have no idea where control will
>wind up.  This is a Good Thing.  It's what makes polymorphism
>powerful: the fact that you're giving someone else some control
>over the situation makes your code flexible.

>The same holds for exceptions.

>Having said that, I just used an exception for the first time
>yesterday.  I (almost) never use them, and I don't even know
>why.  But the nondeterminism isn't it.

Everybody in favor of non-deterministic algorithms (and control
structures) raise your hand!  They are not common, but sometimes
they are just the ticket.  It just requires a different way of thinking
to use them.  Don't knock non-determinism -- even Dijkstra's guarded
conditions are non-deterministic.  Knock instead an inappropriate
use of non-determinism.


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
  1998-09-02  0:00                                                       ` Ell
@ 1998-09-03  0:00                                                       ` Malcolm Steel
       [not found]                                                       ` <o1fH1.543$495.1 <gwinn-0309982042490001@d8.dial-4.cmb.ma.ultra.net>
  2 siblings, 0 replies; 510+ messages in thread
From: Malcolm Steel @ 1998-09-03  0:00 UTC (permalink / raw)


Robert Martin wrote:

> >>But I have cited the section of Dijkstra's book
> >>"Structured Programming" that talks about this;
> >>and have quoted the page where it is elaborated;

> Elliott, you really ought to read the book.  I've given you enough pointers.
> Do your homework.



I have largeley ignored this thread, however I would like to ask a
general question that this dicussion demonstrates:
Why are engineers with new/different ideas always shot down without
consideration ?  So many times I have seem new thoughts and ideas
attacked without any consideration.  A classic move is to quote a book. 
It seems books are law, even i they are not always correct (often they
are not !!!).

I'm not taking sides, infact I beleive that single entry/exit is best,
however, before shooting down alternative thoughts they should be
considered.

Often dicussions become heated between engineers with new thoughts and
the book bashers.  Why ???? ... what ever happend to open minds ?




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Phil Goodwin
  1998-09-01  0:00                                               ` Biju Thomas
@ 1998-09-03  0:00                                               ` Ole-Hjalmar Kristensen
  1 sibling, 0 replies; 510+ messages in thread
From: Ole-Hjalmar Kristensen @ 1998-09-03  0:00 UTC (permalink / raw)


Phil Goodwin<pgoodwin@my-dejanews.com> writes:

> In article <6sf87j$47n$1@hirame.wwa.com>,
>   "Robert Martin" <rmartin@oma.com> wrote:
> >
> > Matthew Heaney wrote in message ...
> >
> > >
> > >Would the implementation be better by not using multiple returns?
> >
> > Yes.  Imagine that you had to change the function to make it thread safe;
> > and that the way to do that was to sieze and release a mutex while the
> > function was executing.  As written you would have to add the release in
> > three separate places.  But if you had avoided the multiple returns, you
> > would have had a single release.
> 
> Or you could use the Initialization is Resource Aquisition idiom and thereby
> choose not to have the problem in the first place, takes care of 'returns'
> caused by exceptions as well.
> 
> You could also choose to refactor the code at the time that you are adding
> the mutex. First rewrite the routine with a single return and no mutex and
> test it to make sure that it still works and then add the mutex and the
> single release.
> 
> I write plenty of little routines that have loops in them that exit in the
> middle. It doesn't make sense to me to alter the algorithm and write extra
> code just so that the routine might be easier to maintain someday (if ever).
> On the other hand, when I DO maintain such a routine I definitely WILL make
> sure that there is only one exit point if that's what is needed to eliminate
> duplicate code.
> 
> I adopted this position in part because of some of what I've read about
> Extreme Programming. I haven't adopted it wholesale, but I do like their
> no-nonsense philosophy. They use two balancing maxims that I've applied to
> this question: Do The Simpest Thing That Could Possibly Work; and Once And
> Only Once. So when I write a function I do the simplest thing that could
> possibly work, which sometimes means sticking a return right smack in the
> middle of a loop. I am especially likely to do this when the loop body is
> less than five lines long anyway. Then, when I have to refactor in order to
> add the aquisistion and release of some resource, I rearrange the routine so
> that I add the code once and only once. The justification for this is that I
> don't want to adopt a coding task because it _might_ be needed during
> maintenance, I would rather do it during maintenance when I KNOW that it
> needs to be done.
> 
> Phil
> 
> -----== Posted via Deja News, The Leader in Internet Discussion ==-----
> http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum

Yes. Another useful principle is to refactor the code by adding
another subroutine which does the aquisition and release, and calls
the exixting routine in between. This avoids changing the semantics of
the existing routine, which may be desirable.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` Mike Spille
  1998-09-03  0:00                                                   ` Richard MacDonald
@ 1998-09-03  0:00                                                   ` Gerry Quinn
  2 siblings, 0 replies; 510+ messages in thread
From: Gerry Quinn @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6skhpr$459$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> wrote:

>Think about this for a minute.  Wouldn't it be nice if you *could* stick a
>line of code at the end of every loop, or at the end of every function, and
>be guaranteed that it would be called?  For example, have you every had to
>put those interesting little print statements into functions:  "entering
>function x", "exitting function x"?  Wouldn't it be nice if you could just
>plop those print statement in without having to anlayze each and every
>function for multiple returns?
>

It would be pretty easy - just wrap the function in another one.  Of 
course by doing this you wouldn't have access to the local variables 
of the function without having to understand the function - but that 
can hardly be the point of 'structured programming', can it...?

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Ole-Hjalmar Kristensen
@ 1998-09-03  0:00                                                       ` Ell
  1998-09-03  0:00                                                         ` Martin Tom Brown
  1998-09-03  0:00                                                         ` Patrick Doyle
  0 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object Ole-Hjalmar Kristensen <ohk@tfdt-o.nta.no> wrote:

: Please cool off! According to Dijkstra (not RCM)
: single-entry/single-exit IS a core concept of structured programming.
: Whether you agree that it is good idea, is another thing.

I suppose you have heard that from his mouth, or you can cite his
writings?

Elliott
--
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00               ` Matthew Heaney
@ 1998-09-03  0:00                 ` Robert Martin
  1998-09-03  0:00                   ` Patrick Logan
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...

>  Seize (M);
>  <do some work that may throw an exception>
>  Release (M);
>
>The problem is that flow of control skips right past the Release when an
>exception occurs.  This loss of control is definately NOT a good thing,
>because it will cause deadlock.
>
>My rebuttal to Robert's argument is that the seize and release calls
>should be called automatically, not manually by the programmer.  Even if
>an exception occurs, Release gets called (automatically), and so no
>resource problems can occur.


And I agree.  Controlled type, or RAI, are good approaches to managing
resources, whether in the presence of exceptions or not.

My point is that the technique is not completely general. It works well for
mutexes, allocated memory buffers, locks, etc.  But does not work as well
for restoring partial results in complex data structures, etc.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Matthew Heaney
  1998-09-03  0:00                                                         ` Patrick Logan
  1998-09-03  0:00                                                         ` Robert Martin
@ 1998-09-03  0:00                                                         ` Robert Martin
  2 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...

>> For example, suppose I need to flush some buffers at the end of each
>> iteration.  I do this by calling 'flush'.   I must write this as:
>>
>>     for(;;)
>>     {
>>        Get(N);
>>        if (N)
>>
>>          <process N>
>>          flush();
>>        }
>>        else {
>>          break;
>>          flush();
>>        }
>>     }
>
>I'm confused by your example.  How does flush() get called in the else
>part, if it's immediately preceeded by a break?

Sorry, flush() should precede break;  (too many articles, too little time.)

>Shouldn't it be just
>
>   for(;;)
>   {
>      Get(N);
>      if (N)
>        <process N>
>        flush();
>      }
>      else {
>        break;
>      }
>   }

No, every Get must be followed by a flush in this case.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Matthew Heaney
  1998-09-03  0:00                                                         ` Patrick Logan
@ 1998-09-03  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                           ` Biju Thomas
                                                                             ` (2 more replies)
  1998-09-03  0:00                                                         ` Robert Martin
  2 siblings, 3 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-03  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...
>"Robert Martin" <rmartin@oma.com> writes:

>>     for(;;)
>>     {
>>        Get(N);
>>        if (N)
>>          <process N>
>>        else
>>          break;
>>     }
>>

>
>Boy oh boy, Robert, we must come from different programming schools!

And that's part of the point I'm trying to make.  There is no single
readability standard.  We all come from different schools in some way or
another.  So what you think is readable, will not be as readable to me, or
to someone else.

>
>The dangerous thing about the code fragment above is that the else part
>can get lost, especially if <process N> is long-ish.
>
>My philosophy is, handle the simple case first, then bail out:
>
>   for (;;)
>   {
>      Get (N);
>
>      if (!N) break;
>
>      <process N>
>   }


Ask yourself why 'break' is the most important concept of this function?
Why is it more important to get the exceptional conditions out of the way
first rather than to get right into the actual purppose of the function.

I prefer a style that moves into the real action of the function as quickly
as possible, while deferring the exceptional conditions to the end.

Consider this, would you prefer that catch statements *precede* try blocks?

catch(memerr)
{
}
catch(fileerr)
{
}
try
{
}


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                 ` Robert Martin
@ 1998-09-03  0:00                   ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: My point is that the technique is not completely general. It works well for
: mutexes, allocated memory buffers, locks, etc.  But does not work as well
: for restoring partial results in complex data structures, etc.

It would work well in a transactional runtime environment that
supported nested transactions. A modification of some structure could
be attempted within a nested transaction. If it failed for any reason,
that transaction could be aborted, restoring the state of the runtime
to what it was before the modification.

Gemstone does not currently offer nested transactions. If you abort,
you abort the all changes since the beginning of the current
transaction. But you could still use a try{}finally{} in this style.

Gemstone does have a "selective abort" where you can choose the
specific objects to abort. You could selectively abort your
modifications in a try{}finally{}. But this is tricky. Selective abort
is usually considered a tool for implementing Gemstone itself, and not
an application developer's tool.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Robert Martin
  1998-09-02  0:00                                                   ` Mike Spille
@ 1998-09-03  0:00                                                   ` Richard MacDonald
  1998-09-03  0:00                                                   ` Gerry Quinn
  2 siblings, 0 replies; 510+ messages in thread
From: Richard MacDonald @ 1998-09-03  0:00 UTC (permalink / raw)


Robert Martin wrote in message <6skhpr$459$1@hirame.wwa.com>...
>Think about this for a minute.  Wouldn't it be nice if you *could* stick a
>line of code at the end of every loop, or at the end of every function, and
>be guaranteed that it would be called?  For example, have you every had to
>put those interesting little print statements into functions:  "entering
>function x", "exitting function x"?  Wouldn't it be nice if you could just
>plop those print statement in without having to anlayze each and every
>function for multiple returns?


Very nice. Good example would be one of those cases where you are using an
expensive resource (e.g., a file) and need to ensure that you close it
whether or not everything worked great or it bombed. Smalltalk uses the
aBlock #ensure: anotherBlock syntax, meaning no matter what happens in
aBlock, anotherBlock is always executed when aBlock terminates. While this
doesn't apply to loops, there are two ways to make it so: (1) Move
everything in the loop to another method, then put the method in a block and
apply the #do:ensure: approach to it. (2) For each loop method in the
library, add another method that includes the #ensure: block. For the
latter, you would want to have both pre and post ensure blocks, so this gets
a little cumbersome. However, you would only have to write it (them) once,
then all your code could use it (them).

I've enjoyed following this discussion, but I think people are concentrating
on too low a level. That is appropriate for procedural code (structured
code). But we are missing higher-level solutions that OO provides us. In
Smalltalk, the do loop is itself an OO method (construction). So why not add
additional methods (constructions)?

P.S. I like the #ensure: option, but I have measured a factor of 20
performance hit in Smalltalk when I use it.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Matthew Heaney
@ 1998-09-03  0:00                                                         ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object Matthew Heaney <matthew_heaney@acm.org> wrote:
: Patrick Logan <plogan@user2.teleport.com> writes:

: > If you memoize the result of the first test, then the second test is
: > about as fast as can be...
: > 
: >   boolean test;
: >   ...
: >   do {
: >     ...
: >     test = N;
: >     if (test)
: >       ...
: >   } while (test);
: > 
: > This does not add a new state to a decision table. It provides a
: > mnemonic for the test condition. The redundant test is minimal
: > compared to the other work in the loop, not to mention the rest of the
: > application. If you are writing small methods anyway, then it is very
: > clear what is occurring.

: The thing I dislike about this code fragment is that it creates an extra
: variable.  

: I still prefer to do this:

:    for (;;) {
:      Get (N);

:      if (N == 0) break;

:      <process N>
:    }

: No extra variable is required.

I am not going to argue *strongly* for or against either style. Just
keep the loop to ten lines, as in these examples, and I can see easily
what it does. If you instead have a longer loop with more
conditionals, etc. then I need to spend more effort examining the loop
to see if there is more than one place the "infinite" loop actually
terminates.

So I can sum up my position is that size *does* matter!

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Ole-Hjalmar Kristensen
@ 1998-09-03  0:00                                                         ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object Ole-Hjalmar Kristensen <ohk@tfdt-o.nta.no> wrote:

: If you believe that this assingnment makes the second test faster in
: the general case, you are very wrong. It may even make the loop
: slower, depending on the optimizer.  I've had this happen to me more
: than once.  I have to side with the middle exit guys in this
: case. One of the reasons why I like the Ada loop construct.

More than that, I believe it is readable and maintainable and fast
enough. I'd wait for a profiler to tell me this is where I should
spend any more effort on performance.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Matthew Heaney
@ 1998-09-03  0:00                                                         ` Patrick Logan
  1998-09-03  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                         ` Robert Martin
  2 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object Matthew Heaney <matthew_heaney@acm.org> wrote:

: Boy oh boy, Robert, we must come from different programming schools!

: The dangerous thing about the code fragment above is that the else
: part can get lost, especially if <process N> is long-ish.

If you think <process N> should be longish *in line* then I can state
it as a fact we come from different schools! Because my school taught
me *modular* programming as well as structured!

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Ell
@ 1998-09-03  0:00                                                         ` Martin Tom Brown
  1998-09-03  0:00                                                         ` Patrick Doyle
  1 sibling, 0 replies; 510+ messages in thread
From: Martin Tom Brown @ 1998-09-03  0:00 UTC (permalink / raw)


On Thursday, in article
     <e8wH1.1153$H8.146210891@newsreader.digex.net>
     ell@access5.digex.net "Ell" wrote:

> In comp.object Ole-Hjalmar Kristensen <ohk@tfdt-o.nta.no> wrote:
> 
> : Please cool off! According to Dijkstra (not RCM)
> : single-entry/single-exit IS a core concept of structured programming.
> : Whether you agree that it is good idea, is another thing.
> 
> I suppose you have heard that from his mouth, or you can cite his
> writings?

Off hand no, but the emphasis on "maintainence of functional domain"
and subsequent development of the box diagram N-S or Chapin charts
which prevented the fundamental maxims of structured programming 
from ever being violated would lend support to his argument.

That this could lead to logical contortions and inefficiency if 
applied too dogmatically was an argument Knuth used in about '75.
ISTR nested loop escapes were used as the counter example then.

Regards,
-- 
Martin Brown  <martin@nezumi.demon.co.uk>     __                CIS: 71651,470
Scientific Software Consultancy             /^,,)__/





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                         ` Robert Martin
@ 1998-09-03  0:00                                                           ` Biju Thomas
  1998-09-03  0:00                                                           ` Phil Goodwin
  1998-09-04  0:00                                                           ` Ell
  2 siblings, 0 replies; 510+ messages in thread
From: Biju Thomas @ 1998-09-03  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Matthew Heaney wrote in message ...
> >"Robert Martin" <rmartin@oma.com> writes:
> 
> >>     for(;;)
> >>     {
> >>        Get(N);
> >>        if (N)
> >>          <process N>
> >>        else
> >>          break;
> >>     }
> >
> >My philosophy is, handle the simple case first, then bail out:
> >
> >   for (;;)
> >   {
> >      Get (N);
> >
> >      if (!N) break;
> >
> >      <process N>
> >   }
> 
> Why is it more important to get the exceptional conditions out of the way
> first rather than to get right into the actual purppose of the function.

Don't you feel more secure when you code like this? When I take care of
the exceptional condition first and proceed to the actual process after
ensuring that everything is well, I don't have to worry about
exceptional and special cases anymore. This may be an illusion, but
helps to keep the mind focussed on the actual purpose of the function.

This is somewhat similar to ensuring pre-conditions in a function.

> I prefer a style that moves into the real action of the function as quickly
> as possible, while deferring the exceptional conditions to the end.
> 
> Consider this, would you prefer that catch statements *precede* try blocks?
> 
> catch(memerr)
> {
> }
> catch(fileerr)
> {
> }
> try
> {
> }

This is a different situation. Here, you don't know that the exceptional
condition has occured, whereas in the previous case, you know that it
occured, and postpone the appropriate actions to a different place in
the code. So, these cases are not comparable.

Biju Thomas




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
  1998-09-03  0:00                                                       ` Ell
@ 1998-09-03  0:00                                                       ` sureshvv
  1998-09-03  0:00                                                         ` Patrick Logan
  1998-09-03  0:00                                                         ` Robert Martin
  1 sibling, 2 replies; 510+ messages in thread
From: sureshvv @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6skqf3$9g0$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:

>  Knowledge of the benefits and costs of
> single-entry/single-exit functions should be firmly ingrained in all
> software engineers.

I would like to find out the costs that are associated with the se/se
structure of functions.

1. Increases level of nesting in code, making it potentially more complex.
2. Requires adding flag variables which have to be tracked, making it
more complex.
3. Special conditions can become embedded in code rather than being readily
apparent.

suresh

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Robert Martin
@ 1998-09-03  0:00                                                     ` sureshvv
  0 siblings, 0 replies; 510+ messages in thread
From: sureshvv @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6skp0i$8i9$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Exceptions are extraordinary.  By the time you throw an exception, things
> have gone very wrong. Yes, there is some cleanup you may need to do.  But
> there is also quite a bit that you can probably ignore.

In one part of the system, Yes. The system could self-rectify and continue to
function or function in a slightly degraded manner long after the exception
is thrown. Of course, depending upon what you decided to cleanup and what you
ignored :-)

suresh


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-03  0:00                                                       ` sureshvv
  1998-09-03  0:00                                                         ` Patrick Logan
  1998-09-06  0:00                                                       ` Charles Hixson
  1 sibling, 1 reply; 510+ messages in thread
From: sureshvv @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6sknla$7so$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Robert Oliver wrote in message <35EDAC92.538A@hfl.tc.faa.gov>...
>
> >
> >I am not arguing against all use of multiple returns in a procedure or
> >function.  I often write a function like this:
> >
> >void AFunction(...)
> >{
> >  if (SomeCondition) return;
> >  if (AnotherCondition) return;
> >  if (AThirdCondition) return;
> >
> >  // now do the real work...
> >
> >  return;
> >}
> >
<portions elided>
> >
> >Of course, it could also be written as:
> >
> >void AFunction(...)
> >{
> >  if not (SomeCondition)    and
> >     not (AnotherCondition) and
> >     not (AThirdCondition)  then
> >
> >  // now do the real work...
> >
> >  endif
> >  return;
> >}
>
> Which is usually how I would choose to write it.  (Active voice instead of
> passive voice. ;^)
>

Note that this has added a level of nesting to the real work (tm). Now also
consider the case where you might have to return different error conditions
to the calling routine. And/Or you have to output some message to a log file
for each of the conditions.

Will the answer still be the same?

suresh

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00               ` mfinney
@ 1998-09-03  0:00                 ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-03  0:00 UTC (permalink / raw)


In article <oUsH1.484$qj1.1164857@newsread.com>,
 <mfinney@lynchburg.net> wrote:
>In <EynyFt.Mwz@ecf.toronto.edu>, doylep@ecf.toronto.edu (Patrick Doyle) writes:
>
>>Having said that, I just used an exception for the first time
>>yesterday.  I (almost) never use them, and I don't even know
>>why.  But the nondeterminism isn't it.
>
>Everybody in favor of non-deterministic algorithms (and control
>structures) raise your hand!  They are not common, but sometimes
>they are just the ticket.  It just requires a different way of thinking
>to use them.  Don't knock non-determinism -- even Dijkstra's guarded
>conditions are non-deterministic.  Knock instead an inappropriate
>use of non-determinism.

Wait, have another look at my quote.  I wasn't knocking nondeterminism.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <35EDC648.76F03F32@draper.com>
@ 1998-09-03  0:00             ` Patrick Doyle
  1998-09-03  0:00               ` Martin Tom Brown
  1998-09-03  0:00               ` Tim McDermott
  0 siblings, 2 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-03  0:00 UTC (permalink / raw)


In article <35EDC648.76F03F32@draper.com>,
Tim McDermott  <mcdermott@draper.com> wrote:
>
>This seems a little extreme to me.  While I have great respect for
>combinatorial explosion, you are talking about a 3-term boolean expression.
>There are only 6 ways to put one of those together, and I have no trouble
>evaluating any of the forms.  I know because I just listed them all, and ran
>through their evaluation with no problem.

Could you explain how you got the 6?

If you want to talk about how many possible boolean expressions there
are with n terms, that's 2^(2^n).  There are 2^n assignments for the
variables, and any combination of those assignments could make
the expression true.

If you're just talking about how many disjunctions there are, even
that is 2^n because any combination of terms can be negated.

Maybe what you're talking about is these?...

 A + B + C
 A & B + C
 A &(B + C)
 A + B & C
(A + B)& C
 A & B & C

However, these aren't really 6 distinct expressions.  The third
and fifth are the same, as are the second and fourth.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                     ` <6sjnlu$83l$1@hirame.wwa.c <35EE5F67.80D@gecm.com>
@ 1998-09-03  0:00                                                       ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-03  0:00 UTC (permalink / raw)


In article <35EE5F67.80D@gecm.com>,
Malcolm Steel  <malcolm.steel@gecm.com> wrote:
>
>I have largeley ignored this thread, however I would like to ask a
>general question that this dicussion demonstrates:
>Why are engineers with new/different ideas always shot down without
>consideration ?  So many times I have seem new thoughts and ideas
>attacked without any consideration.  A classic move is to quote a book. 
>It seems books are law, even i they are not always correct (often they
>are not !!!).

If you are referring to the Martin vs. Coates thing in this thread,
then I'll remind you that it is Elliott that shot down Robert's
statement about what SP is, and it was Elliott who *asked* for
the quotes from the book.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Ell
  1998-09-03  0:00                                                         ` Martin Tom Brown
@ 1998-09-03  0:00                                                         ` Patrick Doyle
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-03  0:00 UTC (permalink / raw)


In article <e8wH1.1153$H8.146210891@newsreader.digex.net>,
Ell  <ell@access5.digex.net> wrote:
>
>I suppose you have heard that from his mouth, or you can cite his
>writings?

Have you been reading this thread?  His writings have been cited.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Matthew Heaney
  1998-09-02  0:00                                                       ` Loryn Jenkins
  1998-09-02  0:00                                                       ` Tim McDermott
@ 1998-09-03  0:00                                                       ` Joe Gamache
  1998-09-04  0:00                                                         ` Charles Hixson
  2 siblings, 1 reply; 510+ messages in thread
From: Joe Gamache @ 1998-09-03  0:00 UTC (permalink / raw)


Matthew Heaney wrote:

> Loryn Jenkins <loryn@s054.aone.net.au> writes:
>
> > Now, someone else was kind enough to show me an even simpler way of
> > doing this ... albeit marginally less efficient (and again, I don't care
> > about this criteria, unless my application beforms below specification
> > and my profiler shows me that this is a hot spot).
> >
> > equal (l,r: LIST): BOOLEAN is
> >       require
> >           l /= Void and r /= Void
> >       do
> >           from
> >               Result := (l.count = r.count)
> >               l.start; r.start
> >           until
> >               not Result or l.off
> >           loop
> >               Result := (l.item = r.item)
> >               l.forth; r.forth
> >           end
> >       end
> >
> > This, at least, loses your nesting objection. In fact, it has less
> > nesting than your original example. However, it might mislead unless the
> > reader was aware of this sort of idiom. (It does simplify things though;
> > so I think I'll be using this style, where appropriate.)
>
> I like that there's less nesting, but still have a couple of issues with
> it:
>
> 1) The decision table for the predicate still has 4 rules instead of 2.
>

If I follow your logic here it seems seriously flawed to me.  You ignore the
contribution of the 'if" statement bailout in your orginal example as two
additional cases for the decision table.  Otherwise, we can carry your
arguement to its logical extreme and "improve" your code by ALWAYS making
infinite loops and "bailing out" in the middle:

function "=" (L, R : Stack_Type) return Boolean is
begin

   if L.Top /= R.Top then
      return False;
   end if;

    Index : Positive := 1;
   while (True) loop                 ! is 'loop' supposed to be 'do' ?? can't
recall
      if L.Items (Index) /= R.Items (Index) then
         return False;
      end if;
       if Index = L.Top then
         return True;                        ! bail out as soon as I know
I can
       end if;
        Index := Index + 1;
   end loop;

end "=";

Please excuse any syntax errors.  I think the above is a nightmare.  Do
people actually think it is an improvement?  But your logic seems to say
there are zero cases to consider in the decision tree for the loop
predicate.  Otherwise there is 4 in your original example and this example.
You can not mathematically have it both ways.

> 2) It still bothers me a little that once you calculate the value of
> Result (the second time, when comparing items), you still do some work
> after (to increment the iterators), even though the result may already
> be False.
>
> The latter point is only a nit.  It's the first point that puts a bee in
> my bonnet.  It may not seem like much in this example, because we're
> "only" going from 2 rules to 4.  But things get scary really fast when
> going 4 to 8.
>
> This was my experience trying to decipher someone else's post, in which
> a flag was added to a decision table with 4 rules, doubling the size to
> 8.  I wouldn't have been able to figure things out without using a
> decision table.  (I haven't caught on to K-maps yet, but decision tables
> are my best friend.)
>
> BTW: Treat minimizing nesting levels seriously.  Whereas Miller's limit
> was 7 plus or minus 2, for a linear sequence of items, the limit is even
> lower (around 3) for nested relationships.  (This info I read in
> Structured Design, by Constantine & Yourdon.)

This bothers me also.  Dr. Miller's work is often quoted in our business.
Yet theproject I'm currently working on is distributed on 27 ultrasparc
computers and
I understand it!  Am I some aberration, some wierd freak of nature capable of

feats of cognition heretofore undreamed of?  As further evidence, my last
project
consisted over well over 100 classes.  I knew and understood not only each
class,
but their interaction with one another as well.  Boy, my ego is really going
now.
Wait!  Everyone else here understands the system on the 27 computers as well.

Either this is a rare group of genius individuals or something else is going
on.
Perhaps it is that Miller's work regarding the "magic" number of 7 +/- 2 was
on short term memory.  Thus, if you are giving a pitch you don't want too
many
bullets, classes, boxes, or anything else on it - if you NEED your audience
to
remember something meaningful.  But, for more intensive study the human
brain's
cognitive limits are often go well beyond 9.  Oh no!  This means I'm only
normal
(okay this may now be debateable....)






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Robert Martin
@ 1998-09-03  0:00                                                     ` Phil Goodwin
  1998-09-03  0:00                                                       ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Phil Goodwin @ 1998-09-03  0:00 UTC (permalink / raw)


Comments interspersed...

In article <6skerj$1u5$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Phil Goodwin wrote in message <6sk01j$1qn$1@nnrp1.dejanews.com>...
> >
> >I would posit that if you are changing the function at all you must do a
> >complete regression test on it. I grant you that the more you change the
> >routine the more likely you are to introduce bugs and that is an important
> >consideration. However, what we are doing here is deffering the risk of
> >creating a more complicated algorithm to the point in time where we know
> that
> >the risk is worthwhile.
>
> Unfortunately, by the time you know that the structure is wrong, it is often
> difficult to justify making it right.  It is almost always easier to find a
> clever fix than it is to restructure so that the clever fix isn't necessary.
> (witness the windowing technique for fixing Y2K bugs).

Then you must either arrange things so that you never have to restructure or
you must have some way to know when to restructure rather than make a 'clever
fix'.

> Now, you might
> suggest that once faced with the choice of clever fix or refactoring, one
> should always choose refactoring.  But I will respond to that with two
> points.

I might suggest that, but, as it happens I will not...

> 1. Your premise is that you shouldn't pay for a risk you aren't sure will
> materialize.  Since you don't know that you'll need another clever fix, your
> premise will lead you to simply make the current clever fix.
>
> 2. Multiple returns *were* the first clever fix.
>
> If you look at these two statements carefully you will realize that they
> form the essense of inductive reasoning; leading to the conclusion that true
> refactoring will never happen.

Right, the premise that you should Do The Simplest Thing That Could Possibly
Work isn't powerful enough to enable decisions in all cases. There is another
useful premise that the Extreme Programming guys call "Once And Only Once"
that is used to trigger refactoring. In short, in prohibits 'clever tricks'
that lead to code duplication. The Once And Only Once rule will save us from
making the mistakes that you have presented in your examples. It may turn out
to be insufficient to overcome all the shortcomings of Do The Simplest Thing
That Could Possibly Work, but I'm not aware of any examples where it doesn't.

> I take slightly different view.  If the cost of protecting myself from risk
> is low, and if the cost of the risk materializing is high, then I will pay
> for the risk up front.  It's like buying insurance.
>
> >The only other option is to assume that the risk will
> >always turn out to be worthwhile and code the more complicated algorithm in
> >every case.
>
> Again, if cost of the more complex algorithm is low, and if the cost of the
> risk is high, then this may not be a bad decision.
>
> >My position is not that strict structured programming has no benefit, it is
> >that it has a cost and that the cost is not justified unless the benefit is
> >recieved.
>
> Is the cost of your medical insurance, or your auto insurance, or your life
> insurance justified?
> Of course it is!  (and you should see my health insurance rates!)  The
> reason it is justified is that the potential downside is enormous.
>
> So the justificaton of a maintainable approach must be that the downside
> potential is high enough to get us to gladly pay the up front costs of
> protection.

So, you are saying that, in the cases where the risk DOES turn out to be
worthwhile the value is so great that it outweighs the cost in all the other
cases where the precaution turned out to be unnecessary? I think that this is
sound reasoning, but it hinges on the premise that the realized value is very
great. So you insure your home but not your plastic lawn furniture. I advocate
for using SE/SE on large complicated functions, but not always on small simple
ones.

The message that I'm interested in conveying is not that the rule is bad and
should be thrown out, but rather that it shouldn't be rigidly applied in every
circumstance. Knowing why the rule exists at all and what benefit following it
confers is IMHO far more important than always following it to the letter
because it's a Good Thing.

Phil

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                           ` Biju Thomas
@ 1998-09-03  0:00                                                           ` Phil Goodwin
  1998-09-04  0:00                                                             ` Matthew Heaney
  1998-09-04  0:00                                                           ` Ell
  2 siblings, 1 reply; 510+ messages in thread
From: Phil Goodwin @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6sm6md$3fh$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Matthew Heaney wrote in message ...
> >My philosophy is, handle the simple case first, then bail out:
> >
> >   for (;;)
> >   {
> >      Get (N);
> >
> >      if (!N) break;
> >
> >      <process N>
> >   }
>
> Ask yourself why 'break' is the most important concept of this function?
> Why is it more important to get the exceptional conditions out of the way
> first rather than to get right into the actual purpose of the function.

You are absolutely right about readability Robert, I read this as "!N is a
precondition of <process N>. It IS important to know what the preconditions of
the function are before you get into the actual purpose of the function.

> I prefer a style that moves into the real action of the function as quickly
> as possible, while deferring the exceptional conditions to the end.
>
> Consider this, would you prefer that catch statements *precede* try blocks?
>
> catch(memerr)
> {
> }
> catch(fileerr)
> {
> }
> try
> {
> }

No but I generally prefer that 'if' statements precede their blocks. Perl lets
you do it either way which is nice sometimes but in general you really want to
know about all the assumptions that are being made up front.

Phil

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                 ` Patrick Doyle
  1998-09-02  0:00                   ` Robert Martin
@ 1998-09-03  0:00                   ` Patrick Logan
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object Patrick Doyle <doylep@ecf.toronto.edu> wrote:
: In article <NshH1.6521$f01.4705828@news.teleport.com>,
: Patrick Logan  <plogan@user2.teleport.com> wrote:
: >In comp.object Patrick Doyle <doylep@ecf.toronto.edu> wrote:
: >
: >: By this logic, polymorphism is indeterminate too.  When you call a
: >: polymorphic function, you have no idea where control will
: >: wind up.  This is a Good Thing.  It's what makes polymorphism
: >: powerful: the fact that you're giving someone else some control
: >: over the situation makes your code flexible.
: >
: >These are apples and oranges. Why the comparison?

: Merely to point out that not knowing the distination of a transfer
: of control does not make for a strong argument against exceptions.
: If it did, it should apply to polymorphism too.

OK. So with polymorphic methods, you are trusting them to do the right
thing. And with exceptions, you are trusting them the exception to be
handled properly. Although as the one throwing the exception, you do
not know what "properly" means: your work is done.

Is this a recap of what's been discussed?

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                 ` Tres Seaver
  1998-09-02  0:00                                                   ` Robert Martin
@ 1998-09-03  0:00                                                   ` Patrick Logan
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-03  0:00 UTC (permalink / raw)


In comp.object Tres Seaver <tseaver@palladion.com> wrote:

: I find it interesting to read all the "single entry / exit" argument in light of
: the prolifieration of exception-based mechanisms.  Exceptions have all of the
: disadvantages of multiple returns, with the added problem of invisibility. 
: Adjusting one's style to remain robust in the face of exceptions automagically
: makes for robustness in the presence of multiple returns, it would seem to me.

That's an interesting point. Should a loop exit from one point only,
and *then* throw an exception? Or should the exception be thrown from
within the loop?

I think the latter, in most cases, but this is an example of
mid-exit. I don't write that many loops the throw exceptions, but I do
it.

I will continue to hammer home the need for *short* methods in any
case. I hate encountering someone's page-long methods. They're almost
bound to be doing something incomprehensible.

Otherwise if they're short their bound to be more manageable no matter
how "unstructured".

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Robert Oliver
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-03  0:00                                                     ` Ell
  1998-09-03  0:00                                                       ` Jeffrey C. Dege
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-03  0:00 UTC (permalink / raw)


Robert Oliver <oliverb@hfl.tc.faa.gov> wrote:

>Ell wrote:
>> 
>> Robert Oliver <oliverb@hfl.tc.faa.gov> wrote:
>> :
>> : Ell wrote:
>> :>
>> :> The assertion that "single entry, single exit" is a required, or even
>> :> desirable, maxim of structured programming is a myth.
>> :>
>> :> No one (including RCM) can show that this maxim is in fact a coding
>> :> heuristic put forward by any of the founders of the structured
>> :> paradigm. [Check past posts in this thread.]
 
>> : Edward Yourdan, in his book Techniques of Program Structure and Design
>> : discusses this article:
>> 
>> : C. Bohm and G. Jacopini, "Flow Diagrams, Turing Machines, and Languages
>> : with Only two Formation Rules", Communications of the ACM, May 19[6]6,
>> : pages 366-371.
>> 
>> : (Is this not *the* foundational article for structured programming?)

It was Dijkstra and Dahle who where considered to be the founders of
the structured paradigm--especially Dijkstra.  See "Art of Literate
Programming" by Knuth (CLSC publishers) page 72

>> : "According to Bohm and Jacopini, we need three basic building blocks in
>> : order to construct a program:
>> 
>> :       1. A process box.
>> :       2. A generalized loop mechanism.
>> :       3. A binary-decision mechanism.
>>  :
>> : The process box, shown in Fig. 4.1, may be thought of as a single
>> : computational statement (or machine language instruction) *or as any
>> : other proper conputational sequence with only one entry and one exit* -
>> : such as a subtoutine."
 
"single entry, single exit" is mentioned here, but again it was
Dijkstra and Dahle who where considered to be founders of the
structured paradigm--especially Dijkstra.

>> Where is the proof that this underlays the structured paradigm and an
>> assertion that something is "proper" doesn't make it so. What structured
>> programming avoided was unstructured flow control. It encouraged the use
>> of procedure/routine calls over 'goto'.  

"single entry and single exit" is an inflexible, inadequate attempt to
express the more comprehensive idea of the structured paradigm that we
should avoid unstructured flow conrrol.  And that wasn't even the only
key or main idea of the structured paradigm according to Dijkstra as
quoted in "Art of Literate Programming".

Dijkstra said the first thing he thought of when "structured
programming" was mentioned was *"abstraction"*.

>> Along with entry into a procedure
>> via a call, the use of 'return' is structured flow control; 'return' can
>> only go back to the calling procedure, unlike 'goto' which can branch to a
>> label anywhere.

>It's interesting that you use the fact that return always returns the
>program to a single exit point (the calling procedure) as an argument that this
>technique is structured.  Indeed, it is at the procedure level.

Right, that's the point about avoiding unstructured flow control.

>curious.  Would you allow goto's if they could not leave the scope of
>the procedure?  Probably not.)

In a post a month ago, I said that I would probably never use 'goto'
to go out of a procedure (if that's possible in Basic, or C)

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Ell
@ 1998-09-03  0:00                                                       ` Jeffrey C. Dege
  0 siblings, 0 replies; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-09-03  0:00 UTC (permalink / raw)


On Thu, 03 Sep 1998 01:32:21 GMT, Ell <ell@access.digex.net> wrote:
>Robert Oliver <oliverb@hfl.tc.faa.gov> wrote:
>
>>> : Edward Yourdan, in his book Techniques of Program Structure and Design
>>> : discusses this article:
>>> 
>>> : C. Bohm and G. Jacopini, "Flow Diagrams, Turing Machines, and Languages
>>> : with Only two Formation Rules", Communications of the ACM, May 19[6]6,
>>> : pages 366-371.
>>> 
>>> : (Is this not *the* foundational article for structured programming?)
>
>It was Dijkstra and Dahle who where considered to be the founders of
>the structured paradigm--especially Dijkstra.  See "Art of Literate
>Programming" by Knuth (CLSC publishers) page 72

Dijkstra and Dahle may have introduced the the formalism of structured
programming, but it is widely recognized that they were inspired by
Bohm and Jacopini's research.  Dijkstra's 1968 letter to the ACM,
"GO TO Statements Considered Harmful", has only two references:

    1. Wirth, Niklaus, and Hoare C. A. R. A contribution to the
       development of ALGOL. Comm. ACM 9 (June 1966), 413-432.
    2. Bohm, Corrado, and Jacopini Guiseppe. Flow diagrams, Turing
       machines and languages with only two formation rules. Comm. ACM 9
       (May 1966), 366-371.
       
-- 
The use of COBOL cripples the mind; its teaching should, therefore, be
regarded as a criminal offence.
		-- Edsger W. Dijkstra, SIGPLAN Notices, Volume 17, Number 5




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-03  0:00                                                       ` Ell
  1998-09-04  0:00                                                         ` Ell
  1998-09-03  0:00                                                       ` sureshvv
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-03  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

>I have found the enthusiasm for this thread quite interesting; but also a
>bit disquieting.  Structured Programming is one of the foundational elements
>of software engineering.  Knowledge of the benefits and costs of
>single-entry/single-exit functions should be firmly ingrained in all
>software engineers.

Your completely unsubstantiated, fantasy lie that "single entry,
single exit" is a key aspect of structured programming is deplorable,
and stinks to high heaven.

Think "avoid unstructured control flow", and not "avoid single entry,
single exit".

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <904556531. <m3lno372be.fsf@mheaney.ni.net>
  1998-09-03  0:00             ` Patrick Doyle
@ 1998-09-03  0:00             ` Patrick Doyle
  1998-09-03  0:00               ` Loryn Jenkins
  1 sibling, 1 reply; 510+ messages in thread
From: Patrick Doyle @ 1998-09-03  0:00 UTC (permalink / raw)


In article <m3lno372be.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>
>My argument concerns the complexity of the decision table for the loop
>predicate.  Adding a flag doubles the number of states.

I don't get this.  Who enumerates the states?  Who really finds this
necessary to understand a loop?

The termination condition is always the disjunction of the normal
termination condition and the flags.  A disjunction is a very
simple, straightforward logical operation, and I believe that
the effort in comprehending a disjunction is O(n), not O(2^n), in
the number of terms.

Look at this:

from
	x := 1
until
	x > maximum
	or error_detected
	or user_interruption
	or list_is_sorted
loop
	...
end

This has four conditions.  Do you really think it's 16 times harder
to understand than just "until x > maximum"?  I'd believe it's 4
times harder.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <904556531. <m3lno372be.fsf@mheaney.ni.net>
@ 1998-09-03  0:00             ` Patrick Doyle
  1998-09-03  0:00             ` Patrick Doyle
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-03  0:00 UTC (permalink / raw)


In article <m3lno372be.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>
>   loop
>
>      Get (N);
>
>      exit when N = 0;
>
>      <process N>
>
>   end loop;
>
>eliminates the redundancy.

Sorry for the two replies...

This is interesting.  It has only one entry and one exit.  Is it
not structured, then?

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                 ` <6sfqul$ggg$1@hirame. <6sidsq$e6c$1@hirame.wwa.com>
@ 1998-09-03  0:00                                                   ` Patrick Doyle
  1998-09-03  0:00                                                     ` Charles Hixson
  0 siblings, 1 reply; 510+ messages in thread
From: Patrick Doyle @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6sidsq$e6c$1@hirame.wwa.com>,
Robert Martin <rmartin@oma.com> wrote:
>
>Correct.  More specifically, I can guarantee that if I put a line of code
>just above the endloop statement (closing brace in my case) it will be
>executed in every iteration.

How would you feel about a loop...exit_when...end_loop structure?
It has only one exit point.  You could still add something to
the end of every iteration by putting it before the exit_when.

This seems pretty safe to me.  Do you see any reason this would
be less manageable than a top- or bottom-exit loop?

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Patrick Logan
@ 1998-09-03  0:00                                                       ` Matthew Heaney
  1998-09-03  0:00                                                         ` Patrick Logan
  1998-09-03  0:00                                                       ` Ole-Hjalmar Kristensen
  1 sibling, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-03  0:00 UTC (permalink / raw)


Patrick Logan <plogan@user2.teleport.com> writes:

> If you memoize the result of the first test, then the second test is
> about as fast as can be...
> 
>   boolean test;
>   ...
>   do {
>     ...
>     test = N;
>     if (test)
>       ...
>   } while (test);
> 
> This does not add a new state to a decision table. It provides a
> mnemonic for the test condition. The redundant test is minimal
> compared to the other work in the loop, not to mention the rest of the
> application. If you are writing small methods anyway, then it is very
> clear what is occurring.

The thing I dislike about this code fragment is that it creates an extra
variable.  

I still prefer to do this:

   for (;;) {
     Get (N);

     if (N == 0) break;

     <process N>
   }

No extra variable is required.









^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                   ` Richard Melvin
@ 1998-09-03  0:00                     ` Jim Cochrane
  0 siblings, 0 replies; 510+ messages in thread
From: Jim Cochrane @ 1998-09-03  0:00 UTC (permalink / raw)


In article <sZ7ktUAz7a71Ewx0@radm.demon.co.uk>,
Richard Melvin  <rmelvin@radm.demon.co.uk> wrote:
>In article <6siqo0$hiv@flatland.dimensional.com>, Jim Cochrane
><jtc@dimensional.com> writes
>>            from
>>                i := 1
>>            invariant
>>                -- for_all j member_of {1..i - 1} it_holds
>>                --   Current @ j = other @ j
>>            until
>>                i > count or Current @ i /= other @ i
>>            loop
>>                i := i + 1
>>            end
>>            check
>>                (i - 1 /= count) implies (Current @ i /= other @ i)
>>                count = other.count
>>            end
>>            Result := i - 1 = count
>
>I'm not a fan of this line - if I was to translate it it into english,
>it would come out as something like 'which exit path did I take from the
>loop?'. In order to work this out, you have to reverse-engineer the
>loop.
>
>To me, i is an implementation detail of the loop - referring to it
>outside the loop almost seems to break encapsulation.

Well, i is an essential component of the loop invariant, which must be
true when the loop has finished, as well as at the beginning of each
iteration of the loop.  It may be helpful to add the following
predicate to the check statement at the end of the loop, which defines
the postcondition of the loop (in comments because it is not codable):

    -- (i - 1 = count) = for_all j member_of {1..count} it_holds
    --                    Current @ j = other @ j

In other words, if and only if the loop has iterated over the entire
array, such that i = count + 1, then each element of Current is equal
to the corresponding element of other (since we know that Current.count
= other.count).  This is precisely the loop's job, to determine if the
two arrays are equal.  The substitution of {1..count} for {1..i - 1} is
an important step that shows how the loop invariant brings about the loop
postcondition.  Therefore i must be available outside of the loop.  It is
no more internal to the loop than the array variables Current or other.

>
>Perhaps it would work better with more descriptive variable names?
>Perhaps numTested and numFoundEqual? 
>(Although that makes the -1 problematic).
>
>-- 
>Richard Melvin


-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
@ 1998-09-03  0:00                                                       ` Matthew Heaney
  1998-09-03  0:00                                                         ` Patrick Logan
                                                                           ` (2 more replies)
  0 siblings, 3 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-03  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:

> For good reason.  There are two independent program states that depend upon
> N.  One is whether or not we call process, and the other is whether or not
> the loop exits.
> 
> Now, we could combine them as:
> 
>     for(;;)
>     {
>        Get(N);
>        if (N)
>          <process N>
>        else
>          break;
>     }
> 
> This is certainly more efficient; and if efficiency is what you need then
> you'd better do this.

Boy oh boy, Robert, we must come from different programming schools!

The dangerous thing about the code fragment above is that the else part
can get lost, especially if <process N> is long-ish.

My philosophy is, handle the simple case first, then bail out:

   for (;;)
   {
      Get (N);

      if (!N) break;

      <process N>
   }

When we fetch N, we're looking for that one special value, 0, that
signals end of input.  I prefer the organization above, because it
emphasizes the special case.

I don't like how you did it, because it treats the break case and the
<process N> case as equals - but they are not.

Your organization is telling me that N is always an integer.  Process
the integer one way if it's 0, and process it another way if it's
positive.  I feel that this is very misleading.

When you <process N>, N really is a (positive) integer.  But when N has
the value 0, it's an end-of-input indicator (which just happens to be
represented as an integer).

This point is perhaps made more clear by using an end-of-input indicator
that's not an integer:

begin
   loop

      Get (N);

      <process N>;

   end loop;
exception
   when End_Error => null;
end;
      
When the user presses CNTL-D, the OS delivers <EOF> to the application,
which Ada.Text_IO turns into an End_Error exception.  Note how similar
it is to

   loop

      Get (N);

      exit when N = 0;

      <process N>;

   end loop;



> For example, suppose I need to flush some buffers at the end of each
> iteration.  I do this by calling 'flush'.   I must write this as:
> 
>     for(;;)
>     {
>        Get(N);
>        if (N)
> 
>          <process N>
>          flush();
>        }
>        else {
>          break;
>          flush();
>        }
>     }

I'm confused by your example.  How does flush() get called in the else
part, if it's immediately preceeded by a break?  Shouldn't it be just

   for(;;)
   {
      Get(N);
      if (N)
        <process N>
        flush();
      }
      else {
        break;
      }
   }

If we handle the special case specially:

   for(;;)
   {
      Get(N);

      if (!N) break;

      <process N>
      flush();
   }

Flush gets called following <process N>, just as it does in your
original fragment.


> Whereas if I had lived with the double test:
> 
>     do {
>        Get(N);
>        if (N) {
>          <process N>
>        }
>        flush();
>     } while (N);

This is not the same as your original fragment, because flush gets
called even if N is 0.  Which behavior did you intend?








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Richard MacDonald (dogmat)
@ 1998-09-03  0:00                                                       ` Matthew Heaney
  0 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-03  0:00 UTC (permalink / raw)


"Richard MacDonald (dogmat)" <macdonaldrj@bv.com> writes:

> Better example. However, my solution for this would be to have a simple loop
> with three lines: (1) Seize the mutex. (2) Call a subroutine to do whatever
> (with one entry and one or more exits). (3) Release the mutex.

This is the example Bob Eachus presented.  There really is one single
point of exit - at the point of call.

function "=" (L, R : T) return Boolean is
   Result : Boolean;
begin
   Seize (Mutex);
   Result := Do_Equality (L, R);
   Release (Mutex);
   return Result;
end;

Now you can terminate the loop (inside Do_Equality now) as early and
often as you want, without any maintenance penalty.










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00             ` Patrick Doyle
                                 ` (2 preceding siblings ...)
  1998-09-03  0:00               ` mfinney
@ 1998-09-03  0:00               ` Matthew Heaney
  1998-09-03  0:00                 ` Robert Martin
  3 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-03  0:00 UTC (permalink / raw)


doylep@ecf.toronto.edu (Patrick Doyle) writes:

> >1. They are indeterminate.  When you throw an exception, you have no idea
> >where control will wind up.  It is not simply an exit from the current
> >scope, or even from the current function.
> 
> By this logic, polymorphism is indeterminate too.  When you call a
> polymorphic function, you have no idea where control will
> wind up.  This is a Good Thing.  It's what makes polymorphism
> powerful: the fact that you're giving someone else some control
> over the situation makes your code flexible.
> 
> The same holds for exceptions.

This is not a correct analogy.  The problem is this

  Seize (M);
  <do some work that may throw an exception>
  Release (M);

The problem is that flow of control skips right past the Release when an
exception occurs.  This loss of control is definately NOT a good thing,
because it will cause deadlock.

My rebuttal to Robert's argument is that the seize and release calls
should be called automatically, not manually by the programmer.  Even if
an exception occurs, Release gets called (automatically), and so no
resource problems can occur.







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Jim Cochrane
@ 1998-09-03  0:00                                                     ` Matthew Heaney
  1998-09-03  0:00                                                       ` Loryn Jenkins
  1998-09-03  0:00                                                       ` Jim Cochrane
  0 siblings, 2 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-03  0:00 UTC (permalink / raw)


jtc@dimensional.com (Jim Cochrane) writes:

> You are correct.  My premise was a bit off.  A better one would be:
> Before implementing a routine, it is necessary to determine what the
> routine must accomplish.  A very effective method of doing this is to
> document the specification for the routine in the form of pre- and
> post-conditions.  Once this is done, the routine can be coded such that it
> meets the post-condition based on the pre-condition.

There may be a misunderstanding here.  In my stack equality example,
there were NO precoditions.

I think that the check

   if L.Top /= R.Top then
      return False;
   end if;

was (incorrectly) interpreted as some kind of precondition check.  But
this interpretation is incorrect.

This fragment means, if the stacks don't have the same depth, then they
aren't equal.

> In the quoted example, documenting the pre-condition would have helped to
> uncover the fact that containers of different sizes would need to be dealt
> with.

In my original example, there weren't any preconditions.

> It would become obvious that a pre-condition of l.size = r.size
> would not be appropriate and thus that the negation of this condition would
> need to be dealt with in the implementation.

The stacks I was comparing in my example all had the same (max) size.
The check I was making was for different depths.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                       ` Tim McDermott
@ 1998-09-03  0:00                                                         ` Matthew Heaney
  0 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-03  0:00 UTC (permalink / raw)


Tim McDermott <mcdermott@draper.com> writes:

> Matthew Heaney wrote:snip
> 
> > The latter point is only a nit.  It's the first point that puts a bee in
> > my bonnet.  It may not seem like much in this example, because we're
> > "only" going from 2 rules to 4.  But things get scary really fast when
> > going 4 to 8.
> 
> This seems a little extreme to me.  While I have great respect for
> combinatorial explosion, you are talking about a 3-term boolean expression.
> There are only 6 ways to put one of those together, and I have no trouble
> evaluating any of the forms.  I know because I just listed them all, and ran
> through their evaluation with no problem.

I don't think I made my point clear.  There are 2**N possibilities to
consider when evaluating a predicate.  That means a 3-term expression
has 8 possibilities, not 6:

   1  2  3  4  5  6  7  8
P  T  T  T  T  F  F  F  F

Q  T  T  F  F  T  T  F  F

R  T  F  T  F  T  F  T  F






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Matthew Heaney
  1998-09-03  0:00                                                       ` Loryn Jenkins
@ 1998-09-03  0:00                                                       ` Jim Cochrane
  1 sibling, 0 replies; 510+ messages in thread
From: Jim Cochrane @ 1998-09-03  0:00 UTC (permalink / raw)


In article <m3g1ea5b93.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>jtc@dimensional.com (Jim Cochrane) writes:
>
>> You are correct.  My premise was a bit off.  A better one would be:
>> Before implementing a routine, it is necessary to determine what the
>> routine must accomplish.  A very effective method of doing this is to
>> document the specification for the routine in the form of pre- and
>> post-conditions.  Once this is done, the routine can be coded such that it
>> meets the post-condition based on the pre-condition.
>
>There may be a misunderstanding here.  In my stack equality example,
>there were NO precoditions.
>

Um, yes, there is a misunderstanding :-).  I was responding to someone who
was resonding to a previous post of mine, which was commenting on someone
else's response to an example posted by Robert Martin.  That is, the code
being discussed is Robert's code, in which he forgot to deal with the fact
that the two containers could have different sizes (number of elements).

>I think that the check
>
>   if L.Top /= R.Top then
>      return False;
>   end if;
>
>was (incorrectly) interpreted as some kind of precondition check.  But
>this interpretation is incorrect.
>
>This fragment means, if the stacks don't have the same depth, then they
>aren't equal.
>
>> In the quoted example, documenting the pre-condition would have helped to
>> uncover the fact that containers of different sizes would need to be dealt
>> with.
>
>In my original example, there weren't any preconditions.
>
>> It would become obvious that a pre-condition of l.size = r.size
>> would not be appropriate and thus that the negation of this condition would
>> need to be dealt with in the implementation.
>
>The stacks I was comparing in my example all had the same (max) size.
>The check I was making was for different depths.

At the risk of adding more confusion, by l.size ... I meant the number of
elements in l, not the maximum size - and again, this was discussing a code
snippet that Robert Martin had posted.

Sorry for the confusion.

-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Robert Martin
                                                                 ` (5 preceding siblings ...)
       [not found]                                               ` <gio+van+no+ni+8-0309982311220001@dialup62.tlh.talstar.com>
@ 1998-09-03  0:00                                               ` mfinney
  1998-09-03  0:00                                                 ` Robert Martin
  6 siblings, 1 reply; 510+ messages in thread
From: mfinney @ 1998-09-03  0:00 UTC (permalink / raw)


In <6simjo$jnh$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> writes:

>mfinney@lynchburg.net wrote in message ...

>>And, as far as maintainability is concerned, I strictly use tree-structured
>>programming and have *never* found it to be a maintenance problem.
>>Sure, sometimes code transformations are required during maintenance,
>>but they are sometimes required during coding.  So what?  There is no
>>way to write code that never requires code transformations during
>>maintenance, and trying to do so just makes the code harder to
>>understand and ultimately increases maintenance cost.  Far better is
>>to endevour to reach 0 bugs so that maintenance is never required.
>>Not easy, perhaps, but it is getting closer and closer every day.  I
>>personally am running somewhere around 0.0001 and 0.0002 errors
>>per line of code --  prior to quality assurance getting the code.

>Reaching zero bugs may not have that big an impact on maintenance, since
>much of maintenance has to do with changes to the requirements.

Reaching zero bugs means that changes are made by development
rather than maintenance.  That distinction is, of course, a matter of
definition.  It also depends on the ratio between code correction and
requirement changes.

>In any case, I note that in this thread nearly every article that advocates
>multiple exits evokes either readability, complexity, or naturalness as the
>justification.  I contend that these are highly subjective things, that are
>not shared by all programmers alike.

Certainly true.  But there does tend to be a rough consensus.  Discussions
like this tend to refine that consensus.

>I also contend that
>these issues are somewhat emotional, as evidenced by the terms such as
>"twist", "warp", "bend", "religious argument", etc. that have also been used
>in this thread.

Quite true, although for the record I must say that I used the term "twist"
as a synonym for "roll" or "rotate" and in an emotionally negative manner.
The terms "warp" and "bend" were used to indicate the emotional "feel"
of forcing code into a perceived unnatural state.

>So, it seems what we have here is "gut feelings" warring against empirical
>data.

I would not agree with that.  First, the "benefits" of structured programming
have not been shown that clearly, and second, there is evidence on the
other side as well.  And, generally what was measured in most studies that
I have seen is the difference between structured programmend and completely
unstructured programming.  Not the difference between structured programming
and tree-structured programming which is the point of this argument.  The only
study quoted so far, favors the middle exit which is actually irrelevant to the
difference between structured programming and tree-structured programming.

>In the end, the decision to use a structured style is a tradeoff.  There are
>benefits, and there are costs.  And there are certainly situations in which
>the costs outweight the benefits (e.g. quick an dirty programs that have
>short lifetimes and require little maintenance during their life).  It is
>also true, however, that for a very large set of circumstances, the benefits
>outweigh the costs.

First, I don't know about you, but I don't write "quick and dirty" programs.
I write all programs in the same manner, regardless of their audience or
intended lifespan -- those targets change far too frequently.

Secondly, the benefits of structured programming over tree-structured
programming have *not* been demostrated, so far as I know.


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                                 ` Robert Martin
@ 1998-09-03  0:00                                                   ` Steven Perryman
  0 siblings, 0 replies; 510+ messages in thread
From: Steven Perryman @ 1998-09-03  0:00 UTC (permalink / raw)


In article <6sfqlr$gat$1@hirame.wwa.com> "Robert Martin" <rmartin@oma.com> writes:

>The chapter that I have cited and quoted is a general description of
>structured programming, its constituents, its motivations, and its benefits.
>If you are looking for a one-liner, I'm afraid that Dijkstra wasn't
>anticipating you.  But the design heuristic is in the chapter in any case;
>just not conviently isolated into a single quotable sentence.

>The essence of the chapter is that all programs ought to be constructed from
>simpler elements that have singly entry points and single exit points.  The
>motivation is understandabililty and provability.

Correct.

The bottom line has always been this :

Dijkstra defined a set of primitive 'blocks' (if, while etc) .
He asserts some 'state of being' prior to entering each block, and the state
after exiting that block. Using the single-entry single-exit concept, he was
able to precisely reason and verify the behaviour of those blocks. The blocks
can then be used to build higher-level blocks (repeat-until, case etc) .

These concepts then appear to have been taken on by folks like the Yourdon
brigade et al, applied to functions and modules, resulting in the era that
is called 'structured programming' (FWIW, I don't know when the term was
officially first used, as is the case for the term 'OO' ) .

While Elliott rants on looking for the one-liner soundbite that isn't, the
rest of us know and accept that Dijkstra's work very much underpins the
notions of 'structured programming in the small' .


Regards,
Steven Perryman
stevenp@nortel.co.uk




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Ell
@ 1998-09-03  0:00                                                     ` Ole-Hjalmar Kristensen
  1998-09-03  0:00                                                       ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Ole-Hjalmar Kristensen @ 1998-09-03  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) writes:

> "Robert Martin" <rmartin@oma.com> wrote:
> 
> >Ell wrote in message <35eeea9b.2174586@news.erols.com>...
> >>
> >>"Robert Martin" <rmartin@oma.com> wrote:
> >>>
> >>>In any case, I note that in this thread nearly every article that
> >>>advocates
> >>>multiple exits evokes either readability, complexity, or naturalness as
> >>>the
> >>>justification.  I contend that these are highly subjective things,
> 
> >>This may be true, though I don't think[] so, but adherence to the dogma
> >>you made up about "single entry and single exit" doesn't make things
> >>clearer as most see it in this case.
> 
> >"clearer", again, is subjective IMHO.
> 
> Quite often the majority or a plurality of programmers is quite
> capable of agreeing on what is readable and more easily maintained.
> That isn't some kind of wild, unsubstantiated idea.  Programmers have
> agreed on that for years.  Geez, loosen up.
> 
> >In any case, I have not been
> >recommending aherence to dogma.
> 
> Yes you have.  You have been citing your imaginary heuristic of
> structured programming - single entry, single exit - more than a call
> girl shouts for Johns at night.  And as I said:
> 
> [You've been palming your "single entry, single exit"]
> >dogma off as some kind of officialdom.  Further, he can't prove it as
> >officialdom and it wouldn't matter if it was because the
> >appropriateness of all heuristics depends on specific concrete
> >circumstances.
> 
> >Rather I have been describing a cost/benfit trade-off.
> 
> And you haven't made your case on this as I see it.
> 
> >On at least two occasions, in this thread, I have said that
> >there is a time and place for multiple returns; but that such times and
> >places need to be chosen well based on a real assesment of the costs; an not
> >a subjective evaluation of what "feels good".
> 
> In that you haven't proven your cost/benefit assertions, what you say
> is what's "gut", and "feels good" to you.
> 
> >>>Finally, I contend that the factors in favor of using a
> >>>single-entry/single-exit style are, on the other hand, quite concrete and
> >>>demonstrable.  It has been shown that adhering to a structured style
> >>
> >>You have not shown at all that "single entry, single exit" is a
> >>general coding maxim of structured programming.
> >
> >Well, that's your opinion.  But I have cited the section of Dijkstra's book
> >"Structured Programming" that talks about this; and have quoted the page
> >where it is elaborated; and have summarized the discussion.  It's quite
> >difficult for me to understand how anyone could read the cited section and
> >not agree that single-entry/single-exit is a core concept of structured
> >programming.  I also note that no one else has challenged that assertion.
> >
> >
> >Robert C. Martin    | Design Consulting   | Training courses offered:
> >Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> >14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> >Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> >
> >"One of the great commandments of science is:
> >    'Mistrust arguments from authority.'" -- Carl Sagan
> >
> >

Please cool off! According to Dijkstra (not RCM)
single-entry/single-exit IS a core concept of structured programming.
Whether you agree that it is good idea, is another thing.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` john-clonts
@ 1998-09-03  0:00                                               ` mfinney
  1998-09-06  0:00                                                 ` Charles Hixson
  0 siblings, 1 reply; 510+ messages in thread
From: mfinney @ 1998-09-03  0:00 UTC (permalink / raw)


In <6sk1k9$3r9$1@nnrp1.dejanews.com>, john-clonts@hlp.com writes:

>What do you mean by 'tree-structured' programming?

If memory serves correctly, one definition of tree-structured
programming is those programs that can be written with the
following control structures...

	1. A named block
	2. A "jump" to the start or end of a named block
	3. A statement which conditionally executes the
		following statement

Or, if C/C++ did not have a "goto" statement, but instead allowed a
do/for/while block to be named and allowed that name to be used
with a break/continue statement (you can get an arbitrary block in
C/C++ by using a do {/*code*/} while (false); control structure).
Then only tree-structured programs could be written (ignoring
exceptions).

A return statement in C/C++ effectively implements a multi-level
break from the current module.  The only other way to accomplish
it in C/C++ is by using the "goto".  Nevertheless, tree-structured
programs are structured and can be characterized in a number of
ways.  Again, if memory serves (all of my references are still packed
from my move), a tree-structured program can also be characterized
as any program which contains no jumps into a block.

For example...

	outer::while (someCondition)
	   {
	   // some code
	   inner::while (anotherCondition)
	      {
	      // some code
	      outer::break; // exit outermost loop
	      inner::continue; // restart innermost loop
	      outer::continue; // restart outermost loop
	      inner::break; // exit innermost loop
	      // some code
	      }
	   // some code
	   }

Here, I am using a notation which is modeled on C++'s "scoping"
operator because you want to specify the "scope" which applies
to the break/continue.

The only difference between tree-structured programming and
structured programming is that only a single level break/continue
is allowed for structured programming and structured programming
only allows a single exit from any block (both tree-structured and
structured programming only allow a single entry to a block).

The use of "goto" is strictly controlled in a tree-structued program
and arbitrary "spaghetti" cannot be written.  Knuth has shown that
for any given set of control structures, there are some programs which
cannot be easily represented.  The set of programs which can be
easily represented (without using "flag" tricks or other work-arounds)
by structured programs is strictly less than the set of programs which
can be easily represented by tree-structured programs.

I personally believe that the incidence of programs which can be easily
represented as tree-structured programs but not structured programs is
high enough that restricting oneself to structured programming is not
reasonable.  That is, of course, a personal judgement call, but I do have
a reasonable amount of experience to back it up.  While I have found
many, if not most, programs don't fit the structured program mold, I have
found very few, if any, which do not fit the tree-structured program mold.
I have often wished for additional control structures, but every one of them
is tree-structured.


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Patrick Logan
  1998-09-03  0:00                                                       ` Matthew Heaney
@ 1998-09-03  0:00                                                       ` Ole-Hjalmar Kristensen
  1998-09-03  0:00                                                         ` Patrick Logan
  1 sibling, 1 reply; 510+ messages in thread
From: Ole-Hjalmar Kristensen @ 1998-09-03  0:00 UTC (permalink / raw)


Patrick Logan <plogan@user2.teleport.com> writes:

> In comp.object Matthew Heaney <matthew_heaney@acm.org> wrote:
> : "Robert Martin" <rmartin@oma.com> writes:
> 
> : > >So it's the structured approach which causes the redundancy, becuase Get
> : > >must be called twice.
> : > 
> : > Consider:
> : > 
> : >    do {
> : >       Get(N);
> : >       if (N)
> : >         <process N>
> : >    } while (N);
> : > 
> : > Structured programming allows the loop condition to be either at the top or
> : > the bottom.
> 
> : The thing I dislike about the above code fragment is that N gets tested
> : twice.
> 
> If you memoize the result of the first test, then the second test is
> about as fast as can be...
> 
>   boolean test;
>   ...
>   do {
>     ...
>     test = N;
>     if (test)
>       ...
>   } while (test);
> 
> This does not add a new state to a decision table. It provides a
> mnemonic for the test condition. The redundant test is minimal
> compared to the other work in the loop, not to mention the rest of the
> application. If you are writing small methods anyway, then it is very
> clear what is occurring.
> 
> -- 
> Patrick Logan    (H) mailto:plogan@teleport.com 
>                  (W) mailto:patrickl@gemstone.com 
>                  http://www.gemstone.com

If you believe that this assingnment makes the second test faster in
the general case, you are very wrong. It may even make the loop
slower, depending on the optimizer.
I've had this happen to me more than once.
I have to side with the middle exit guys in this case. One of the
reasons why I like the Ada loop construct.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Matthew Heaney
@ 1998-09-03  0:00                                                       ` Loryn Jenkins
  1998-09-03  0:00                                                       ` Jim Cochrane
  1 sibling, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-03  0:00 UTC (permalink / raw)


>    if L.Top /= R.Top then
>       return False;
>    end if;

Jim Cochrane is right: this precondition comment was discussing the C++
fragment from Robert Martin.

However, to help historians here, I didn't misinterpret your code as a
precondition. I misinterpreted it as checking the first item on the
stack (you know, the stuff at the `top'). Hence, given those semantics,
I thought it necessary to add the precondition

	l.count = r.count


However, addressing Richard Melvin's comment that this is an abuse of
DBC, I actually don't agree. While, as Jim Cochrane says, it is better
to think through the required preconditions and the desired
postcondition, and determine exactly what the routine needs to do, it is
still *good* practise to document *requirements of the actual routine*
(even if they are less than satisfactory). That way, client programmers
have a chance to decide:

(i)  exactly what to check before using the routine
(ii) whether they want to use the routine at all.

I'll give you an example:

Pylon is a small, lightweight and portable data structure library
written in Eiffel. It has some pretty interesting, well designed
features. However, one of the features I disliked was the insertion
procedure on SETs. Among other preconditions, it required:

	not_in_set: not has (v)
		--where v is the input argument

Now, for a SET class, I thought that this was an unreasonable request.
(Isn't it part of this container's job to handle SETness, as opposed to
BAGness?)

I was able to determine the exact behaviour extremely efficiently,
thanks to this documentation.

I was also able to determine that ISE's open source data structure
library, EiffelBase, handled insertion to the SET as I would've
expected.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00             ` Patrick Doyle
@ 1998-09-03  0:00               ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-03  0:00 UTC (permalink / raw)


> The termination condition is always the disjunction of the normal
> termination condition and the flags.  A disjunction is a very
> simple, straightforward logical operation, and I believe that
> the effort in comprehending a disjunction is O(n), not O(2^n), in
> the number of terms.
> 
> Look at this:
> 
> from
>         x := 1
> until
>         x > maximum
>         or error_detected
>         or user_interruption
>         or list_is_sorted
> loop
>         ...
> end
> 
> This has four conditions.  Do you really think it's 16 times harder
> to understand than just "until x > maximum"?  I'd believe it's 4
> times harder.

Mathematically, maybe. I don't think it's even four times harder,
sociologically speaking.

Obviously, this is just my personal experience reading the code the
first time: I took longer to understand the first and second portions of
the statement, because of the change in operator. However, once I had
read and comprehended the second line, the next two were real easy, real
fast.

I'm human, not machine.

And no, I *do not* figure out a truth table for every loop I write.
Instead, I use the abstractional capabilities of the tools at hand.
Bertrand Meyer described these abstractions quite nicely in the paper
located at http://www.elj.com/elj/v1/n3/bm/loop/. Just scan down until
you get to the section beginning:

	[This for me is the key reason.] 


It is interesting to note that I *like* abstracting things. Whereas many
of my colleagues (and particularly my brother, I notice), likes
approaching things procedurally. I don't know why.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                   ` Robert Martin
@ 1998-09-04  0:00                     ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-04  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: Patrick Logan wrote in message ...
: >
: >But you (the method developer whose method is throwing an exception)
: >don't care what happens next. You only care that your method has held
: >up its end of the bargain.

: Agreed.

: I think we are lost.

: My initial point was that exceptions violate se/se structures, but we accept
: that because they are extraordinary means of control transfer.   Exceptions,
: due to their extraordinary character, provide a benefit that outweighs the
: cost of losing the se/se structure.

Well, one could be compulsive about SE/SE and place all the exceptions
at the bottom of the method. I don't do that, but I write small
methods anyway, and I am becoming more aware of the importance of that
over anything else under discussion in this thread.

I will try to communicate better what I attempted earlier. It has
little if anything to do with SE/SE.

Previously you wrote:

: >: [Upon return from a method invocation] there is a postcondition
: >: that you can depend upon.  But once you throw an exception, there
: >: is very little you can say about what happens next.

My point is that when you invoke a method, you are relying on that
method's contract in order to *proceed* in fulfilling your own contract.

But when you are throwing an exception, you *are* fulfilling your own
contract.

When you say "there is very little you can say about what happens
next" I agree. Whatever you can say has been said. You have fulfilled
your contract. End of story. Nothing else matters to you.

My argument (if it can be called that) is really with Patrick's
bringing this issue up at all. It is apples and oranges to me, and I'm
frustrated because I don't know how to compare apples and
oranges. (Sorry Patrick. I know you have a point, I just have not been
able to grasp it yet.)

I hope this helps, at least to point out the general vicinity in which
I am lost!

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                           ` Biju Thomas
  1998-09-03  0:00                                                           ` Phil Goodwin
@ 1998-09-04  0:00                                                           ` Ell
  1998-09-04  0:00                                                             ` Ell
                                                                               ` (3 more replies)
  2 siblings, 4 replies; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

>Matthew Heaney wrote in message ...
>>
>>"Robert Martin" <rmartin@oma.com> writes:
>>>
>>>     for(;;)
>>>     {
>>>        Get(N);
>>>        if (N)
>>>          <process N>
>>>        else
>>>          break;
>>>     }
>>>

>>Boy oh boy, Robert, we must come from different programming schools!

>And that's part of the point I'm trying to make.  There is no single
>readability standard.  We all come from different schools in some way or
>another.  So what you think is readable, will not be as readable to me, or
>to someone else.

But generally it is possible to get a plurality or majority to agree
on what is readable.  In most cases readability decisions are made by
polling project developers where I work and have worked in the past.
You have to go with something, why not the plurality, or majority?

>>The dangerous thing about the code fragment above is that the else part
>>can get lost, especially if <process N> is long-ish.
>>
>>My philosophy is, handle the simple case first, then bail out:
>>
>>   for (;;)
>>   {
>>      Get (N);
>>
>>      if (!N) break;
>>
>>      <process N>
>>   }

Makes imminent sense to me.

>Ask yourself why 'break' is the most important concept of this function?
>Why is it more important to get the exceptional conditions out of the way
>first rather than to get right into the actual purppose of the function.
>
>I prefer a style that moves into the real action of the function as quickly
>as possible, while deferring the exceptional conditions to the end.

I advocate that in general we should test to see that pre-conditions
are met, and if they aren't, bail.  Why even try to process if
pre-conditions have not been met?

if (!pre-condition)
	bail
else
	do_processing()
endif

Elliott


>Consider this, would you prefer that catch statements *precede* try blocks?
>
>catch(memerr)
>{
>}
>catch(fileerr)
>{
>}
>try
>{
>}

Testing for pre-conditions before processing is not equal to what the
try/catch idiom is about.  'catch' is about catching *exceptions*
which occur *within* 'try' processing.  It is not about testing
*pre-conditions* to what is necessary for successfully processing in a
block.  The difference is that exceptions in processing may
legitimately occur even though pre-conditions for processing have been
met.  N'est ce pas?

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Ell
@ 1998-09-04  0:00                                                         ` Ell
  1998-09-03  0:00                                                           ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:

>"Robert Martin" <rmartin@oma.com> wrote:
>
>>I have found the enthusiasm for this thread quite interesting; but also a
>>bit disquieting.  Structured Programming is one of the foundational elements
>>of software engineering.  Knowledge of the benefits and costs of
>>single-entry/single-exit functions should be firmly ingrained in all
>>software engineers.

>Your completely unsubstantiated, fantasy lie that "single entry,
>single exit" is a key aspect of structured programming is deplorable,
>and stinks to high heaven.

>Think "avoid unstructured control flow", and not "avoid single entry,
>single exit".

Rather:

Think "avoid unstructured control flow", and not "avoid [creating code
which has multiple exits]".  

That's the true spirit of one aspect of the structured paradigm as I
see it.  The other being that we should use abstractions to design
code and to model functional domain processes.  

It was Dijkstra who said he thinks of *abstraction* when someone
mentions "structured programming".  (The Art of Literate Programming,
Knuth, CLCS,  page 72)

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                     ` <gio+van+no+ni+8-0309982244140001@dialup62.tlh.talstar.com>
@ 1998-09-04  0:00                                                       ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


gio+van+no+ni+8@tal+star+spam.com (Giovanni 8) wrote:

>"[R]eading a thousand-page source listing to learn about the
> components & architecture of a software system is a formidable,
> extremely time-consuming challenge.  Sometimes it is an
> impossible task because a maintenance programmer's 'span of
> understanding' is only 7K to 15K source code lines; & to
> understand this amount of code requires about 3 to 6 months
> of time." --- Carma McClure 1992 _The 3 Rs of Software Automation_
> pg 97 (citing Fletcher J. Buckley 1989-11-?? "Some Standards
> for Software Maintenance" _IEEE Computer_ vol 22 #1 pg 69)

Hence one of the major reasons I recommend that holistic analysis and
physical design (global, and local architectural)  object models be
created.  I find that the average person gains a more comprehensive
understanding of a system or its parts in a quicker amount of time
viewing graphical models as opposed to reading code.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                         ` Patrick Logan
@ 1998-09-04  0:00                                                           ` Matthew Heaney
  0 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-04  0:00 UTC (permalink / raw)


Patrick Logan <plogan@user2.teleport.com> writes:

> (Reminds me of the revived GOTO controversy, in what? The
> Communications of the ACM about ten years ago or so.)

Funny you should mention that - this thread reminded me of that too.  

The ACM Forum articles started with "'GOTO Considered Harmful'
Considered Harmful" by Frank Rubin, CACM, vol 30, no 3, Mar 87, and
continuing every issue through Dec 87.

The editor concluded the Forum letters with the statement:

"With this second rejoinder from Frank Rubin it seems expedient to bring
to a close the publication of correspondence generated by his March 1987
Forum letter, greater response by far than with any other issue ever
considered in these pages."

(Even Dijkstra himself jumped in a couple of times.)

I guess opinions on this subject haven't changed much in 11 years!

Matt





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00               ` Tim McDermott
  1998-09-04  0:00                 ` Patrick Doyle
@ 1998-09-04  0:00                 ` Matthew Heaney
  1998-09-04  0:00                   ` Patrick Doyle
  1998-09-08  0:00                   ` Tim McDermott
  1 sibling, 2 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-04  0:00 UTC (permalink / raw)


Tim McDermott <mcdermott@draper.com> writes:

> I guess the moral of the story is that this stuff really is hard, even at 3
> terms.

Yes!  That's the point I was trying make too.

Although I can reason about a disjunction with two or three terms, I
still prefer a loop predicate with just one term.

By separating the array iteration from the item comparison, I can reason
about the two different termination conditions independently.  So
instead of one (larger) problem with two terms, I have two (smaller)
problems, with one term each.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                           ` Phil Goodwin
@ 1998-09-04  0:00                                                             ` Matthew Heaney
  1998-09-04  0:00                                                               ` Jeffrey C. Dege
  0 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-04  0:00 UTC (permalink / raw)


Phil Goodwin<pgoodwin@my-dejanews.com> writes:

> > Matthew Heaney wrote in message ...
> > >My philosophy is, handle the simple case first, then bail out:
> > >
> > >   for (;;)
> > >   {
> > >      Get (N);
> > >
> > >      if (!N) break;
> > >
> > >      <process N>
> > >   }
> >
> > Ask yourself why 'break' is the most important concept of this
> > function?  Why is it more important to get the exceptional conditions
> > out of the way first rather than to get right into the actual purpose
> > of the function.
> 
> You are absolutely right about readability Robert, I read this as "!N
> is a precondition of <process N>. It IS important to know what the
> preconditions of the function are before you get into the actual
> purpose of the function.

Perhaps I should have included a comment that said,

  /* Process a stream of integers.
   * 
   * The stream is terminated by the value 0. 
   */

The problem just easily could have been:

  /* Process a stream of characters.
   *
   * The stream is terminated by the value EOF.
   */
  for (;;) {
     Get (C);

     if (C == EOF) break;

     <process C>
   }

My point is that this is a common kind of problem.  You process a stream
of items, but one of those items is special, and means "no more items
follow."  I argue that the formulation above is the most natural way to
implement this kind of problem.

Researchers showed empirically that using the construction above,
programmers produced fewer errors:

Cognitive Strategies and Looping Constructs: An Empirical Study
Soloway, Bonar, Ehrlich
CACM, Nov 83, Vol 26, No 11, p853-860

As they say, the proof is in the pudding, not the pudding recipe.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                             ` Matthew Heaney
@ 1998-09-04  0:00                                                               ` Jeffrey C. Dege
  1998-09-04  0:00                                                                 ` Ell
  1998-09-04  0:00                                                                 ` Patrick Logan
  0 siblings, 2 replies; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-09-04  0:00 UTC (permalink / raw)


On Fri, 04 Sep 1998 05:07:36 GMT, Matthew Heaney <matthew_heaney@acm.org> wrote:
>
>  /* Process a stream of characters.
>   *
>   * The stream is terminated by the value EOF.
>   */
>  for (;;) {
>     Get (C);
>
>     if (C == EOF) break;
>
>     <process C>
>   }
>
>My point is that this is a common kind of problem.  You process a stream
>of items, but one of those items is special, and means "no more items
>follow."  I argue that the formulation above is the most natural way to
>implement this kind of problem.

What are the alternatives?

	Get(C);
	while (C != EOF)
	{
		<process C>
		Get(C)
	}

	while (Get(C), C != EOF)
	{
		<process C>
	}


	goto LABEL5;
	do
	{
		<process C>
	LABEL5:
		Get(C);
	}
	while (C != EOF);

	boolean done = false;
	while (!done)
	{
		Get(C);

		if (C == EOF)
			done = true;
		else
		{
			<process C>
		}
	}

	jump_buf jumpBuffer;
	if (!setjmp(jumpBuffer))
	{
		for (;;)
		{
			Get(C);

			if (C==EOF)
				longjmp(1);
			
			<process C>
		}
	}

>Researchers showed empirically that using the construction above,
>programmers produced fewer errors:
>
>Cognitive Strategies and Looping Constructs: An Empirical Study
>Soloway, Bonar, Ehrlich
>CACM, Nov 83, Vol 26, No 11, p853-860
>
>As they say, the proof is in the pudding, not the pudding recipe.
>

-- 
"Necessity is the mother of invention" is a silly proverb.  "Necessity
is the mother of futile dodges" is much nearer the truth.
		-- Alfred North Whitehead




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Ell
@ 1998-09-04  0:00                                                     ` Andre Tibben
  1998-09-04  0:00                                                       ` Patrick Doyle
  0 siblings, 1 reply; 510+ messages in thread
From: Andre Tibben @ 1998-09-04  0:00 UTC (permalink / raw)


Ell wrote:
> >FYI, here is the entry in the Hacker Jargon Dictionary:
> >
> >spaghetti code /n./ Code with a complex and tangled control structure, esp.
> >one using many GOTOs, exceptions, or other `unstructured' branching
> >constructs. Pejorative. The synonym `kangaroo code' has been reported,
> >doubtless because such code has so many jumps in it.
> 
> 'exit', and 'return' are not "unstructured" branching as I see it.

They are unstructered in the sense that they can be placed anywhere in
the
enclosing function.

A much more structered way to express return values would be to have a
special
place to specify the return value (possibly just an expression before
the end)
and use the 'return'or 'exit' keyword only for special cases where you
do want
to exit at another place. An editor could in that case use a really ugly
color
to make it apparent that extra care is needed when changing the code.

Andre Tibben





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                           ` Robert Martin
@ 1998-09-04  0:00                                                             ` Ell
  1998-09-04  0:00                                                               ` Robert Martin
  1998-09-04  0:00                                                               ` Patrick Doyle
  0 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

>
>Ell wrote in message <35f23ce2.7649859@news.erols.com>...
>
>>
>>Think "avoid unstructured control flow", and not "avoid [creating code
>>which has multiple exits]".

>You had best define 'unstructured' in this context.  Dijkstra's definition
>of 'unstructured control flow' is control flow that does not conform
>precisely to the four standard sequencing elements {sequence, selection, top
>exit loop, bottom exit loop}, all of which have a single entry and a single
>exit.

Where is this documented?  Where has Dijkstra stated that flow control
must conform precisely to the 4 specific elements you mention?  I know
that sequence, selection, and *looping * are major appropriate flow
control elements, but please show where Dijkstra says that "top exit
loop" and "bottom exit loop" are, or should be standard flow control
elements.

>>That's the true spirit of one aspect of the structured paradigm as I
>>see it.  The other being that we should use abstractions to design
>>code and to model functional domain processes.
>>
>>It was Dijkstra who said he thinks of *abstraction* when someone
>>mentions "structured programming".

>Indeed, Dijkstra talks about abstraction quite a bit in the book "Structured
>programming".  One of his uses of the term is that the four sequencing
>elements he recommends can all be considered to be units whose internals
>can, at times, be ignored (i.e. abstracted away) because they have a single
>entry and a single exit.

Please refer to relevant citations to back up this assertion.  I have
seen nothing that Dijkstra refers to explicitly about se/se on other
than what you quoted about flowcharts.  And this everyone knows is how
to create flowcharts on a page - one entry point, one exit.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Charles Hixson
  1998-09-04  0:00                                                       ` adam
@ 1998-09-04  0:00                                                       ` Patrick Logan
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-04  0:00 UTC (permalink / raw)


In comp.object Charles Hixson <charleshixsn@earthlink.net> wrote:

: I hope that you are wrong about what they are doing.  I fear that
: you aren't.  Windowing is a good solution for recovering the data
: before saving it into a new format.  It's a very bad permanent
: "solution".  Usually.

From what I've read, the people writing about "windowing" realize it
is a temporary solution (the duration of the window). What's *really*
scary is the people who indicate they are going to "fix on failure"!

OTOH some of these situations could turn into an opportunity for
Extreme Programming and building "spike" solutions.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                               ` Jeffrey C. Dege
  1998-09-04  0:00                                                                 ` Ell
@ 1998-09-04  0:00                                                                 ` Patrick Logan
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-04  0:00 UTC (permalink / raw)


In comp.object Jeffrey C. Dege <jdege@jdege.visi.com> wrote:

: >  for (;;) {
: >     Get (C);
: >     if (C == EOF) break;
: >     <process C>
: >   }

: What are the alternatives?

[other alternatives omitted]

And then there is...

void processInput()
{
  Get(C);
  if (EOF != C) {
    <process C>
    processInput();
  }
}

...which works fine if your compiler compiles tail recursion into
efficient code.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                               ` Jeffrey C. Dege
@ 1998-09-04  0:00                                                                 ` Ell
  1998-09-04  0:00                                                                 ` Patrick Logan
  1 sibling, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


In comp.object Jeffrey C. Dege <jdege@jdege.visi.com> wrote:

: -- 
: "Necessity is the mother of invention" is a silly proverb.  "Necessity
: is the mother of futile dodges" is much nearer the truth.
: 		-- Alfred North Whitehead

We can take that the tone here is not Whitehead's because you are
including your own material in these supposed quotes.  This is highly
dishonest, and disingenuous in my opinion.  

It's a shame that you smear the name of Whitehead and unjustifiably
associate him with your craftite beliefs as you repeatedly do.  Whitehead
deserves much better than to be the poster guy for craftism, empiricism,
and your backward brand of pragmatism (c/e/p). 

Of course "necessity is the mother of futile dodges", as it is
"necessity"!  "Necessity" can only futilely be avoided because by
definition it is "necessity" (necessary).  

OTOH that doesn't mean that by addressing "necessity" we can't thereby
gain greater freedom, which is what often happens.

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                             ` Robert Martin
  1998-09-04  0:00                                                               ` sureshvv
@ 1998-09-04  0:00                                                               ` Ell
  1998-09-04  0:00                                                                 ` Robert Martin
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: Joe Gwinn wrote in message ...
:>
:>So, the whole 1970s debate about structured programming (and thus GOTOs)
:>reduced to the fond hope that if we tied the hands of those lost-puppy
:>programmers, they would no longer be lost, and would then think ahead and
:>write good code.

: Negative.  That is not the point, nor ever was the point.  The point of
: structured programming was not the elimination of GOTO.  Indeed, you can
: write perfectly structured programs with GOTO.  The point of structured
: programming was to recusively form the structure of an algorithm using units
: that have a single-entry and a single exit.

Please show us a quote by Dahle and Dijkstra which states that se/se is
*the* key concept of structured programming.

And that would mean something other than the quote about the heuristics of
creating a flowchart on a page (which itself never says se/se is *the* key
concept of structured programming).

Please stop the fantasy and "gut wishes".

Also please explain why the concept of "abstraction" is never involved in
how you define the structured paradigm although Dijkstra said it was the
first thing he thought of?

Again, please stop the fantasy and "gut wishes".

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                             ` Robert Martin
  1998-09-03  0:00                                                               ` Mike Spille
@ 1998-09-04  0:00                                                               ` Ray Blaak
  1998-09-06  0:00                                                                 ` Charles Hixson
  1998-09-04  0:00                                                               ` Gerry Quinn
       [not found]                                                               ` <EyyLos.2nx@yc.estec.esa.nl>
  3 siblings, 1 reply; 510+ messages in thread
From: Ray Blaak @ 1998-09-04  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> writes:
> It seems to me that:
> 
>  if (A is right)
>    if (B is right)
>      if (C is right)
>         then do the work.
> 
> emphasizes the work more than:
> 
> if (A is wrong) then return;
> if (B is wrong) then return;
> if (C is wrong) then return;
> do the work;
> 

A compromise that allows both positive logic and reduced nesting is to
calculate a guard value, and only do the work if the guard is true:

  doit := (A is right);
  doit := doit and (B is right);
  doit := doit and (C is right);
  if doit then do the work;

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
blaak@infomatch.com                            The Rhythm has my soul.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                             ` Matthew Heaney
  1998-09-01  0:00                                               ` Loryn Jenkins
  1998-09-01  0:00                                               ` dewarr
@ 1998-09-04  0:00                                               ` Jean-Marc Jezequel
  1998-09-04  0:00                                                 ` Richard Melvin
  2 siblings, 1 reply; 510+ messages in thread
From: Jean-Marc Jezequel @ 1998-09-04  0:00 UTC (permalink / raw)


IMHO, Dijkstra's point with se/se loops is first on *correctness*, that
is linked with provability. This is the most important thing from a
software engineering point of view. Maintenability comes second.
Readability comes third (but is actualy linked to maintenability).
Easyness of writing comes *last*.
(well, in the real world issues such as efficiency or more often costs
and delay sinterfere at any level in this hierarchy;-). I agree with Bob
Martin's point of view on the role of engineers: making trade-offs).

According to this point of view, the point is not to craft a piece of
code and throw it to the tester in a kind of simulated annealing until
it works. IMHO the professional engineer should design a piece of code
as trivial as a loop *in such a way that it can be proven correct*.
At least one systematic way of doing this have been documented by the
structured programming folks (Dijkstra, Hoare...).
Let me recall it in the context of the current thread on list equality
implemented with a loop:

equal (l,r: LIST): BOOLEAN is
        require l /= Void; r /=Void

This is a six steps process:

1. Design the loop invariant. It should provide a concise and
preferably formal description of the properties of the loop.
But even if it's not formal, it is usefull since it outline the intent.
Here, it is simply that the two list r and l are equal so far (which
could be made more formal saying that foreach i such as
0<i<l.current_index r.item(i) = l.item(i))

[For those who need refreshing on loop invariant:
It is a Boolean expression that must be true on initialization of the
loop variables, maintained with each iteration of the loop, and held to
be true at the termination of the loop. A loop invariant can be used to
reason about the correctness of a loop. see below]

2. Find the termination condition.
Here it is: either we find 2 differing elements or we reach the end of
one of the lists. That is, if Result contains the comparison result:
until not Result or l.off or r.off

So now, if the loop terminates, then the loop invariant is true and the
termination condition holds (by definition), which means that either the
lists are equal or Result=false. This property is called *partial
correctness*. Let us see how to prove total correctness.

Total correctness is just partial correctness {\em and} the proof that
the loop terminates (i.e., the termination condition eventually will 
hold). The idea of a loop variant is to characterize how each iteration
can bring the loop closer to its termination.


3. Find the variant (how the loop can advance toward its
termination).
[A loop variant is a non-negative integer expression that is decreased
by at least one at each iteration. By definition, it cannot go below
zero, thus the number of iterations of a loop with a variant is
bounded and then the loop eventually terminates.]
A suitable variant for this example is:
variant l.count-l.current_index+1

In writing the loop body, we must ensure that it is a strictly
decreasing function that takes non-negative values only.
This proof completes the partial correctness to give
the total correctness of the loop. In other words, the loop terminates
and computes the right result.


4. Write the body of the loop:

4a) First deduce from the variant the progression instruction,
4b) Then write the code corresponding to the restoration of the
invariant.

loop
   Result := l.item /= r.item -- establish invariant
   l.forth; r.forth -- progression for the variant
end

5. Write the initialization part to set up the loop invariant.

Result := True; l.start; r.start

6. Optimize, and/or modify to make it more readable
e.g., initialize Result to something less trivial:

        Result := l.first /= r.first
        from l.start; r.start
	invariant equal_so_far: --foreach i such as 0<i<l.current_index 
					-- r.item(i) = l.item(i)
        variant l.count-l.current_index+1
        until not Result or l.off --r.off omitted since l.off=>r.off
        loop
              Result := l.item /= r.item
              l.forth; r.forth
        end

7. Check your proof. Test (it's as easy to make an error in the proof as
it is in the code. Eiffel helps here by checking invariants and variants
at runtime. But the method is valid and usefull for *any* language).
Ship.

To sum up my point, when there is a documented way of doing something
(here building loops) the engineer should follow it (albeit not blindly:
she must still make appropriate trade-offs). Doing it elseway for no
good reason is not engineering: it is handcrafting (which is not
necessarily pejorative in my mouth).

-- 
Jean-Marc Jezequel               Tel : +33 299 847 192         
IRISA/CNRS                       Fax : +33 299 847 171         
Campus de Beaulieu               e-mail : jezequel@irisa.fr 
F-35042 RENNES (FRANCE)          http://www.irisa.fr/prive/jezequel




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                   ` Robert Martin
  1998-09-03  0:00                                                     ` Charles Hixson
@ 1998-09-04  0:00                                                     ` Rick Smith
  1998-09-04  0:00                                                       ` Robert Martin
                                                                         ` (3 more replies)
  1 sibling, 4 replies; 510+ messages in thread
From: Rick Smith @ 1998-09-04  0:00 UTC (permalink / raw)



Robert Martin wrote in message <6ske0c$16k$1@hirame.wwa.com>...
>
> ...  But of course many of the Y2K problems are not being
>solved by expanding the field to four digits.  Rather they are adding
*code*
>not *space*.  The technique is called windowing.  Whenver date subtractions
>or comparisons are done in the code, they interpreted as follows:
>
>   if date > X assume 1900 else assume 2000
>
>If X is 50 then any date larger than 50 is assumed to be in the 20th
>century.  Otherwise the data is assumed to be in the 21st century.
>
>This, of course, means that there will be a Y2050 crisis.  Ah, but no.
>Because X is not universally agreed upon.  Some applications use 60, some
>use 40.  So what we really have is a smearing of the crisis over the next
>several decades.

Portions are correct for fixed windowing only! Consider that when reading
data into the system, one could apply the window to create a 4 digit date,
internally. In that situation, "date subtractions or comparisons" would be
done on 4 digit dates.

However, flexible windowing assumes a range around the current (system)
date. In these cases, there is no specific "crisis" date and, in fact, may
never
have a "crisis" date.

Besides, most dates need to have range checks for reasonableness.
For example, should the date for a current transaction be accepted, without
error or warning, if the date is more than a few days from the current date?

Some data has a lifetime that makes 4 digit years unnecessary. If the
requirements for an existing system state that a "back order" must be
resolved within 30 days of the order date and that completed orders will
not be held for more than 5 years, what is the benefit of changing the
system to store 4 digit years with the order?

The benefits of windowing should be clear.

1. No user should be required to enter more data than is necessary. If the
correct 4 digit year can be determined by the last two digits, do not ask
for more than these 2 digits.

2. Given the choice between windowing and reformating persistent data,
choose windowing. Reformating existing data could break other parts
of the system.

Finally, for new systems or when reformating persistent data choose
to store the data with 4 digit years or replace a calendar date format
with a standard date format.

>Of course none of those old COBOL programs will still be running then...

Of course they will!  :-)
-------------------------------
Rick Smith
e-mail: < ricksmith@aiservices.com >






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                               ` Ell
@ 1998-09-04  0:00                                                                 ` Robert Martin
  1998-09-04  0:00                                                                   ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-04  0:00 UTC (permalink / raw)



Ell wrote in message <42OH1.2$vl.24707107@newsreader.digex.net>...
>In comp.object Robert Martin <rmartin@oma.com> wrote:
>
>: Joe Gwinn wrote in message ...
>:>
>:>So, the whole 1970s debate about structured programming (and thus GOTOs)
>:>reduced to the fond hope that if we tied the hands of those lost-puppy
>:>programmers, they would no longer be lost, and would then think ahead and
>:>write good code.
>
>: Negative.  That is not the point, nor ever was the point.  The point of
>: structured programming was not the elimination of GOTO.  Indeed, you can
>: write perfectly structured programs with GOTO.  The point of structured
>: programming was to recusively form the structure of an algorithm using
units
>: that have a single-entry and a single exit.
>
>Please show us a quote by Dahle and Dijkstra which states that se/se is
>*the* key concept of structured programming.

Elliott, I can't help it if you are too lazy to go look up the references
I've given you; and I've given you plenty.  It seems clear that you know
very little about structured programming, and that you have no interested in
learning more.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan









^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                             ` Robert Martin
  1998-09-03  0:00                                                               ` Mike Spille
  1998-09-04  0:00                                                               ` Ray Blaak
@ 1998-09-04  0:00                                                               ` Gerry Quinn
       [not found]                                                               ` <EyyLos.2nx@yc.estec.esa.nl>
  3 siblings, 0 replies; 510+ messages in thread
From: Gerry Quinn @ 1998-09-04  0:00 UTC (permalink / raw)


In article <6sn2lv$t6m$1@hirame.wwa.com>, "Robert Martin" <rmartin@oma.com> wrote:
>
>Now, in a real se/se function that checks a few things before doing the real
>work, the real work will be the most indented part of the function.  People
>who train themselves to know that the real work is the stuff that is most
>indented, have little trouble finding it.

Extra indentation is in itself a practical disadvantage (the extent of 
which depends on the development system), which may cause programmers 
to use names which are too short, and/or run statements over multiple 
lines, leading to a lack of clarity.

(You guessed it, VC5...)

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                     ` Rick Smith
@ 1998-09-04  0:00                                                       ` Robert Martin
  1998-09-04  0:00                                                       ` Charles Hixson
                                                                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-04  0:00 UTC (permalink / raw)



Rick Smith wrote in message ...
>
>However, flexible windowing assumes a range around the current (system)
>date. In these cases, there is no specific "crisis" date and, in fact, may
>never
>have a "crisis" date.


Of course the more applications that use a window around the current system
date, the better.  But in my travels, I have talked to a few Y2K managers,
and they give me the impression that they are using fixed windowing alot.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                             ` Ell
@ 1998-09-04  0:00                                                               ` Robert Martin
  1998-09-05  0:00                                                                 ` Loryn Jenkins
  1998-09-04  0:00                                                               ` Patrick Doyle
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-04  0:00 UTC (permalink / raw)



Ell wrote in message <35ef7dff.24318728@news.erols.com>...
>"Robert Martin" <rmartin@oma.com> wrote:
>
>>
>>Ell wrote in message <35f23ce2.7649859@news.erols.com>...
>>
>>>
>>>Think "avoid unstructured control flow", and not "avoid [creating code
>>>which has multiple exits]".
>
>>You had best define 'unstructured' in this context.  Dijkstra's definition
>>of 'unstructured control flow' is control flow that does not conform
>>precisely to the four standard sequencing elements {sequence, selection,
top
>>exit loop, bottom exit loop}, all of which have a single entry and a
single
>>exit.
>
>Where is this documented?  Where has Dijkstra stated that flow control
>must conform precisely to the 4 specific elements you mention?

Elliott, I've already answered this question several times.  I can only
assume that you reason you keep asking this is that you don't want to look
it up for yourself on the off chance that you might find it to be true.  Let
me assure you, if you read the citings I have given you so many times you
*will* find that Dijkstra recommended four, and only four, control elements.


>Please refer to relevant citations to back up this assertion.  I have
>seen nothing that Dijkstra refers to explicitly about se/se on other
>than what you quoted about flowcharts.  And this everyone knows is how
>to create flowcharts on a page - one entry point, one exit.

Then clearly you have not read much of Dijkstra.  The citation you want is
the citation I have given you many many times.  Go look it up Elliott.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan

>
>Elliott






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                               ` <gio+van+no+ni+8-0309982212300001@dialup62.tlh.talstar.com>
@ 1998-09-04  0:00                                                 ` Robert I. Eachus
       [not found]                                                   ` <gio+van+no+ni+8-0809981840170001@dialup75.tlh.talstar.com>
  0 siblings, 1 reply; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-04  0:00 UTC (permalink / raw)


In article <gio+van+no+ni+8-0309982212300001@dialup62.tlh.talstar.com> gio+van+no+ni+8@tal+star+spam.com (Giovanni 8) writes:

 > I've run across this, too.  Back before interactive debuggers
 > it was common to use gotos to reach a "normal" return, that,
 > with debugging turned on in the pre-compiler, would generate
 > a sort of trace log.  But even there, it has the disadvantage
 > of covering up the "actual" point from which one is returning.
 > Why not deal with error handling right there, where the most
 > information is available?

   I think we are geting to the point of violent agreement.  The
"structured" code:

<<Bad1>>

   loop
     Get(Next);
     if Next /= null;
     [lots of normal case code]
     else exit;
     end if;
   end loop;

   or

<<Bad2>>

   Get(Next);
   while Next /= done loop
     [lots of normal case code]
     Get(Next);
   end loop;

   should be regarded as broken while the equivalents:

<<Good1>>

   loop
     Get(Next);
     if Next = null
     then exit;
     else
      [lots of normal case code]
     end if;
   end loop;

   or  

<<Good2>>

   loop
     Get(Next);
     exit when Next = null;
     [lots of normal case code]
   end loop;

   or

<<Good3>>

   while Get(Next) loop;
     [lots of normal case code]
   end loop;

are winners.  The chief reason the first examples should be regarded
as broken is that they result in one conceptual action being split
often across several pages.  Either the maintainer has to find two
widely separated calls to Get that are really the same call, or you
have to flip through several pages of code to find out where the then
part of the if ends.  Either can lead to errors.

   Among those marked as good, we can argue all year as to which is
best, but in reality who cares.  If maintaining that code, we will all
be looking elsewhere for problems.  I happen to prefer Good2 and those
with a strong C background, or programming in C or C++ will probably
prefer Good3.  (In Ada you have to add a level of indirection so that
the (now function) Get can modify its argument, and the new value is a
side effect while the function actually returns a boolean.  For Ada
programmers this idiom is somewhat distateful, but in C it is almost
standard.) Other languages favor other styles.





--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                                 ` Robert Martin
@ 1998-09-04  0:00                                                                   ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

>
>Ell wrote in message <42OH1.2$vl.24707107@newsreader.digex.net>...
>>In comp.object Robert Martin <rmartin@oma.com> wrote:
>>
>>: Joe Gwinn wrote in message ...
>>:>
>>:>So, the whole 1970s debate about structured programming (and thus GOTOs)
>>:>reduced to the fond hope that if we tied the hands of those lost-puppy
>>:>programmers, they would no longer be lost, and would then think ahead and
>>:>write good code.
>>
>>: Negative.  That is not the point, nor ever was the point.  The point of
>>: structured programming was not the elimination of GOTO.  Indeed, you can
>>: write perfectly structured programs with GOTO.  The point of structured
>>: programming was to recusively form the structure of an algorithm using
>units
>>: that have a single-entry and a single exit.
>>
>>Please show us a quote by Dahle and Dijkstra which states that se/se is
>>*the* key concept of structured programming.

>Elliott, I can't help it if you are too lazy to go look up the references
>I've given you;  and I've given you plenty.  

You haven't given us anything but more references to flowchart rules.

>It seems clear that you know
>very little about structured programming, and that you have no interested in
>learning more.

Martin you have not shown us one *shred* of evidence that se/se is a
defining feature of the structured paradigm.  The stuff about
flowcharts is just that, stuff about flowcharts nothing more and
nothing less.  

Please stop trying to insult our intelligence.

In fact it is you who are making it clear to all that you are more
interested in upholding your inappropriately, rigid fantasy as opposed
to dealing with the facts.  You should be ashamed of yourself.

Again here you are standing in public with no clothes on, while
shrilly proclaiming yourself well dressed.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                           ` Ell
@ 1998-09-04  0:00                                                             ` Ell
  1998-09-05  0:00                                                             ` Loryn Jenkins
                                                                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


"Robert Martin" <rmartin@oma.com> wrote:

[ In reference to the idea of testing for pre-conditions before
processing, RCM, in part, said the following: ]

>Consider this, would you prefer that catch statements *precede* try blocks?
>
>catch(memerr)
>{
>}
>catch(fileerr)
>{
>}
>try
>{
>}

Testing for pre-conditions before processing is not equal to what the
try/catch idiom is about.  'catch' is about catching *exceptions*
which occur *within* 'try' processing.  It is not about testing
*pre-conditions* to what is necessary for successfully processing in a
block.  The difference is that exceptions in processing may
legitimately occur even though pre-conditions for processing have been
met.  N'est ce pas?

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00               ` Tim McDermott
@ 1998-09-04  0:00                 ` Patrick Doyle
  1998-09-04  0:00                 ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-04  0:00 UTC (permalink / raw)


In article <35EEF597.A1119EF4@draper.com>,
Tim McDermott  <mcdermott@draper.com> wrote:
>
>Patrick Doyle wrote:
>
>> If you want to talk about how many possible boolean expressions there
>> are with n terms, that's 2^(2^n).  There are 2^n assignments for the
>> variables, and any combination of those assignments could make
>> the expression true.
>
>There are 4 possible 1-term boolean expressions?  Could you list them?Perhaps
>this is a terminology problem.  By 3-term, I don't mean 3 variables used as often
>as you like, I mean 3 occurances of any variable and 2 operators (again
>neglecting negation).
>I am counting "A & (!A)" as a 2-term expression.

Ok, I understand now.

As for the 4 possible 1-term boolean expressions, you have A, !A, True
(which could be written A + !A) and False (which could be written
A * !A).  If you want to get rid of the trivial True and False ones,
the number is still O(2^(2^n)) (actually being 2^(2^n) - 2).

>>  A + B + C
>>  A & B + C
>>  A &(B + C)
>>  A + B & C
>> (A + B)& C
>>  A & B & C
>>
>> However, these aren't really 6 distinct expressions.  The third
>> and fifth are the same, as are the second and fourth.
>
>Hmmm.  With A and B false and C true, the second expresion is true, while the
>fourth is false.  The third and fifth expressions differ when A is false and B
>and C are true.  (assuming '&' has higher precedence than '+')

Oh, I was neglecting the variable names.  The second expression can
be rewritten as  C + B & A  which, neglecting the letters, is the
same as  A + B & C.

If you don't neglect the letters, then these are not the only possible
expressions.  There would also be:

 A & C + B
(A + C)& B

It's easier to enumerate them if you consider the possibilities with
prefix notation.  There will be two operators followed by three
variables, like this:

&+BCA

If the operators are the same, the order of the variables doesn't
matter.  So, there are two of those; one for & and one for +.

If the ops are different, then the order of the first two variables
doesn't matter, but the third does.  That gives 2 operator
combinations and 3 distinct variable combinations, for a total
of 6 possibilities.

Altogether, then, there are eight such expressions.

As for what you said about this being hard, I'd agree that counting
theory is hard; but I don't see the relevance of that to understanding
a loop.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                             ` Ell
  1998-09-04  0:00                                                               ` Robert Martin
@ 1998-09-04  0:00                                                               ` Patrick Doyle
  1998-09-05  0:00                                                                 ` Ell
  1 sibling, 1 reply; 510+ messages in thread
From: Patrick Doyle @ 1998-09-04  0:00 UTC (permalink / raw)


In article <35ef7dff.24318728@news.erols.com>,
Ell <ell@access.digex.net> wrote:
>
>"Robert Martin" <rmartin@oma.com> wrote:
>>
>>You had best define 'unstructured' in this context.  Dijkstra's definition
>>of 'unstructured control flow' is control flow that does not conform
>>precisely to the four standard sequencing elements {sequence, selection, top
>>exit loop, bottom exit loop}, all of which have a single entry and a single
>>exit.
>
>Where is this documented?  Where has Dijkstra stated that flow control
>must conform precisely to the 4 specific elements you mention?  I know
>that sequence, selection, and *looping * are major appropriate flow
>control elements, but please show where Dijkstra says that "top exit
>loop" and "bottom exit loop" are, or should be standard flow control
>elements.

When Robert does so, do you promise to finally admit you're wrong?  :-)

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                 ` Matthew Heaney
@ 1998-09-04  0:00                   ` Patrick Doyle
  1998-09-08  0:00                   ` Tim McDermott
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-04  0:00 UTC (permalink / raw)


In article <m3ogsw503u.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>
>By separating the array iteration from the item comparison, I can reason
>about the two different termination conditions independently.  So
>instead of one (larger) problem with two terms, I have two (smaller)
>problems, with one term each.

...thus doubling your problems.  :-)

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                     ` Andre Tibben
@ 1998-09-04  0:00                                                       ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-04  0:00 UTC (permalink / raw)


In article <35EF1276.2AF4D06B@a1.nl>, Andre Tibben  <a.tibben@a1.nl> wrote:
>Ell wrote:
>> 
>> 'exit', and 'return' are not "unstructured" branching as I see it.
>
>They are unstructered in the sense that they can be placed anywhere in
>the enclosing function.

More importantly, they are unstructured in the sense that they are
not implementing any of the *structures* that Dijkstra proposed.

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                             ` Robert Martin
@ 1998-09-04  0:00                                                               ` sureshvv
  1998-09-04  0:00                                                               ` Ell
  1 sibling, 0 replies; 510+ messages in thread
From: sureshvv @ 1998-09-04  0:00 UTC (permalink / raw)


In article <6snpvb$e6f$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:

> The point of structured
> programming was to recusively form the structure of an algorithm using units
> that have a single-entry and a single exit.  And this structure has some
> concrete and well understood benefits.

I agree. The question is if a function (or a loop) should necessarily be a
single monolithic block or is it better constituted with smaller blocks,
where under clearly stated conditions only a sub-sequence of the blocks are
executed.

suresh


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                               ` Mike Spille
  1998-09-03  0:00                                                                 ` Robert Martin
@ 1998-09-04  0:00                                                                 ` sureshvv
  1998-09-04  0:00                                                                   ` Robert Martin
  1 sibling, 1 reply; 510+ messages in thread
From: sureshvv @ 1998-09-04  0:00 UTC (permalink / raw)


In article <35EEF0D1.939F1907@tisny.com>,
  Mike Spille <mspille@tisny.com> wrote:
> Robert Martin wrote:
> >

> >
> >  if (A is right)
> >    if (B is right)
> >      if (C is right)
> >         then do the work.
> >
> > emphasizes the work more than:
> >
> > if (A is wrong) then return;
> > if (B is wrong) then return;
> > if (C is wrong) then return;
> > do the work;
> >
> > So, I think the notion of "emphasis" is somewhat subjective.
> >
>
> Defintely so - I find having the most important code stuck in column X (where
> X can vary, depending on how many checks and the nesting level) very hard
> to follow over large programs.  Having the important stuff at the zero
> indentation level seems much more natural.

As I indicated in another post add the following realistic requirements

1. A log message has to be output indicating the failed condition
2. A different value has to be returned for each of the conditions

and you will see how much more cumbersome the se/se structure will become.

I think, a function is best partitioned as a sequence of small number of
independent paragraphs (scopes) - where each paragraph can be understood in a
context independent manner. I contend that this is better for readability AND
maintainability.

The multiple-return structure accomplishes this better than the se/se
structure. The se/se strcuture often creates a monolithic paragraph,
creating a scope that extends across many lines.
In fact, I feel that the multiple-return structure is more in line with the
"structured" organization of programs.

suresh

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                     ` Charles Hixson
@ 1998-09-04  0:00                                                       ` adam
  1998-09-06  0:00                                                         ` Gerry Quinn
  1998-09-04  0:00                                                       ` Patrick Logan
  1 sibling, 1 reply; 510+ messages in thread
From: adam @ 1998-09-04  0:00 UTC (permalink / raw)


In article <35EF7971.1CDE6B7D@earthlink.net>,
  Charles Hixson <charleshixsn@earthlink.net> wrote:

>
> I hope that you are wrong about what they are doing.  I fear that you
> aren't.  Windowing is a good solution for recovering the data before
> saving it into a new format.  It's a very bad permanent "solution".
> Usually.

I hope no one thinks it's intended as a permanent solution.  Given that
there's less than a year and a half until 2000 hits, what this solution does
is to buy a lot of time to come up with a "real" solution.  (I'm assuming
that the windowing solution requires a lot less resources than expanding the
date.)	I agree that this solution may not make a lot of sense for an
organization that can *comfortably* go to a 4-digit date and have everything
in place by the time it's needed.

Of course, there's the danger that pointy-haired managers will then fail to
work on the "real" solution for the next 49 years, because "it's not causing
any problems right now", and "our whole computer systems will be obsolete by
then anyway", and "we've never heard of George Santayana".  Now I have to go
dig up the very funny joke that appeared on rec.humor.funny recently, about a
COBOL programmer who got so sick of Y2K problems that he had himself cryo-
genically frozen to be awakened in 2003, only the cryogenic machine wasn't
Y2K compliant so it didn't wake him up in time, and they finally woke him up
almost 8000 years later because they were about to have a Year 10000 problem
and they needed someone who knew COBOL.

				-- Adam

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                       ` <o1fH1.543$495.1 <gwinn-0309982042490001@d8.dial-4.cmb.ma.ultra.net>
@ 1998-09-04  0:00                                                         ` Samuel Mize
  1998-09-04  0:00                                                           ` Ell
  1998-09-05  0:00                                                           ` Loryn Jenkins
  0 siblings, 2 replies; 510+ messages in thread
From: Samuel Mize @ 1998-09-04  0:00 UTC (permalink / raw)


In article <gwinn-0309982042490001@d8.dial-4.cmb.ma.ultra.net>,
Joe Gwinn <gwinn@ma.ultranet.com> wrote:
>The issues are in my experience quite independent.  I have seen lots of
>spaghetti code with nary a GOTO, and perfectly clear code with many GOTOs.
>
>I would submit that good programmers write clear, simple code, regardless
[of language used]

This is certainly true.


>...The key issue is clarity of thought;

Well, clarity of thought and clarity of exposition.  A complex bit of
code may be clear in one's mind, but be the devil to recall or decrypt
for later debugging or maintenance changes.

One benefit from structured programming is to make everyone use a
simpler, common "language" of programming -- a set of idioms that will
simplify communication with other programmers, including ourselves in
later time.

Humpty Dumpty had perfectly clear thoughts, but he didn't use the
agreed-to language, so his thoughts weren't clear to others.


...So, the whole 1970s debate about structured programming (and thus GOTOs)
>reduced to the fond hope that if we tied the hands of those lost-puppy
>programmers, they would no longer be lost, and would then think ahead and
>write good code.

Well, I suppose that's a fair representation of the overblown claims
that some people made for it.

I understood it to be an attempt to codify the heuristics that better
programmers use, so neophytes could learn more easily how to code
clearly.  It goes hand-in-glove, necessarily, with structured design,
which is a similar attempt to codify how better programmers organize
their thinking before they code.

But I had the good fortune to have structured programming presented,
not as a set of language constructs, but as one of a number of useful
ways of organizing one's thinking.  Others would be functional, logic,
and object-oriented programming.  Note that code in LISP isn't
necessarily functional, and gotoless code isn't necessarily structured.

The core intuition was always that the program should HAVE structure;
that you should be able to easily see how it is organized, and how it
organizes its activities.  It shouldn't be just a
stream-of-consciousness sequence of instructions.

Structured programming isn't necessarily single-entry-single-exit, or
gotoless programming, although those sub-flavors do exist.

Further, within a project or team, you should have an agreed-to set of
structures, so you can interchange code easily.

It's like teaching a new carpenter how to build a standard wall with
studs and sheet rock.  There are a lot of other ways to build a wall,
and for some walls another method is better.  But it's wise to teach a
student the standard methods first, and teach them how and why they
work (and when and why they DON'T work), before you turn him loose on
a building.

Further, if he builds a weird-style wall, no matter how good a wall it
is, the electricians and plumbers won't know how to work with it.

I've always felt my institution (Kansas State University) did a really
remarkable job of providing a sensible, pragmatic introduction to a
lot of technologies.

I also like how one of my professors described some of the programs he
saw: apparently they gather a pack of discarded, mispunched cards
left behind by other students, slap a JCL card on the front, then try
to debug it.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                         ` Samuel Mize
@ 1998-09-04  0:00                                                           ` Ell
  1998-09-05  0:00                                                           ` Loryn Jenkins
  1 sibling, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


smize@news.imagin.net (Samuel Mize) wrote:

[ Much good stuff elided.]
>I've always felt my institution (Kansas State University) did a really
>remarkable job of providing a sensible, pragmatic introduction to a
>lot of technologies.

Too bad about "sensible, pragmatic".  I realize the value of having
your feet on the ground sometimes, but that's not the best overall way
to view, approach, and live life as I see things.

Why be "grounded" when there is so much  to gain by going against the
grain, taking risks, making big leaps over always being evolutionary,
often making things unstable versus always striving for stability,
etc, etc.

For example rather than have classes depend on a so-called stable
abstraction, it might make a lot of sense to metamorphize a heavily
depended upon abstraction and to thereby metamorphize most, or some of
it's inheriting children.  In addition it might be best for clients
that depend on services from a heavily depended upon abstraction to
undergo change in order to accommodate the change in its server class
set, or hierarchy.

You can study history for yourself, but pragmatism rarely contributes
truly great ideas, nor does it consistently provide truly
_progressive_ changes in the world, or in even a single area of human
endeavor.

Down with pragmatism!  Up with hope!

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                 ` Loryn Jenkins
@ 1998-09-04  0:00                                                                   ` Ell
  1998-09-05  0:00                                                                     ` Loryn Jenkins
  0 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-04  0:00 UTC (permalink / raw)


Loryn Jenkins <loryn@s054.aone.net.au> wrote:

>> Then clearly you have not read much of Dijkstra.  The citation you want is
>> the citation I have given you many many times.  Go look it up Elliott.

>Yes, look it up. Read it. Acknowledge that that is what Dijkstra was
>saying.

How can I acknowledge that, if I haven't seen it?  And you all can't
point to that stuff on flowcharting as some kind of proof that the
founders of SP said we should adhere to se/se.  

>Remember, you *may* disagree with him. But it is silly not reading what
>he actually said.

That book is out of print and RCM knows it.  If RCM had *any* shred of
text to prove that they explicitly advocated se/se in structured
coding he would quote it.

> And it is fantasy arguing that he wasn't discussing
>se/se.

It's a deplorable attempt at deception for RCM to state that se/se is
a cornerstone of SP without a shred of evidence.

It's fantastic gullibility to think RCM is right about se/se without a
shred of evidence; to believe him based on faith, because I'll bet
dollars to doughnuts that you can't show me any proof either.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                                 ` sureshvv
@ 1998-09-04  0:00                                                                   ` Robert Martin
  1998-09-04  0:00                                                                     ` Mike Spille
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-04  0:00 UTC (permalink / raw)



sureshvv@hotmail.com wrote in message <6sp902$buj$1@nnrp1.dejanews.com>...
>In article <35EEF0D1.939F1907@tisny.com>,
>  Mike Spille <mspille@tisny.com> wrote:
>> Robert Martin wrote:
>> >
>
>> >
>> >  if (A is right)
>> >    if (B is right)
>> >      if (C is right)
>> >         then do the work.
>> >
>> > emphasizes the work more than:
>> >
>> > if (A is wrong) then return;
>> > if (B is wrong) then return;
>> > if (C is wrong) then return;
>> > do the work;
>> >
>> > So, I think the notion of "emphasis" is somewhat subjective.
>> >
>>
>> Defintely so - I find having the most important code stuck in column X
(where
>> X can vary, depending on how many checks and the nesting level) very hard
>> to follow over large programs.  Having the important stuff at the zero
>> indentation level seems much more natural.
>
>As I indicated in another post add the following realistic requirements
>
>1. A log message has to be output indicating the failed condition
>2. A different value has to be returned for each of the conditions
>
>and you will see how much more cumbersome the se/se structure will become.

int f(char* name) // returns status value
{
  int status = 0;
  if (File* f = fopen(name, "r"))
  {
    if (char* buffer = malloc(80))
    {
      DoSomethingUseful(f,buffer);
      free(buffer);
    }
    else // malloc failure
    {
      Log("malloc failure");
      status = -2;
    }
    fclose(f);
  }
  else // fopen failure
  {
    Log("Failure to fopen");
    status = -1;
  }
  return status;
}


Perhaps you think this is cumbersome.  I don't.  Cumbersome is a rather
subjective term.

>I think, a function is best partitioned as a sequence of small number of
>independent paragraphs (scopes) - where each paragraph can be understood in
a
>context independent manner. I contend that this is better for readability

That's nearly a quote from Dijkstra!

>AND maintainability.

That equates maintainability with readability; a position that I don't
believe to be valid.  Granted something must be readable to be maintainable;
however something that is readable is not necessarily maintainable.

>The multiple-return structure accomplishes this better than the se/se
structure.

Does it?  I think that's subjective.

>The se/se strcuture often creates a monolithic paragraph,

Quite to the contrary, the se/se structure is defined as a structure that is
recursively decomponsible into four discrete se/se control elements.  The
recursive decomposition goes right down to the level of single lines of
code.  Thus, an se/se structure cannot be monolithic (literally "one rock").

>creating a scope that extends across many lines.

Lots of things creates scopes that extend accross many lines.  Functions,
classes, try blocks.  I'll grant you that scopes should be as small as
possible in order to be understood.

>In fact, I feel that the multiple-return structure is more in line with the
>"structured" organization of programs.

You are free to feel that way, but the strict definition of SP does not
support your "feeling".


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan









^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                                   ` Robert Martin
@ 1998-09-04  0:00                                                                     ` Mike Spille
  1998-09-05  0:00                                                                       ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Mike Spille @ 1998-09-04  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> 
> int f(char* name) // returns status value
> {
>   int status = 0;
>   if (File* f = fopen(name, "r"))
>   {
>     if (char* buffer = malloc(80))
>     {
>       DoSomethingUseful(f,buffer);
>       free(buffer);
>     }
>     else // malloc failure
>     {
>       Log("malloc failure");
>       status = -2;
>     }
>     fclose(f);
>   }
>   else // fopen failure
>   {
>     Log("Failure to fopen");
>     status = -1;
>   }
>   return status;
> }
> 
> Perhaps you think this is cumbersome.  I don't.  Cumbersome is a rather
> subjective term.
> 

I find it quite cumbersome, and error prone to boot.  I'd do it as:

int f(char* name) // returns status value
{
  char buf[80];
  FILE* f = fopen(name, "r");
  if (f == NULL) {
    Log("Failure to fopen");
    return (-1);
  }

  DoSomethingUseful(f,buf, sizeof(buf));
  fclose (f);
}

That is, use a stack-based buffer and pass in the size of the char array to
do something useful so it doesn't walk off the end of the buffer by mistake
(assuming that DoSomethingUseful is smart enough to include a size argument).

My point?  I focused on what the routine was supposed to do, not on a
methodology, and ended up with a more efficient, less error-prone, shorter
version.  (And I think it's more readable :-)

[snip]

> >The se/se strcuture often creates a monolithic paragraph,
> 
> Quite to the contrary, the se/se structure is defined as a structure that is
> recursively decomponsible into four discrete se/se control elements.  The
> recursive decomposition goes right down to the level of single lines of
> code.  Thus, an se/se structure cannot be monolithic (literally "one rock").
> 

Well...putting theory aside, you wrote a poor-performing, IMHO hard to read
C routine (well, C++ since some declarations happen in the middle
of the routine).  You did this to demonstrate the positive aspect of
se/se.

I ignored theory, stared at your function for awhile, figured out what it
was supposed to do semantically, and then wrote it to accomplish its
function.  My version puts error reporting next to where it happens
(yours moves error-handling away from error-checking; the fclose test
and handling code are far apart), doesn't waste time malloc()ing,
and is alot shorter.  I didn't consciously follow any paradigm or
methodology - I just used the language features as clearly and consisely
as I could.

> >creating a scope that extends across many lines.
> 
> Lots of things creates scopes that extend accross many lines.  Functions,
> classes, try blocks.  I'll grant you that scopes should be as small as
> possible in order to be understood.
> 
> >In fact, I feel that the multiple-return structure is more in line with the
> >"structured" organization of programs.
> 
> You are free to feel that way, but the strict definition of SP does not
> support your "feeling".
> 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

	-Mike




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                     ` Rick Smith
  1998-09-04  0:00                                                       ` Robert Martin
@ 1998-09-04  0:00                                                       ` Charles Hixson
       [not found]                                                       ` <gio+van+no+ni+8-0809981818260001@dialup75.tlh.talstar.com>
  1998-09-08  0:00                                                       ` adam
  3 siblings, 0 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-04  0:00 UTC (permalink / raw)


Rick Smith wrote:
... 
> Some data has a lifetime that makes 4 digit years unnecessary. If the
> requirements for an existing system state that a "back order" must be
> resolved within 30 days of the order date and that completed orders will
> not be held for more than 5 years, what is the benefit of changing the
> system to store 4 digit years with the order?
> 
> The benefits of windowing should be clear.
> 
> 1. No user should be required to enter more data than is necessary. If the
> correct 4 digit year can be determined by the last two digits, do not ask
> for more than these 2 digits.
> 
...
> -------------------------------
> Rick Smith
> e-mail: < ricksmith@aiservices.com >
The problem comes when the validity of assumptions changes.  In 1990 to
say that if someone was born after xx/xx/90, then they were actually
born before 1900 is reasonable.  In 2000, what do you say about someone
who was born in xx/xx/00?  A 2-digit date was a perfectly valid entry
value, it won't be for about 5 years (10 years?), and then it will be
again.  But this is an easy problem to overlook (most test data sets
won't have any people more than 100 years old, and in most years a
2-digit entry field is good enough for everyone [no one living in my
service area and entered in my database is currently verified to have
lived to more than 105]). Also, it probably wouldn't cause any trouble
in my application anyway (it doesn't matter much if a transit pass is
denied to someone who is over 100 years old, they wouldn't have used it
anyway -- given today's medicine).  But there are a lot of guards in
those sentences.  Things external to my program that could change to
cause my currently working program to stop working.  And I don't have
control over any of them.

If the bus service starts a public relations campaign to provide free
chauffered rides to seniors (or super-seniors), it will SUDDENLY be
important that I handle the exceptional cases that I had been previously
ignoring.  ETC!

On the other hand, the basic thrust of your argument is certainly
correct.  But one needs to be careful to build in overrides!  E.g., have
the century field exist on the form, but be automatically filled in with
the most common default assumption, and then do an automatic tab over
the field, so that one must manually select the century to be able to
enter it.  The century could also be a choice list, that includes all
currently reasonable values.  If the list of values is stored in a
preferences file, then it would be no problem to add values once a
century (even after the vendor stops supporting the environment).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                               ` Loryn Jenkins
  1998-09-01  0:00                                                 ` Matthew Heaney
@ 1998-09-04  0:00                                                 ` Charles Hixson
  1998-09-05  0:00                                                   ` Loryn Jenkins
  1 sibling, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-04  0:00 UTC (permalink / raw)


Loryn Jenkins wrote:
..
> Ah! For some reason, I thought you were testing the first item on the
> stack. So, my amended code, to match your semantics is thus:
> 
>  equal (l,r: LIST): BOOLEAN is
>        require
>                l /= Void and r /= Void
>        do
>                Result := l.count /= r.count
>                if Result then
>                        from
>                                l.start; r.start
>                        until
>                                not Result or l.off
>                        loop
>                                Result := l.item /= r.item
>                                l.forth; r.forth
>                        end
>                end
>        end
> 
...
> 
> Loryn Jenkins
> 
> PS: I really would agree with you if the only counter examples were Tim
> McDermott's and Jim Cochrane's ones.
Is the if test important?  The until test should catch it anyway, and
the code would read more cleanly without it.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                       ` Joe Gamache
@ 1998-09-04  0:00                                                         ` Charles Hixson
  1998-09-05  0:00                                                           ` Patrick Logan
  0 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-04  0:00 UTC (permalink / raw)


Joe Gamache wrote:
> 
> Matthew Heaney wrote:
> 
> > Loryn Jenkins <loryn@s054.aone.net.au> writes:
> >
...
It seems to me that at least a part of this is about how much optimizing
you assume that the compilers do.
If you assume that they aren't doing much, then you try to write code
that will execute efficiently.  If you assume that they do LOTS of
optimization, then you write code that's maximally clean, and leave it
to the compiler to figure out what's most efficient. 
Of course this is only part of it, but I think that changes in the
algorithm that scale linearly are generally overwhelmed by differences
between compiler implementations, and also that the best code for this
year may not be the best code for next year.

I am particularly leery of using constructs like "and then" to optimize
performance.  That works this year, but two years from not the parallel
version of the code will hit a linearizing bottleneck. (Well, two years
may be optimistic, but if the code ends up in a library, two years is
nothing to the changes that it may need to survive).

Perhaps what is needed is a formalization of the (Eiffels?)
Command-Query Separation so that compilers can choose to abort a query
in progress if it's returned value would be irrelevant.  And perhaps the
order of the arguments to a boolean operator could reflect the
programmers best guess as to which it would be most profitable to try
first (I know it is frequently implemented this way, but if it were
formalized, then it would become something that both programmers and
compilers could depend on, and this could be helpful).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                               ` Jean-Marc Jezequel
@ 1998-09-04  0:00                                                 ` Richard Melvin
  1998-09-07  0:00                                                   ` Jean-Marc Jezequel
  0 siblings, 1 reply; 510+ messages in thread
From: Richard Melvin @ 1998-09-04  0:00 UTC (permalink / raw)


In article <35EFD468.BDD7CB0A@irisa.fr>, Jean-Marc Jezequel <Jean-
Marc.Jezequel@irisa.fr> writes
>
>        Result := l.first /= r.first
>        from l.start; r.start
>       invariant equal_so_far: --foreach i such as 0<i<l.current_index 
>                                       -- r.item(i) = l.item(i)
>        variant l.count-l.current_index+1
>        until not Result or l.off --r.off omitted since l.off=>r.off
>        loop
>              Result := l.item /= r.item
>              l.forth; r.forth
>        end

Nice proof.

Unfortunately your code contains at least one, and arguably two, bugs:

- will throw an exception or return wrong result on unequal 
  length lists.

- will interfere with iteration over lists in the calling function 
 (unless the language you are using passes lists by value, 
  not identity).

I've got a theory as to the people writing strict single/entry single
code are having such a hard time with this (defect rate > 20%):

- iteration through a list is actually quite hard, through two 
  lists multiply so - there are quite a lot of opportunities for error.
  Of course, it doesn't seem that hard to most people, as they have
  memorised the correct way to loop through a list, given their 
  language and library.

- With tree structured code, you can use this memorised pattern
  of iteration every time, and put the custom code within the loop 
  body, including early exit.

- with strict structured code, you can't do this, as you have to 
  adjust the loop condition, at least introducing new terms, 
  and possibly adjusting existing ones.

Anyway, it's just a theory - no doubt someone will now post a batch 
of tree-structured code with bugs.
-- 
Richard Melvin




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                               ` Robert Martin
@ 1998-09-05  0:00                                                                 ` Loryn Jenkins
  1998-09-04  0:00                                                                   ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-05  0:00 UTC (permalink / raw)


> Then clearly you have not read much of Dijkstra.  The citation you want is
> the citation I have given you many many times.  Go look it up Elliott.

Yes, look it up. Read it. Acknowledge that that is what Dijkstra was
saying.

Remember, you *may* disagree with him. But it is silly not reading what
he actually said. And it is fantasy arguing that he wasn't discussing
se/se.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                         ` Samuel Mize
  1998-09-04  0:00                                                           ` Ell
@ 1998-09-05  0:00                                                           ` Loryn Jenkins
  1998-09-09  0:00                                                             ` Samuel Mize
  1998-09-11  0:00                                                             ` Robert I. Eachus
  1 sibling, 2 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-05  0:00 UTC (permalink / raw)


> Humpty Dumpty had perfectly clear thoughts, but he didn't use the
> agreed-to language, so his thoughts weren't clear to others.

This is dubious at best. Although many linguists in the American
Chomskyist school chould agree with you (that is, their dubious claim of
the division between 'competence' and 'performance'). Outside of there,
few linguists would agree with this philosophical position.

It is much more to the point that language is an instrument which 
*construes reality*. It is quite inapropriate to claim that thoughts can
be organised outside of the semiotic systems that construct it.

Loryn Jenkins
BA, Linguistics.
Macqurie University.
Sydney, Australia.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                           ` Ell
  1998-09-04  0:00                                                             ` Ell
@ 1998-09-05  0:00                                                             ` Loryn Jenkins
  1998-09-06  0:00                                                               ` Charles Hixson
       [not found]                                                             ` <35F074C9.E10C <35F2E907.594CD023@earthlink.net>
  1998-09-10  0:00                                                             ` Tim Ottinger
  3 siblings, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-05  0:00 UTC (permalink / raw)


> Testing for pre-conditions before processing is not equal to what the
> try/catch idiom is about.

Very true.

> I advocate that in general we should test to see that pre-conditions
> are met, and if they aren't, bail.  Why even try to process if
> pre-conditions have not been met?
> 
> if (!pre-condition)
>         bail
> else
>         do_processing()
> endif

This is an interesting approach to DBC: specify your preconditions and
write your function to ensure the preconditions are met, else bail.

However, I think Meyer's approach to DBC is more powerful than this.
Basically, Meyer's approach is to make the calling routine check the
preconditions, not the called routine.

Imagine the following routine:

	put (v: SOME_ENTITY) is
		require
			not has (v)
				-- where `has' tests by OID.
		do
			...
		ensure
			...
		end

I would argue that the calling routine is in the best position to check
this precondition. For example, the calling routine may be creating an
object, then inserting it into this object. It doesn't have to call
`has' to make sure the object isn't yet inserted. Whereas, another
client may have to check it.

Checking for your own preconditions is simply defensive programming. The
problem is that a calling class has no way of knowing (beforehand)
whether the routine is going to work or not. Unless it too checks the
preconditions, in which case your software is starting to be weighed
down by multiple, repeated checks for consistency. And this is what
preconditions and DBC is all about doing: eliminating uncertainty;
eliminating the redundant code bloat of redundant error checking.

On the other hand, if you're not going to expect your client routine to
check the precondition, then you *must* handle everything yourself. (ie
you shouldn't just *bail.) Why? Because that implies that the client
routine is going to have to check *after the fact* whether the routine
succeeded or failed. Then it's going to have to do something about it.
You see, it would have been better to get the client routine to do its
own checking before hand, then *expect* the routine to work.

Now, when you observe this approach to DBC, then you gain a powerful
insight into a disciplined use of exception handling. (Hint: It's used
much less commonly than in the standard idiom apparent in C++ and Java
world.)

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                                     ` Mike Spille
@ 1998-09-05  0:00                                                                       ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-05  0:00 UTC (permalink / raw)


Mike Spille <mspille@tisny.com> wrote:

>Robert Martin wrote:
>>
>> [code elided]
>> Perhaps you think this is cumbersome.  I don't.  Cumbersome is a rather
>> subjective term.

On our teams if you were out voted you'd have to change it.  All code
is subject to review.  In other words what is cumbersome can generally
be agreed upon by the majority, or plurality of any mixed skill team
of professional programmers.

Spille wrote:
>> >In fact, I feel that the multiple-return structure is more in line with the
>> >"structured" organization of programs.
 
>> You are free to feel that way, but the strict definition of SP does not
>> support your "feeling".

There is absolutely nothing to support your assertion, so it can not
be absolutely anything other than unadulterated "feeling" on your
part.

Where oh where oh where is this "strict definition of SP"?   You are
making a fundamental assertion here, and any sane academic in the
world would say that the burden of proof that se/se is a key defining
criterion of SP is clearly upon you.

For shame Robert Martin, for shame!  

[And given the overwhelming pro-RCM, pro-craftite makeup of the
moderators for the proposed comp.object.moderated group, they would
suppress any questioning of your blatantly intellectually dishonest
assertions.  You could just slide by slippery as a snake.]

[And what makes this even more bogus, and outrageous is that these
moderators have been elected for life.  There is no provision at all
for periodic elections.]

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                               ` Patrick Doyle
@ 1998-09-05  0:00                                                                 ` Ell
  1998-09-05  0:00                                                                   ` Jeffrey C. Dege
  1998-09-05  0:00                                                                   ` Loryn Jenkins
  0 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-09-05  0:00 UTC (permalink / raw)


doylep@ecf.toronto.edu (Patrick Doyle) wrote:

>Ell <ell@access.digex.net> wrote:
>>
>>"Robert Martin" <rmartin@oma.com> wrote:
>>>
>>>You had best define 'unstructured' in this context.  Dijkstra's definition
>>>of 'unstructured control flow' is control flow that does not conform
>>>precisely to the four standard sequencing elements {sequence, selection, top
>>>exit loop, bottom exit loop}, all of which have a single entry and a single
>>>exit.

>>Where is this documented?  Where has Dijkstra stated that flow control
>>must conform precisely to the 4 specific elements you mention?  I know
>>that sequence, selection, and *looping * are major appropriate flow
>>control elements, but please show where Dijkstra says that "top exit
>>loop" and "bottom exit loop" are, or should be standard flow control
>>elements.

>When Robert does so, do you promise to finally admit you're wrong?  :-)

How long will take for him not to show evidence, as he well should,
before you acknowledge that he's blowing smoke?

And moreover at that point will you acknowledged that you gave RCM the
"gut feeling" benefit of the doubt, as evidenced by your comments
above, because you have an ideological affinity with him, or for some
other non-valid reason?

Whatever it is that causes you to spontaneously adopt RCM's position
in a discussion, it is not based on facts.  Because generally I've
produced more concrete, and more accurate facts on the issues than he
has over the years.  And likewise I have generally adopted the more
correct position in discussions on comp.object over the years.

If you acknowledge this, will you then quit as proposed moderator?

Because as evidenced here, you will accept RCM's position without
facts simply because you have an ideological affinity, or other
non-valid reason to do so.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                 ` Ell
@ 1998-09-05  0:00                                                                   ` Jeffrey C. Dege
  1998-09-05  0:00                                                                     ` Matthew Heaney
  1998-09-05  0:00                                                                   ` Loryn Jenkins
  1 sibling, 1 reply; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-09-05  0:00 UTC (permalink / raw)


On Sat, 05 Sep 1998 02:47:33 GMT, Ell <ell@access.digex.net> wrote:
>doylep@ecf.toronto.edu (Patrick Doyle) wrote:
>
>
>>When Robert does so, do you promise to finally admit you're wrong?  :-)
>
>How long will take for him not to show evidence, as he well should,
>before you acknowledge that he's blowing smoke?
>
>And moreover at that point will you acknowledged that you gave RCM the
>"gut feeling" benefit of the doubt, as evidenced by your comments
>above, because you have an ideological affinity with him, or for some
>other non-valid reason?

I expect the reason that Patrick Doyle believes that Robert Martin
is correct in claiming that Dijsktra advocated se/se is because every
reference to structured programming they've ever seen also claimed
that Dijkstra advocated se/se.

I don't have Dijkstra's books and articles available, but the software
engineering texts I do have are unanimous on this point.

From "Software Engineering, Methods and Management", by Annelise von
Mayrhuaser, 1990, (ISBN 0-12-727320-4), p. 373:

	The goal of the coding effort is to translate the design into a
	set of Single-Entry-Single-Exit (SESE) modules.

From "Software Engineering", by Stephen R. Schach, 1990, (ISBN 0-256-08515-3),
p. 311:

	A product is structured if the code blocks are connected by
	concatenation, selection, and iteration only, and every block has
	exactly one entry and one exit.

Neither of these authors are seminal figures in SE like Dijkstra or
Knuth, But then, these aren't ground-breaking expositions of new
ideas, they are undergraduate-level textbooks for SE survey courses,
which is why I have them lying around the house.

These two quotes do not, admittedly, demonstrate that Dijkstra advocated
se/se as a part of structured programming.  They do, however, explain
why Robert and Patrick are so adamanent about the idea that se/se is
a part of structured programming, because the authors of the college
textbooks said so.

It is certainly possible that Dijkstra didn't stress se/se in his
original work on structured programming.  The only one of his early
works on the subject I have access to is his GOTO letter, which
doesn't begin to explore the consequences of the idea.  But what
is certainly true is that the programming profession, for a great
many years now, has considered se/se one of the fundamental
principles of structured programming.

-- 
The aim of science is to seek the simplest explanations of complex
facts.  Seek simplicity and distrust it.
		-- Whitehead.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                         ` Charles Hixson
@ 1998-09-05  0:00                                                           ` Patrick Logan
  1998-09-05  0:00                                                             ` Charles Hixson
  0 siblings, 1 reply; 510+ messages in thread
From: Patrick Logan @ 1998-09-05  0:00 UTC (permalink / raw)


In comp.object Charles Hixson <charleshixsn@earthlink.net> wrote:

: Of course this is only part of it, but I think that changes in the
: algorithm that scale linearly are generally overwhelmed by differences
: between compiler implementations, and also that the best code for this
: year may not be the best code for next year.

I have read a little bit on Comp.arch over the last six months or so
about how the hard core algorithm/performance people are finding
significant differences in performance by paying attention to memory
hierarchies, level 2 caches, etc. Some of these folks describe the
best results come from treating the L2 and the CPU as an old, limited
RAM computer. In this case, going to the off chip RAM is like going to
core memory in "olden days".

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                   ` Loryn Jenkins
@ 1998-09-05  0:00                                                                     ` Robert Martin
  1998-09-06  0:00                                                                       ` Loryn Jenkins
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-05  0:00 UTC (permalink / raw)



Loryn Jenkins wrote in message <35F0B75E.F259FCE6@s054.aone.net.au>...

>Elliot. It may or may not surprise you. But there are many things that I
>agree with you on, and disagree with Robert. (eg I believe he tends to
>overstate the motivation for OO as dependency management. Whereas, for
>me, OO is more about conceptually modelling coherent sets of behaviours
>that can be assigned to a well-defined entity. Which, if I understand it
>right, is closer to your position than his.)


There are two aspects to dependency management.  One is to isolate those
things which ought not depend upon each other.  The other is to associate
those things that ought to be associated.  i.e. the old duo of cohesion and
coupling.  Your nicely worded phrase "conceptually modelling coherent sets
of behaviors" is a good way of expressing the cohesion side of the equation;
and I, of course, have no quarrel with it.  Objects, after all, ought to
consist of conceptually cohesive groupings of functions and data.  Object
models, on the other hand, should consist of an interelated set of such
objects which have been decoupled as much as possible.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                   ` Jeffrey C. Dege
@ 1998-09-05  0:00                                                                     ` Matthew Heaney
  1998-09-05  0:00                                                                       ` Robert Martin
                                                                                         ` (2 more replies)
  0 siblings, 3 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-05  0:00 UTC (permalink / raw)


jdege@jdege.visi.com (Jeffrey C. Dege) writes:

> These two quotes do not, admittedly, demonstrate that Dijkstra advocated
> se/se as a part of structured programming.  They do, however, explain
> why Robert and Patrick are so adamanent about the idea that se/se is
> a part of structured programming, because the authors of the college
> textbooks said so.
> 
> It is certainly possible that Dijkstra didn't stress se/se in his
> original work on structured programming.  The only one of his early
> works on the subject I have access to is his GOTO letter, which
> doesn't begin to explore the consequences of the idea.  But what
> is certainly true is that the programming profession, for a great
> many years now, has considered se/se one of the fundamental
> principles of structured programming.

The best answer to the question "What is structured programming?" was
provided by David Gries, in Chap 6, On Structured Programming, of his
book Programming Methodology (Springer-Verlag, 1978).

The chapter begins with the statement:

"The term structured programming has been used with many different
meanings since Edsger W. Dijkstra first coined the term.  Actually, the
term appeared in the title of his monograph Notes On Structured
Programming [that's the "little black book" - matt], but as far as I can
determine not in the monograph itself!"

So Dijkstra never precisely defined the term "structured programming."

Next sentence in Gries:

"The lack of a precise definition has allowed, even encouraged, people
to use it as they wished, to attribute to sp ["sp" is how Gries
abbreviates "structured programming" - matt] what they themselves
learned from reading Notes On Structures Programming, however different
this might have been from Dijkstra's intent."

Now we're getting warm.  Ed Yourdon other authors have stated that
structured programming means single entry/single exit modules, but did
Dijkstra say this specifically?  The answer would appear to be no.

(I myself have the little black book around, and I'm going to make it a
point to re-read it.  Sadly, this classic text is long out of print, but
I was able to find one in a used bookstore.)

Next sentence of Gries:

"Taken out of context or viewed in the wrong light, some of the
resulting definations of sp that have appeared in the literature seem
stupid (e.g., sp is programming without gotos), and it is quite
understandable that programmers have looked askance when asked to learn
and practice it."

Gries lists impressions that various people have of sp.  Here are some
of them:

(start of quote)
1. It is a return to common sense.

2. It is the general method by which our leading programmers program.

3. It is programming without the use of goto statements.

5. It is top down programming

6. sp theory deals with converting arbitrarily large and complex
flowcharts into standard forms so that they can be represented by
iterating and nesting a small number of basic and standard control logic
structures (these usually being sequencing, alternation, and iteration)

7. sp is a manner of organizing and coding programs that makes that
programs easily understood and modified

8. The purpose of sp is to control complexity through theory and
discipline 

9. sp should be characterized not by the absence of gotos, but by the
presence of structure

10. A major function of the structuring of the program is to keep a
correctness proof feasible [this one comes from Dijkstra, in Notes On
Structured Programming]

11. A fundamental concept (of sp) is a proof of correctness.

13. sp is no panacea--it really consists of a formal notation for
orderly thinking, an attribute not commonly inherent in programmers or
any other type...
(end of quote)

Take a close look at item 10, from Dijkstra himself.  Dijkstra stated in
his original ACM letter is that there is a "conceptual gap between the
static program and the dynamic process."  His complaint was that an
_unstructured_ program made it hard to reason about the program's
behavior.

What some advocates of the se/se policy seem to be forgetting is that
the whole point is being able to mentally reason about behavior.  By
reading the program text, can you figure out what this program does?

I provided a couple of simple examples, one of them an idiom for using a
special input value to terminate a loop:

loop
   Get (N);
   exit when N = 0;
   <process N>
end loop;

Is there anyone who doesn't understand what this code fragment does?  

Structured programming means keeping the code simple, where "simple"
means "being able to easily tell what it does."  It means being able to
prove that it's correct.  See item 7.

In spite of the fact that this loop exits from the middle, I would argue
that it does indeed fit the defination of a "structured" program.

We've been debating whether a program that terminates a loop from the
middle, or does an early return, is really a "structured" program, but I
think this misses the point.  

We should instead be asking, Can I mentally reason about this program's
behavior?  Am I able to write a correctness proof for this program?  Am
I confident that this program works?

That's the real meaning of "structured."

Back to Gries:

"Let me give C. A. R. Hoare's definition, which I feel captures the
essence of sp: "The task of organizing one's thought in a way that
leads, in a reasonable time, to an understandable expression of a
computing task, has come to be called sp.""

Again, I would argue that in my comparision operation, even though it
terminates via multiple returns, can indeed be called a "structured"
program, because it's "an understandable expression of a computing
task."  

I chose the implementation I did precisely because it simplifies mental
reasoning about its behavior.  When I get the answer, deliver it NOW,
without trying to navigate a circuitous route to the end of the
subprogram, only to deliver it THEN.

Two more lines I'd like to quote from Gries:

"I would add to this that one should always strive for simplicity and
elegance.  The simplest solution is always the easiest to understand."






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                             ` Ell
  1998-09-02  0:00                                               ` Robert Oliver
@ 1998-09-05  0:00                                               ` Ray Gardner
  1998-09-05  0:00                                                 ` Matthew Heaney
       [not found]                                               ` <m31zpq4pim.fsf@mheaney.ni.ne <m3af36wtwh.fsf@mheaney.ni.net>
  2 siblings, 1 reply; 510+ messages in thread
From: Ray Gardner @ 1998-09-05  0:00 UTC (permalink / raw)


Ell wrote:
 > >>For example, there's a pernicious myth that exiting (or returning) from
 > >>the middle of a loop is bad, and that the only proper way to write a
 > >>loop is to state the termination condition explicitly, as a predicate
 > >>appearing at the top of the loop.
 > 
 > >Yes.  That pernicious myth is called "structured programming".
 > 
 > Please cite even just a single structured programming text, or founder
 > where what you say here was asserted.

And later Ell wrote:
 > The assertion that "single entry, single exit" is a required, or even
 > desirable, maxim of structured programming is a myth.
 > 
 > No one (including RCM) can show that this maxim is in fact a coding
 > heuristic put forward by any of the founders of the structured
 > paradigm. [Check past posts in this thread.]

RCM had responded with a direct quote from Dijkstra, but Ell 
rejected it without understanding it.  And rejected it again 
after RCM explained it.  

To recap, in Dijkstra's Notes on Structured Programming in the 
classic _Structured Programming_ (1972), EWD referred to the 
single-entry/single-exit property of the flowcharts of the if-
then-else, case-of, while-do, and repeat-until control 
structures.  Ell apparently thought EWD was talking about how 
flowcharts should be represented on a page.  EWD was actually 
using the flowcharts as a graphical aid to make a point about 
program topology. 

To support this interpretation, I'll just quote this from the 
same source, p. 20:

"... restricting ourselves to the three mentioned types of 
decomposition lead to flowcharts of a restricted topology compared 
with the flowcharts one can make when arrows can be drawn from 
any block leading into any other."

EWD then goes on at length to explain why such a topology is 
desireable.

Ell, you might consider this: in the entire monograph EWD 
never mentions goto, exit, break, return or any other change in 
the flow of control outside of the selection and repetition 
statements mentioned above.  And he certainly had no such other 
modes of flow control in mind when he wrote his "GOTO considered 
harmful" letter; he was accustomed to Algol, which has no 
exit/break/return or similar statements.  (Also consider that 
goto-less programming in Pascal has the same restriction, since 
Pascal lacks exit/break/return etc.)

Ell, remember that you asked for a cite from "even a single 
structured programming text, or founder" to support single-
entry/single-exit.  Okay.  Hard to say who you can consider "a" 
founder other than "the" founder, EWD.  But consider Niklaus 
Wirth: "For the intellectual manageability, it is crucial that 
the constituent operations at each level of abstraction are 
connected according to sufficiently simple, well understood 
_program schemas_, and that each operation is described as a 
piece of program with _one starting point_ and a _single 
terminating point_."  [Emphases were italics in the original.]  
"On the Composition of Well-Structured Programs", N. Wirth, in 
ACM Computing Surveys, December 1974 (Special Issue on 
Programming), p.249. 

How about this:  "A _proper program_ is a program with a control 
structure that (1.) has a single entry line and a single exit 
line, and (2.) for each node, has a path through that node from 
the entry line to the exit line."  _Structured Programming: 
Theory and Practice, R.C. Linger, H.D. Mills, B.I. Witt, Addison-
Wesley, 1979, p. 94.  (Ell has already commented on a similar use 
of the word "proper".  Ell, you should understand that the word 
is being used here in a technical fashion as part of a 
*definition*, similar to the use of "well-formed formula" in 
mathematical logic.  And, anticipating that you'll claim that 
this has nothing to do with structured programming per se, I'll 
point out that the entire book is about programming via the use 
of "proper programs" as defined above.) 

Since you mentioned structured COBOL, I'll mention this:

"GO TO statements are not allowed.  The rationale here is to 
force programmers to think ahead and use _only_ 1-in, 1-out 
control structures." ... "STOP RUN may only occur as the last 
statement of the main procedure of a program.  EXIT PROGRAM may 
only occur as the last paragraph of the main procedure of a 
subprogram.  The rationale here is to make the logical exit of a 
program identical to the lexical end of its main procedure." 
_COBOL With Style (Programming Proverbs)_, L.J. Chmura, H.F. 
Ledgard, Hayden, 1976.  A book on structured programming in 
COBOL.

Many other writers have discussed structured programming in terms 
of single-entry/single-exit control structures, often without 
using those terms explicitly.  But what else could they mean when 
they develop a programming style that uses only sequence, 
if-then-else, while-do, repeat-until, and sometimes case-of, 
without ever mentioning or using goto, return, break, exit, 
continue, or any other discontinuity of control?

For an even heavier dose of Dijkstra, try his _A Discipline of 
Programming_ (Prentice-Hall, 1976) where he develops a fairly 
complete theory of proof-oriented _nondeterministic_ procedural 
programming semantics using only assignment and "guarded 
commands" for conditional and repetitive (if ... fi and do ... 
od) statements.  He never explicitly mentions "single-
entry/single-exit", but it's clear from his exposition that 
there is no other form of flow control in his system.

You mentioned (twice) page 72 of Knuth's _Literate Programming_ 
(not _The Art of ... as you've twice mis-cited it, and the 
publisher is CSLI, not CLSC or CLCS as you've twice misnamed 
them).  This page is part of a reprint of Knuth's classic paper 
"Structured Programming with go to Statements", originally in ACM 
Computing Surveys, December 1974.  You might consider what Knuth 
said on p. 18 of your book: "It is impossible to read the recent 
book _Structured Programming_ [Dahl (not Dahle), Dijkstra, and 
Hoare] without having it change your life."  And then take RCM's 
advice and read the book.  Perhaps that's what it'll take to get 
you to believe that Dijkstra was advocating exactly what RCM said 
he was.  (You won't do it because you might find RCM is right.)  

BTW, while it's true that Dijkstra considered abstraction to be 
central to his notion of structured programming, page 72 of 
Knuth's book nowhere says "It was Dijkstra who thinks of 
*abstraction* when someone mentions 'structured programming'."   
It does quote Dijkstra as saying that when he's dealing with one 
level of abstraction, it occupies 90% of his attention while the 
rest is kept in mind in the background.  Yes, abstraction is key 
to Dijkstra's notion of structured programming.  But so is the 
use of the limited set of control structures mentioned above, and 
so is his oft-mentioned "separation of concerns". 

I've been doing this long enough (30 years) to remember when this 
stuff was new, and I have many of the original books and papers 
in my library.  I also had the personal experience of bringing 
structured programming into a COBOL spaghetti shop in 1974.   So 
I do know a little about this stuff.  I'm not saying structured 
programming is only about control structures.  And I'm not saying 
that no one has tried "enhancing" the original idea of structured 
programming with additional control structures.  Wulf, Zahn, 
Dahl, Knuth and others have suggested other forms of loops.  But 
the original idea, as expounded by Dijkstra, Mills, Wirth, 
Ledgard, and others does indeed restrict you to single-
entry/single-exit control structures, and they don't exit loops 
in the middle. 




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                     ` Matthew Heaney
  1998-09-05  0:00                                                                       ` Robert Martin
@ 1998-09-05  0:00                                                                       ` Matthew Heaney
  1998-09-05  0:00                                                                         ` Robert Martin
  1998-09-08  0:00                                                                         ` Tim McDermott
  1998-09-09  0:00                                                                       ` Tim Ottinger
  2 siblings, 2 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-05  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> writes:

> What some advocates of the se/se policy seem to be forgetting is that
> the whole point is being able to mentally reason about behavior.  By
> reading the program text, can you figure out what this program does?
> 
> I provided a couple of simple examples, one of them an idiom for using a
> special input value to terminate a loop:
> 
> loop
>    Get (N);
>    exit when N = 0;
>    <process N>
> end loop;
> 
> Is there anyone who doesn't understand what this code fragment does?  
> 
> Structured programming means keeping the code simple, where "simple"
> means "being able to easily tell what it does."  It means being able to
> prove that it's correct.  See item 7.
> 
> In spite of the fact that this loop exits from the middle, I would argue
> that it does indeed fit the defination of a "structured" program.


I've been flipping through Structured Programming, by Linger, Mills, and
Witt (Addison-Wesley, 1979), which I read a couple of years ago.  In
Chap 3 they list a few control structures, among them:

(start of quote)
The dowhiledo structure has general form

  do1
    dopart1
  while
    whiletest
  do2
    dopart2
  od

The dowhiledo below prints individual characters from a string, up to a
blank character:

  do1
    get next character from string
  while
    character not blank
  do2
    print character
  od
(end of quote)

Except for the sense of the whiletest, this is the similar to the Ada
fragment I presented earlier.  For example:

  loop
     Get (From => S, Char => C);

     exit when C = ' ';

     Put (C);
   end loop;

So we see that the middle exit loop construct really does fit the
definition of "structured."  Harlan Mills was a mathematician who
believed in writing provably correct programs, and his book Structured
Programming shows how to do that for, among other loops, the dowhiledo
form.

The dowhildo form is discussed again on p116-7, in the section on prime
programs.  His definition (p118) of structured programming is:

(start of quote)
Definition: A structured program is a compound program constructed from
a fixed basis set of prime programs.
(end of quote)

In other words, his basis set forms a set of axioms, from which program
behavior can be derived.  He includes the dowhiledo form in his set of
axioms.

Conclusion: Feel free to exit from the middle of a loop.  This form of
loop stands as a peer to other forms, among them the whiledo and dountil
constructs.  If anyone argues that "oh, but it's not structured," then
hand them a copy of Mills' book.

Software Productivity (Dorset House, 1988) is a collection of Mills'
papers.  Highly recommended!





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                               ` Ray Gardner
@ 1998-09-05  0:00                                                 ` Matthew Heaney
  1998-09-07  0:00                                                   ` Ray Gardner
  0 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-05  0:00 UTC (permalink / raw)


rgardner@nyx.net (Ray Gardner) writes:

> RCM had responded with a direct quote from Dijkstra, but Ell But the
> original idea, as expounded by Dijkstra, Mills, Wirth, Ledgard, and
> others does indeed restrict you to single- entry/single-exit control
> structures, and they don't exit loops in the middle.

Oh!  You were doing well up to that last line.  Read about the
dowhiledo structure, in section 3.3.3, Iteration Structures, of
Structured Programming, by Linger, Mills, and Witt.

A list of prime programs also appears on p115, and the one at the bottom
is a dowhiledo loop.  He explicates the meaning of that loop structure
on p116-7.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                     ` Matthew Heaney
@ 1998-09-05  0:00                                                                       ` Robert Martin
  1998-09-05  0:00                                                                       ` Matthew Heaney
  1998-09-09  0:00                                                                       ` Tim Ottinger
  2 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-05  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...
>
>The best answer to the question "What is structured programming?" was
>provided by David Gries, in Chap 6, On Structured Programming, of his
>book Programming Methodology (Springer-Verlag, 1978).
>
>The chapter begins with the statement:
>
>"The term structured programming has been used with many different
>meanings since Edsger W. Dijkstra first coined the term.  Actually, the
>term appeared in the title of his monograph Notes On Structured
>Programming [that's the "little black book" - matt], but as far as I can
>determine not in the monograph itself!"
>
>So Dijkstra never precisely defined the term "structured programming."

If one looks at the little black book, one sees on its cover the words
"Structured Programming" writtin in Gold.  When one opens the book, one sees
that the first section was written by Dijkstra and is entitled "Notes on
Structured Programmin".    In part 7 of this first section we find the flow
charts which describe the four cannonical control flows; the term "single
entry at the top and a single exit at the bottom", and a discussion of the
benefits of constructing programs from these four single-entry/single-exit
forms.

In light of this it seems that Gries was incorrect when he asserted that
Dijkstra never precisely defined "structured programming".  It is probably
true that the book nowhere says: "Structured Programming is..."; but I think
that requiring such a statement is unecessary.  The contents of the book
*is* the definition of Structured Programming.
>
>Next sentence in Gries:
>
>"The lack of a precise definition has allowed, even encouraged, people
>to use it as they wished, to attribute to sp ["sp" is how Gries
>abbreviates "structured programming" - matt] what they themselves
>learned from reading Notes On Structures Programming, however different
>this might have been from Dijkstra's intent."

I don't believe it was a lack of precision that caused this.  I think it was
a lack of study.  There are plenty of folks, even now, who will simply
assume that they know what a technique is without taking the time to study
it.  This has happened with structured programming, and it has happeded with
object oriented programming.
>
>Now we're getting warm.  Ed Yourdon other authors have stated that
>structured programming means single entry/single exit modules, but did
>Dijkstra say this specifically?  The answer would appear to be no.

I quite disagree.  Dijkstra very clearly recommended that programs be
constructed from his four single-entry/single-exit control structures in his
"notes on structured programming".

>(I myself have the little black book around, and I'm going to make it a
>point to re-read it.  Sadly, this classic text is long out of print, but
>I was able to find one in a used bookstore.)

I lost my first copy about ten years ago; but I was able to find another
without too much trouble.  They are around.
>

>
>10. A major function of the structuring of the program is to keep a
>correctness proof feasible [this one comes from Dijkstra, in Notes On
>Structured Programming]

>Take a close look at item 10, from Dijkstra himself.  Dijkstra stated in
>his original ACM letter is that there is a "conceptual gap between the
>static program and the dynamic process."  His complaint was that an
>_unstructured_ program made it hard to reason about the program's
>behavior.

This is also a major theme running through his section of the book.

>What some advocates of the se/se policy seem to be forgetting is that
>the whole point is being able to mentally reason about behavior.  By
>reading the program text, can you figure out what this program does?

Yes, this was the point.  But the *mechanism* named "structured programming"
was Dijkstra's way of addressing that point.  There may be lots and lots of
different ways to address the point, but the only one that can be called
"structured programming" is the one that uses Dijkstra's four cannonical
control flows.

>I provided a couple of simple examples, one of them an idiom for using a
>special input value to terminate a loop:
>
>loop
>   Get (N);
>   exit when N = 0;
>   <process N>
>end loop;
>
>Is there anyone who doesn't understand what this code fragment does?
>
>Structured programming means keeping the code simple, where "simple"
>means "being able to easily tell what it does."  It means being able to
>prove that it's correct.  See item 7.

That list was pretty funny.  I especially like item 1. "A return to common
sense".  Or item 8 "controlling complexity through theory and discipline."
Most of those definitions are either wrong or meaningless.  Item 7. is no
different.  It certainly describes an attribute of structured programming
"easy to read and understand" but does not tell you *how* you made the code
easy to read and understand.

By the definition in Item 7. If my code is easy to read and understand, it
must be structured.  I believe that statisticians call that a "type one
error".  i.e. given that A implies B, it is a type one error to assume that
B implies A.  If we accept as a given that structured programs are easy to
read and understand, we cannot therefore assume that all programs that are
easy to read and understand are structured programs.
>
>In spite of the fact that this loop exits from the middle, I would argue
>that it does indeed fit the defination of a "structured" program.

Whether it fits Dijkstra's definition is a matter of debate.  It can be
rewritten as:

while (Get(N), N != 0)
  Process(N);

Which certainly appears close to a top-exit loop.  But this begs a question
that I don't think Dijkstra really every answered.  Must the condition in a
loop be nothing but a pure condition?  Or can it be a series of process
steps that result in a testable condition?  I prefer the latter.

I think that, as long as we treat the code that prepares the looping
condition (i.e. Get(N)) as atomic with the loop condition itself, then we
really have a top-exit loop.

Thus, after giving this some thought, I would agree with you that the code
you wrote above fits the definition of  "structured programming".  On the
other hand I disagree with your reasoning.  It is not structured because it
is easy to read.  It is structured because it is a form of top-exit loop.

Does this mean that all mid-exit loops are suddenly conformant to structured
programming?  I don't think so.  I think that when the code leading up to
the looping condition cannot be considered atomic,  (i.e. it contains
statements that do not impact the looping condition, or will change in ways
that are independent of the looping condition) then the resultant code is
not conformant to Dijkstra's rules.

For example:

for(;;)
{
  Get(N);
  if (N == 0) break;
  Process(N);
}

The above is structured because the first two statements of the loop body
are part of the loop condition. However:

for (;;)
{
  char* buf = malloc(80);
  int n = Get(buf,80);
  if (n == 0)
  {
    free(buf);
    break;
  }
  Process(buf, n);
  free(buf);
}

[Please, no complaints about the way the heap memory is being managed..
Presume that there is some good reason why its being managed that way.]

This is not a structured program because the code preceeding the loop
condition is not atomic.  It is not directly part of the loop condition, and
has side-effect that must be dealt with later.

On the other hand:

for (;;)
{
  char* buf = malloc(80);
  int n = Get(buf, 80);
  if (n != 0)
  {
    Process(buf, n);
  }
  free(buf);
  if (n == 0) break;
}

This is a structured program because it conforms to a bottom-exit looping
structure.

>
>We've been debating whether a program that terminates a loop from the
>middle, or does an early return, is really a "structured" program, but I
>think this misses the point.

It may miss some point somewhere, but it does not miss the point when the
point is the definition of structured programming.

There is another type one error we can make.  If we assume that structured
programming is "good", we cannot therefore assume that "good" implies
structured programming.  There may be many different kinds of good programs,
some of them having mid loop exits.  Such programs are not structured
programs, but that doesn't mean that they are not good programs.
>
>We should instead be asking, Can I mentally reason about this program's
>behavior?  Am I able to write a correctness proof for this program?  Am
>I confident that this program works?
>
>That's the real meaning of "structured."

I'll agree that that was Dijkstra's motivation.  But if we go no further
than the above statement then *every* program is structured, at least in the
author's eyes.  *Every* program can be reasoned about.  Every program can be
proven correct (given enough time), every program can be worked into a shape
that inspires confidence in its correctness.

Dijkstra's contribution was more than the above simple statement.
Dijkstra's contribution was a *technique* for helping to create programs
that are easy to reason about, easier to prove correct, easier to be
confident in.

>Two more lines I'd like to quote from Gries:
>
>"I would add to this that one should always strive for simplicity and
>elegance.  The simplest solution is always the easiest to understand."


This is often true but, unfortunately, simplicity is often subjective.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                       ` Matthew Heaney
@ 1998-09-05  0:00                                                                         ` Robert Martin
  1998-09-06  0:00                                                                           ` Loryn Jenkins
  1998-09-08  0:00                                                                         ` Tim McDermott
  1 sibling, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-05  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...
>I've been flipping through Structured Programming, by Linger, Mills, and
>Witt (Addison-Wesley, 1979), which I read a couple of years ago.  In
>Chap 3 they list a few control structures, among them:
>
>The dowhiledo structure

>So we see that the middle exit loop construct really does fit the
>definition of "structured."

According to Harlan Mills.  But not according to Dijkstra.

>Conclusion: Feel free to exit from the middle of a loop.

No, you should not feel free to do anything.  You should weigh the costs of
everything you do.  You should not feel free to use top-exit loops, you
should not feel free to use 'exceptions', you should not feel free to use
'templates', etc, etc.  Everything has a cost/benefit value that needs to be
assessed.  Once making that assessment, you *decide* to use certain
structures.  And if you *decide* to use mid-exit loops, so be it.  But the
decision should *never* be:  "I used it because it is part of structured
programming", or "I used it because its part of object oriented
programming", or "I used it because it is a well known design pattern".

> This form of
>loop stands as a peer to other forms, among them the whiledo and dountil
>constructs.  If anyone argues that "oh, but it's not structured," then
>hand them a copy of Mills' book.

I haven't read this book, so I can't say if it is good or bad.  Probably it
is very good.  However, I don't recognize Mill's authority to add to the
definition of SP.  Dijkstra coined the term, he has the right to say what
gets added to it, and what gets taken away from it.

I would admit to dowhiledo being part of SP if dowhiledo fell into the
common usage of SP.  Unfortunately, you posted some 14 or more definitions
that were part of the common usage of SP.  Those 14 definition, in one way
or another, encompassed *all* of programming; making common usage
meaningless.  That makes me want to go back to the originator and stick to
his definition.

BTW, if every you use a programming structure that you have thought through
and decided to used based upon your judgement of the situation, and then
someone else wrinkles up their nose and says "but its not structured
programming", you have the perfect right to say: "So what?".  *You* are the
engineer, *You* are responsible, *You* make the decision.  But you'd better
understand the cost/benefit trade-off.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                       ` Loryn Jenkins
@ 1998-09-05  0:00                                                                         ` Robert Martin
  1998-09-06  0:00                                                                           ` Loryn Jenkins
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-05  0:00 UTC (permalink / raw)



Loryn Jenkins wrote in message <35F1B862.C1FFA000@s054.aone.net.au>...
>> There are two aspects to dependency management.  One is to isolate those
>> things which ought not depend upon each other.  The other is to associate
>> those things that ought to be associated.  i.e. the old duo of cohesion
and
>> coupling.  Your nicely worded phrase "conceptually modelling coherent
sets
>> of behaviors" is a good way of expressing the cohesion side of the
equation;
>> and I, of course, have no quarrel with it.  Objects, after all, ought to
>> consist of conceptually cohesive groupings of functions and data.  Object
>> models, on the other hand, should consist of an interelated set of such
>> objects which have been decoupled as much as possible.
>
>Well ... decoupled appropriately.

Of course!

>Perhaps this is simply a difference in emphasis. Obviously, you run into
>trouble when you have bidirectional dependencies everywhere. Obviously,
>you run into trouble if you have cyclic dependencies between clusters.

Absolutely.  You also run into trouble when you have high level concepts
depending upon implementation details.

>This is an extremely important aspect of architecture.

It is probably the most important aspect of software archictecture.

>It just doesn't seem to me to be one of the fundamental, driving forces
>of OO. (OO does enable it nicely, though.)

Agreed, it is one of the fundemental driving forces of software engineering;
and there have been many different approaches to addressing that force.  OO
is just one such approach.  It is also one of the most successful
approaches.



Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                           ` Loryn Jenkins
@ 1998-09-05  0:00                                                                             ` Robert Martin
  1998-09-06  0:00                                                                               ` Loryn Jenkins
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-05  0:00 UTC (permalink / raw)



Loryn Jenkins wrote in message <35F1BB50.C57557E1@s054.aone.net.au>...
>> I haven't read this book, so I can't say if it is good or bad.  Probably
it
>> is very good.  However, I don't recognize Mill's authority to add to the
>> definition of SP.  Dijkstra coined the term, he has the right to say what
>> gets added to it, and what gets taken away from it.
>
>That's getting a bit extreme, isn't it, Robert?
>
>Academics are forever renegotiating the boundaries in any area of
>discourse. I know, in my area, Systemic-Functional Linguistics, there is
>an awful lot of discussions as  to the details, goals, methods and
>boundaries.
>
>To alienate every academic working within the tradition other than the
>founder (Halliday) would seem to me to be nonsense.


Granted.  On the other hand, lets say that I wrote a book in which I said
that the C assert statement was another perfectly acceptable way of
implementing Design by Contract.  And then lets say that some other guy read
my book and quoted it in a newsgroup like this.  Would Design by Contract
suddenly now incorporate my use of the C assert statement?  I think not.  I
think Meyer, and the folks who have studied his work would stake a stance
against such an inclusion.

I didn't mean to alienate Harlan Mills work; I expect that it is quite good.
But I am also not willing to accept Mathew Heaney's demand that mid exit
loops are part of the structured paradigm just because he quoted Mill's
book.  I'll want more substantiation than that.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                           ` Patrick Logan
@ 1998-09-05  0:00                                                             ` Charles Hixson
  0 siblings, 0 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-05  0:00 UTC (permalink / raw)


Well, that was intended more as an example of environmental change.  Put
more abstractly, code should be written to optimize the implementation
of the algorithm.  The execution environment WILL change.  The compiler
implemented for the new environment should optimize the code to run in
the environment that it is designed to operate in itself.

I realize that
a) this is a bit optimistic, and
b) there are lots of optimizations that the compiler can't do, because
it doesn't understand the purpose of the code
but (e.g.):
IF queries were guaranteed not to change the state of the object being
queried AND there was a method of aborting a query in progress, THEN in
certain circumstances code could be executed in parallel without even
the overhead of threads.

My real question then, I guess, becomes:
Is it reasonable to insist that queries not cause any permanent changes
to the state of the system, other than returning a value?  If you do
insist upon this, what about commands that exist within the queries?  Is
it feasible to even think about enforcing this requirement?

I suppose a second question would be:  Can queries really be executed in
parallel with less overhead than spinning off a thread?

Patrick Logan wrote:
> 
> In comp.object Charles Hixson <charleshixsn@earthlink.net> wrote:
> 
> : Of course this is only part of it, but I think that changes in the
> : algorithm that scale linearly are generally overwhelmed by differences
> : between compiler implementations, and also that the best code for this
> : year may not be the best code for next year.
> 
> I have read a little bit on Comp.arch over the last six months or so
> about how the hard core algorithm/performance people are finding
> significant differences in performance by paying attention to memory
> hierarchies, level 2 caches, etc. Some of these folks describe the
> best results come from treating the L2 and the CPU as an old, limited
> RAM computer. In this case, going to the off chip RAM is like going to
> core memory in "olden days".
> 
> --
> Patrick Logan    (H) mailto:plogan@teleport.com
>                  (W) mailto:patrickl@gemstone.com
>                  http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                                   ` Ell
@ 1998-09-05  0:00                                                                     ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-05  0:00 UTC (permalink / raw)


Ell wrote:
> 
> Loryn Jenkins <loryn@s054.aone.net.au> wrote:
> 
> >> Then clearly you have not read much of Dijkstra.  The citation you want is
> >> the citation I have given you many many times.  Go look it up Elliott.
> 
> >Yes, look it up. Read it. Acknowledge that that is what Dijkstra was
> >saying.
> 
> How can I acknowledge that, if I haven't seen it?  And you all can't
> point to that stuff on flowcharting as some kind of proof that the
> founders of SP said we should adhere to se/se.
> 
> >Remember, you *may* disagree with him. But it is silly not reading what
> >he actually said.
> 
> That book is out of print and RCM knows it.

That's what libraries are for.


> If RCM had *any* shred of
> text to prove that they explicitly advocated se/se in structured
> coding he would quote it.

A charitable interpretation of what they have already quoted has
demonstrated that.

But leave that aside. Let us say that many people who have read the book
have made that interpretation. It is certainly possible for you to claim
that no, se/se is not what Dijkstra was going on about, he was really
using se/se as a tool to demonstrate that, say, code should be provable.
And it is the provability of code that is the foundation of structured
programming.

This may or may not be correct. But it is an acceptable line of
argument.

But an even better line of argument may in fact be, yes, Dijkstra does
believe in se/se. But what he should have been concentrating on was,
say, provability.

> 
> > And it is fantasy arguing that he wasn't discussing
> >se/se.
> 
> It's a deplorable attempt at deception for RCM to state that se/se is
> a cornerstone of SP without a shred of evidence.

How about, 'a cornerstone of SP as advocated by Dijkstra'. (That doesn't
necessarily mean he was right; that doesn't necessarily mean that it is
today, in fact, the basis for SP (as practised by the majority of
practitioners.) It merely means that he advocated it. (And, I think, it
would be incorrect to debate that his view has influenced many people.
That is, it is an historical fact that his views have influenced many
people (other than RCM ... take BM as an example) about the use of
se/se.

> 
> It's fantastic gullibility to think RCM is right about se/se without a
> shred of evidence;

What evidence? A quotation? Hah. That's not proof that se/se is right.
That's only proof that it is an historical fact Dijkstra argued for
se/se. Whether se/se is right is another matter entirely.

> to believe him based on faith, because I'll bet
> dollars to doughnuts that you can't show me any proof either.

Like you, I don't have the book at hand. But RCM's claims of Dijkstra's
position seems 'right' to me (based on triangulating what I've read of
many other people who've read Dijkstra).

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                 ` Ell
  1998-09-05  0:00                                                                   ` Jeffrey C. Dege
@ 1998-09-05  0:00                                                                   ` Loryn Jenkins
  1998-09-05  0:00                                                                     ` Robert Martin
  1 sibling, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-05  0:00 UTC (permalink / raw)


> Because as evidenced here, you will accept RCM's position without
> facts simply because you have an ideological affinity, or other
> non-valid reason to do so.

Elliot. It may or may not surprise you. But there are many things that I
agree with you on, and disagree with Robert. (eg I believe he tends to
overstate the motivation for OO as dependency management. Whereas, for
me, OO is more about conceptually modelling coherent sets of behaviours
that can be assigned to a well-defined entity. Which, if I understand it
right, is closer to your position than his.)

But that has nothing to do with how I (and, I suspect, Patrick) deals
with Robert. I believe you'll find we deal with courtesy. Just take a
look at the discussion between myself and Matthew Heaney. We absolutely
disagreed. But neither of us called names at each other.

Loryn Jenkins

PS: Who Patrick agrees or disagrees with has nothing to do with his
proposed moderation duties. But when people simply name call, I hope he
does return the post.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                 ` Charles Hixson
@ 1998-09-05  0:00                                                   ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-05  0:00 UTC (permalink / raw)


Charles Hixson wrote:
> 
> Loryn Jenkins wrote:
> ..
> > Ah! For some reason, I thought you were testing the first item on the
> > stack. So, my amended code, to match your semantics is thus:
> >
> >  equal (l,r: LIST): BOOLEAN is
> >        require
> >                l /= Void and r /= Void
> >        do
> >                Result := l.count /= r.count
> >                if Result then
> >                        from
> >                                l.start; r.start
> >                        until
> >                                not Result or l.off
> >                        loop
> >                                Result := l.item /= r.item
> >                                l.forth; r.forth
> >                        end
> >                end
> >        end
> >
> ...
> >
> > Loryn Jenkins
> >
>
> Is the if test important?  The until test should catch it anyway, and
> the code would read more cleanly without it.

Not really. It is an optimization.

But do note, that if you removed it, you *must* change the loop to the
following:

> >  equal (l,r: LIST): BOOLEAN is
> >        require
> >                l /= Void and r /= Void
> >        do
> >                        from
> >                                l.start; r.start
> >                        until
> >                                not Result or l.off or r.off
> >                        loop
> >                                Result := l.item /= r.item
> >                                l.forth; r.forth
> >                        end
> >        end

... just in case r is shorter than l.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                     ` Robert Martin
@ 1998-09-06  0:00                                                                       ` Loryn Jenkins
  1998-09-05  0:00                                                                         ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-06  0:00 UTC (permalink / raw)


> There are two aspects to dependency management.  One is to isolate those
> things which ought not depend upon each other.  The other is to associate
> those things that ought to be associated.  i.e. the old duo of cohesion and
> coupling.  Your nicely worded phrase "conceptually modelling coherent sets
> of behaviors" is a good way of expressing the cohesion side of the equation;
> and I, of course, have no quarrel with it.  Objects, after all, ought to
> consist of conceptually cohesive groupings of functions and data.  Object
> models, on the other hand, should consist of an interelated set of such
> objects which have been decoupled as much as possible.

Well ... decoupled appropriately.

Perhaps this is simply a difference in emphasis. Obviously, you run into
trouble when you have bidirectional dependencies everywhere. Obviously,
you run into trouble if you have cyclic dependencies between clusters.

This is an extremely important aspect of architecture.

It just doesn't seem to me to be one of the fundamental, driving forces
of OO. (OO does enable it nicely, though.)

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                         ` Robert Martin
@ 1998-09-06  0:00                                                                           ` Loryn Jenkins
  1998-09-05  0:00                                                                             ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-06  0:00 UTC (permalink / raw)


> I haven't read this book, so I can't say if it is good or bad.  Probably it
> is very good.  However, I don't recognize Mill's authority to add to the
> definition of SP.  Dijkstra coined the term, he has the right to say what
> gets added to it, and what gets taken away from it.

That's getting a bit extreme, isn't it, Robert?

Academics are forever renegotiating the boundaries in any area of
discourse. I know, in my area, Systemic-Functional Linguistics, there is
an awful lot of discussions as  to the details, goals, methods and
boundaries.

To alienate every academic working within the tradition other than the
founder (Halliday) would seem to me to be nonsense.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                               ` Robert Martin
@ 1998-09-06  0:00                                                                 ` Jeffrey C. Dege
  1998-09-06  0:00                                                                   ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-09-06  0:00 UTC (permalink / raw)


On Sun, 6 Sep 1998 09:21:11 -0500, Robert Martin <rmartin@oma.com> wrote:
>
>Charles Hixson wrote in message <35F252DD.5187538@earthlink.net>...
>
>>Code should be easy to understand AND to maintain.  Both need to be
>>optimized.  Somehow.
>
>And that will never happen until we all understand the costs and benefits of
>each technique, and abandon the practice of blindly following a technique.
>SP is one such technique.  Using mid exit loops is another.  We cannot
>assert that SP is *always good*.  By the same token we cannot assert that
>mid exit loops are always good.

Be careful, your pragmatism is showing again...

-- 
For every problem there is one solution which is simple, neat, and wrong.
-- H. L. Mencken




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                   ` Ell
@ 1998-09-06  0:00                                                                     ` Jeffrey C. Dege
  0 siblings, 0 replies; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-09-06  0:00 UTC (permalink / raw)


On Sun, 06 Sep 1998 22:09:41 GMT, Ell <ell@access5.digex.net> wrote:
>In comp.object Robert Martin <rmartin@oma.com> wrote:
>
>: Matthew Heaney wrote in message ...
>
>:>I argue against using only a single return statement, because it often
>:>means that you have to do work to do ... nothing.  Once I determine my
>:>answer (or satisfy the conditions for loop termination), then I'd rather
>:>return immediately, instead of having to figure out how to navigate my
>:>way to the end of the subprogram.
>
>: This is effective iff returning immediately is, and always will be, the
>: right thing to do.  But if there is a reasonable chance that you will have
>: to do some error handling at some time in the future, then maintaining an
>: se/se style provides place holders for that future code.
>:
>: BTW, that is nothing more than a benefit.  One could still make a realistic
>: and valid decision to forego that benefit.
>
>And one could attempt to achieve other possibly more useful benfits given
>specific circumstances.

Ye gads, you're agreeing with each other...

-- 
For every problem there is one solution which is simple, neat, and wrong.
-- H. L. Mencken




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                 ` Charles Hixson
@ 1998-09-06  0:00                                                   ` mfinney
  0 siblings, 0 replies; 510+ messages in thread
From: mfinney @ 1998-09-06  0:00 UTC (permalink / raw)


In <35F2F3F9.69ED1C30@earthlink.net>, Charles Hixson <charleshixsn@earthlink.net> writes:
>mfinney@lynchburg.net wrote:
>> 
>> In <6sk1k9$3r9$1@nnrp1.dejanews.com>, john-clonts@hlp.com writes:
>> 
>> >What do you mean by 'tree-structured' programming?
>> 
>....
>> For example...
>> 
>>         outer::while (someCondition)
>>            {
>>            // some code
>>            inner::while (anotherCondition)
>>               {
>>               // some code
>>               outer::break; // exit outermost loop
>>               inner::continue; // restart innermost loop
>>               outer::continue; // restart outermost loop
>>               inner::break; // exit innermost loop
>>               // some code
>>               }
>>            // some code
>>            }
>> 
>.... 
>> Michael Lee Finney
>I feel that this is a structure to be avoided when it is easy to do so. 
>I haven't needed this kind of sturcture more than about 10 times since
>the '80's.  OTOH, sometimes it's what the sturcture of the problem seems
>to demand.  Sometimes avoiding it would cause more problems than it
>solves.  In such a case, be VERY careful to make your code as clear and
>obvious as possible, because this IS a
>more-difficult-to-understand-than-usual idiom.

I certainly don't need it often.  I do frequently need the multiple return
from a block or the n 1/2 loop (resulting in a mid-block loop break) which
at least the first is not structured (but is tree-structured).  And, there is
a reasonable argument both ways about the mid-block loop break being
structured because it is se-se, but the exit is neither at the top nor the
bottom.  I would personally argue that it meets the spirit, but not the
letter of structured programming.  It is, however, tree-structured.

The need for the more comprehensive forms of tree-structured
programming are rarer, but they do essentially encapsulate most
of the need for more powerful control structures while maintaining
most or all of the benefits of structured programming.  I don't believe
that I have ever written a program, even in assembly language,
which was not tree-structured -- but I have written many programs,
time and again, which are not structured just because here or there
I needed just a bit more than is available with structured programming.
And since efficiency *does* count -- at least sometimes -- adding
flags or other forms of additional tests is generally not acceptable
to me.


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                 ` Jeffrey C. Dege
@ 1998-09-06  0:00                                                                   ` Robert Martin
  0 siblings, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-06  0:00 UTC (permalink / raw)



Jeffrey C. Dege wrote in message ...
>On Sun, 6 Sep 1998 09:21:11 -0500, Robert Martin <rmartin@oma.com> wrote:
>>
>>Charles Hixson wrote in message <35F252DD.5187538@earthlink.net>...
>>
>>>Code should be easy to understand AND to maintain.  Both need to be
>>>optimized.  Somehow.
>>
>>And that will never happen until we all understand the costs and benefits
of
>>each technique, and abandon the practice of blindly following a technique.
>>SP is one such technique.  Using mid exit loops is another.  We cannot
>>assert that SP is *always good*.  By the same token we cannot assert that
>>mid exit loops are always good.
>
>Be careful, your pragmatism is showing again...


Yeah -- I'm a real dangerous fellow!


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-01  0:00                                         ` Matthew Heaney
@ 1998-09-06  0:00                                           ` Charles Hixson
  1998-09-06  0:00                                             ` Matthew Heaney
  0 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


Matthew Heaney wrote:
> 
... 
> The flag makes it _much_ harder, because it doubles the number of rules
> in the decision table.

Is THAT why!  O.  I knew that it made the code more difficult to
understand, but I hadn't ever connected it with a decision table.

And someone said earlier that adding an internal if-branch added an edge
to the directed-graph (?), so I guess that if you use an if test on a
flag to get around executing part of the code on the first/last pass,
then you are adding both complexities (or are they different ways of
saying the same thing?

But somehow pulling chunks of code into a function and then calling that
function makes things simpler, even though the flow of execution follows
the same path, so something else is going on here.

I tend to think that one of the major activities of programming is
properly "chunking" the problem into pieces that have low-bandwidth
connections with the rest of the code.  This is what made the FORTRAN
COMMON blocks such a bad idea, they didn't cut down the bandwidth.

There is, of course, more to it than that.  Anonymous blocks that occur
in the middle of code may actually be isolated in just the manner that a
called routine would be, but they aren't "visually isolated" and this
makes it difficult to model them as isolated chunks.

As a result of this analysis, I feel that Java's Anonymous inner class
construct is a very bad idea.  On the other hand, a named internal class
would be a good idea.  It could even have exactly the same meaning
(including even [ugh!] read/write access to internal class variables). 
But if it were declared in a visually separated location (c.f., Pascal's
internal functions), then it would be an means of helping the chunking.

Personally, I think that if this were to be implemented, there should
be, say, a "sealed internal class" that didn't have access to the
internal class variables of the class that contained it.  This would
help improve the isolation.  But almost all of the effect of this can be
obtained by just not declaring the class as internal.  I just feel that
a tightly coupled class that doesn't really have any use outside the
context of another class should be declared internal to that class (Ada
can manage this by appropriate use of Private, but, to me, it's a rather
tricky thing to handle this properly [I'm not sure if one can completely
declare a class within the code body of an Ada file, and if you did, I
think that it would have full access to the locally declared variables,
thus expanding the bandwidth of the interface]).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                           ` Charles Hixson
@ 1998-09-06  0:00                                             ` Matthew Heaney
  0 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-06  0:00 UTC (permalink / raw)


Charles Hixson <charleshixsn@earthlink.net> writes:

> I just feel that a tightly coupled class that doesn't really have any
> use outside the context of another class should be declared internal
> to that class...

Yes.

> ... (Ada can manage this by appropriate use of Private, but, to me,
> it's a rather tricky thing to handle this properly [I'm not sure if
> one can completely declare a class within the code body of an Ada
> file, and if you did, I think that it would have full access to the
> locally declared variables, thus expanding the bandwidth of the
> interface]).

I don't understand what you think is "tricky" about declaring one type
in the same module as another:

package P is

   type T is private;
...
private

   type U is ...;

   type T is
      record
         O : U;
         ...
      end record;

end P;


Do you object to T being able to see the representation of U?  Then just
make U private:

private

   package Q is

     type U is private;
...
   private
  
      type U is ...;

   end Q;

   type T is
      record
         O : U;
...
      end record;

end P;

        
Do you not like that U can see the representation of T?  Then make T's
representation type private:

private

   type U is ...;

   package Q is
   
     type T_Rep is private;
...
   private
   
     type T_Rep is ...;

   end Q;

   type T is new Q.T_Rep;

end P;


There's nothing hard or tricky going on here.  Just normal scope rules.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                               ` Ray Blaak
@ 1998-09-06  0:00                                                                 ` Charles Hixson
  1998-09-06  0:00                                                                   ` Robert Martin
  0 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


Ray Blaak wrote:
...
> A compromise that allows both positive logic and reduced nesting is to
> calculate a guard value, and only do the work if the guard is true:
> 
>   doit := (A is right);
>   doit := doit and (B is right);
>   doit := doit and (C is right);
>   if doit then do the work;
> 
> --
> Cheers,                                        The Rhythm is around me,
>                                                The Rhythm has control.
> Ray Blaak                                      The Rhythm is inside me,
> blaak@infomatch.com                            The Rhythm has my soul.

It may be just me, but I find this final example to be the least
intelligible of the variants offered.  Yes, it is structured.  But it's
harder to understand.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                         ` Robert Martin
  1998-09-03  0:00                                                           ` Mike Spille
@ 1998-09-06  0:00                                                           ` Charles Hixson
  1998-09-06  0:00                                                             ` Robert Martin
  1 sibling, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


Robert Martin wrote:
... 
>   if (condition.1) return;
>   else if (condition.2) return;
>   else do something useful;
>   return;
> };
> 
> Which, in reality, is:
> 
> void f()
> {
>   if (condition.1) return;
>   else{
>     if (condition.2) return;
>     else {
>       do something useful;
>     }
>   }
> };
> 
> So, early returns do not actually reduce nesting; they just appear to.  The
...
> 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan
If you are going to use else-if's, then the early return doesn't
accomplish anything, and the routine could be rephrased as:
 void f()
 {
   if (!condition.1 & !condition.2) 
   {  do something useful;
   }
 };

Just a transform, I know.  But, actually, that's my point.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                               ` Loryn Jenkins
@ 1998-09-06  0:00                                                                                 ` Charles Hixson
  1998-09-06  0:00                                                                                   ` Patrick Doyle
  1998-09-07  0:00                                                                                 ` Ray Gardner
  1 sibling, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


I find myself not understanding the basis of this discussion.

To me it seems reasonable to ask, "Do reasonable experts in the field
consider that loops that exit in the middle are a part of structured
programming".

The answer, obviously, is:  This is not a matter of total agreement.

There have been agruments that say:  If you have to repeat blocks of
code, then you are violating the principles of structured programming.

There have been statements made that:  "Loops should be single
entry/single exit" (so that program correctness can be proved?).

These are both valid points.  But if the same code can be topologically
transformed from one form to another without altering it's deep flow of
control (e.g., pull all of the code within isolatable blocks into a
function call, and then call it, and accept a returned value.  Then we
can say
while (the)
  ...
  if (the) gostack := distimms (the, doshes,".");
loop

testing a flag each time throught the loop.  When is it true?  That's
hard to say without examining the code in detail (which I haven't
invented).

Is this really any different from:
while (the)
  ...
  exit when (\the);
  gostack := distimms (the, doshes,".");
loop

But this identity is only obvious because the huge chunk of code has
been factored out into the distimms routine.

In fact when we look at this, we can see that it is also equivalent to:

if (the)
{ beginloop
    ...
    exit when (\the);
    gostack := distimms (the, doshes,".");
  endloop
}
If these are all equivalent, does it really make sense to say that one
of them is structured and another isn't.  Consider a further pair of
transforms:
if (the)
{  when (firstPartOfTheLoop (the) )
   {   if (the) gostack := distimms (the, doshes, ".");
   }
}

and
if (the)
{  when (the)
   { flag := firstPartOfTheLoop (the);
     if (the) gostack := distimms (the, doshes, ".");
   }
   flag := firstPartOfTheLoop (the);
}

Now, I obviously haven't checked these with a compiler, but baring typos
I think that is is obvious that these pieces of code are all isomorphic,
so it seems TO ME unreasonable to claim that some of them are structured
and others of them aren't.

I would like to hear about why others would find it reasonable.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                     ` <6skqf3$ <35F0B5B0.8E2D0166@s054.aone.net.au>
@ 1998-09-06  0:00                                                       ` Will Rose
  1998-09-06  0:00                                                         ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Will Rose @ 1998-09-06  0:00 UTC (permalink / raw)


Loryn Jenkins (loryn@s054.aone.net.au) wrote:
: Ell wrote:
: > 
: > Loryn Jenkins <loryn@s054.aone.net.au> wrote:
: > 
: > >> Then clearly you have not read much of Dijkstra.  The citation you want is
: > >> the citation I have given you many many times.  Go look it up Elliott.
: > 
: > >Yes, look it up. Read it. Acknowledge that that is what Dijkstra was
: > >saying.
: > 
: > How can I acknowledge that, if I haven't seen it?  And you all can't
: > point to that stuff on flowcharting as some kind of proof that the
: > founders of SP said we should adhere to se/se.
: > 
: > >Remember, you *may* disagree with him. But it is silly not reading what
: > >he actually said.
: > 
: > That book is out of print and RCM knows it.

: That's what libraries are for.


: > If RCM had *any* shred of
: > text to prove that they explicitly advocated se/se in structured
: > coding he would quote it.

: A charitable interpretation of what they have already quoted has
: demonstrated that.

: But leave that aside. Let us say that many people who have read the book
: have made that interpretation. It is certainly possible for you to claim
: that no, se/se is not what Dijkstra was going on about, he was really
: using se/se as a tool to demonstrate that, say, code should be provable.
: And it is the provability of code that is the foundation of structured
: programming.

: This may or may not be correct. But it is an acceptable line of
: argument.

: But an even better line of argument may in fact be, yes, Dijkstra does
: believe in se/se. But what he should have been concentrating on was,
: say, provability.

: > 
: > > And it is fantasy arguing that he wasn't discussing
: > >se/se.
: > 
: > It's a deplorable attempt at deception for RCM to state that se/se is
: > a cornerstone of SP without a shred of evidence.

: How about, 'a cornerstone of SP as advocated by Dijkstra'. (That doesn't
: necessarily mean he was right; that doesn't necessarily mean that it is
: today, in fact, the basis for SP (as practised by the majority of
: practitioners.) It merely means that he advocated it. (And, I think, it
: would be incorrect to debate that his view has influenced many people.
: That is, it is an historical fact that his views have influenced many
: people (other than RCM ... take BM as an example) about the use of
: se/se.

: > 
: > It's fantastic gullibility to think RCM is right about se/se without a
: > shred of evidence;

: What evidence? A quotation? Hah. That's not proof that se/se is right.
: That's only proof that it is an historical fact Dijkstra argued for
: se/se. Whether se/se is right is another matter entirely.

: > to believe him based on faith, because I'll bet
: > dollars to doughnuts that you can't show me any proof either.

: Like you, I don't have the book at hand. But RCM's claims of Dijkstra's
: position seems 'right' to me (based on triangulating what I've read of
: many other people who've read Dijkstra).

I'm not sure which book started this discussion, but Dijkstra's
"Notes on Structured Programming" in "Structured Programming",
Dahl, Dijkstra and Hoare, say inter alia:

When we now take the position that it is not only the programmer's
task to produce a correct program but also to demonstrate its correctness
in a convincing manner, then the above remarks [on program size and
structure] have a profound influence on the programmer's activity;
the object he has to produce must be usefully structured.

The remaining part of this monograph will be mainly an exploration of
what program structure can be used to good advantage.  In what follows
it will become apparent that program correctness is not my only concern,
program adaptability or manageability will be another.  This stress on
program manageability is my deliberate choice, a choice that, therefore,
I should like to justify.

...[description of flowcharts which] "share the property that they
have a single entry at the top and single exit at the bottom"...

...Alternatively: restricting ourselves to the three mentioned types
of decomposition leads to flowcharts of restricted topology compared
with the flowcharts one can make when arrows can be drawn from one
block leading to any other.  Compared with that greater freedom, to
restrict oneself to the clauses presents itself as a sequenceing
discipline.

Why do I propose to adhere to this sequencing discipline?  The
justfication for this decision can be presented in many ways...



Will
cwr@crash.cts.com





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                                           ` Joe Gwinn
  1998-09-03  0:00                                                             ` Robert Martin
@ 1998-09-06  0:00                                                             ` Charles Hixson
  1998-09-06  0:00                                                               ` Matthew Heaney
                                                                                 ` (2 more replies)
  1 sibling, 3 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


Joe Gwinn wrote:
> 
> It seems to me that there is an unspoken assumption in the long debate
> about GOTOs and spaghetti code:  It doesn't follow that presence of GOTOs
> makes code spaghetti, or that code without GOTOs is always clear and easy
> to understand, write, and maintain.
> 
> The issues are in my experience quite independent.  I have seen lots of
> spaghetti code with nary a GOTO, and perfectly clear code with many GOTOs.
> 
... 
> Joe Gwinn

I suppose that it is possible to write spaghetti code without using
goto's, I've never tried.  I do know that with goto's INSTEAD OF while,
until, elsif, begin...end, etc. it was very difficult NOT to write
spaghetti code, and since there was originally the theory said that the
best code economized on the number of CPU cycles, rather than optimized
intelligibility, there was every reason TO write code that took
short-cuts.  Actually, there was a second optimization which said that
code should use the minimum amount of core memory, so sometimes
instructions would modify other instructions, so that blocks of code
wouldn't need to be repeated with only slight changes.

Spaghetti code didn't mean multiple return statements to the same
location in the first 10 lines of the routine.  O my no.

I used to use several different colors of pen so that I could keep track
of which direction the flow of control was going on the current branch. 
And seven levels wasn't unusual.  My usual code was blue for down, green
for up, red for a branch to an error exit, and black for a format
statement reference.

I BELIEVE in structured programming.  I'm just not sure that se/se
actually captures what it's really about.  And I'm sorry, but even if
Dijkstra did invent it, I don't feel that he necessarily understood what
he was inventing.  So quotes about what he said strike me as beside the
point.  YES, it was VERY important for him to say it.  YES, he made
great improvements in the art of programming.  YES, he is one of the
founders of what modern programming IS.  This doesn't make him perfect
and omniscient and omnipotent.

Early returns from routines frequently make them easier to understand. 
And maintain.  Se/se is something that is worth moderate efforts.  It
is, however, related to something else.  Something that I don't yet have
words to wrap around, but lots of other people on this list seem to also
feel it.

Code should be easy to understand AND to maintain.  Both need to be
optimized.  Somehow.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                       ` adam
@ 1998-09-06  0:00                                                         ` Gerry Quinn
  0 siblings, 0 replies; 510+ messages in thread
From: Gerry Quinn @ 1998-09-06  0:00 UTC (permalink / raw)


In article <6spj4u$pi0$1@nnrp1.dejanews.com>, adam@irvine.com wrote:

>
>Of course, there's the danger that pointy-haired managers will then fail to
>work on the "real" solution for the next 49 years, because "it's not causing
>any problems right now", and "our whole computer systems will be obsolete by
>then anyway", and "we've never heard of George Santayana".  

Can't they 'window' again in 2049 by bringing everything back to the 
present state?

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                             ` Charles Hixson
  1998-09-06  0:00                                                               ` Matthew Heaney
@ 1998-09-06  0:00                                                               ` Robert Martin
  1998-09-06  0:00                                                                 ` Jeffrey C. Dege
  1998-09-08  0:00                                                               ` adam
  2 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-06  0:00 UTC (permalink / raw)



Charles Hixson wrote in message <35F252DD.5187538@earthlink.net>...

>I BELIEVE in structured programming.

Stop believing in structured programming, it is not a faith.  Instead, make
sure that you understand what it is, and what its costs and benefits are.
Then you can decide when to follow it, and when not.

>I'm just not sure that se/se actually captures what it's really about.

If you are saying that se/se is not the only way to attain the goals that
Dijkstra was shooting at, you are almost certainly right.  However, the
technique defined by Dijkstra for attaining those goals is called Structured
Programming.

>And I'm sorry, but even if
>Dijkstra did invent it, I don't feel that he necessarily understood what
>he was inventing.  So quotes about what he said strike me as beside the
>point.

They are certainly beside the point if the point is to "do things right".
Even Dijkstra said his technique was unproven.  But those quotes are not
beside the point, if the point is describe an unambiguous definition for the
term "Structured Programming".  Again, we don't want to create the
"Structured Programming" == "GOOD" relationship.  We just want to describe
what structured programming is, and understand its costs and benefits.

>YES, it was VERY important for him to say it.  YES, he made
>great improvements in the art of programming.  YES, he is one of the
>founders of what modern programming IS.  This doesn't make him perfect
>and omniscient and omnipotent.

I hope nobody thinks otherwise.

>Early returns from routines frequently make them easier to understand.

For some.

>And maintain.

Sometimes.

>Se/se is something that is worth moderate efforts.

In many cases.

>It is, however, related to something else.  Something that I don't yet have
>words to wrap around, but lots of other people on this list seem to also
>feel it.
>
>Code should be easy to understand AND to maintain.  Both need to be
>optimized.  Somehow.

And that will never happen until we all understand the costs and benefits of
each technique, and abandon the practice of blindly following a technique.
SP is one such technique.  Using mid exit loops is another.  We cannot
assert that SP is *always good*.  By the same token we cannot assert that
mid exit loops are always good.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                 ` Charles Hixson
@ 1998-09-06  0:00                                                                   ` Robert Martin
  1998-09-07  0:00                                                                     ` Patrick Logan
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-06  0:00 UTC (permalink / raw)



Charles Hixson wrote in message <35F24AC9.40FE817C@earthlink.net>...
>Ray Blaak wrote:
>...
>> A compromise that allows both positive logic and reduced nesting is to
>> calculate a guard value, and only do the work if the guard is true:
>>
>>   doit := (A is right);
>>   doit := doit and (B is right);
>>   doit := doit and (C is right);
>>   if doit then do the work;
>>
>> --
>> Cheers,                                        The Rhythm is around me,
>>                                                The Rhythm has control.
>> Ray Blaak                                      The Rhythm is inside me,
>> blaak@infomatch.com                            The Rhythm has my soul.
>
>It may be just me, but I find this final example to be the least
>intelligible of the variants offered.  Yes, it is structured.  But it's
>harder to understand.

Which demonstrates how subjective intelligibility is.  I find the above
quite clear.  It can easily be rephrased as:

if ((A is right) and (B is right) and (C is right))
  then do the work;

Which, to me, is the ultimate in clarity.

Clarity, intelligibility, understandability, readablility...  All these
things are subjective.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                           ` Charles Hixson
@ 1998-09-06  0:00                                                             ` Robert Martin
  1998-09-06  0:00                                                               ` Charles Hixson
  1998-09-09  0:00                                                               ` sureshvv
  0 siblings, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-06  0:00 UTC (permalink / raw)



Charles Hixson wrote in message <35F2496D.7C4BDC42@earthlink.net>...
>Robert Martin wrote:
>...
>>   if (condition.1) return;
>>   else if (condition.2) return;
>>   else do something useful;
>>   return;
>> };
>>
>> Which, in reality, is:
>>
>> void f()
>> {
>>   if (condition.1) return;
>>   else{
>>     if (condition.2) return;
>>     else {
>>       do something useful;
>>     }
>>   }
>> };
>>
>> So, early returns do not actually reduce nesting; they just appear to.
The
>...
>>
>> Robert C. Martin    | Design Consulting   | Training courses offered:
>> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
>> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
>> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
>>
>> "One of the great commandments of science is:
>>     'Mistrust arguments from authority.'" -- Carl Sagan
>If you are going to use else-if's, then the early return doesn't
>accomplish anything, and the routine could be rephrased as:
> void f()
> {
>   if (!condition.1 & !condition.2)
>   {  do something useful;
>   }
> };
>
>Just a transform, I know.  But, actually, that's my point.

PRECISELY!

Early returns form a boolean equation which is an OR of terms:

if this then return.
    or
if that then return.
    or
if the_other then return
    or
do something useful.

But, as you noted, we can apply Demorgan's theorem and turn this into an AND
of factors

if (!this AND !that AND !the_other)
  then do something useful

Just a transformation,  And one that turns a multiple exit function into an
se/se function.

we might then decide that long boolean equations are better split apart:

if (!this)
  if (!that)
    if (!the_other)
      then do something useful.

Which is an idiom that we can learn to read as a set of ANDS.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                             ` Charles Hixson
@ 1998-09-06  0:00                                                               ` Matthew Heaney
  1998-09-06  0:00                                                                 ` Robert Martin
  1998-09-06  0:00                                                               ` Robert Martin
  1998-09-08  0:00                                                               ` adam
  2 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-06  0:00 UTC (permalink / raw)


Charles Hixson <charleshixsn@earthlink.net> writes:

> Early returns from routines frequently make them easier to understand. 
> And maintain.  Se/se is something that is worth moderate efforts.  It
> is, however, related to something else.  Something that I don't yet have
> words to wrap around, but lots of other people on this list seem to also
> feel it.

As Bob Eachus pointed out, we can't even agree on what "single exit"
means.  According to him, you could interpret that to mean that the
subprogram has a single point of return - to the point of call.

According to that interpretation, multiple returns from a subprogram do
indeed have a single exit, and thus fall under the rubric of "structured
programming."

I argue against using only a single return statement, because it often
means that you have to do work to do ... nothing.  Once I determine my
answer (or satisfy the conditions for loop termination), then I'd rather
return immediately, instead of having to figure out how to navigate my
way to the end of the subprogram.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                             ` Robert Martin
@ 1998-09-06  0:00                                                               ` Charles Hixson
  1998-09-09  0:00                                                               ` sureshvv
  1 sibling, 0 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
...
> 
> But, as you noted, we can apply Demorgan's theorem and turn this into an AND
> of factors
> 
> if (!this AND !that AND !the_other)
>   then do something useful
> 
> Just a transformation,  And one that turns a multiple exit function into an
> se/se function.
> 
> we might then decide that long boolean equations are better split apart:
> 
> if (!this)
>   if (!that)
>     if (!the_other)
>       then do something useful.
> 
> Which is an idiom that we can learn to read as a set of ANDS.
> 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

However, this is only reasonably intelligible BECAUSE the "do something
useful" is limited to a very few lines.  I suppose that this could be an
argument in favor of having small function bodies, but I generally find
that the natural size of a function body is determined by local data
dependencies, and that splitting off pieces that are actually connected
with thick pipes makes things harder to understand.  Therefore, if I can
do some quick validity tests at the START of a routine, and return error
codes if necessary, then that lets me express the functions real form
without excessive internal checks.
And yes, formally this is equivalent to wrapping the body of the routine
in an if block, so that it could be mechanically transformed into a
se/se form (if one had the correct software tool).  But that form would
be harder to understand.

N.B.:  One limitation that I advocate here is that the early returns
from routines be performed BEFORE the routine does anything which would
create any non-temporary changes.  I.E., it's ok to initialize/change
local variables, but not anything that is non-local, and not anything
that would be remembered between calls.  This limitation avoids the
maintenance problems that have been described earlier as endemic to
non-se/se routines.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                                 ` Charles Hixson
@ 1998-09-06  0:00                                                                                   ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-06  0:00 UTC (permalink / raw)


In article <35F246E3.4424EF94@earthlink.net>,
Charles Hixson  <charleshixsn@earthlink.net> wrote:
>
>Now, I obviously haven't checked these with a compiler, but baring typos
>I think that is is obvious that these pieces of code are all isomorphic,
>so it seems TO ME unreasonable to claim that some of them are structured
>and others of them aren't.
>
>I would like to hear about why others would find it reasonable.

Dijkstra's structures are Turing equivalent, given a basic block
at least as powerful as assignment.  Thus, saying that a program
is structured because a structured program can be transformed
into it makes every conceivable program structured.

So, unless we want to dilute the term to meaninglessness, I
think we ought to disallow such transformations.  Remember,
structured programming is about the relationship between
the text of a program and its dynamic behaviour.  Thus, one
can't neglect the text as you have done, and claim that
transformations lead to equivalent programs, any more than
you could alter the dynamic behaviour and consider it equivalent.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                           ` <l5HC1.6840$wN.18 <35F238F7.F57D3EC7@earthlink.net>
@ 1998-09-06  0:00                             ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-06  0:00 UTC (permalink / raw)


In article <35F238F7.F57D3EC7@earthlink.net>,
Charles Hixson  <charleshixsn@earthlink.net> wrote:
>
>But somehow pulling chunks of code into a function and then calling that
>function makes things simpler, even though the flow of execution follows
>the same path, so something else is going on here.
>
>I tend to think that one of the major activities of programming is
>properly "chunking" the problem into pieces that have low-bandwidth
>connections with the rest of the code.  

Abstraction, man!  That's what you're grasping at here.  :-)

Abstraction is what makes things easier to understand.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                             ` Loryn Jenkins
@ 1998-09-06  0:00                                                               ` Charles Hixson
  1998-09-07  0:00                                                                 ` Loryn Jenkins
  0 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


Loryn Jenkins wrote:
... 
> This is an interesting approach to DBC: specify your preconditions and
> write your function to ensure the preconditions are met, else bail.
> 
> However, I think Meyer's approach to DBC is more powerful than this.
> Basically, Meyer's approach is to make the calling routine check the
> preconditions, not the called routine.
...
> Loryn Jenkins

But frequently the programmer does not have the choice of what language
is to be used.  E.g., most of my work for the last couple of years has
been in various flavors of Visual Basic.  (At least it's lots better
than Dartmouth Basic).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                               ` adam
  1998-09-02  0:00                                                 ` Robert Martin
@ 1998-09-06  0:00                                                 ` Charles Hixson
  1 sibling, 0 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


adam@irvine.com wrote:
... 
> be little more than speculation.  Someone might say, "Putting all the
> predicate information at the top of the loop leads to better code",
> but where's the empirical evidence that this is the case?  I mean, we
> could come up with all sorts of logic about why doing this should be
> better, but without some sort of study, our logic is based on
> assumptions about what *seems* like it should be more maintainable,
> assumptions that may or may not hold water.
> 
> At best, these assumptions may reflect the poster's personal
> experience; but since not everyone thinks the same way, an assertion
> based on someone's experience may not be all that useful.  One person
... 
> experience produces better judgment.  But I just haven't seen any
> compelling evidence that, for a programmer who understands the
> importance of readability and has good judgment, any particular style
> will be preferable to any other particular style (occasional GOTO's
> vs. avoiding them like the plague, single-exit vs.  multiple-exit,
> using return's in the middle of your procedures, etc.).  I just don't
> see that we have enough empirical evidence to support any such
> conclusion.
> 
>                                 -- Adam
> 
> -----== Posted via Deja News, The Leader in Internet Discussion ==-----
> http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum

A very important point.  There is probably a range of "best choice"s,
and it may be that no one person is in a position to recognize all of
them.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                               ` Matthew Heaney
@ 1998-09-06  0:00                                                                 ` Robert Martin
  1998-09-06  0:00                                                                   ` Ell
  1998-09-11  0:00                                                                   ` Robert I. Eachus
  0 siblings, 2 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-06  0:00 UTC (permalink / raw)



Matthew Heaney wrote in message ...

>As Bob Eachus pointed out, we can't even agree on what "single exit"
>means.  According to him, you could interpret that to mean that the
>subprogram has a single point of return - to the point of call.

Dijkstra was quite specific about it.  He drew dotted boxes around the flow
charts that depicted the four possible control structures, and showed one
line crossing through the top into the control structure, and another
leaving the control structure and crossing the dotted line at the bottom.
>
>I argue against using only a single return statement, because it often
>means that you have to do work to do ... nothing.  Once I determine my
>answer (or satisfy the conditions for loop termination), then I'd rather
>return immediately, instead of having to figure out how to navigate my
>way to the end of the subprogram.

This is effective iff returning immediately is, and always will be, the
right thing to do.  But if there is a reasonable chance that you will have
to do some error handling at some time in the future, then maintaining an
se/se style provides place holders for that future code.

BTW, that is nothing more than a benefit.  One could still make a realistic
and valid decision to forego that benefit.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-02  0:00                                                     ` Robert Martin
  1998-09-03  0:00                                                       ` sureshvv
@ 1998-09-06  0:00                                                       ` Charles Hixson
  1998-09-07  0:00                                                         ` Loryn Jenkins
  1 sibling, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


I feel it important to call attention to the fact that the returns are
occuring BEFORE and non-temporary effects happen.

There are different things that multiple returns can be.  I feel this
form to be BENEFICIAL, and analogous to the pre-conditions of Eiffel. 
OTOH, a return from within the body of "now do the real work" would be
an ill-structured added return.  The problem is that we are calling
different program structures by the same name.  And our languages don't
support the early-return with a different syntax, so it is very easy to
confuse them.

Robert Martin wrote:
> 
> Robert Oliver wrote in message <35EDAC92.538A@hfl.tc.faa.gov>...
> 
> >
> >I am not arguing against all use of multiple returns in a procedure or
> >function.  I often write a function like this:
> >
> >void AFunction(...)
> >{
> >  if (SomeCondition) return;
> >  if (AnotherCondition) return;
> >  if (AThirdCondition) return;
> >
> >  // now do the real work...
> >
> >  return;
> >}
> >
> >I think this makes sense when AFunction is called from many places and
> >the
> >conditions need to be tested each time.  I can look at the beginning of
> >the
> >function and know that there will be nothing done in these three
> >circumstances.
> >It's not without danger as RCM has pointed out, but I often choose to
> >live
> >with the risk.
> 
> *Deciding* to live with the risk is perfectly legitimate.  There is no way
> to eliminate all risk.  Thus we must choose the risks we live with.  But it
> is important that the risks be understood.
> >
> >Of course, it could also be written as:
> >
> >void AFunction(...)
> >{
> >  if not (SomeCondition)    and
> >     not (AnotherCondition) and
> >     not (AThirdCondition)  then
> >
> >  // now do the real work...
> >
> >  endif
> >  return;
> >}
> 
> Which is usually how I would choose to write it.  (Active voice instead of
> passive voice. ;^)
> 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-03  0:00                                               ` mfinney
@ 1998-09-06  0:00                                                 ` Charles Hixson
  1998-09-06  0:00                                                   ` mfinney
  0 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-06  0:00 UTC (permalink / raw)


mfinney@lynchburg.net wrote:
> 
> In <6sk1k9$3r9$1@nnrp1.dejanews.com>, john-clonts@hlp.com writes:
> 
> >What do you mean by 'tree-structured' programming?
> 
...
> For example...
> 
>         outer::while (someCondition)
>            {
>            // some code
>            inner::while (anotherCondition)
>               {
>               // some code
>               outer::break; // exit outermost loop
>               inner::continue; // restart innermost loop
>               outer::continue; // restart outermost loop
>               inner::break; // exit innermost loop
>               // some code
>               }
>            // some code
>            }
> 
... 
> Michael Lee Finney
I feel that this is a structure to be avoided when it is easy to do so. 
I haven't needed this kind of sturcture more than about 10 times since
the '80's.  OTOH, sometimes it's what the sturcture of the problem seems
to demand.  Sometimes avoiding it would cause more problems than it
solves.  In such a case, be VERY careful to make your code as clear and
obvious as possible, because this IS a
more-difficult-to-understand-than-usual idiom.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                       ` Will Rose
@ 1998-09-06  0:00                                                         ` Ell
  1998-09-06  0:00                                                           ` Jeffrey C. Dege
  0 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-06  0:00 UTC (permalink / raw)



In comp.object Will Rose <cwr@cts.com> wrote:

: I'm not sure which book started this discussion, but Dijkstra's
: "Notes on Structured Programming" in "Structured Programming",
: Dahl, Dijkstra and Hoare, say inter alia:

: "When we now take the position that it is not only the programmer's
: task to produce a correct program but also to demonstrate its
: correctness in a convincing manner, then the above remarks [on program
: size and structure] have a profound influence on the programmer's
: activity; the object he has to produce must be usefully structured."
:
: "The remaining part of this monograph will be mainly an exploration of
: what program structure can be used to good advantage.  In what follows
: it will become apparent that program correctness is not my only concern,
: program adaptability or manageability will be another.  This stress on
: program manageability is my deliberate choice, a choice that, therefore,
: ..."

Yes *this* is the overall *spirit* we should be working in.  And quite
often restricting a loop, or procedure to se/se makes things less
maintainable in the judgement of a plurality or majority of project
programmers. 

Multiple exits to enhance maintenance can work while preserving the
ability to prove program correctness.  This happens if multiple exits
exist in a program which uses procedure calls and returns to calling
procedures 99.5% of the time as I see it.  

: ...[description of flowcharts which] "share the property that they
: have a single entry at the top and single exit at the bottom"...

OK, the single entry at the top and single exit at the bottom of the
flowchart, as a means of helping to prove correctness, and as they say
of improving maintainability.

As I see it they made no specification that when going through a physical
coding structure coding that represents for example a diamond decision
that we must have only a single exit out. 

In fact the graphical depiction of the decision diamond itself has *2*
paths out it!     'Yes' and 'No', 'Greater', or 'Lesser', etc.

: ...Alternatively: restricting ourselves to the three mentioned types
: of decomposition leads to flowcharts of restricted topology compared
: with the flowcharts one can make when arrows can be drawn from one
: block leading to any other.

["Blocks" here certainly should be taken as procedures/functions/routines
nowadays because I'm sure they would frown on going from one
unencapsulated tagged block of code to another when we now have
encapsulated procedures/functions/routines.]

Certainly they aren't saying you shouldn't navigate to another "block",
but that you must use discipline to get there.  As you quote them: 

: "Compared with that greater freedom, to restrict oneself to the clauses
: presents itself as a sequencing discipline."

As I see it, proof and maintainability are fundamentally made easier by
using procedure calls and returning to the caller, whether using multiple
or single exits.  Really, what better way overall is there to handle
navigation in general?

The se/se people in their attempt to preserve proof and maintainability
are being too rigid and dogmatic.  In fact many uses of se/se make proof
and maintenance more difficult.  The se/se people in trying to hard miss
the point.

The spirit and essence of what I get from Dahle and Dijkstra on
structured programming is:
   1) Use procedure calls and return to procedures
   2) Design procedures as abstractions (Dijkstra in "Art of Literate
      Programming" by Knuth)

Navigation should be from one highly coherent, loosely coupled task
abstraction procedure to another.  Navigation should not be from one
isolated loop, branch, or process structure to another, but between
complete task abstraction procedures/functions/routines.  [Dijkstra also
mentions creating a hierarchy of abstractions - a layered design.]

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                 ` Robert Martin
@ 1998-09-06  0:00                                                                   ` Ell
  1998-09-06  0:00                                                                     ` Jeffrey C. Dege
  1998-09-11  0:00                                                                   ` Robert I. Eachus
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-06  0:00 UTC (permalink / raw)


In comp.object Robert Martin <rmartin@oma.com> wrote:

: Matthew Heaney wrote in message ...

:>As Bob Eachus pointed out, we can't even agree on what "single exit"
:>means.  According to him, you could interpret that to mean that the
:>subprogram has a single point of return - to the point of call.

: Dijkstra was quite specific about it.  He drew dotted boxes around the flow
: charts that depicted the four possible control structures, and showed one
: line crossing through the top into the control structure, and another
: leaving the control structure and crossing the dotted line at the bottom.

But a control stucture can be viewed as a logical whole.  Control flow
passes through what the structure represents logically, not every phyiscal
aspect.  For example how can control flow go through both physical exit
paths of branch structure?  It's impossible.

:>I argue against using only a single return statement, because it often
:>means that you have to do work to do ... nothing.  Once I determine my
:>answer (or satisfy the conditions for loop termination), then I'd rather
:>return immediately, instead of having to figure out how to navigate my
:>way to the end of the subprogram.

: This is effective iff returning immediately is, and always will be, the
: right thing to do.  But if there is a reasonable chance that you will have
: to do some error handling at some time in the future, then maintaining an
: se/se style provides place holders for that future code.
:
: BTW, that is nothing more than a benefit.  One could still make a realistic
: and valid decision to forego that benefit.

And one could attempt to achieve other possibly more useful benfits given
specific circumstances.

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                         ` Ell
@ 1998-09-06  0:00                                                           ` Jeffrey C. Dege
  0 siblings, 0 replies; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-09-06  0:00 UTC (permalink / raw)


On Sun, 06 Sep 1998 21:44:00 GMT, Ell <ell@access5.digex.net> wrote:
>In comp.object Will Rose <cwr@cts.com> wrote:
>
>: "The remaining part of this monograph will be mainly an exploration of
>: what program structure can be used to good advantage.  In what follows
>: it will become apparent that program correctness is not my only concern,
>: program adaptability or manageability will be another.  This stress on
>: program manageability is my deliberate choice, a choice that, therefore,
>: ..."
>
>Yes *this* is the overall *spirit* we should be working in.  And quite
>often restricting a loop, or procedure to se/se makes things less
>maintainable in the judgement of a plurality or majority of project
>programmers. 

I absolutely agree.  In fact, so do most of the software engineering texts
I've seen.  Stephen Schach, who provided the definition of of structured
programming that I quoted in an earlier post, explicitly recommends that
the classical definition be loosened enough to allow breaks and gotos
in the forward direction, particularly as a method of handling exceptional
errors.

>Multiple exits to enhance maintenance can work while preserving the
>ability to prove program correctness.  This happens if multiple exits
>exist in a program which uses procedure calls and returns to calling
>procedures 99.5% of the time as I see it.  

I've heard people talk about how breaks and multiple returns confuse code,
and I'll have to admit, if a function or loop is lengthy, it can difficult
to identify embedded returns or breaks.  In these longer constructs,
enforcing se/se makes them clearer.  In a fairly short function or a short
loop, identifying multiple returns or breaks is quite easy.

So we might say that it is perfectly OK to use multiple returns in a
short function or loop.  But I think that's the wrong answer, entirely. 
We should say that it's _not_ OK to have long functions or loops.

Breaking from the middle of a 20-line loop is perfectly understandable.
Breaking from the middle of a 400-line loop is not.  The answer is
not to never break from a 400-line loop, but rather not to have 400-line
loops.

-- 
When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.  




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                         ` Robert Martin
@ 1998-09-06  0:00                                                                           ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-06  0:00 UTC (permalink / raw)


> Agreed, it is one of the fundemental driving forces of software engineering;

That, I'll pay.

> and there have been many different approaches to addressing that force.  OO
> is just one such approach.  It is also one of the most successful
> approaches.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                             ` Robert Martin
@ 1998-09-06  0:00                                                                               ` Loryn Jenkins
  1998-09-06  0:00                                                                                 ` Charles Hixson
  1998-09-07  0:00                                                                                 ` Ray Gardner
  0 siblings, 2 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-06  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Loryn Jenkins wrote in message <35F1BB50.C57557E1@s054.aone.net.au>...
> >> I haven't read this book, so I can't say if it is good or bad.  Probably
> it
> >> is very good.  However, I don't recognize Mill's authority to add to the
> >> definition of SP.  Dijkstra coined the term, he has the right to say what
> >> gets added to it, and what gets taken away from it.
> >
> >That's getting a bit extreme, isn't it, Robert?
> >
> >Academics are forever renegotiating the boundaries in any area of
> >discourse. I know, in my area, Systemic-Functional Linguistics, there is
> >an awful lot of discussions as  to the details, goals, methods and
> >boundaries.
> >
> >To alienate every academic working within the tradition other than the
> >founder (Halliday) would seem to me to be nonsense.
> 
> Granted.  On the other hand, lets say that I wrote a book in which I said
> that the C assert statement was another perfectly acceptable way of
> implementing Design by Contract.

Yes, but DBC can be implemented with comments. Remember, it's a
methodological principle, not a language feature, per se. (It's just
*sooo* nice to have compiler support.)

I do take your point, though.

> And then lets say that some other guy read
> my book and quoted it in a newsgroup like this.  Would Design by Contract
> suddenly now incorporate my use of the C assert statement?  I think not.  I
> think Meyer, and the folks who have studied his work would stake a stance
> against such an inclusion.
> 
> I didn't mean to alienate Harlan Mills work; I expect that it is quite good.
> But I am also not willing to accept Mathew Heaney's demand that mid exit
> loops are part of the structured paradigm just because he quoted Mill's
> book.  I'll want more substantiation than that.

That's true. The academic tradition then, causes one to ask, "Was
Dijkstra aware of Mills' work? Was he aware of it? Did he agree /
disagree with it? Did Dijkstra treat Mills as 'on the playing field', or
'out of the ball park'? Did their writings target or influence the same
sets of practitioners?"

All these seem to be social questions. Questions of discourse.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
@ 1998-09-07  0:00 Robert Martin
  1998-09-08  0:00 ` Mike Spille
  0 siblings, 1 reply; 510+ messages in thread
From: Robert Martin @ 1998-09-07  0:00 UTC (permalink / raw)


Mike Spille wrote in message <35F0484A.2108A9F@tisny.com>...
>Robert Martin wrote:
>>
>>
>> int f(char* name) // returns status value
>> {
>>   int status = 0;
>>   if (File* f = fopen(name, "r"))
>>   {
>>     if (char* buffer = malloc(80))
>>     {
>>       DoSomethingUseful(f,buffer);
>>       free(buffer);
>>     }
>>     else // malloc failure
>>     {
>>       Log("malloc failure");
>>       status = -2;
>>     }
>>     fclose(f);
>>   }
>>   else // fopen failure
>>   {
>>     Log("Failure to fopen");
>>     status = -1;
>>   }
>>   return status;
>> }
>>
>> Perhaps you think this is cumbersome.  I don't.  Cumbersome is a rather
>> subjective term.
>>
>
>I find it quite cumbersome, and error prone to boot.  I'd do it as:
>
>int f(char* name) // returns status value
>{
>  char buf[80];
>  FILE* f = fopen(name, "r");
>  if (f == NULL) {
>    Log("Failure to fopen");
>    return (-1);
>  }
>
>  DoSomethingUseful(f,buf, sizeof(buf));
>  fclose (f);
>}
>
>That is, use a stack-based buffer and pass in the size of the char array to
>do something useful so it doesn't walk off the end of the buffer by mistake
>(assuming that DoSomethingUseful is smart enough to include a size
argument).

Come one Mike, I was using the program as an example.  It's not a real
program.  If you like I'll add the requirement that the buffer *must* come
from the heap because stack and heap memory run at different speeds, and the
'DoSomethingUseful' function needs the heap speed memory. (Sounds crazy but
one of my clients has a platform with just such a constraint).  As for
passing in the size, you have a point -- but its completely irrelevant to
the topic at hand.    In short, you are clutching at straws.

>My point?  I focused on what the routine was supposed to do, not on a
>methodology,

And apparently not on what we were discussing.  We were not discussing
whether buffers should be stack or heap based.  We were not discussing
whether size variables should be passed along with buffers.  We were
discussing whether or not se/se makes a function cumbersome.  I used an
example to make a point, and you side stepped the point.

>(And I think it's more readable :-)

Which makes my point about subjectivity for me.



--

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                               ` Charles Hixson
@ 1998-09-07  0:00                                                                 ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-07  0:00 UTC (permalink / raw)


Charles Hixson wrote:
> 
> Loryn Jenkins wrote:
> ...
> > This is an interesting approach to DBC: specify your preconditions and
> > write your function to ensure the preconditions are met, else bail.
> >
> > However, I think Meyer's approach to DBC is more powerful than this.
> > Basically, Meyer's approach is to make the calling routine check the
> > preconditions, not the called routine.
> ...
> > Loryn Jenkins
> 
> But frequently the programmer does not have the choice of what language
> is to be used.  E.g., most of my work for the last couple of years has
> been in various flavors of Visual Basic.  (At least it's lots better
> than Dartmouth Basic).

DBC is a methodological principle. You can use this design mechanism in
any language.

DBC simply forms a protocol that holds between various routines in the
software. You are currently using such a protocol (even if you haven't
thought of it in these terms). This is just a different one.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                       ` Charles Hixson
@ 1998-09-07  0:00                                                         ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-07  0:00 UTC (permalink / raw)


> There are different things that multiple returns can be.  I feel this
> form to be BENEFICIAL, and analogous to the pre-conditions of Eiffel.

Eiffel preconditions never alter the control flow. Therefore, I don't
think these are analogous.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                 ` Matthew Heaney
@ 1998-09-07  0:00                                                   ` Ray Gardner
  1998-09-07  0:00                                                     ` Ell
  1998-10-09  0:00                                                     ` Matthew Heaney
  0 siblings, 2 replies; 510+ messages in thread
From: Ray Gardner @ 1998-09-07  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> wrote:
> rgardner@nyx.net (Ray Gardner) writes:
> 
> > RCM had responded with a direct quote from Dijkstra, but Ell But the
> > original idea, as expounded by Dijkstra, Mills, Wirth, Ledgard, and
> > others does indeed restrict you to single- entry/single-exit control
> > structures, and they don't exit loops in the middle.
> 
> Oh!  You were doing well up to that last line.  Read about the
> dowhiledo structure, in section 3.3.3, Iteration Structures, of
> Structured Programming, by Linger, Mills, and Witt.
> 
> A list of prime programs also appears on p115, and the one at the bottom
> is a dowhiledo loop.  He explicates the meaning of that loop structure
> on p116-7.

Thanks for the correction, Matt.  Of course my main point was 
that the founder(s) of SP did limit the control structures to 
single-entry / single-exit structures, and that still stands.  
The middle-exit loop (with single exit) is still such a structure 
whether Dijkstra used it or not.  (He didn't).

I realize this subthread about what SP is or isn't started with 
your post supporting a middle-exit loop and citing the Soloway 
et al. study from CACM 11/83.  I was mainly replying to Ell's 
disbelief that SP concerns se/se structures only.

The Soloway study was interesting.  RCM asked you about the study 
so I assume he doesn't have it ready at hand, so I'll answer a 
couple of his questions about it.

The study was a based on a trivial programming assignment given 
to students.  116 were novices in their first Pascal class, 112 
were "intermediates" in their second programming class, and 52 
were "advanced" (juniors and seniors in systems programming and 
programming methodology classes).

The assigment was to write a Pascal program to read a list of 
numbers terminated with a sentinel value of 99999 and compute the 
average (excluding the sentinel value).  Programs were considered 
correct even if they didn't check against division by 0 (i.e. 
only a sentinel value was read), so a correct program could be 
written about 15 or 16 lines of code.  Syntax errors were ignored.

Half the subjects had to use standard Pascal (but without goto 
apparently) and the others used a modified Pascal (Pascal-L) with 
a loop...leave...again structure in lieu of all other loop 
constructs. 

Before writing any code (and before being told about the modified 
Pascal) all subjects were asked to write a "plan" in any language 
other than a programming language.  The plans were studied to see 
if they "naturally" specified a "process/read" strategy or a 
"read/process" strategy.  Most, including advanced, wrote a 
"read/process" approach, though a third of the advanced chose 
"process/read" (I'd guess because they expected to write in a 
Pascal style), and about 2/3 of the novices had plans too vague 
to be classified.

Here, process/read means the loop processes data before reading 
the next data item, meaning there is a "priming" read before 
entering the loop.  This is seen as appropriate for straight 
Pascal.  read/process means the loop reads, tests for sentinel, 
and then processes the data.  Straight Pascal needs to use flags, 
duplicate conditions, etc. to get the correct behavior, but 
read/process is considered appropriate for Pascal-L because 
it can be done with no duplication of the read statement.

Interestingly, the few novices who chose process/read with 
straight Pascal all got the program right, none of the 
read/process novices did.  Of the novices who chose read/process 
for Pascal-L (all but 1), only about half got it right.

In the intermediate group on straight Pascal, 18 chose 
process/read and 16 of those got it right, while 21 chose 
read/process and only 3 got it right.  On Pascal-L, 43 chose 
read/process and 34 were correct, while 7 tried process/read but 
only 2 got it right.

The advanced Pascal group showed 16 out of 18 correct with 
process/read, with only 5 trying read/process and only 2 of those 
getting it right.  With Pascal-L, 23 out of 24 choosing 
read/process were correct, as were the only 2 who used 
process/read.

Soloway et al. conclude from these numbers that the mid-exit 
loop strategy leads to more correct results.  I'm no 
statistician, but I'm not entirely convinced.  The first 
paragraph of the paper suggests they were really interested in 
making programming easier for non-programmers.  It's true that 
more subjects got it right in each category with Pascal-L than 
with straight Pascal.  But I also note that more advanced 
subjects were more likely to choose the "appropriate" strategy 
for the language.  I figure they'd learned (in class or on their 
own) about the "priming read" approach, which is key to getting 
it right without a mid-exit loop structure.  I wonder how much 
better all the Pascal groups would have done if they'd been 
properly instructed on this.  (I assume they weren't, or more of 
the novices and intermediates would have chosen the process/read 
approach for Pascal.) 

What's really appalling is how many students got this simple 
thing wrong.  The novices were 3/4 through their first 
programming course and "had been taught about and had experience 
with the while loop and the other two looping constructs"; the 
intermediates were 2/3 through their second course.  I'm not sure 
if this says more about the students or the school, though I'd 
guess many of the novices and intermediates included those 
lacked the aptitude for the work and later quit programming.

The article mentions another "series of studies by Sheppard et 
al." regarding the readability effects of mid-exit loops on 
professional programmers.  It's in Computer, Dec. 1979.  
Unfortunately I only joined IEEE-CS in 1984, so I don't have that 
one at hand.  Perhaps someone in these newsgroups who does have 
it can summarize?  It might be more interesting than the Soloway 
article.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                               ` Loryn Jenkins
  1998-09-06  0:00                                                                                 ` Charles Hixson
@ 1998-09-07  0:00                                                                                 ` Ray Gardner
  1998-09-07  0:00                                                                                   ` Patrick Logan
  1 sibling, 1 reply; 510+ messages in thread
From: Ray Gardner @ 1998-09-07  0:00 UTC (permalink / raw)


Loryn Jenkins <loryn@s054.aone.net.au> wrote:
> Robert Martin wrote:
> > 
> > I didn't mean to alienate Harlan Mills work; I expect that it is quite good.
> > But I am also not willing to accept Mathew Heaney's demand that mid exit
> > loops are part of the structured paradigm just because he quoted Mill's
> > book.  I'll want more substantiation than that.
> 
> That's true. The academic tradition then, causes one to ask, "Was
> Dijkstra aware of Mills' work? Was he aware of it? Did he agree /
> disagree with it? Did Dijkstra treat Mills as 'on the playing field', or
> 'out of the ball park'? Did their writings target or influence the same
> sets of practitioners?"
> 
> All these seem to be social questions. Questions of discourse.

Here's a clue, maybe.  Don't read too much into it.  From 
"EWD494: Trip Report E.W. Dijkstra 16th April/7th May, 1975, 
U.S.A. and Canada", reprinted in _Selected Writings on Computing: 
A Personal Perspective_, E.W. Dijkstra, Springer-Verlag, 1982 (a 
_really_ neat sample of Dijkstra's EWD papers, which I think were 
mostly circulated only to colleagues by a sort of samizdat):

[Dijkstra stays with A. Wasserman, lectures at Berkeley, speaks 
at ACM Pacific 75, lectures at Stanford, stays at Knuth's house.  
Parties back at Wasserman's, meeting Karp, Floyd, and Backus.  
Goes to LA for the International Conference on Software 
Reliability.  Acerbic remarks.  Goes to ISI (?) to meet with 
Manna, Ershov, Burstall, Randell, Turski, Wulf, and others, sees 
an unconvincing demonstration of automatic program-proving.  Goes 
to Phoenix for an ACM Chapter meeting [damn, why didn't we ever 
get him to Denver when we had a viable chapter?], goes to Mission 
Viejo to visit the Burroughs Large Systems Plant.  Flies to 
Montreal to attend an IBM conference on Software Engineering 
Education.] 

"... in my innocence I had expected an audience of computer 
scientists.  My driver, however, was a manager, who opened the 
conversation with something like 'so you are the world expert on 
structured programming and chief programmer teams.'.  Then I knew 
that I was out in the wilderness and politely refused to be 
associated with Harlan D. Mills."

[More very acerbic remarks: "The ... conference was very 
instructive for me, although I learned a lot without which I 
would have been happier.  At most fify percent of the partcipants 
were computing scientists; the rest were either IBM officials or 
managers of the [DP] departments of large IBM customers.  I had 
full opportunity to observe all the intricate love/hate relations 
between the angles of the triangle 'university-manufacturer-
customer'.  It was all very frightening and I wish that I had a 
mastery of my pen like Arthur Koestler, for then I could have 
written a companion volume to his 'The Call Girls'."

"The central victims in this drama are the [MBAs] and the firms 
dependent on their services ... They really have painted 
themselves into a corner with very sticky molasses!  They have 
made a number of unforgiveable mistakes.  One mistake is that 
they have based their full automation upon the IBM/360.  When 
that machine was announced, it was immediately clear to many --
even inside IBM!-- that it would be practically impossible to 
write decent software for it... You cannot program a crooked 
machine to go straight ... The next mistake is that they decided 
to program in COBOL. ... OS/360 is no longer 'logical spaghetti', 
but 'logical barbed wire'. ... on the whole it was ghastly; 
unreal.  I was severely shocked by the cultural level of the 
business participants. ..."]

"Later I heard Harlan Mills give a summing up of some of the 
things I had said --together with some Harlanesk additions-- for 
that business audience.  It was terrible, a misuse of language to 
which to the best of my powers I could not give a meaning.  So, 
every third phrase I interrupted Harlan 'please could you explain 
or restate what you tried to say', but it was hopeless.  Tom Hull 
helped me and I was very grateful to him.  Later, when it was all 
over, our eyes met, and Tom gasped 'Jezus!'.  It was the first 
time that I had heard him use strong language.  How to sell empty 
but impressive slogans under the cloak of academic 
respectibility... ." 

"Turski's comments were short: 'They don't want computer 
scientists, nor software engineers, they want brainwashed mental 
cripples.'.  It is too true... ."

"On the last morning, Harlan Mills gave the summing up talk.  It 
was again very much of the same, but, remarkably enough, I 
learned something from him, viz. the expression 'entry level 
jobs'.  His argument was that the university should not train 
experts --as an aside: training and education were constantly 
confused-- because the jobs those experts should get were not 
'entry level jobs'.  This may be a profound difference between 
the academic community and (at least some of) the business 
community: there is not the slightest objection to giving the 
most responible university function, viz. a full professorship, 
to a youngster who has just got his Ph.D.  It does not happen so 
very often, because really brilliant people are rare; but nothing 
in the university environment forbids it ... But to the business 
communities represented it was unthinkable to give a youngster 
any real responsibility... ."





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                   ` Ray Gardner
@ 1998-09-07  0:00                                                     ` Ell
  1998-09-07  0:00                                                       ` Ell
                                                                         ` (3 more replies)
  1998-10-09  0:00                                                     ` Matthew Heaney
  1 sibling, 4 replies; 510+ messages in thread
From: Ell @ 1998-09-07  0:00 UTC (permalink / raw)


rgardner@nyx.net (Ray Gardner) wrote:

>.... Of course my main point was 
>that the founder(s) of SP did limit the control structures to 
>single-entry / single-exit structures, and that still stands.

And your proof is what?

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                     ` Ell
@ 1998-09-07  0:00                                                       ` Ell
  1998-09-09  0:00                                                         ` Adrian P. Morgan
  1998-09-07  0:00                                                       ` Patrick Doyle
                                                                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-07  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:

>rgardner@nyx.net (Ray Gardner) wrote:
>
>>.... Of course my main point was 
>>that the founder(s) of SP did limit the control structures to 
>>single-entry / single-exit structures, and that still stands.

>And your proof is what?

And either way I agree with an earlier writer and point of view that
whatever Dijkstra, Dahle and Hoare may or may not have said about
exits, it isn't gospel.  Intelligent people can and should latch on to
the spirit and essence of what they were saying.  

As I and many others see it the use of multiple exits is can be
consistent with the structured programming goal of being able to
prove, and improve the maintainability of, code.  In fact multiple
exits, in the opinion of many if not most programmers, makes some code
even more maintainable than using a single exit.  And apparently
Donald Knuth concurs that provability is not in conflict with multiple
exits.

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                                                 ` Ray Gardner
@ 1998-09-07  0:00                                                                                   ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-07  0:00 UTC (permalink / raw)


In comp.object Ray Gardner <rgardner@nyx.net> wrote:

: "EWD494: Trip Report E.W. Dijkstra 16th April/7th May, 1975, 
: U.S.A. and Canada", reprinted in _Selected Writings on Computing: 
: A Personal Perspective_, E.W. Dijkstra, Springer-Verlag, 1982 (a 
: _really_ neat sample of Dijkstra's EWD papers, which I think were 
: mostly circulated only to colleagues by a sort of samizdat):

I love this book. I've had it for almost 15 years. I pick it up
several tiems a year and read his trip reports, etc. What a
personality!

Dijkstra gave a talk at Data General in Boston in the mid 1980's. What
a character! At that time, he claimed to not be using a computer or to
want one. We gave him one of the first PC compatible lap tops ever
made. He looked at it, and said he'd consider using it.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                   ` Robert Martin
@ 1998-09-07  0:00                                                                     ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-07  0:00 UTC (permalink / raw)


: >>   doit := (A is right);
: >>   doit := doit and (B is right);
: >>   doit := doit and (C is right);
: >>   if doit then do the work;

This violates one of the principles I try always to follow: single
assignment. Unless a variable is in a loop, being updated to reflect
the state of the loop, I will never assign a second value to it.

If I wanted the form above, I'd rephrase it like this:

boolean a_ok :=          (A is right);
boolean b_ok := a_ok and (b is right);
boolean c_ok := b_ok and (c is right);
if c_ok then do the work;

But I don't like this form anyway because it makes me wonder why test
for b_ok if it has already been established that a_ok is false. This
is so far away from the idioms I use all the time that it makes me
wonder what was one the developer's mind and what I might not be
correctly understanding.

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                             ` <35F074C9.E10C <35F2E907.594CD023@earthlink.net>
@ 1998-09-07  0:00                                                               ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-07  0:00 UTC (permalink / raw)


In article <35F2E907.594CD023@earthlink.net>,
Charles Hixson  <charleshixsn@earthlink.net> wrote:
>Loryn Jenkins wrote:
>> 
>> However, I think Meyer's approach to DBC is more powerful than this.
>> Basically, Meyer's approach is to make the calling routine check the
>> preconditions, not the called routine.
>
>But frequently the programmer does not have the choice of what language
>is to be used.  E.g., most of my work for the last couple of years has
>been in various flavors of Visual Basic.  (At least it's lots better
>than Dartmouth Basic).

Choice of language doesn't enter into it.  A precondition is a
condition that must hold for the effects of a routine to be well-
defined.  If that routine is called without the preconditions
being satisfied, then you have a bug in your program.  Thus,
the caller must either check that the precondition holds, or
else verify it by other means.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                 ` Richard Melvin
@ 1998-09-07  0:00                                                   ` Jean-Marc Jezequel
  0 siblings, 0 replies; 510+ messages in thread
From: Jean-Marc Jezequel @ 1998-09-07  0:00 UTC (permalink / raw)
  To: Richard Melvin

Richard Melvin a �crit:
> 
> In article <35EFD468.BDD7CB0A@irisa.fr>, Jean-Marc Jezequel <Jean-
> Marc.Jezequel@irisa.fr> writes
> >

> Nice proof.
> 
> Unfortunately your code contains at least one, and arguably two, bugs:

Absolutely. I was interrupted while writing this message just before
writing initialization code, and resumed it back only hours later, just
before leaving for the week-end. And this stupid computer took what I
wrote, not what I meant ;-) Usual problem for many of us.

> - will throw an exception or return wrong result on unequal
>   length lists.

True.
> >        Result := l.first /= r.first
Was meant to be Result := l.count /= r.count
(copy paste error).

> - will interfere with iteration over lists in the calling function
>  (unless the language you are using passes lists by value,
>   not identity).

true again.
There is even another error in it, that magically disappears in step 6
(exercice left to the reader. Hint: the code is correct, the proof is
correct, still there is an error. See last line of this message for
another hint.)
 
> I've got a theory as to the people writing strict single/entry single
> code are having such a hard time with this (defect rate > 20%):
 
I have no theory on that. Was just showing why Dijkstra insisted on
se/se loops: in this way programs can be made provable. Sorry guys for
my sloppiness in the actual showing. BTW, it illustrate another of my
points: don't rely on hand-made proofs *only* (even when you take care
of not doing any error in the proof, how can you proove that what you
wrote correspond to your *intent*?).

-- 
Jean-Marc Jezequel               Tel : +33 299 847 192         
IRISA/CNRS                       Fax : +33 299 847 171         
Campus de Beaulieu               e-mail : jezequel@irisa.fr 
F-35042 RENNES (FRANCE)          http://www.irisa.fr/prive/jezequel




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                     ` Ell
  1998-09-07  0:00                                                       ` Ell
@ 1998-09-07  0:00                                                       ` Patrick Doyle
  1998-09-07  0:00                                                         ` dewarr
  1998-09-07  0:00                                                       ` dewarr
  1998-09-07  0:00                                                       ` Ray Gardner
  3 siblings, 1 reply; 510+ messages in thread
From: Patrick Doyle @ 1998-09-07  0:00 UTC (permalink / raw)


In article <35f34bbd.7903825@news.erols.com>, Ell <ell@access.digex.net> wrote:
>rgardner@nyx.net (Ray Gardner) wrote:
>
>>.... Of course my main point was 
>>that the founder(s) of SP did limit the control structures to 
>>single-entry / single-exit structures, and that still stands.
>
>And your proof is what?

Can you prove they recommended using other structures?

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <35EC937F.94420C51@ibm.net>
@ 1998-09-07  0:00             ` Michael F Brenner
  0 siblings, 0 replies; 510+ messages in thread
From: Michael F Brenner @ 1998-09-07  0:00 UTC (permalink / raw)


Biju > The problem with such refactoring during maintenance is that it may
     > introduce new problems, and you need to do extensive testing to make
     > sure that you haven't broken anything. Often, this type of extensive
     > testing may not be feasible at all during maintenance, because of budget
     > and time constraints. This type of attitude may explain why new releases
     > of software (which are supposed to do bug fixing too) introduce more
     > bugs than the original version.

I think you meant: this type of attitude (refactoring during maintenance)
explains new bugs being released. 

However, I think this is what is true: this type of attitude (coding 
systems that are expensive to test automatically) 
explains new bugs being released.

Most large systems have:
no automated unit testing (all paths or all extreme values), 
no automated stress testing, 
no automated functional (requirements) testing,
no automated regression (to previous baselines) testing,
no automated hanging pointer testing, 
no automated performance testing, and
no automated memory leakage measurement.

Exits in the middle of the loop or any other syntactic feature
used (gotos, nested tasking, complex expressions, high complexity
measures, high lines of code, etc.) are all just noise compared
to the lifecycle cost of not automatically testing for bugs,
hanging pointers, and memory leakage. We should remove the log 
before worrying about the twig.

Mike Brenner




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                     ` Ell
                                                                         ` (2 preceding siblings ...)
  1998-09-07  0:00                                                       ` dewarr
@ 1998-09-07  0:00                                                       ` Ray Gardner
  1998-09-07  0:00                                                         ` Ell
  3 siblings, 1 reply; 510+ messages in thread
From: Ray Gardner @ 1998-09-07  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:
> rgardner@nyx.net (Ray Gardner) wrote:
> 
> >.... Of course my main point was 
> >that the founder(s) of SP did limit the control structures to 
> >single-entry / single-exit structures, and that still stands.
> 
> And your proof is what?
> 
> Elliott

Ell, the "proof" is in my post of 5 Sept 1998, more-or-less 
directed to you personally, which was the result of more than a 
couple of hours of research for *your* benefit.  Not that I 
expected any thanks.  But since you seem to have missed it, I'll 
waste a little bandwidth and repost.  (I could just give you a 
pointer to DejaNews, but you seem to never look up any cites 
people give you.  Consider that you asked for a quote from a 
founder, RCM gives you a direct quote from *the* primary source, 
and you complain that it's out of print and "RCM knows it".  Did 
you expect a primary source from 25 years ago to be in print?  As 
another poster mentioned, that's what libraries are for.  I don't 
know if you live near any major metropolitan areas, but a quick 
check shows two copies on the shelf in Denver and one in Boulder 
in libraries where they can be browsed by anyone.)  So once more: 


[Repost of my message <905028596.876380@iris.nyx.net>]

Ell wrote:
 > >>For example, there's a pernicious myth that exiting (or returning) from
 > >>the middle of a loop is bad, and that the only proper way to write a
 > >>loop is to state the termination condition explicitly, as a predicate
 > >>appearing at the top of the loop.
 > 
 > >Yes.  That pernicious myth is called "structured programming".
 > 
 > Please cite even just a single structured programming text, or founder
 > where what you say here was asserted.

And later Ell wrote:
 > The assertion that "single entry, single exit" is a required, or even
 > desirable, maxim of structured programming is a myth.
 > 
 > No one (including RCM) can show that this maxim is in fact a coding
 > heuristic put forward by any of the founders of the structured
 > paradigm. [Check past posts in this thread.]

RCM had responded with a direct quote from Dijkstra, but Ell 
rejected it without understanding it.  And rejected it again 
after RCM explained it.  

To recap, in Dijkstra's Notes on Structured Programming in the 
classic _Structured Programming_ (1972), EWD referred to the 
single-entry/single-exit property of the flowcharts of the if-
then-else, case-of, while-do, and repeat-until control 
structures.  Ell apparently thought EWD was talking about how 
flowcharts should be represented on a page.  EWD was actually 
using the flowcharts as a graphical aid to make a point about 
program topology. 

To support this interpretation, I'll just quote this from the 
same source, p. 20:

"... restricting ourselves to the three mentioned types of 
decomposition lead to flowcharts of a restricted topology compared 
with the flowcharts one can make when arrows can be drawn from 
any block leading into any other."

EWD then goes on at length to explain why such a topology is 
desireable.

Ell, you might consider this: in the entire monograph EWD 
never mentions goto, exit, break, return or any other change in 
the flow of control outside of the selection and repetition 
statements mentioned above.  And he certainly had no such other 
modes of flow control in mind when he wrote his "GOTO considered 
harmful" letter; he was accustomed to Algol, which has no 
exit/break/return or similar statements.  (Also consider that 
goto-less programming in Pascal has the same restriction, since 
Pascal lacks exit/break/return etc.)

Ell, remember that you asked for a cite from "even a single 
structured programming text, or founder" to support single-
entry/single-exit.  Okay.  Hard to say who you can consider "a" 
founder other than "the" founder, EWD.  But consider Niklaus 
Wirth: "For the intellectual manageability, it is crucial that 
the constituent operations at each level of abstraction are 
connected according to sufficiently simple, well understood 
_program schemas_, and that each operation is described as a 
piece of program with _one starting point_ and a _single 
terminating point_."  [Emphases were italics in the original.]  
"On the Composition of Well-Structured Programs", N. Wirth, in 
ACM Computing Surveys, December 1974 (Special Issue on 
Programming), p.249. 

How about this:  "A _proper program_ is a program with a control 
structure that (1.) has a single entry line and a single exit 
line, and (2.) for each node, has a path through that node from 
the entry line to the exit line."  _Structured Programming: 
Theory and Practice, R.C. Linger, H.D. Mills, B.I. Witt, Addison-
Wesley, 1979, p. 94.  (Ell has already commented on a similar use 
of the word "proper".  Ell, you should understand that the word 
is being used here in a technical fashion as part of a 
*definition*, similar to the use of "well-formed formula" in 
mathematical logic.  And, anticipating that you'll claim that 
this has nothing to do with structured programming per se, I'll 
point out that the entire book is about programming via the use 
of "proper programs" as defined above.) 

Since you mentioned structured COBOL, I'll mention this:

"GO TO statements are not allowed.  The rationale here is to 
force programmers to think ahead and use _only_ 1-in, 1-out 
control structures." ... "STOP RUN may only occur as the last 
statement of the main procedure of a program.  EXIT PROGRAM may 
only occur as the last paragraph of the main procedure of a 
subprogram.  The rationale here is to make the logical exit of a 
program identical to the lexical end of its main procedure." 
_COBOL With Style (Programming Proverbs)_, L.J. Chmura, H.F. 
Ledgard, Hayden, 1976.  A book on structured programming in 
COBOL.

Many other writers have discussed structured programming in terms 
of single-entry/single-exit control structures, often without 
using those terms explicitly.  But what else could they mean when 
they develop a programming style that uses only sequence, 
if-then-else, while-do, repeat-until, and sometimes case-of, 
without ever mentioning or using goto, return, break, exit, 
continue, or any other discontinuity of control?

For an even heavier dose of Dijkstra, try his _A Discipline of 
Programming_ (Prentice-Hall, 1976) where he develops a fairly 
complete theory of proof-oriented _nondeterministic_ procedural 
programming semantics using only assignment and "guarded 
commands" for conditional and repetitive (if ... fi and do ... 
od) statements.  He never explicitly mentions "single-
entry/single-exit", but it's clear from his exposition that 
there is no other form of flow control in his system.

You mentioned (twice) page 72 of Knuth's _Literate Programming_ 
(not _The Art of ... as you've twice mis-cited it, and the 
publisher is CSLI, not CLSC or CLCS as you've twice misnamed 
them).  This page is part of a reprint of Knuth's classic paper 
"Structured Programming with go to Statements", originally in ACM 
Computing Surveys, December 1974.  You might consider what Knuth 
said on p. 18 of your book: "It is impossible to read the recent 
book _Structured Programming_ [Dahl (not Dahle), Dijkstra, and 
Hoare] without having it change your life."  And then take RCM's 
advice and read the book.  Perhaps that's what it'll take to get 
you to believe that Dijkstra was advocating exactly what RCM said 
he was.  (You won't do it because you might find RCM is right.)  

BTW, while it's true that Dijkstra considered abstraction to be 
central to his notion of structured programming, page 72 of 
Knuth's book nowhere says "It was Dijkstra who thinks of 
*abstraction* when someone mentions 'structured programming'."   
It does quote Dijkstra as saying that when he's dealing with one 
level of abstraction, it occupies 90% of his attention while the 
rest is kept in mind in the background.  Yes, abstraction is key 
to Dijkstra's notion of structured programming.  But so is the 
use of the limited set of control structures mentioned above, and 
so is his oft-mentioned "separation of concerns". 

I've been doing this long enough (30 years) to remember when this 
stuff was new, and I have many of the original books and papers 
in my library.  I also had the personal experience of bringing 
structured programming into a COBOL spaghetti shop in 1974.   So 
I do know a little about this stuff.  I'm not saying structured 
programming is only about control structures.  And I'm not saying 
that no one has tried "enhancing" the original idea of structured 
programming with additional control structures.  Wulf, Zahn, 
Dahl, Knuth and others have suggested other forms of loops.  But 
the original idea, as expounded by Dijkstra, Mills, Wirth, 
Ledgard, and others does indeed restrict you to single-
entry/single-exit control structures, and they don't exit loops 
in the middle. 




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                     ` Ell
  1998-09-07  0:00                                                       ` Ell
  1998-09-07  0:00                                                       ` Patrick Doyle
@ 1998-09-07  0:00                                                       ` dewarr
  1998-09-09  0:00                                                         ` Ray Gardner
  1998-09-07  0:00                                                       ` Ray Gardner
  3 siblings, 1 reply; 510+ messages in thread
From: dewarr @ 1998-09-07  0:00 UTC (permalink / raw)


In article <35f34bbd.7903825@news.erols.com>,
  ell@access.digex.net wrote:
> rgardner@nyx.net (Ray Gardner) wrote:
>
> >.... Of course my main point was
> >that the founder(s) of SP did limit the control structures to
> >single-entry / single-exit structures, and that still stands.
>
> And your proof is what?
>
> Elliott
>

There is no "founder" of structured programming. The
idea of structured programming is an old one, well known
to anyone writing Algol-60 from very early on. Various
people have produced specific rules concerning their
idea of how to adapt this principle to particular
programming languages (e.g. the "structured period"
for ANSI-74 COBOL), but I would not say it is reasonable
to regard anyone as "founding" structured programming.

EWD's letter on gotos to the ACM was simply noting a
general principle well known to any student algol-60
programmer for years. it is true that Fortran had
made it much more difficult, though not impossible,
for people to understand the basic idea of writing
code that has a clear control flow structure.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                       ` Ray Gardner
@ 1998-09-07  0:00                                                         ` Ell
  1998-09-07  0:00                                                           ` Ell
  1998-09-09  0:00                                                           ` Ray Gardner
  0 siblings, 2 replies; 510+ messages in thread
From: Ell @ 1998-09-07  0:00 UTC (permalink / raw)


rgardner@nyx.net (Ray Gardner) wrote:

[stuff elided]

As I said that stuff is not proof to me they advocated se/se.  To me
their point was to encourage use disciplined navigation for proof and
maintainability.  Multiple returns can be disciplined navigation.

But either way, I'm not a dogmatist.  I'll unite with the spirit of
maintainability and not rigid adherence to a practice when it clearly
contradicts that.

The main things I get from all of the structured writers is:
	a) Use procedure calls (with consequent return)
	b) Use procedural task abstraction (not isolated structures)

Elliott




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                         ` Ell
@ 1998-09-07  0:00                                                           ` Ell
  1998-09-09  0:00                                                           ` Ray Gardner
  1 sibling, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-07  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:

>The main things I get from all of the structured writers is:
>	a) Use procedure calls (with consequent return)

More generally:

	a)  Use discipline in navigation (which has many forms)
>	b)  Use procedural task abstraction (not isolated structures)
>
>Elliott





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                       ` Patrick Doyle
@ 1998-09-07  0:00                                                         ` dewarr
  0 siblings, 0 replies; 510+ messages in thread
From: dewarr @ 1998-09-07  0:00 UTC (permalink / raw)


In article <Eyx023.IC8@ecf.toronto.edu>,
  doylep@ecf.toronto.edu (Patrick Doyle) wrote:
> In article <35f34bbd.7903825@news.erols.com>, Ell <ell@access.digex.net>
wrote:
> >rgardner@nyx.net (Ray Gardner) wrote:
> >
> >>.... Of course my main point was
> >>that the founder(s) of SP did limit the control structures to
> >>single-entry / single-exit structures, and that still stands.
> >
> >And your proof is what?
>
> Can you prove they recommended using other structures?
>
>  -PD
>


Well it is not clear who you think "they" are (the
"founders" of structured programming).

Certainly Wirth is happy to use a goto in Pascal where
it makes sense (see the code for example for heap sort
in his algorithms book).

Similarly Knuth has pointed out the value of midloop
exits in some cases ...

Actually I think the real point here is that the
"founders" tend to be a lot less dogmatic than their
followers :-)
> --
> --
> Patrick Doyle
> doylep@ecf.toronto.edu
>

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00 Software landmines (loops) Robert Martin
@ 1998-09-08  0:00 ` Mike Spille
  0 siblings, 0 replies; 510+ messages in thread
From: Mike Spille @ 1998-09-08  0:00 UTC (permalink / raw)


Robert Martin wrote:
> 
> Mike Spille wrote in message <35F0484A.2108A9F@tisny.com>...
> >Robert Martin wrote:
> >>
> >>
> >> int f(char* name) // returns status value
> >> {
> >>   int status = 0;
> >>   if (File* f = fopen(name, "r"))
> >>   {
> >>     if (char* buffer = malloc(80))
> >>     {
> >>       DoSomethingUseful(f,buffer);
> >>       free(buffer);
> >>     }
> >>     else // malloc failure
> >>     {
> >>       Log("malloc failure");
> >>       status = -2;
> >>     }
> >>     fclose(f);
> >>   }
> >>   else // fopen failure
> >>   {
> >>     Log("Failure to fopen");
> >>     status = -1;
> >>   }
> >>   return status;
> >> }
> >>
> >> Perhaps you think this is cumbersome.  I don't.  Cumbersome is a rather
> >> subjective term.
> >>
> >
> >I find it quite cumbersome, and error prone to boot.  I'd do it as:
> >
> >int f(char* name) // returns status value
> >{
> >  char buf[80];
> >  FILE* f = fopen(name, "r");
> >  if (f == NULL) {
> >    Log("Failure to fopen");
> >    return (-1);
> >  }
> >
> >  DoSomethingUseful(f,buf, sizeof(buf));
> >  fclose (f);
> >}
> >
> >That is, use a stack-based buffer and pass in the size of the char array to
> >do something useful so it doesn't walk off the end of the buffer by mistake
> >(assuming that DoSomethingUseful is smart enough to include a size
> argument).
> 
> Come one Mike, I was using the program as an example.  It's not a real
> program.  If you like I'll add the requirement that the buffer *must* come
> from the heap because stack and heap memory run at different speeds, and the
> 'DoSomethingUseful' function needs the heap speed memory. (Sounds crazy but
> one of my clients has a platform with just such a constraint).  As for
> passing in the size, you have a point -- but its completely irrelevant to
> the topic at hand.    In short, you are clutching at straws.
> 

No, I was pointing out that you lost for the forest for the trees.
While pointing out the possible advantages of single entry/return,
you meanwhile ignored common C/C++ coding practices: keep functions
as small as possible, don't malloc() unnecessarily, always pass
array sizes around with arrays.  By concentrating on the advantages
of your particular style, you managed to write a rather poor
function.

> >My point?  I focused on what the routine was supposed to do, not on a
> >methodology,
> 
> And apparently not on what we were discussing.  We were not discussing
> whether buffers should be stack or heap based.  We were not discussing
> whether size variables should be passed along with buffers.  We were
> discussing whether or not se/se makes a function cumbersome.  I used an
> example to make a point, and you side stepped the point.
> 

Once upon a time a buddy of mine was writing a C coding guidelines
manual for a company we both worked for.  He asked me to proof
read it for him.  I did so, and while I had some mild objections
here and there I found his guidelines reasonable - with one
exception.  At the end of the guide he provided an example that
demonstrated some of the major style-points he had touched upon.
His example did indeed avoid all the downfalls he had warned
against in his writing, and followed the style he'd outlined
perfectly.

Unfortunately, the algorithm he had coded was horrendously
inefficient, and buggy to boot.  In his zeal to promote his
guidelines, he'd forgotten to focus on what the algorithm
was supposed to do.

I would say that you did the same - you focused so much on the
style of the code that you ignored the algorithm.  The end-goal
of writing a function is primarily that it does what you want
it to do, and does it well.  If you focus more on following a
given set of rules than you do on what you're trying to
accomplish, your results are going to reflect your priorities.

> >(And I think it's more readable :-)
> 
> Which makes my point about subjectivity for me.
> 
> --
> 
> Robert C. Martin    | Design Consulting   | Training courses offered:
> Object Mentor       | rmartin@oma.com     |   Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
> 
> "One of the great commandments of science is:
>     'Mistrust arguments from authority.'" -- Carl Sagan

	-Mike




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.480 <904556531.66622 <EyyLos.2nx@yc.estec.esa.nl>
@ 1998-09-08  0:00             ` duncan
  1998-09-16  0:00               ` Matthew Heaney
  1998-09-08  0:00             ` Jim Cochrane
  1 sibling, 1 reply; 510+ messages in thread
From: duncan @ 1998-09-08  0:00 UTC (permalink / raw)



One issue which I haven't yet seen addressed in this thread (but then
our news feed is particularly patchy) is abnormal flow of control.

As far as I can see, the single entry/single exit paradigm assumes
that there is a simple flow of control, through the code as you can
see it. So far, nobody has made any comment on "abnormal" flow of
control, such as interrupts, multi-threading, and what might be more
interesting in these news groups, exceptions.

Any comments?

This is my article, not my employer's, with my opinions and my disclaimer!
--
Duncan Gibson, ESTEC/YCV, Postbus 299, 2200AG Noordwijk, The Netherlands
Tel: +31 71 5654013   Fax: +31 71 5656142  Email: duncan@yc.estec.esa.nlx
To avoid junk email my quoted address is incorrect. Use nl instead of nlx.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                               ` <EyyLos.2nx@yc.estec.esa.nl>
  1998-09-08  0:00                                                                 ` Robert Martin
@ 1998-09-08  0:00                                                                 ` John G. Volan
  1998-09-08  0:00                                                                   ` duncan
  1 sibling, 1 reply; 510+ messages in thread
From: John G. Volan @ 1998-09-08  0:00 UTC (permalink / raw)


duncan@yc.estec.esa.nlx wrote:
> 
> int doSomething(Tree *pTop)
> {
>   int errorCode;
> 
>   if (pTop != NULL)
>   {
>     if (pTop->pChild != NULL)
>     {
>       if (pTop->pChild->pChild != NULL)
>       {
>          /* lots of nesting omitted */
> 
>                          if (pTop->pChild...->pChild != NULL)
>                          {
>                            errorCode = reallyDoSomething(pTop->pChild...->pChild);
>                          } else
>                          {
>                            errorCode = ERRORX;
>       } else
>       {
>         errorCode = ERROR3;
>       }
>     } else
>     {
>       errorCode = ERROR2;
>     }
>   } else
>   {
>     errorCode = ERROR1;
>   }
>   return(errorCode);
> }

For what it's worth, the above could be transformed into:

int doSomething(Tree *pTop)
{
  int errorCode;

  if (pTop == NULL)
  {
    errorCode = ERROR1;
  }
  else if (pTop->pChild == NULL)
  {
    errorCode = ERROR2;
  }
  else if (pTop->pChild->pChild == NULL)
  {
    errorCode = ERROR3;
  }
  ...
  /* lots of nesting omitted */
  ...
  else if (pTop->pChild...->pChild == NULL)
  {
    errorCode = ERRORX;
  }
  else
  {
    errorCode = reallyDoSomething(pTop->pChild...->pChild);
  }
  return(errorCode);
}

As you can see, the nesting has been considerably reduced, yet this
function is still single entry/single exit.  It also shares with the
early-return version the advantage of showing the choice of error-code
close to the test that determines the error.

Best of both worlds? :-)

> int compareThings(Thing *pLeft, Thing *pRight)
> {
>     assert(pLeft != NULL && pRight != NULL);
> 
>     if (pLeft->x != pRight->x)
>     {
>         if (pLeft->x < pRight->x)
>         {
>             return(-1);
>         } else
>         {
>             return(+1);
>         }
>     }
>     if (pLeft->y != pRight->y)
>     {
>        /* similar logic */
>     }
>     /* other members */
>     return(0);
> }

Again, the above can be transformed to:

int compareThings(Thing *pLeft, Thing *pRight)
{
    assert(pLeft != NULL && pRight != NULL);

    int result = 0;

    if (pLeft->x < pRight->x)
    {
        result = -1;
    }
    else if (pLeft->x > pRight->x)
    {
        result = +1;
    }
    else if (pLeft->y < pRight->y)
    {
        result = -1;
    }
    else if (pLeft->y > pRight->y)
    {
        result = +1;
    }
    /* other members */
    else
    {
        result = 0;
    }
    return result;
}

-- 
indexing
   description: "Signatures for John G. Volan"
   self_plug: "Ex Ada guru", "Java 1.1 Certified", "Eiffelist wannabe"
   two_cents: "Java would be even cooler with Eiffel's assertions/DBC, %
              %generics, true MI, feature adaptation, uniform access, %
              %selective export, expanded types, etc., etc..."
class JOHN_VOLAN_SIGNATURE inherit SIGNATURE invariant
   disclaimer: not (opinion implies employer.opinion)
end -- class JOHN_VOLAN_SIGNATURE




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                                                                 ` John G. Volan
@ 1998-09-08  0:00                                                                   ` duncan
  1998-09-08  0:00                                                                     ` Patrick Doyle
  0 siblings, 1 reply; 510+ messages in thread
From: duncan @ 1998-09-08  0:00 UTC (permalink / raw)


In article <35F534F6.D3CCE360@sprintmail.com>,
John G. Volan <johnvolan@sprintmail.com> wrote:
>
> [... transformed heavily indented nested if's to single level of
> indentation by effectively NOTing the test condition and adjusting
> the formatting ...]
>
>As you can see, the nesting has been considerably reduced, yet this
>function is still single entry/single exit.  It also shares with the
>early-return version the advantage of showing the choice of error-code
>close to the test that determines the error.
>
>Best of both worlds? :-)

Yes, but this was my point. Many people rail against early returns
as being "problematic" for whatever reason or purpose. To my mind,
provided you restrict early returns to 'pre-condition checking', the
logic can still be preserved, and can be just as "readable" (or indeed
"unreadable") as a se/se solution. [*]

If you sprinkle return statements in the middle of the inner gubbins
of the routine where resources have been allocated, or modified, or
waiting to be reallocated, then it is much more difficult to ensure
that each early return actually leaves the system in an appropriate
state. This is especially true when the maintenance/upgrade phase
begins when nobody remembers all of the gotchas any more.

[*] Note that sometimes the natural flow of one form of a test can make
it a lot easier to understand what is going on than choosing the negative
form of the test just to fit with a particular style. This can also
influence which form you would use. Unfortunately no examples of this
spring to mind other than:

	if (IsX(a))
	{
		ProcessX(a);
	} else
	if (IsY(a))
	{
		ProcessY(a);
	} else
	{
		ProcessZ(a);
	}

as opposed to

	if (!IsX(a))
	{
		if (!IsY(a))
		{
			ProcessZ(a);
		} else
		{
			ProcessY(a);
		}
	} else
	{
		ProcessX(a);
	}

And as has been already noted, what is "readable" or "unreadable" is
very subjective.

This is my article, not my employer's, with my opinions and my disclaimer!
--
Duncan Gibson, ESTEC/YCV, Postbus 299, 2200AG Noordwijk, The Netherlands
Tel: +31 71 5654013   Fax: +31 71 5656142  Email: duncan@yc.estec.esa.nlx
To avoid junk email my quoted address is incorrect. Use nl instead of nlx.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                                                                   ` duncan
@ 1998-09-08  0:00                                                                     ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-08  0:00 UTC (permalink / raw)


In article <Eyz1vB.EoC@yc.estec.esa.nl>,  <duncan@yc.estec.esa.nlx> wrote:
>In article <35F534F6.D3CCE360@sprintmail.com>,
>John G. Volan <johnvolan@sprintmail.com> wrote:
>>
>>As you can see, the nesting has been considerably reduced, yet this
>>function is still single entry/single exit.  It also shares with the
>>early-return version the advantage of showing the choice of error-code
>>close to the test that determines the error.
>>
>>Best of both worlds? :-)
>
>Yes, but this was my point. Many people rail against early returns
>as being "problematic" for whatever reason or purpose. To my mind,
>provided you restrict early returns to 'pre-condition checking', the
>logic can still be preserved, and can be just as "readable" (or indeed
>"unreadable") as a se/se solution. [*]

Yes but, unless I'm mistaken, that was *John's* point:  His code
contained no early returns, and still preserved se/se without
deep nesting.

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                     ` Rick Smith
                                                                         ` (2 preceding siblings ...)
       [not found]                                                       ` <gio+van+no+ni+8-0809981818260001@dialup75.tlh.talstar.com>
@ 1998-09-08  0:00                                                       ` adam
  1998-09-08  0:00                                                         ` Rick Smith
  3 siblings, 1 reply; 510+ messages in thread
From: adam @ 1998-09-08  0:00 UTC (permalink / raw)


In article <VxRH1.379$I%.1143059@news1.atlantic.net>,
  "Rick Smith" <ricksmith@aiservices.com> wrote:

> 1. No user should be required to enter more data than is necessary. If the
> correct 4 digit year can be determined by the last two digits, do not ask
> for more than these 2 digits.

Well, just to be nitpicky:  Does this mean that if the window of reasonable
dates is small enough, the user should only be asked for 1 digit, because the
correct 4-digit year could be determined from just the last digit and because
"we should never ask the user for more data than is necessary"?

I don't think the "minimum amount of data necessary" philosophy makes any
sense here.  Rather, I think the legitimate reason here is that if users have
been entering 2-digit years all along, it might make sense to keep the user
interface the way it is.  (I'm assuming we're talking about data entry people
or other users who have been using the application for a while and have
gotten accustomed to it.)  However, if, in the same application, there are
some places where 2 digits are sufficient and other places where it isn't
(and thus 4 digits are "necessary"---unless you want to say that only the
last 3 digits should be sufficient! :))  I'd personally prefer all the years
to be 4 digits.  As a user, I would much rather have consistency than an
overzealous attempt at "allowing me to enter just the minimum amount of data
I have to".  The latter would actually make things less efficient, since I'd
have to look at the screen and think about whether I need to type in 2 or 4
digits, instead of just automatically entering a 4-digit year every time.  Of
course, non-touch typists (and I mean those of you who have to hunt for the 9
key *twice* when entering the year 1998) may see things differently.

				-- Adam

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                       ` Matthew Heaney
  1998-09-05  0:00                                                                         ` Robert Martin
@ 1998-09-08  0:00                                                                         ` Tim McDermott
  1998-09-08  0:00                                                                           ` Patrick Doyle
  1998-09-17  0:00                                                                           ` Matthew Heaney
  1 sibling, 2 replies; 510+ messages in thread
From: Tim McDermott @ 1998-09-08  0:00 UTC (permalink / raw)




Matthew Heaney wrote:

> (start of quote)
> The dowhiledo structure has general form
>
>   do1
>     dopart1
>   while
>     whiletest
>   do2
>     dopart2
>   od

snip

> Conclusion: Feel free to exit from the middle of a loop.

As defined, you can exit from the middle of a dowhiledo, but not from the top
or bottom.  This is still a se/se structure.  You can't use this structure to
justify multiple returns.

Note too, that Chapter 3 deals with PDL.  in Chapter 4, (titled "Structured
Programming") Paragraph 4.2.2  states:

"A _proper program_ [Mills italics - Tim] is a program with a control stucture
that

    1. has a single entry line and a single exit line, and
    2. for each node, has a path through that node from the entry line to the
exit line."

Tim





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                               ` <EyyLos.2nx@yc.estec.esa.nl>
@ 1998-09-08  0:00                                                                 ` Robert Martin
  1998-09-08  0:00                                                                 ` John G. Volan
  1 sibling, 0 replies; 510+ messages in thread
From: Robert Martin @ 1998-09-08  0:00 UTC (permalink / raw)



duncan@yc.estec.esa.nlx wrote in message ...


[re large se/se functions]

>Even with an indent level of only 2 spaces, the code would
>regularly march off the right of the screen and wrap around,
>making readability, maintenance and reformatting in the event
>of a change an absolute nightmare.


[re modularization of above large functions.]
>
>However, the system already had serious performance problems without
>adding several function calls and associated context switching...

In this extreme situation it seems clear that you'd want to use multiple
exits.  The cost of the se/se solution in this context probably outweighs
any benefits that might be derived.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
    'Mistrust arguments from authority.'" -- Carl Sagan







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.480<904556531.666222@ <6t42kg$son$1@hirame.wwa.com>
@ 1998-09-08  0:00             ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-08  0:00 UTC (permalink / raw)


In article <6t42kg$son$1@hirame.wwa.com>,
Robert Martin <rmartin@oma.com> wrote:
>
>duncan@yc.estec.esa.nlx wrote in message ...
>
>>Even with an indent level of only 2 spaces, the code would
>>regularly march off the right of the screen and wrap around,
>>making readability, maintenance and reformatting in the event
>>of a change an absolute nightmare.
>
>In this extreme situation it seems clear that you'd want to use multiple
>exits.  The cost of the se/se solution in this context probably outweighs
>any benefits that might be derived.

It seems clear, IMHO, that what's really needed is a better
data abstraction.  Having multiple functions which all traverse
a data structure and do all sorts of error checking along the
way seems to scream for a better abstraction.

Of course, this is based on limited info about the project,
and the design certainly could have been justified.

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                                                                         ` Tim McDermott
@ 1998-09-08  0:00                                                                           ` Patrick Doyle
  1998-09-08  0:00                                                                             ` Patrick Logan
  1998-09-17  0:00                                                                           ` Matthew Heaney
  1 sibling, 1 reply; 510+ messages in thread
From: Patrick Doyle @ 1998-09-08  0:00 UTC (permalink / raw)


In article <35F56A3B.8DEA51A7@draper.com>,
Tim McDermott  <mcdermott@draper.com> wrote:
>
>As defined, you can exit from the middle of a dowhiledo, but not from the top
>or bottom.  This is still a se/se structure.  You can't use this structure to
>justify multiple returns.

I don't like multiple exits much myself, but something occurred
to me...

An if-then-else statement can have multiple returns:

	if a = 1 then
		...
	elseif a = 2 then
		...
	elseif a = 3 then
		...
	end

Each "elseif" is an exit from this block of code, as is the "end".

How does this figure into the se/se picture?

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                                                                           ` Patrick Doyle
@ 1998-09-08  0:00                                                                             ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-08  0:00 UTC (permalink / raw)


In comp.object Patrick Doyle <doylep@ecf.toronto.edu> wrote:

: An if-then-else statement can have multiple returns:

: 	if a = 1 then
: 		...
: 	elseif a = 2 then
: 		...
: 	elseif a = 3 then
: 		...
: 	end

: Each "elseif" is an exit from this block of code, as is the "end".

: How does this figure into the se/se picture?

This is the definitions of IF/ELSE. The rationale is that there are
several blocks of code, but only *one* will execute. That one block
itself has a single entry and exit.

BTW the cutest thing about Smalltalk is that IF/ELSE is implemented
using the single entry/exit form you are alluding to above. In
Smalltalk, True is a class and False is a class. Both inherit from
Boolean.

True>>ifTrue: trueBlock ifFalse: falseBlock

  ^trueBlock value


False>>ifTrue: trueBlock ifFalse: falseBlock

  ^falseBlock value

So in this case IF/ELSE is implemented in a "pure" SE/SE fashion!  8^)

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                             ` Charles Hixson
  1998-09-06  0:00                                                               ` Matthew Heaney
  1998-09-06  0:00                                                               ` Robert Martin
@ 1998-09-08  0:00                                                               ` adam
  1998-09-09  0:00                                                                 ` Gerry Quinn
  2 siblings, 1 reply; 510+ messages in thread
From: adam @ 1998-09-08  0:00 UTC (permalink / raw)


In article <35F252DD.5187538@earthlink.net>,
  Charles Hixson <charleshixsn@earthlink.net> wrote:

> I suppose that it is possible to write spaghetti code without using
> goto's, I've never tried.

Sigh . . . does anyone *try* to write spaghetti code?  The thing is, someone
who's inexperienced and hasn't read enough code to know whether code is
readable or not, is certainly capable of writing unreadable, convoluted code
without using GOTO.  I can't say whether I've written any such code (because
if I did, I would have been too inexperienced to recognize it...), but I do
know that I've *seen* plenty of convoluted code written by people brought up
in the "GOTO is evil" religion.  Maybe it shouldn't be called "spaghetti
code" since the control doesn't wind up over itself; maybe "rotini code" is
more appropriate since although the different parts aren't entangled, they're
all completely twisted within themselves.  But if the goal is to write code
that doesn't give  a migraine to someone who tries to understand it, rather
than merely to identify which form of pasta is appropriate to a particular
piece of code, then Joe is absolutely right that it's possible to write code
without GOTO that is just as twisted as the unstructured, GOTO-loaded code
that older programmers used to write.

> I do know that with goto's INSTEAD OF while,
> until, elsif, begin...end, etc. it was very difficult NOT to write
> spaghetti code

How could it be that difficult?  I found it quite easy.  I used to work in
COBOL in the late 1970's, before COBOL had decent control structures, and I
learned that in many cases, it seemed better to *avoid* PERFORM .. WHILE,
since it took important chunks of code out-of-line and made it more difficult
for readers to understand.  So, instead of PERFORM..WHILE, I often wrote code
like

    START-OF-LOOP.
        IF some-condition THEN GOTO LOOP-END.
    BODY-OF-LOOP.
        ... do whatever
        GOTO START-OF-LOOP.
    LOOP-END.

(Usually with more appropriate paragraph names.)  This is well-structured, and
not difficult to write, and should be easy enough to understand for anyone who
has a clue what WHILE loops do in the first place.  So I can't imagine what
would merit calling this "spaghetti code", unless you belong to the
"GOTO-Is-Evil" religion (St. Edsger's Church) and believe that spaghettiness
can be determined by counting the number of GOTO's.

> and since there was originally the theory said that the
> best code economized on the number of CPU cycles, rather than optimized
> intelligibility, there was every reason TO write code that took
> short-cuts.

Ummm, I don't see how this has anything to do with Joe's point.  Sure, if
you think GOTO's are fine *AND* one of your prime motivations is to eliminate
as many cycles as possible, you're more likely to write unintelligible code;
but Joe is only questioning the assumption about GOTO's, and is saying nothing
whatsoever about nanosecond-squeezing code.

				-- Adam

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                                                       ` adam
@ 1998-09-08  0:00                                                         ` Rick Smith
  0 siblings, 0 replies; 510+ messages in thread
From: Rick Smith @ 1998-09-08  0:00 UTC (permalink / raw)



adam@irvine.com wrote in message <6t3use$5la$1@nnrp1.dejanews.com>...
>In article <VxRH1.379$I%.1143059@news1.atlantic.net>,
>  "Rick Smith" <ricksmith@aiservices.com> wrote:
>
>> 1. No user should be required to enter more data than is necessary. If
the
>> correct 4 digit year can be determined by the last two digits, do not ask
>> for more than these 2 digits.
>
>Well, just to be nitpicky:  Does this mean that if the window of reasonable
>dates is small enough, the user should only be asked for 1 digit, because
the
>correct 4-digit year could be determined from just the last digit and
because
>"we should never ask the user for more data than is necessary"?
>
The second sentence should have been "..., do not require more ..."
This change causes the second sentence to match the meaning of
the first sentence. In that sense, the user should be permitted to enter
one digit or two digits or four digits, if that is the choice of the user.
IMO, it is better that RSI not be the fault of the developer for requiring
the entry of too much data.

>I don't think the "minimum amount of data necessary" philosophy makes any
>sense here.  Rather, I think the legitimate reason here is that if users
have
>been entering 2-digit years all along, it might make sense to keep the user
>interface the way it is.  (I'm assuming we're talking about data entry
people
>or other users who have been using the application for a while and have
>gotten accustomed to it.)  However, if, in the same application, there are
>some places where 2 digits are sufficient and other places where it isn't
>(and thus 4 digits are "necessary"---unless you want to say that only the
>last 3 digits should be sufficient! :))  I'd personally prefer all the
years
>to be 4 digits.  As a user, I would much rather have consistency than an
>overzealous attempt at "allowing me to enter just the minimum amount of
data
>I have to".  The latter would actually make things less efficient, since
I'd
>have to look at the screen and think about whether I need to type in 2 or 4
>digits, instead of just automatically entering a 4-digit year every time.
Of
>course, non-touch typists (and I mean those of you who have to hunt for the
9
>key *twice* when entering the year 1998) may see things differently.
>
One reason that users have been entering two digit years, "all along,"
is that developers have required them to do so. Allowing one digit
years, provides the opportunity for users to become accustomed to
entering less data.

A recent discussion in news:comp.lang.cobol concerned the longevity
of four digit years. The concenus was that by 03 (or 2003) most of the
systems that had been modified to accept four digit years, for data
entry, will have been modified to reduce the requirement to two digits.
I do not remember there being any disagreement that it would happen;
it was just a question of when.
-------------------------------
Rick Smith
e-mail: < ricksmith@aiservices.com >






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                 ` Matthew Heaney
  1998-09-04  0:00                   ` Patrick Doyle
@ 1998-09-08  0:00                   ` Tim McDermott
  1998-09-17  0:00                     ` Matthew Heaney
  1 sibling, 1 reply; 510+ messages in thread
From: Tim McDermott @ 1998-09-08  0:00 UTC (permalink / raw)




Matthew Heaney wrote:

> Tim McDermott <mcdermott@draper.com> writes:
>
> > I guess the moral of the story is that this stuff really is hard, even at 3
> > terms.
>
> Yes!  That's the point I was trying make too.
>
> Although I can reason about a disjunction with two or three terms, I
> still prefer a loop predicate with just one term.
>
> By separating the array iteration from the item comparison, I can reason
> about the two different termination conditions independently.  So
> instead of one (larger) problem with two terms, I have two (smaller)
> problems, with one term each.

Since I wrote that bit about this being hard, I reallized that the difficulty
arose from Partick Doyle and I talking about different things that looked similar
enough to confuse me for a while.  He was talking about logical fromulae; I was
talking about textual forms.

Leaving all that aside, evaluting a 3-proposition predicate requires the
evaluation of the 3 propositions (neglecting short-circuiting) and applying 2
operators.  Evaluating a 2-proposition predicate involves evaluation of 2
propostitions and applying 1 operator.  It looks like the delta is 1 proposition
evaluation and 1 operator application.  Not a big deal IMO.


> By separating the array iteration from the item comparison, I can reason
> about the two different termination conditions independently.  So
> instead of one (larger) problem with two terms, I have two (smaller)
> problems, with one term each.

But here you are assuming that the termination conditions are disjoint!  In the
general case they are not.  Have you never had the experience of writing
something of the form

while (A) {

if (B) return b;
...
if (C) return c;
...
if (D) return d;

}

only to discover some time later that A&!B&!C (the path predicate of the if(D)
statement forces the value of D?  Worse yet, that the evaluation of the loop
predicate interacts with the evaluation of the if predicates.  My experience
tells me that distributing complexity is a Bad Idea.

That is not to say that I always use se/se.  But I know that se/se is better
form, and I have a real good idea of the risks of multiple return coding.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]           ` <35f51e53.480 <904556531.66622 <EyyLos.2nx@yc.estec.esa.nl>
  1998-09-08  0:00             ` duncan
@ 1998-09-08  0:00             ` Jim Cochrane
  1998-09-09  0:00               ` duncan
  1998-09-09  0:00               ` Charles Hixson
  1 sibling, 2 replies; 510+ messages in thread
From: Jim Cochrane @ 1998-09-08  0:00 UTC (permalink / raw)


Of course, if the conditions being checked in the code below are really
pre-conditions - that is, it can be considered a coding error that the
function is called with one of these conditions true, then it would be
better coded as:

void Worker::do_something (Tree *top)
{
    assert (top != NULL && top->child != NULL && ...);

    _error_code = really_do_something(top->child...->child);
    if (_error_code != 0) // or whatever value means non-error
    {
	_error_occurred = true;
    }
    else
    {
	_error_occurred = false;
    }
}

Where the assertion would be documented as a pre-condition of the function
specification.

Then a client would do:

    // ensure the pre-condition for root
    worker.do_something (root);
    if (worker.error_occurred())
    {
	//report/handle the error with worker.error_code() ...
    }

[Changed to an OO style, since the discussion is occurring on OO
newsgroups.]

The difference, of course, is that the checking for null pointers becomes
part of the function specification rather than being explicitely coded (the
assertion will probably be turned of in the production release).  This is
the difference between design by contract and defensive coding.

In article <EyyLos.2nx@yc.estec.esa.nl>,  <duncan@yc.estec.esa.nlx> wrote:
>
>
>This is a response to several articles in different subthreads, so
>you might not have seen some of the quoted articles on your way here...
>
> ...
>Although many people may have been taught about Structured Programming,
>and the importance of single entry and single exit points for program
>proving and testing, there are often times when other factors - shall I
>say "political" rather than technical - come into play.
>
>For example, I once worked on a C project where se/se was the be-all
>and end-all of the technical factors, with the testing for errors at
>every point coming in a close second. As the system consisted of 7
>sub-systems all communicating via shared memory there was the risk
>that although the logic in one system would preclude future errors,
>this couldn't be guaranteed in general. The data was organised in
>huge tree structures, all linked by pointers. Therefore, each routine
>always did "redundant" testing:
>
>int doSomething(Tree *pTop)
>{
>  int errorCode;
>
>  if (pTop != NULL)
>  {
>    if (pTop->pChild != NULL)
>    {
>      if (pTop->pChild->pChild != NULL)
>      {
>         /* lots of nesting omitted */
>
>                         if (pTop->pChild...->pChild != NULL)
>                         {
>                           errorCode = reallyDoSomething(pTop->pChild...->pChild);
>                         } else
>                         {
>                           errorCode = ERRORX;
>      } else
>      {
>        errorCode = ERROR3;
>      }
>    } else
>    {
>      errorCode = ERROR2;
>    }
>  } else
>  {
>    errorCode = ERROR1;
>  }
>  return(errorCode);
>}
>
-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                       ` <gio+van+no+ni+8-0809981818260001@dialup75.tlh.talstar.com>
@ 1998-09-08  0:00                                                         ` Mark A Biggar
  1998-09-08  0:00                                                         ` Rick Smith
  1 sibling, 0 replies; 510+ messages in thread
From: Mark A Biggar @ 1998-09-08  0:00 UTC (permalink / raw)


Giovanni 8 wrote:
>  Good point.  I've run into things like health care data.  Looking
> at the data in the data base, one must ask: Was that person born
> in 1985 or was it 1885?  Since a growing number of people are
> living more than 100 years, it's a significant problem.

This is exactly the situation my sister ran into.  She works in the
perscription claims processing group of a large health insurance company
and they just went through a whole Y2K evaluation of their databases.
What they discovered was that even though the database used 2 digit years
all over the place, they actually had almost no Y2K problems.  This was
because the only dates where 2 vs 4 digits really mattered in the DB was
for birthdates, which had always been stored in theire DB with 4 digits
because when the DB first came on line in the mid 80's they had to correctly
handle 90+ year old people born before 1900.  All other dates in the DB where
effectively some form of expiration date, none of which are before 1980.  So
there were only a few places where they had to tweek the code to think that
years 00-79 corresponded to 2000-2079 (most of the code already made this
assumption) and didn't have to change the DB at all.  So, I guess they lucked
out!

--
Mark Biggar
mark.a.biggar@lmco.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                       ` <gio+van+no+ni+8-0809981818260001@dialup75.tlh.talstar.com>
  1998-09-08  0:00                                                         ` Mark A Biggar
@ 1998-09-08  0:00                                                         ` Rick Smith
  1 sibling, 0 replies; 510+ messages in thread
From: Rick Smith @ 1998-09-08  0:00 UTC (permalink / raw)



Giovanni 8 wrote in message ...
>> Rick Smith wrote:

>> The benefits of windowing should be clear.
>>
>> 1. No user should be required to enter more data than is
>>    necessary.  If the correct 4 digit year can be determined
>>    by the last two digits, do not ask for more than these
>>    2 digits.
>
>Yes, but how big is that "if"?

A computer is a tool that should make jobs easier for users.
Yet, I have seen too many cases where the developer uses
fixed, inflexible formatting to ease *their* job of validating
and processing the data; rather than making reasonable
assumptions about data content to make it easier for the
user to enter data.

Fixed, inflexible formatting would require the entry of a year,
for date of hire, even if the turn over for the organization is
90 per cent. This means that, with respect to date of hire,
at least, 90 per cent of the time, the year is not required.

If it has any semblence to a date, I will try to process it as such;
but it is still your responsibility to determine if I have properly
recognized the date you intended.

>> 2. Given the choice between windowing and reformating
>>    persistent data, choose windowing.  Reformating existing
>>    data could break other parts of the system.
>
>I disagree.  The other parts of the system are already broken;
>you've just been skating on thin ice.  Repair them.  Repair
>your date formats.  It doesn't really take all that long one
>once you bite the bullet, and go on with life secure in knowing
>that that problem will never ever catch up with you again.

Disagree. There are, at least, three classes of programs, with
respect to how they use the date.

1. Processes the date and must be corrected.
2. Passes the date without significant processing
    (e.g., printing the date in reports).
3. Uses a structure which contains a date but does not use
     the date, itself (e..g, uses employee master which has hire
     date).

Changing the format of the date means that programs of
types 2 and 3 must be changed even though they are not
broken.

>> Finally, for new systems or when reformating persistent data
>> choose to store the data with 4 digit years or replace a
>> calendar date format with a standard date format.
>
>Hmmm.  Which "standard"?  M$'s standard?  The one that only
>recently has been changed to handle dates after 1999-12-31?
>There's an ISO standard (1685?) that at least allows a
>reaonable format.

Depends upon language, platform, etc. Just make certain that
a standard exists. ISO appears fine in most cases; including the
transport of data among systems. The COBOL standard integer
date could be used within COBOL. However, C's time_t should
never be stored in persistent data nor passed to other systems
(from a discussion in < news:comp.std.c >).
-------------------------------
Rick Smith
e-mail: < ricksmith@aiservices.com >






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                           ` Loryn Jenkins
@ 1998-09-09  0:00                                                             ` Samuel Mize
  1998-09-09  0:00                                                               ` sureshvv
  1998-09-10  0:00                                                               ` Tim Ottinger
  1998-09-11  0:00                                                             ` Robert I. Eachus
  1 sibling, 2 replies; 510+ messages in thread
From: Samuel Mize @ 1998-09-09  0:00 UTC (permalink / raw)


In article <35F06D6A.91A3D34E@s054.aone.net.au>,
Loryn Jenkins  <loryn@acm.org> wrote:
>> Humpty Dumpty had perfectly clear thoughts, but he didn't use the
>> agreed-to language, so his thoughts weren't clear to others.
>
>This is dubious at best. Although many linguists in the American
>Chomskyist school chould agree with you ...

OK, I'll restate my point without reference to the Classics.

If someone uses Tagalog or Mayan words as identifiers, he (or she, in
all cases) would understand his own code easily.  However, it would be
hard and error-prone for others from a typical project team to
understand it.

This is similar to someone who understands clearly what he intends the
code to do, but expresses it in a way that is not clear to a reader.

An appeal to clarity of thought won't shape up that person's code; his
thoughts are perfectly clear, just complex.

In fact, one could argue that some obscure code comes from too MUCH
clarity of thought.  When one is deeply immersed in the details of an
algorithm, its conditions and behavior are clear.  So, code can seem
clear to the writer, because it's easy to see what it's doing -- IF
you already know in detail what it's doing!

Another way to express that may be that the writer has "chunked"
together some of the complex concepts in the algorithm.  (I'm using
the term loosely.)  So from his point of view, he's expressing a few
simple ideas in the code.  But the reader, not having those "chunks"
already in mind, has to interpret the full complexity of the code.


>It is much more to the point that language is an instrument which 
>*construes reality*. It is quite inapropriate to claim that thoughts can
>be organised outside of the semiotic systems that construct it.

Well, I certainly can't argue with that!  I can't even follow it.
Let's see if my understanding is within a furlong of your intent.

I think the difference is that the coder typically constructs his
thoughts in one semiotic system: a combination of diagrams, native
language, and code fragments.  Then he expresses them in another:
compilable code.  The reader, to really understand the code, must then
rebuild something equivalent to the original construction before the
code makes as much sense to him as it did to the writer.

Using a constrained set of structures simplifies understanding the
code, but sometimes makes it harder to write it.  This is like to
using a limited, non-technical vocabulary when explaining things (like
linguistics).  Such a limited vocabulary would make it easier to
understand an explanation, but harder to write it.

But we're discussing structure.  Here's a better analogy.  The
previous paragraph was originally all one sentence that expressed that
complex idea.  I clearly understood what I wanted to say, but it took
me some time and effort to simplify my expression of it.

One heuristic that is often helpful in improving clarity of expression
is to break up a long, complex sequence into shorter, well-structured
components.  This is true in English and in code.

That's the central intuition of "structured programming," as I
understand the term, which is in a broad sense.  Single entry/exit,
end-exit loops, and other constraints, are specific approaches to
defining the structures to be used.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-30  0:00                                   ` Robert Martin
                                                       ` (5 preceding siblings ...)
       [not found]                                     ` <35f51e53.48044143@ <904556531.666222@miso.it.uq.edu.au>
@ 1998-09-09  0:00                                     ` Jonas M�ls�
       [not found]                                     ` <35f51e53.48044143@ <6t6l4n$rep@jbm.nada.kth.se>
  7 siblings, 0 replies; 510+ messages in thread
From: Jonas M�ls� @ 1998-09-09  0:00 UTC (permalink / raw)


Matthew Heaney writes:
>
>
>
>I can almost live that.  The real problem, however, is that using an
>extra flag to terminate VASTLY complicates the predicate.  In fact, the
>flag doubles the number of states I have to think about when mentally
>evaluating the predicate!  That's the real source of the loop
>termination errors.
>
>
>Using an exit from the middle avoids the headaches (literally)
>engendered by using an extra flag in the predicate.  When you want to
>exit, you just say that you want to exit, directly.  No mental
>gymnastics are required in order to determine whether you'll "really"
>exit, as would be the case using the flag approach.


	Using an exit from the top avoids the headaches 
	(quite literally) of having to figure out the 
	condition for completing another round in the loop, 
	which is one of the main conditions to specify, 
	in order to avoid loop termination errors.


	Also, I have never encountered a real situation
	where I have needed an extra flag in the predicate.
	One can actually do fine without them. As an example,
	I hereby present to you three variations of str_index.

	The first one strictly exits at the top. The other two
	in the middle. The first one is much easier to reason 
	about, and to understan, IMHO. Anyway, introducing an
	extra flag in the predicate is very often a sign of
	"patching the loop". Done right, one does not need it.



/** str_index
 *
 * str_index returns a pointer to the first occurrence of
 * the given character in the given string.
 * If the given character does not occur in the given
 * string, str_index returns NULL.
 * 
 * If the given pointer is NULL, the result is undefined.
 * 
 */






char *
str_index (
    char   *s,			/* string to search           */
    char    c)			/* character to search for    */
{
    while (*s != '\0'  &&  *s != c)
	++s;

    return   (*s != c)  ?  NULL : s;
}   



char *
str_index2 (
    char   *s,			/* string to search           */
    char    c)			/* character to search for    */
{
    while (*s != '\0')
	if (*s == c)
	    return s;
	else
	    ++s;

    return  0;
}   





char *
str_index3 (
    char   *s,			/* string to search           */
    char    c)			/* character to search for    */
{
    while (*s != '\0')
    {
	if (*s == c)
	    return s;

	++s;
    }

    return  0;
}   






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                             ` Samuel Mize
@ 1998-09-09  0:00                                                               ` sureshvv
  1998-09-10  0:00                                                                 ` prochak
  1998-09-17  0:00                                                                 ` Matthew Heaney
  1998-09-10  0:00                                                               ` Tim Ottinger
  1 sibling, 2 replies; 510+ messages in thread
From: sureshvv @ 1998-09-09  0:00 UTC (permalink / raw)


In article <6t6b3m$30j8$1@prime.imagin.net>,
  smize@imagin.net (Samuel Mize) wrote:
>
> One heuristic that is often helpful in improving clarity of expression
> is to break up a long, complex sequence into shorter, well-structured
> components.  This is true in English and in code.
>

Well said. The multi-return structure enables you to separate
code in small  independent blocks, each of which may be examined
and understood with less interference from surrounding blocks.
The se-se structure creates large blocks, requiring more
context information.

> That's the central intuition of "structured programming," as I
> understand the term, which is in a broad sense.  Single entry/exit,
> end-exit loops, and other constraints, are specific approaches to
> defining the structures to be used.
>

Agreed. In this case, se-se is a good starting point. But the tree
structure (as someone referred to it; i would be interested in a reference)
IMHO, is superior in capturing this intent of structured programming
(irresp. of if Dijkstra would approve of it).

suresh

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                         ` Adrian P. Morgan
@ 1998-09-09  0:00                                                           ` Charles Hixson
  1998-09-10  0:00                                                             ` mfinney
  0 siblings, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-09  0:00 UTC (permalink / raw)


Adrian P. Morgan wrote:
...
> Couldn't we say, perhaps, that "structuredness" is a
> continuum, a measure of the tightness of control over
> jumps in a program, ranging from totally uncivilised
> garbage at the "Not Structured" level, all the way up to
> strict SE/SE at the "Very Structured" level?  The
> unqualified term "Structured" not only *is* but *should*
> be somewhat ambiguous (since oversimplifying these issues
> doesn't help anyone).
> 
> That way, everyone could be right.  Which would be nice.
> 
> --
> Here and there I like to preserve a few islands of sanity
> within the vast sea of absurdity which is my mind.
> After all, you can't survive as an eight foot tall
> flesh eating dragon if you've got no concept of reality.

The problem is that with the limited range of structures comes a limited
range of errors that can occur.  The se/se school is limiting a
particular set of errors:  If you use their approach you WILL NOT make
the errors that they have excluded.  On the other hand, advocates of,
e.g., early returns, feel that by testing for errors early you can
remove complications from the code, and thus remove a DIFFERENT source
of errors.  The two are incompatible.  You can choose which you consider
more important, but you only get to pick one.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00             ` Jim Cochrane
  1998-09-09  0:00               ` duncan
@ 1998-09-09  0:00               ` Charles Hixson
  1998-09-10  0:00                 ` Loryn Jenkins
  1998-09-17  0:00                 ` Matthew Heaney
  1 sibling, 2 replies; 510+ messages in thread
From: Charles Hixson @ 1998-09-09  0:00 UTC (permalink / raw)


Jim Cochrane wrote:
> 
> Of course, if the conditions being checked in the code below are really
> pre-conditions - that is, it can be considered a coding error that the
> function is called with one of these conditions true, then it would be
> better coded as:
> 
> void Worker::do_something (Tree *top)
> {
>     assert (top != NULL && top->child != NULL && ...);
> 
>     _error_code = really_do_something(top->child...->child);
>     if (_error_code != 0) // or whatever value means non-error
>     {
>         _error_occurred = true;
>     }
>     else
>     {
>         _error_occurred = false;
>     }
> }
> 
> Where the assertion would be documented as a pre-condition of the function
> specification.
> 
> Then a client would do:
> 
>     // ensure the pre-condition for root
>     worker.do_something (root);
>     if (worker.error_occurred())
>     {
>         //report/handle the error with worker.error_code() ...
>     }
> 
> [Changed to an OO style, since the discussion is occurring on OO
> newsgroups.]
> 
> The difference, of course, is that the checking for null pointers becomes
> part of the function specification rather than being explicitely coded (the
> assertion will probably be turned of in the production release).  This is
> the difference between design by contract and defensive coding.
> 
...
> --
> Jim Cochrane
> jtc@dimensional.com

It has been claimed that Design By Contract (DBC) can be done entirely
by comments and documentation.  I, personally, don't believe it.  It is
my expectation that the routines with explicit pre-conditions and
post-conditions would work as desired in the Eiffel environment, where
the developer could have pre-conditions enabled while developing it, and
only remove them (IN LAYERS!) when the final code was produced.  I don't
think that this would work at all as well without support from the IDE.

Now it is true, that the failures of DBC in an environment that doesn't
support it can be traced to the contract not being lived up to, but
ENFORCEABILITY IS A PART OF THE CONTRACT.  In an environment that
doesn't enforce the contract, violations will not be detected, and I
don't know about you, but my programs always need to have the bugs
cleaned out of them before they are ready for delivery.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                             ` Robert Martin
  1998-09-06  0:00                                                               ` Charles Hixson
@ 1998-09-09  0:00                                                               ` sureshvv
  1 sibling, 0 replies; 510+ messages in thread
From: sureshvv @ 1998-09-09  0:00 UTC (permalink / raw)


In article <6su70s$db8$1@hirame.wwa.com>,
  "Robert Martin" <rmartin@oma.com> wrote:
>
> Charles Hixson wrote in message <35F2496D.7C4BDC42@earthlink.net>...
> >Robert Martin wrote:
> >...
> >>   if (condition.1) return;
> >>   else if (condition.2) return;
> >>   else do something useful;
> >>   return;
> >> };
> >>
> >> Which, in reality, is:
> >>
> >> void f()
> >> {
> >>   if (condition.1) return;
> >>   else{
> >>     if (condition.2) return;
> >>     else {
> >>       do something useful;
> >>     }
> >>   }
> >> };
> >>
> >> So, early returns do not actually reduce nesting; they just appear to.

But appearance is important. If we make the code appear simpler
yet retaining its functionality, we have made it more readable/maintainable.

I diasagree with your notion that creating placeholders in code where you
might end up adding code in future is the way to make code more maintainable.
On the contrary, maintainability is when the code is sufficiently decoupled
that you may rip out any one piece (eg., class method), be able to totally
rewrite it and rebuild the system without breaking it.

>
> Early returns form a boolean equation which is an OR of terms:
>
> if this then return.
>     or
> if that then return.
>     or
> if the_other then return
>     or
> do something useful.
>
> But, as you noted, we can apply Demorgan's theorem and turn this into an AND
> of factors
>
> if (!this AND !that AND !the_other)
>   then do something useful
>
> Just a transformation,  And one that turns a multiple exit function into an
> se/se function.
>

This is why I added a couple of realistic requirements, where
- a different message should be logged for each input condition
- a different value has to be returned for each input condition

With these requirements a simple transformation will not do
and the se/se solution becomes less readable.

> we might then decide that long boolean equations are better split apart:
>
> if (!this)
>   if (!that)
>     if (!the_other)
>       then do something useful.
>
> Which is an idiom that we can learn to read as a set of ANDS.

Wonderfully adaptable creatures that we are, we can learn to do almost
anything :-) But why?

suresh


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                         ` Ell
  1998-09-07  0:00                                                           ` Ell
@ 1998-09-09  0:00                                                           ` Ray Gardner
  1 sibling, 0 replies; 510+ messages in thread
From: Ray Gardner @ 1998-09-09  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:
> rgardner@nyx.net (Ray Gardner) wrote:
> 
> [stuff elided]
> 
> As I said that stuff is not proof to me they advocated se/se.  To me
> their point was to encourage use disciplined navigation for proof and
> maintainability.  Multiple returns can be disciplined navigation.

Ell, you have an interesting notion of rational discourse.  You 
ask for a single cite of a structured programming text, or 
founder, asserting that loops should be single-entry / single-
exit.  You are then given not one but four or five cites by 
various posters.  Now you say "that stuff is not proof to me they 
advocated se/se."  I ask you: what you would consider "proof" to 
be, if not the direct quotes you asked for.  Unfortunately, I 
don't think we can get Prof. Dijkstra to come on the NG and tell 
you himself.  If he did, would you say that wasn't "proof to me" 
either? 

So really, what would be "proof" that they did?  And why do you 
ask for cites when you know in advance that you aren't going to 
accept any?  Why do you engage in discourse at all when you seem 
entirely impervious to reasoned persuasion/discussion/argument? 

Let me ask you this:  Have you ever, in any newsgroup 
discussions, ever, ever had the good grace to say: "Hey, you're 
right and I was wrong."?  If not, is it only because you were 
never wrong?

Do you sometimes get the feeling that the entire world (or at 
least a newsgroup) is against you?  Do you ever wonder why?  Do 
you care?  Do you like it that way?  Why is your tone so often 
antagonistic, e.g. "And your proof is what?"  For cat's sake, I 
posted because I thought you really wanted to know what the 
original writings on SP said.  For all my effort digging up 
quotes, you blow me off with "As I said that stuff is not proof 
to me...".  I've wondered sometimes at the antagonism between you 
and other posters.  Now I've tasted it myself, I can understand 
why people find you a bit difficult to deal with.  What are you 
like to work with?  Do you get along better with your co-workers 
than you do with your newsgroup "colleagues", or do you take that 
sort of tone with them?  "And your proof is what?"  Why not 
"Sorry, I must have missed that post.  Could you fill me in?" 

> But either way, I'm not a dogmatist.  I'll unite with the spirit of
> maintainability and not rigid adherence to a practice when it clearly
> contradicts that.

How pragmatic of you.  :-)  I've used break statements and 
multiple exits on occasion myself.  (Even a slew of goto 
statements in a Duff's Device-like piece of data decompression 
code.)  But the issue you originally disputed was what the 
original writings on SP said, and that's not a matter of opinion.  
Those writings exist, they've been quoted to you, and you 
adamantly discount that.  Why? 

> The main things I get from all of the structured writers is:
>     a) Use procedure calls (with consequent return)
>     b) Use procedural task abstraction (not isolated structures)
> 
> Elliott

Which of the "structured writers" have you read?  Dijkstra?  
Wirth?  Hoare?  Mills?  Ledgard?  Yourdon?  Anybody (other than 
Knuth; we know you've got _Literate Programming_, including "SP 
with go to Statements")?  Any book titles at hand?





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                       ` dewarr
@ 1998-09-09  0:00                                                         ` Ray Gardner
  1998-09-11  0:00                                                           ` Robert I. Eachus
  0 siblings, 1 reply; 510+ messages in thread
From: Ray Gardner @ 1998-09-09  0:00 UTC (permalink / raw)


dewarr@my-dejanews.com wrote:
> In article <35f34bbd.7903825@news.erols.com>,
>   ell@access.digex.net wrote:
> > rgardner@nyx.net (Ray Gardner) wrote:
> >
> > >.... Of course my main point was
> > >that the founder(s) of SP did limit the control structures to
> > >single-entry / single-exit structures, and that still stands.
> >
> > And your proof is what?
> >
> > Elliott
> >
> 
> There is no "founder" of structured programming. The
> idea of structured programming is an old one, well known
> to anyone writing Algol-60 from very early on. Various
> people have produced specific rules concerning their
> idea of how to adapt this principle to particular
> programming languages (e.g. the "structured period"
> for ANSI-74 COBOL), but I would not say it is reasonable
> to regard anyone as "founding" structured programming.
> 
> EWD's letter on gotos to the ACM was simply noting a
> general principle well known to any student algol-60
> programmer for years. it is true that Fortran had
> made it much more difficult, though not impossible,
> for people to understand the basic idea of writing
> code that has a clear control flow structure.

Nice to get a response from you, Professor Dewar.  (I assume 
that's you of Indirect Threaded Code / Spitbol / GNAT fame.  
Say, did Chuck Moore come up with ITC on his own or get it from 
your paper?)  

You're certainly better able than I to say what was or wasn't 
"well known to any student algol-60 programmer" for years before 
1968.  My collection of literature barely reaches back that far, 
so I don't have ready access to, say, the algorithms published in 
CACM in the mid-1960s.  (I recall you lamenting the passing of 
that.)  

I do have one item at hand: the book _Programming Languages_ 
edited by F Genuys (Academic Press, 1968) edited by F Genuys, 
containing some material presented at the 1966 NATO Summer School 
in Programming.  It includes the classic EWD paper on 
"Co-operating Sequential Processes" and a lengthy set of notes on 
"Compiler Writing Techniques" (L. Bolliet), and both contain a 
fair amount of Algol code, replete with plenty of goto 
statements.  Given that EWD and Bolliet were well beyond the 
"student programmer" stage, I wonder if some of the ideas of 
SP were not as well-known as you recall. 

It is certainly true that EWD was not the first to advocate 
avoidance of goto statements; he said as much in his famous 
letter.  Knuth (in Structured Programming with go to Statements) 
notes that EWD was "experimenting" with a goto-less Algol in the 
mid-60s, and quotes him saying that avoiding goto was "difficult 
... we are so familiar with the jump that it requires some effort 
to forget it!".  Knuth also finds Naur (editor of the Algol-60 
report) questioning the goto in 1963, the earliest printed 
reference to avoiding goto Knuth found. 

I'm sure many good Algol (and other language) programmers used 
good judgment in refining and structuring their code in the 
1960s.  Does that mean they practiced SP?  Or that SP had no 
founder?  Seems to me that depends on how you define SP. 

Knuth says that Dijkstra's paper "Structured Programming" in 
_Software Engineering Techniques_ (Report on the 1969 Rome 
conference, NATO Science Committee) gave SP its name.  Of course 
EWD's more widely known 1972 "Notes on Structured Programming" in 
the little black book is generally accepted as having really 
kicked off the SP "revolution".  After that, there was a 
veritable flood of papers, letters, books and courses on SP.  So 
maybe not all the ideas were EWD's alone or original with him; 
the emphasis on the limited use of control structures was not 
new, but what about the explicitness of the motivation for it?  
EWD was interested in developing programs that he could convince 
himself and others were correct.  Maybe others had the same idea 
but didn't express it explicitly and convincingly.  I think that 
if you agree that there is any such thing as SP, you really have 
to credit EWD with naming it and describing it.  In fact, I would 
argue that those two papers _are_ the definition of SP.  If ideas 
are just sort of "in the wind" for a few years, and then someone 
pulls them together and starts a whole field of people thinking 
about them, you don't consider him the founder?  I do. 





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                       ` Ell
@ 1998-09-09  0:00                                                         ` Adrian P. Morgan
  1998-09-09  0:00                                                           ` Charles Hixson
  0 siblings, 1 reply; 510+ messages in thread
From: Adrian P. Morgan @ 1998-09-09  0:00 UTC (permalink / raw)


Ell wrote:
 ^ 
 | And either way I agree with an earlier writer and point of view that
 | whatever Dijkstra, Dahle and Hoare may or may not have said about
 | exits, it isn't gospel.  Intelligent people can and should latch on
to
 | the spirit and essence of what they were saying.
 v 

Couldn't we say, perhaps, that "structuredness" is a 
continuum, a measure of the tightness of control over 
jumps in a program, ranging from totally uncivilised 
garbage at the "Not Structured" level, all the way up to 
strict SE/SE at the "Very Structured" level?  The 
unqualified term "Structured" not only *is* but *should* 
be somewhat ambiguous (since oversimplifying these issues 
doesn't help anyone).

That way, everyone could be right.  Which would be nice.

-- 
Here and there I like to preserve a few islands of sanity
within the vast sea of absurdity which is my mind.
After all, you can't survive as an eight foot tall 
flesh eating dragon if you've got no concept of reality.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00             ` Jim Cochrane
@ 1998-09-09  0:00               ` duncan
  1998-09-11  0:00                 ` Jim Cochrane
  1998-09-09  0:00               ` Charles Hixson
  1 sibling, 1 reply; 510+ messages in thread
From: duncan @ 1998-09-09  0:00 UTC (permalink / raw)


In article <6t4dmi$rhp@flatland.dimensional.com>,
Jim Cochrane <jtc@dimensional.com> wrote:
>Of course, if the conditions being checked in the code below are really
>pre-conditions - that is, it can be considered a coding error that the
>function is called with one of these conditions true, then it would be
>better coded as:
>
>void Worker::do_something (Tree *top)
>{
>    assert (top != NULL && top->child != NULL && ...);
>
>    _error_code = really_do_something(top->child...->child);
>    if (_error_code != 0) // or whatever value means non-error
>    {
>	_error_occurred = true;
>    }
>    else
>    {
>	_error_occurred = false;
>    }
>}
>
>Where the assertion would be documented as a pre-condition of the function
>specification.
>
>Then a client would do:
>
>    // ensure the pre-condition for root
>    worker.do_something (root);
>    if (worker.error_occurred())
>    {
>	//report/handle the error with worker.error_code() ...
>    }
>
>[Changed to an OO style, since the discussion is occurring on OO
>newsgroups.]
>
>The difference, of course, is that the checking for null pointers becomes
>part of the function specification rather than being explicitely coded (the
>assertion will probably be turned of in the production release).  This is
>the difference between design by contract and defensive coding.


The first 'Commandments' for coding were:
1. Thou shalt use single entry/single exit routines.
2. Thou shalt guarantee all pointers before dereferencing.

As mentioned before, the system was made up of 7 sub-systems,
all running as separate processes, and communicating via
shared memory. Hence there was a lot of 'redundant' checking.

Yes, you could use 'assert' but seeing as the error checking
had to go into the production code anyway, there was little point.

Yes, the pre-conditions could have been checked before the
routine was actually called, but now you have moved knowledge
of where in the tree data structure the relevant information
lives into the caller. When you consider that some of the paths
through the tree involved following 6 or more pointers, that's
a lot of encapsulation and data hiding that has been lost.
All of the code for determining which error has occurred has
also been moved from the routine to the caller...

These are all tradeoffs that need to be made. I believe that
there are various 'good practices' which should be included
in an ideal world, but until I find employment in the ideal
world, it's going to be a case of making these tradeoffs, and
some of the 'good practices' may not be applied in all cases.

Of course it helps if you are aware of the 'good practices'
in the first place so that you know what you are missing.

Cheers
Duncan

This is my article, not my employer's, with my opinions and my disclaimer!
--
Duncan Gibson, ESTEC/YCV, Postbus 299, 2200AG Noordwijk, The Netherlands
Tel: +31 71 5654013   Fax: +31 71 5656142  Email: duncan@yc.estec.esa.nlx
To avoid junk email my quoted address is incorrect. Use nl instead of nlx.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                   ` <gio+van+no+ni+8-0809981840170001@dialup75.tlh.talstar.com>
@ 1998-09-09  0:00                                                     ` Nick Leaton
       [not found]                                                       ` <gio+van+no+ni+8-1609980026290001@dialup26.tlh.talstar.com>
  0 siblings, 1 reply; 510+ messages in thread
From: Nick Leaton @ 1998-09-09  0:00 UTC (permalink / raw)


Giovanni 8 wrote:
> 
> > Robert I. Eachus wrote:
> >> Giovanni 8 wrote:
> >> I've run across this, too.  Back before interactive debuggers
> >> it was common to use gotos to reach a "normal" return, that,
> >> with debugging turned on in the pre-compiler, would generate
> >> a sort of trace log.  But even there, it has the disadvantage
> >> of covering up the "actual" point from which one is returning.
> >> Why not deal with error handling right there, where the most
> >> information is available?
> 
> > I think we are geting to the point of violent agreement.
> > The "structured" code:
> >
> > <<Bad1>>
> >
> >    loop
> >      Get(Next);
> >      if Next /= null;
> >      [lots of normal case code]
> >      else exit;
> >      end if;
> >    end loop;
> >...
> >    should be regarded as broken while the equivalents:
> >
> > <<Good1>>
> >
> >    loop
> >      Get(Next);
> >      if Next = null
> >      then exit;
> >      else
> >       [lots of normal case code]
> >      end if;
> >    end loop;
> 
> >    or
> > <<Good2>>
> >
> >    loop
> >      Get(Next);
> >      exit when Next = null;
> >      [lots of normal case code]
> >    end loop;
> 
> >    or
> > <<Good3>>
> >
> >    while Get(Next) loop;
> >      [lots of normal case code]
> >    end loop;
> 
> Great, if the "Get" knows what abnormal conditions to handle
> for this particular context (module, function, whatever), &
> then one would work in other "normal" conditions, as well.
> 
> This reminds me of reading Wirth's _Systematic Programming_.
> He presented these pat examples, to which few common problems
> could be made to conform.  (Even his "proof" of a GCD
> algorithm just kind of brushed past a crucial point.)
> 
> It's more like
>   loop
>   {
>     Get(Next);
>     if (thiscondition) then
>     {
>       do this;
>       return;
>     }
>     else if (thatcondition) then
>     {
>       do that;
>       return;
>     }
>     else if (theother) then
>     {
>        do goodstuff;
>     }
>     else if (yetanother) then
>     {
>        do othergoodstuff;
>     }
>     else
>       do unforeseencondition;
>     endif
>     do morestuff
>   }
>   endloop when(x);
>   do aftertheloopstuff
>   return;
> 
> Yes, it's defensive programming.   Enlighten me.

So lets say the loop calculates a square root. What should 'do this' and
'do that' do? What if it is in an aircraft, in a simulation? Do you want
to rewrite square root for each case?

-- 

Nick




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                                                               ` adam
@ 1998-09-09  0:00                                                                 ` Gerry Quinn
       [not found]                                                                   ` <gio+van+no+ni+8-1609980034390001@dialup26.tlh.talstar.com>
  0 siblings, 1 reply; 510+ messages in thread
From: Gerry Quinn @ 1998-09-09  0:00 UTC (permalink / raw)


In article <6t4dge$t8u$1@nnrp1.dejanews.com>, adam@irvine.com wrote:
>In article <35F252DD.5187538@earthlink.net>,
>  Charles Hixson <charleshixsn@earthlink.net> wrote:
>
>> I suppose that it is possible to write spaghetti code without using
>> goto's, I've never tried.
>
>Sigh . . . does anyone *try* to write spaghetti code?  The thing is, someone
>who's inexperienced and hasn't read enough code to know whether code is
>readable or not, is certainly capable of writing unreadable, convoluted code
>without using GOTO.  

I agree - in fact I would argue that if you are carrying a flag for 
deciding when to exit, the flag is part of the flow of control - with 
all the potential pasta that entails.

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                                     ` Matthew Heaney
  1998-09-05  0:00                                                                       ` Robert Martin
  1998-09-05  0:00                                                                       ` Matthew Heaney
@ 1998-09-09  0:00                                                                       ` Tim Ottinger
  1998-09-17  0:00                                                                         ` Matthew Heaney
  2 siblings, 1 reply; 510+ messages in thread
From: Tim Ottinger @ 1998-09-09  0:00 UTC (permalink / raw)


Matthew Heaney wrote a very fine, well-researched note
here. I think it was great, except that he took "reason
about..." to mean "understand...". To understand a code
fragment is not the same as to reason about it. 

Understanding is necessary, but insufficient. From 
practice, we know that 'easy to understand' is desirable,
but not enough. What about robustness, reentrancy, absence
of race conditions, atomicity, ease of change, efficiency,
etc? There is a lot more to consider than just simplicity,
though we always strive to keep as much simplicity as we
can stand.

But this is not the point of "reasoning about" structure,
either. It's about understanding the full character of 
the code that's written, so I'll return to the idea of
'reasoning about' structure...

It's not enough to merely understand an instance of
a structure of code. The goal was to do much more than
this, and establish a formal or semi-formal practice...
an 'engineering discipline'.

When Dijkstra mentions reasoning about structures, he
is talking about proofs and the like... the ability to
characterize (perhaps mathematically) the structure of
the code, to measure it, to draw correlations between
it and other things, to prove it correct or incorrect,
to apply transformations (read: optimizations) to the
structure.

There are patterns of structure, and there can be
patterns of structure intentionally applied. I wonder
if the /Nature Of Order/ won't even have us starting
to drive towards some kind of formalism in code 
structure. 

I won't say that I go as far as many in the path of
formalized structure, but I am increasingly appreciating 
the goal and the value of a more formalized
way to reach it. 

That said, I have to plan to go restructure a little 
code, and catch up on reading /Structured Programming/
(Dahl, Dijkstra, Hoare, academic press "computer
science classics" series, ISBN 0-12-200550-3). 

Bye now.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                           ` Charles Hixson
@ 1998-09-10  0:00                                                             ` mfinney
       [not found]                                                               ` <gio+van+no+ni+8-1609981736190001@dialup47.tlh.talstar.com>
  0 siblings, 1 reply; 510+ messages in thread
From: mfinney @ 1998-09-10  0:00 UTC (permalink / raw)


In <35F70F41.67AC4347@earthlink.net>, Charles Hixson <charleshixsn@earthlink.net> writes:

>The problem is that with the limited range of structures comes a limited
>range of errors that can occur.  The se/se school is limiting a
>particular set of errors:  If you use their approach you WILL NOT make
>the errors that they have excluded.  On the other hand, advocates of,
>e.g., early returns, feel that by testing for errors early you can
>remove complications from the code, and thus remove a DIFFERENT source
>of errors.  The two are incompatible.  You can choose which you consider
>more important, but you only get to pick one.

The use of non se-se control structures to match the problem's "structure"
is really an important concept.

The use se-se did originate to reduce the number of errors, and as a first
attempt, was a very good thing.  The problem is that the first attempt at
anything is almost never the "correct" answer.

I believe that what we need to do is to study many, many programs and
find out what the "natural" structure of the programs are (in the small
scale).  Then we need to design control structures to match each of the
patterns that we find.  There are, of course, an infinite number of patterns
but we can limit ourselves to those which we find repeated on a somewhat
regular basis.

Many authors have looked at control structure variations such as the n 1/2
loop problem.  There are others such as exit from a binary tree insert which
has three different exit conditions with different actions occuring at each
exit (add left, found it, add right).  Knuth introduced situation labels to
assist with problems like this.

I have made a study of many control structures for years as a hobby and
virtually all of them are tree-structured, but they are not structured.  It
is clear that many people feel that the original se-se structures are just
too limiting, but they still want "structure".  When considering control
structure improvements, the right place to put the line seems to be tree-
structured instead of structured.  It gives just the right amount of
flexability and still maintains a regular program structure.

As far as "provability" is concerned, any of the "regular" control structures
can be constructed from the se-se control structures with the possible
addition of extra flags and tests.  That means that if se-se is provable
then these additional control structures are also provable -- and probably
in a much more direct manner.  In a different post, I have a minimum set
of control structures from which all tree-structured code can be built.  I'm
sure that nice properties for those can be found which assist proving
program correctness.

However, proving program correctness is kind of a moot point at the
moment because nobody can do it for any kind of a sizeable program.
I have hopes that the advances in theorem proving combined with OO
built using preconditions/invariants/postconditions from the ground up
could give major advances in proving program correctness.  The use of
program transformations which start with a predicate and then use
transformations which provably retain correctness to convert the
predicate, step by step, to an executable program can also assist in
that area.  I feel that combining all of these things together (better
control structures, OO grounded with invariants and program
transformations) can result in large programs which are provably
correct -- but not by hand.  As always, the tedious details are where
computers are useful.

Even Robert agrees that the use of a particular se-se control structure
should be based on costs and benefits.  Of course, the major problem
with that is that nobody knows what the costs and benefits really are
when compared to slight variations such as exit from the middle of a
loop.  We all believe that there are significant benefits from the use
of structured programming compared to the original unstructured
programming.  But there is no evidence that I have seen that the 
original structured programming is better or even as good as some of
the "improvements" in control structures that have been invented over
the last 20 years or so.  I personally believe that these control structures
*do* improve things by reducing errors both in coding and in maintenance
because they improve the programmer's ability to reason about the
program in a "natural" manner.  However, that is just my opinion and is
only backed up by my experience (which is around 28 years or so, perhaps
not quite as long as Robert's, but hopefully just as good <g>).

I do know that I apply the principles above as much as possible (and would
do a lot more if I had the computer support I need) and the results have
been very good -- but perhaps the results would be just as good anyway.
There you get the question of the programmer vs the process.


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                     ` <35f51e53.48044143@ <6t6l4n$rep@jbm.nada.kth.se>
@ 1998-09-10  0:00                                       ` Mats Weber
  1998-09-17  0:00                                       ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Mats Weber @ 1998-09-10  0:00 UTC (permalink / raw)


Jonas M�ls� wrote:

>         Also, I have never encountered a real situation
>         where I have needed an extra flag in the predicate.
>         One can actually do fine without them. As an example,
>         I hereby present to you three variations of str_index.
> 
>         The first one strictly exits at the top. The other two
>         in the middle. The first one is much easier to reason
>         about, and to understan, IMHO. Anyway, introducing an
>         extra flag in the predicate is very often a sign of
>         "patching the loop". Done right, one does not need it.
> 
> 
> char *
> str_index (
>     char   *s,                  /* string to search           */
>     char    c)                  /* character to search for    */
> {
>     while (*s != '\0'  &&  *s != c)
>         ++s;
> 
>     return   (*s != c)  ?  NULL : s;
> }

The problem with this variant is that you are comparing *s with c once more
than in the other two variants. With characters, this is perfectly OK, but
this could become a problem if the comparison for equality is more expensive,
for instance if you are comparing larger structures or have a more complicated
equality function.

In fact, you are using "*s == c" as a flag to check why you exited form your
loop. Try to reprogram your example doing each comparison only once: you will
need a flag if you don't use return in the loop.

(I find the other two variants more readable, but that is a matter of taste).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                             ` Samuel Mize
  1998-09-09  0:00                                                               ` sureshvv
@ 1998-09-10  0:00                                                               ` Tim Ottinger
       [not found]                                                                 ` <01bddccc$98b2dda0$ca3aea9e@tom>
  1 sibling, 1 reply; 510+ messages in thread
From: Tim Ottinger @ 1998-09-10  0:00 UTC (permalink / raw)


Samuel Mize wrote:
> If someone uses Tagalog or Mayan words as identifiers, he (or she, in
> all cases) would understand his own code easily.  However, it would be
> hard and error-prone for others from a typical project team to
> understand it.
> 
> This is similar to someone who understands clearly what he intends the
> code to do, but expresses it in a way that is not clear to a reader.
> 
> An appeal to clarity of thought won't shape up that person's code; his
> thoughts are perfectly clear, just complex.

now, wait a minute here. Obscurity and complexity are not the same
thing. I've seen simple code written in obscure ways. There is a 
mighty big gulf there. Now, complexity can obscure to be sure, but
there are many other ways to obscure other than being complex.


> In fact, one could argue that some obscure code comes from too MUCH
> clarity of thought.  

I would never accept this argument. I would say that sometimes
simple solutions are not obvious. That's when clarity of exposition
takes over. But clarity of thought does not cause one to write
obscure code. 

What does happen, by the way, is that a reader may see a problem
as being unrealistically simple. In MT programs, for example, they
might not understand how to solve the problems caused by race 
conditions and update anomalies, and may not even understand
the problems. To them, the multi-threaded code seems needlessly
complex and overdesigned. In reality, it's probably as simple
as it can be given the requirements. The obscurity is not 
caused by clarity of thought on the part of the writer, but
by cloudiness of thought on the part of the reader. 

While generalization is a valuable skill, overgeneralization
is not.

tim






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-04  0:00                                                           ` Ell
                                                                               ` (2 preceding siblings ...)
       [not found]                                                             ` <35F074C9.E10C <35F2E907.594CD023@earthlink.net>
@ 1998-09-10  0:00                                                             ` Tim Ottinger
  1998-09-10  0:00                                                               ` dewarr
  3 siblings, 1 reply; 510+ messages in thread
From: Tim Ottinger @ 1998-09-10  0:00 UTC (permalink / raw)


Ell wrote:
> But generally it is possible to get a plurality or majority to agree
> on what is readable.  

what on earth makes you think that?

> In most cases readability decisions are made by
> polling project developers where I work and have worked in the past.
> You have to go with something, why not the plurality, or majority?

This is in direct opposition to your anti-pragmatism post which
I read earlier this evening. 

For that matter, why not join the majority of people
who believe se/se is the basis of SP?





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                                 ` <01bddccc$98b2dda0$ca3aea9e@tom>
@ 1998-09-10  0:00                                                                   ` Tim Ottinger
  0 siblings, 0 replies; 510+ messages in thread
From: Tim Ottinger @ 1998-09-10  0:00 UTC (permalink / raw)


Nicholas Kitchener wrote:
> Complexity is in the mind of the developer - a system is not complex
> it just has a definition and exists.

I would argue completely to the contrary. I would say that obscurity
is in the mind of the developer, but that complexity is a very real
thing. It involves he number of entities in a system, and the number
of interconnections between them: explicit and implicit. If you were
to weight the complexity of a system, I'd consider all implicit 
interconnections between entities (modules and data items) to be
double the weight of all explicit ones, and the number of connections
to be double the weight of the number of entities.

Eventually we'd have to visit Brad Cox's idea of "surface area"
also. It's key to the way that we reduce *apparent* complexity.

Obscurity is how easy it is to understand functioning. If there
is a lot of apparent complexity, then obscurity results. But 
obscurity can result from other causes not related to complexity.

Let's try to to keep these two concerns separate. Obscurity is
subjective, but complexity is objective.

> One question - does the speed at which a developer can produce or
> modify a system affect the developer's perceiption of how complex
> the system is?

It certainly may affect his idea of how simple it is. It's more
familiarity than anything else, I think. Familiarity is absolutely
orthogonal to complexity. A programmer may find a complex but 
very familiar system easy to maintain. It's complex, but easy to
work with. 

There's more that goes into this, but complexity and
familiarity are major concerns!

> If the documentation, design are clearly described and the code is
> commented properly then I think you'll classify the problem as less
> complex than one where it's just you can uncommented code.

Not true. I'd consider it to be less obscure, though. They're
not the same thing at all.

> A very good point- I think that many of us have come up against this
> in a slightly different form too: managers and commercial bods who
> believe that they understand the internals of a system and then they
> speak to the client in a technical capacity.

Sure. It happens.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-10  0:00                                                             ` Tim Ottinger
@ 1998-09-10  0:00                                                               ` dewarr
  1998-09-11  0:00                                                                 ` prochak
  1998-09-12  0:00                                                                 ` Ell
  0 siblings, 2 replies; 510+ messages in thread
From: dewarr @ 1998-09-10  0:00 UTC (permalink / raw)


In article <35F74AEC.21982C2B@oma.com>,
  Tim Ottinger <ottinger@oma.com> wrote:
> Ell wrote:
> > But generally it is possible to get a plurality or majority to agree
> > on what is readable.
>
> what on earth makes you think that?
>
> > In most cases readability decisions are made by
> > polling project developers where I work and have worked in the past.
> > You have to go with something, why not the plurality, or majority?
>
> This is in direct opposition to your anti-pragmatism post which
> I read earlier this evening.
>
> For that matter, why not join the majority of people
> who believe se/se is the basis of SP?
>
>


For me, the reason it makes sense to simply take majority
votes on style issues is that consistency is THE most
important issue, much more important than the actual
decisions (it's like driving, it really doesn't matter if
you drive on the left or right, but it is really important
to agree -- this observation thanks to Tarski :-)

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                               ` sureshvv
@ 1998-09-10  0:00                                                                 ` prochak
  1998-09-11  0:00                                                                   ` Patrick Doyle
  1998-09-17  0:00                                                                 ` Matthew Heaney
  1 sibling, 1 reply; 510+ messages in thread
From: prochak @ 1998-09-10  0:00 UTC (permalink / raw)


In article <6t6shq$f53$1@nnrp1.dejanews.com>,
  sureshvv@hotmail.com wrote:
> In article <6t6b3m$30j8$1@prime.imagin.net>,
>   smize@imagin.net (Samuel Mize) wrote:
> >
> > One heuristic that is often helpful in improving clarity of expression
> > is to break up a long, complex sequence into shorter, well-structured
> > components.  This is true in English and in code.
> >
>
> Well said. The multi-return structure enables you to separate
> code in small  independent blocks, each of which may be examined
> and understood with less interference from surrounding blocks.
> The se-se structure creates large blocks, requiring more
> context information.

When followed religiously in a large block of code, the se-se rule
does lead to this kind of problem. It doesn't have to if the code
and language allows creating more functions/procedures to encapsulate
the pieces of that large code block. But that also can go too far
to where the main line of code is a sequence of procedure calls
and the procedures are grotesquely short (one liners).

A certain amount of this is the old maxim: everything in moderation.

>
> > That's the central intuition of "structured programming," as I
> > understand the term, which is in a broad sense.  Single entry/exit,
> > end-exit loops, and other constraints, are specific approaches to
> > defining the structures to be used.
> >
>
> Agreed. In this case, se-se is a good starting point. But the tree
> structure (as someone referred to it; i would be interested in a reference)
> IMHO, is superior in capturing this intent of structured programming
> (irresp. of if Dijkstra would approve of it).
>
> suresh
>
The tree structure can get out of hand also. If there are too many
exits in the code, then I'd begin to question the design there too.



I'm not sure who I agree with in this discussion. I understand the
central principle of structured programming to be: predictability.
Dijkstra and other theorists want se-se type code structures to be
able to derive proofs about the code. Programmers (me) look at it
as a way to know, when reading some code, where to look next when
coming across a GOTO statement. In unstructured code, I'm forced
to always do a linear search from the first line of the code listing.
In structured code, I expect everything to "flow downhill" so the
target must be later in the listing (except for well-defined loops,
which I know exists because something labeled it so at the loop
entry. ie the single entry is just as important as the single exit.)

Actually, writing that last line, I realized what is perhaps a better
way to state the structured programming principle:
all code structures have a WELL-DEFINED entry and a WELL-DEFINED exit.

So where necessary, there are early loop exits, there are multiple
returns within functions, and whereever else goto's are NEEDED.
But the goto's are not sprinkled thruout the code for arguements of
"efficiency" or "code reuse".

How do you know if it is WELL-DEFINED? That's what code reviews and
walkthru's and software inspections are for. There are no absolutes.
The code must fit the application, the department/company producing it,
and must be maintainable as needed. That last part is where the
predictability of the code structure pays off. As long as the previous
coders keep the same style thruout a program, I can learn it much
faster than if there is a jumble of styles (even if they all follow
the se-se rule!). It is not the multiple exits that are directly
harmful. In contrast, it is the well-defined structure that leads me
to know how it exits so I can concentrate on the conditional
clause which is application specific. I don't have to see the whole
routine every time.

Dijkstra may not agree with me, but goto's are not bad or good,
but arbitrary use of goto's is always bad.



--
Ed Prochak
Magic Interface, Ltd.
440-498-3702

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00               ` Charles Hixson
@ 1998-09-10  0:00                 ` Loryn Jenkins
  1998-09-17  0:00                 ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-10  0:00 UTC (permalink / raw)


> It has been claimed that Design By Contract (DBC) can be done entirely
> by comments and documentation.  I, personally, don't believe it.  It is
> my expectation that the routines with explicit pre-conditions and
> post-conditions would work as desired in the Eiffel environment, where
> the developer could have pre-conditions enabled while developing it, and
> only remove them (IN LAYERS!) when the final code was produced.  I don't
> think that this would work at all as well without support from the IDE.
> 
> Now it is true, that the failures of DBC in an environment that doesn't
> support it can be traced to the contract not being lived up to, but
> ENFORCEABILITY IS A PART OF THE CONTRACT.  In an environment that
> doesn't enforce the contract, violations will not be detected, and I
> don't know about you, but my programs always need to have the bugs
> cleaned out of them before they are ready for delivery.

Yes, of course it can. And yes, it would not nearly be as clean or easy
to do without the Eiffel environment support.

Having said that, Geoff Eldridge has used this style quite successfully
in Perl (as documentation only); Don Harrison has used it very
successfully in Ada (using Ada approximations pre-, post-conditions and
invariants); others have used it to good effect in C++.

It most certainly is a rigorous methodological approach to designing
software (and therefore is not specific to a language), but is greatly
helped by automated tool support.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-10  0:00                                                                 ` prochak
@ 1998-09-11  0:00                                                                   ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-09-11  0:00 UTC (permalink / raw)


In article <6t9d4k$tdt$1@nnrp1.dejanews.com>,  <prochak@my-dejanews.com> wrote:
>
>A certain amount of this is the old maxim: everything in moderation.

Hey, there's an argument for the "yes" vote if ever I heard one.  :-)

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00               ` duncan
@ 1998-09-11  0:00                 ` Jim Cochrane
  1998-09-11  0:00                   ` duncan
  0 siblings, 1 reply; 510+ messages in thread
From: Jim Cochrane @ 1998-09-11  0:00 UTC (permalink / raw)


In article <Ez0D7y.DCG@yc.estec.esa.nl>,  <duncan@yc.estec.esa.nlx> wrote:
>In article <6t4dmi$rhp@flatland.dimensional.com>,
>Jim Cochrane <jtc@dimensional.com> wrote:
>>Of course, if the conditions being checked in the code below are really
>>pre-conditions - that is, it can be considered a coding error that the
>>function is called with one of these conditions true, then it would be
>>better coded as:
>>
>>void Worker::do_something (Tree *top)
>>{
>>    assert (top != NULL && top->child != NULL && ...);
>>
>>    _error_code = really_do_something(top->child...->child);
>>    if (_error_code != 0) // or whatever value means non-error
>>    {
>>	_error_occurred = true;
>>    }
>>    else
>>    {
>>	_error_occurred = false;
>>    }
>>}
>>
>>Where the assertion would be documented as a pre-condition of the function
>>specification.
>>
>>Then a client would do:
>>
>>    // ensure the pre-condition for root
>>    worker.do_something (root);
>>    if (worker.error_occurred())
>>    {
>>	//report/handle the error with worker.error_code() ...
>>    }
>>
>>[Changed to an OO style, since the discussion is occurring on OO
>>newsgroups.]
>>
>>The difference, of course, is that the checking for null pointers becomes
>>part of the function specification rather than being explicitely coded (the
>>assertion will probably be turned of in the production release).  This is
>>the difference between design by contract and defensive coding.
>
>
>The first 'Commandments' for coding were:
>1. Thou shalt use single entry/single exit routines.
>2. Thou shalt guarantee all pointers before dereferencing.
>
>As mentioned before, the system was made up of 7 sub-systems,
>all running as separate processes, and communicating via
>shared memory. Hence there was a lot of 'redundant' checking.

I understand that things are not black and white in the "real world" and
that compromises sometimes need to be made.  (For one thing, the fact that
C was used here, which has no exception handling mechanism, is a factor in
what path to take.)  However, I think if I was in this situation, I would
ask a few questions, such as:

What are the error handling requirements in the case where a pointer is null?
If one of these errors does occur, is this a coding error, a bug?
If so, where would the source of this bug likely be?
If one of these errors occurred, will the program still be able to run
correctly?  In other words, can the program recover from the error, or
should it report the error and terminate in order to not cause a problem,
such as corrupted data?
Who (what module(s) or routine(s)) is responsible for building the tree so that
the required nodes were not null?  If the answer is that no-one was
responsible, can the design be changed so that this responsibility can be
assigned to a particular module or modules?
Who (what module or routine) is responsible for setting things right (if
that is possible) if an error does occur?
Can the fact that a certain depth of the tree is required be considered a
contract that must be established by some (direct or indirect) client
routine, even if it is in another process?
Can the design be changed so that, even if assertions cannot reasonably be
used, the structure is less awkward?  (At the very least, it seems, the
original "do_something" function could be structured to check for the error
and report it first, rather than nesting the check of each node, as the
original did:

    if (null_descendant (root, required_depth, &null_depth))
    {
	//report that error occurred at depth null_depth and deal with it
    }
    else
    {
        really_do_something(top->child...->child);
	...
    })

I suppose my main point is that rather than simply following an edict, it
is important to ask questions like these to find out if there might be a
better way of doing things.  If this was done, and the decision to proceed
as you described was done for a good reason, then that is basically all you
can ask.

>
>Yes, you could use 'assert' but seeing as the error checking
>had to go into the production code anyway, there was little point.
>
>Yes, the pre-conditions could have been checked before the
>routine was actually called, but now you have moved knowledge
>of where in the tree data structure the relevant information
>lives into the caller. When you consider that some of the paths
>through the tree involved following 6 or more pointers, that's
>a lot of encapsulation and data hiding that has been lost.
>All of the code for determining which error has occurred has
>also been moved from the routine to the caller...
>
>These are all tradeoffs that need to be made. I believe that
>there are various 'good practices' which should be included
>in an ideal world, but until I find employment in the ideal
>world, it's going to be a case of making these tradeoffs, and
>some of the 'good practices' may not be applied in all cases.
>
>Of course it helps if you are aware of the 'good practices'
>in the first place so that you know what you are missing.

Definitely - both because you will likely be able to apply these practices
in the future, and, even in the case where such a compromise is made, this
knowledge will still allow you to do a better job (write more correct code,
etc.) within the context of the existing environment.

>
>Cheers
>Duncan
>
>This is my article, not my employer's, with my opinions and my disclaimer!
>--
>Duncan Gibson, ESTEC/YCV, Postbus 299, 2200AG Noordwijk, The Netherlands
>Tel: +31 71 5654013   Fax: +31 71 5656142  Email: duncan@yc.estec.esa.nlx
>To avoid junk email my quoted address is incorrect. Use nl instead of nlx.


-- 
Jim Cochrane
jtc@dimensional.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-11  0:00                 ` Jim Cochrane
@ 1998-09-11  0:00                   ` duncan
  0 siblings, 0 replies; 510+ messages in thread
From: duncan @ 1998-09-11  0:00 UTC (permalink / raw)


In article <6taqch$42b@flatland.dimensional.com>,
Jim Cochrane <jtc@dimensional.com> wrote:
>
>I understand that things are not black and white in the "real world" and
>that compromises sometimes need to be made.  (For one thing, the fact that
>C was used here, which has no exception handling mechanism, is a factor in
>what path to take.)  However, I think if I was in this situation, I would
>ask a few questions, such as:
>
>What are the error handling requirements in the case where a pointer is null?
>If one of these errors does occur, is this a coding error, a bug?
>If so, where would the source of this bug likely be?
>If one of these errors occurred, will the program still be able to run
>correctly?  In other words, can the program recover from the error, or
>should it report the error and terminate in order to not cause a problem,
>such as corrupted data?
>Who (what module(s) or routine(s)) is responsible for building the tree so that
>the required nodes were not null?  If the answer is that no-one was
>responsible, can the design be changed so that this responsibility can be
>assigned to a particular module or modules?
>Who (what module or routine) is responsible for setting things right (if
>that is possible) if an error does occur?
>Can the fact that a certain depth of the tree is required be considered a
>contract that must be established by some (direct or indirect) client
>routine, even if it is in another process?
>Can the design be changed so that, even if assertions cannot reasonably be
>used, the structure is less awkward?  (At the very least, it seems, the
>original "do_something" function could be structured to check for the error
>and report it first, rather than nesting the check of each node, as the
>original did:
>
>    if (null_descendant (root, required_depth, &null_depth))
>    {
>	//report that error occurred at depth null_depth and deal with it
>    }
>    else
>    {
>        really_do_something(top->child...->child);
>	...
>    })
>
>I suppose my main point is that rather than simply following an edict, it
>is important to ask questions like these to find out if there might be a
>better way of doing things.  If this was done, and the decision to proceed
>as you described was done for a good reason, then that is basically all you
>can ask.


I agree with everything you say.

The system I've been describing was one I worked on 10 years
ago, but it taught everyone concerned many valuable lessons.

Unfortunately, we inherited all of this code (in C) from a
previous programming group in a different country, so all of
the decisions had already been made and we had to go along
with the existing style.

With the usual tight schedule for such things, it was simply
not possible to revisit the original analysis and design
decisions.

As I've stressed before, the system consisted of 7 processes
communicating via shared memory, and I believe that the
obsessive checking of all pointers stemmed from paranoia
about which process could update what and when.

As it turned out, the project was canned after our group had
been working on it for a year, mainly because it was just
too slow, and just for the hell of it someone instrumented
some of of the code before all 4000+ source files were wiped
from disk and we moved on to other things.  He discovered
that the paranoia was not well founded.  He discovered that
only two out of the seven processes actually had need to
access the data simultaneously, and even then they took
copies on which to work and derived results into their own
area of shared memory. No other processes could run until
these two completed, so there was no chance of incomplete
data being read prematurely. A lot of the code was simply
over-engineered to take into account something that was not
likely to happen.  All access to the shared memory was
controlled by semaphores. All pointer access was checked.
No wonder it ran so slowly.

Maybe earlier designs were more likely to suffer from
problems - it ran on custom built hardware until we got our
hands on it - or it was considered that even a crash
resulting from the unlikely was still not acceptable.

The whole purpose of this string of articles is to illustrate
that sometimes it is not always possible to follow all of the
'good practices' that you have learned, and that there will
always be compromises.


Cheers
Duncan

This is my article, not my employer's, with my opinions and my disclaimer!
--
Duncan Gibson, ESTEC/YCV, Postbus 299, 2200AG Noordwijk, The Netherlands
Tel: +31 71 5654013   Fax: +31 71 5656142  Email: duncan@yc.estec.esa.nlx
To avoid junk email my quoted address is incorrect. Use nl instead of nlx.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-10  0:00                                                               ` dewarr
@ 1998-09-11  0:00                                                                 ` prochak
  1998-09-12  0:00                                                                 ` Ell
  1 sibling, 0 replies; 510+ messages in thread
From: prochak @ 1998-09-11  0:00 UTC (permalink / raw)


In article <6t937n$ep6$1@nnrp1.dejanews.com>,
  dewarr@my-dejanews.com wrote:
> In article <35F74AEC.21982C2B@oma.com>,
>   Tim Ottinger <ottinger@oma.com> wrote:
> > Ell wrote:
> > > But generally it is possible to get a plurality or majority to agree
> > > on what is readable.
> >
> > what on earth makes you think that?
> >
> > > In most cases readability decisions are made by
> > > polling project developers where I work and have worked in the past.
> > > You have to go with something, why not the plurality, or majority?
> >
> > This is in direct opposition to your anti-pragmatism post which
> > I read earlier this evening.
> >
> > For that matter, why not join the majority of people
> > who believe se/se is the basis of SP?
> >
> >
>
> For me, the reason it makes sense to simply take majority
> votes on style issues is that consistency is THE most
> important issue, much more important than the actual
> decisions (it's like driving, it really doesn't matter if
> you drive on the left or right, but it is really important
> to agree -- this observation thanks to Tarski :-)
>

Thank goodness somebody else sees the important issue here.
As a department or project team, pick a style and stick with it.
As an individual (especially a contractor like me), be flexible
enough to pick up and use the client's style. To paraphrase an
internet programming maxim: be strict in what you write, but
flexible in what you read.

(see another post of mine on the se-se issue about consistancy)


> -----== Posted via Deja News, The Leader in Internet Discussion ==-----
> http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum
>


--
Ed Prochak
Magic Interface, Ltd.
440-498-3702

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-05  0:00                                                           ` Loryn Jenkins
  1998-09-09  0:00                                                             ` Samuel Mize
@ 1998-09-11  0:00                                                             ` Robert I. Eachus
  1998-09-12  0:00                                                               ` Loryn Jenkins
  1 sibling, 1 reply; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-11  0:00 UTC (permalink / raw)


In article <35F06D6A.91A3D34E@s054.aone.net.au> Loryn Jenkins <loryn@s054.aone.net.au> writes:

 > It is much more to the point that language is an instrument which 
 > *construes reality*. It is quite inapropriate to claim that thoughts can
 > be organised outside of the semiotic systems that construct it.

   Many of the regular contributers to this group will disagree with
this statement, some of us more than others.  There are people who
"think within the lines," and cannot possibly have a thought which
cannot be expressed in their native tounge.  Exceptional people can
think new thoughts and extend the language to fix.  This produces
progress and also evolution of languages.

   But the reason I reacted to this statement is that compiler
designers and especially language developers use techniques which
allow them to use one language to manipulate another.  The simplest
example of this is BNF, used to define the grammars for many
programming languages.  During the debate in Salem over the notation
to be used in Ada 9X to define classes, each side had only to use one
or two slides to define their proposal, the rest of the time could be
used to describe the anticipated effects of the notation on the
thinking of the programmers using it.  (Neither proposal was "more
powerful," both could be used to create exactly the same class
structures, the argument was about the impact of the chosen notation
on the thinking processes of the users.)

   In fact, many of the debates that made it to one of the workshops
were exactly in this style, such as the names of the operations in
Ada.Finalization.  (Result, Initialize, Adjust, Finalize.)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                         ` Ray Gardner
@ 1998-09-11  0:00                                                           ` Robert I. Eachus
  0 siblings, 0 replies; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-11  0:00 UTC (permalink / raw)



   Robert Dewar said:

   > There is no "founder" of structured programming. The
   > idea of structured programming is an old one, well known
   > to anyone writing Algol-60 from very early on. Various
   > people have produced specific rules concerning their
   > idea of how to adapt this principle to particular
   > programming languages (e.g. the "structured period"
   > for ANSI-74 COBOL), but I would not say it is reasonable
   > to regard anyone as "founding" structured programming.

   Anecdotal, but worth noting.  In the mid-sixties when the Algol-60
standard was being reviewed, Wirth came up with a "clean" proposal
known as Algol-W.  This lost to the very complex language which became
Algol-68.  But along the way there was an implementation of Algol-W
created for the IBM 360 series, origianlly written I think in 1967.

   Much later 1976? I used this compiler to create a parser for a
programming languages course.  I found it extremely frustrating that
the compiler printed a warning message "Is this goto really
necessary?" for each of five gotos which implemented "panic mode"
error recovery in the (recursive descent) parser.  Today, of course I
could use exceptions and appropriately located handlers to do the same
thing. 

   I think that the warning message was original equipment on the
compiler, someone else may know.  But more importantly, I saw this
message for the first time in that parser, although I had compiled
many programs using that compiler, both programs I had earlier written
in Algol-60, and programs targeted to that compiler.  So I know that
when I programmed in Algol-60, I just plain did not use gotos.  Not
because I was taught that way--heck my first program was written in
SOAP-IV for an IBM-650--but because Algol-60 discouraged gotos.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-12  0:00                                                               ` Loryn Jenkins
@ 1998-09-11  0:00                                                                 ` alan walkington
  1998-09-12  0:00                                                                   ` Loryn Jenkins
  0 siblings, 1 reply; 510+ messages in thread
From: alan walkington @ 1998-09-11  0:00 UTC (permalink / raw)


Loryn:

Ahh, but you DID post it.  (And I suppose we are now WAY off topic for this
NG :-) )

>One day, if you're interested, I'll try to describe something like this
>in terms that doesn't carry a whole lot of linguistic baggage.

Within the context of your first post, that is not possible.

> It is much more to the point that language is an instrument which
> *construes reality*. It is quite inapropriate to claim that thoughts can
> be organised outside of the semiotic systems that construct it.

ANY terms you use will be organized withing the semiotic system which is
used to construe them, and as such will carry their own inevitible
linguistic baggage.

Ain't  this fun?

Alan Walkington
Sr. Software Engineer
U.D.L.P. San Jose
-----------------------------------------------------
home: walky@netmagic.net
work: alan_walkington@udlp.com







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-06  0:00                                                                 ` Robert Martin
  1998-09-06  0:00                                                                   ` Ell
@ 1998-09-11  0:00                                                                   ` Robert I. Eachus
  1998-09-12  0:00                                                                     ` Patrick Logan
  1 sibling, 1 reply; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-11  0:00 UTC (permalink / raw)


In article <6sur5m$n9o$1@hirame.wwa.com> "Robert Martin" <rmartin@oma.com> writes:

 > Dijkstra was quite specific about it.  He drew dotted boxes around the flow
 > charts that depicted the four possible control structures, and showed one
 > line crossing through the top into the control structure, and another
 > leaving the control structure and crossing the dotted line at the bottom.

    Exactly, and exactly what I was talking about.  The evil is having
two lines into the box, or two lines out.  But I also contend, and I
certainly never heard anything to the contrary from Dijkstra, that a
procedure WHICH IMPLEMENTS A SINGLE CONTROL CONSTRUCT, is a perfect
realization of Dijkstra's discipline.  In fact, one of my favorite
Dijkstra quotes is, "I have a small head and I must live within it."
This was said in a discussion of exactly these issues.

    During the summer of 1980, GE and RPI sponsored a two-day
symposium on software engineering.  The conference was shortly after
the "Green is Ada" announcement.  After a session where Dijkstra
presented some of his thoughts on software engineering a group
including Dijkstra were discussing the control structures in Red,
Blue, Green and Yellow.  I don't remember exactly which control
structure from which language started the discussion.  But Dijkstra
repeated his statement from the session and went on to explain that
what he didn't like about the power of some of these constructs was
that they allowed building single control constructions that had
dozens of potential paths through them.  One of the proposals for how
to limit the complexity was to basically draw a line through the flow
chart and count threads of control that were crossed.  Someone said
"One is perfect, two is fine, and three is spaghetti."  Everyone
laughed, including Dijkstra, and we went on to other topics.

    Early exits help avoid that definition of spaghetti, while some of
the se/se proposals we have seen egregiously violate it.  And I think
that is a perfect summation of what structured programming is about.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-11  0:00                                                             ` Robert I. Eachus
@ 1998-09-12  0:00                                                               ` Loryn Jenkins
  1998-09-11  0:00                                                                 ` alan walkington
  0 siblings, 1 reply; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-12  0:00 UTC (permalink / raw)


Robert I. Eachus wrote:
> 
> In article <35F06D6A.91A3D34E@s054.aone.net.au> Loryn Jenkins <loryn@s054.aone.net.au> writes:
> 
>  > It is much more to the point that language is an instrument which
>  > *construes reality*. It is quite inapropriate to claim that thoughts can
>  > be organised outside of the semiotic systems that construct it.
> 
>    Many of the regular contributers to this group will disagree with
> this statement, some of us more than others.


Grin :) We're talking at cross-purposes here.

Given that I don't want to spend the time explaining my philosophical
position on this (ie getting you guys up to speed with linguistics,
etc.), I shouldn't have posted it.

But I may say that your counter-example isn't a counter-example.

One day, if you're interested, I'll try to describe something like this
in terms that doesn't carry a whole lot of linguistic baggage.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-11  0:00                                                                   ` Robert I. Eachus
@ 1998-09-12  0:00                                                                     ` Patrick Logan
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-09-12  0:00 UTC (permalink / raw)


In comp.object Robert I. Eachus <eachus@spectre.mitre.org> wrote:

: One of the proposals for how to limit the complexity was to
: basically draw a line through the flow chart and count threads of
: control that were crossed.  Someone said "One is perfect, two is
: fine, and three is spaghetti."  Everyone laughed, including
: Dijkstra, and we went on to other topics.

: Early exits help avoid that definition of spaghetti, while some of
: the se/se proposals we have seen egregiously violate it.  And I
: think that is a perfect summation of what structured programming is
: about.

Maybe you also have to draw a line from top to bottom and count the
number of returns?

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-10  0:00                                                               ` dewarr
  1998-09-11  0:00                                                                 ` prochak
@ 1998-09-12  0:00                                                                 ` Ell
  1998-09-12  0:00                                                                   ` dewarr
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-09-12  0:00 UTC (permalink / raw)


In comp.object dewarr@my-dejanews.com wrote:
:
:   Tim Ottinger <ottinger@oma.com> wrote:
:>
:> Ell wrote:
:> >
:> > But generally it is possible to get a plurality or majority to
:> > agree on what is readable.

:> what on earth makes you think that?

Because I see it happening in all kinds of callective decision making
groups.  For goodness sake you don't?  The bowling team, co-workers headed
out to blow steam off on Friday, church groups, tour groups, band members,
mob groups, etc, etc.  People frequently able to reach majority
decisions and if not there's almost always a plurality for one
position or another.

You all's view that we can know little to nothing for sure, and that one
view is as good as another is so hackerish.  It's such an on the knees
appeal to accept unbridled and in many cases extremely harmful
individulism.

:> > In most cases readability decisions are made by
:> > polling project developers where I work and have worked in the past.
:> > You have to go with something, why not the plurality, or majority?
:>
:> This is in direct opposition to your anti-pragmatism post which
:> I read earlier this evening.

How?  The pragmatist position is the super individualistic one.

:> For that matter, why not join the majority of people
:> who believe se/se is the basis of SP?

What majority?  Where?  Most on comp.object seem to think it means
navigating with discipline - using procedure calls to "meld"  multiple
returns into a single one.  I.e. avoiding one way, non-round trip
navigation, entering a block of code from the start.

: For me, the reason it makes sense to simply take majority
: votes on style issues is that consistency is THE most
: important issue, much more important than the actual
: decisions (it's like driving, it really doesn't matter if
: you drive on the left or right, but it is really important
: to agree

Wrong headed pragmatism, pure and simple.

It's ludicrous on the face of it to say all that matters is making a
decision, not the content of the decision itself.  That's like saying it's
more important that we all decided to poison ourselves, rather than
questioning the whole decision. 

 -- this observation thanks to Tarski :-)

I'm not surprised.  I would be ashamed of this not happy.

Elliott
-- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-12  0:00                                                                 ` Ell
@ 1998-09-12  0:00                                                                   ` dewarr
  1998-09-12  0:00                                                                     ` Charles Hixson
  1998-09-14  0:00                                                                     ` Ell
  0 siblings, 2 replies; 510+ messages in thread
From: dewarr @ 1998-09-12  0:00 UTC (permalink / raw)


In article <X4tK1.6$VP3.188022798@newsreader.digex.net>,
  Ell <ell@access1.digex.net> wrote:
>
>: For me, the reason it makes sense to simply take majority
>: votes on style issues is that consistency is THE most
>: important issue, much more important than the actual
>: decisions (it's like driving, it really doesn't matter if
>: you drive on the left or right, but it is really important
>: to agree>>>
>
>Wrong headed pragmatism, pure and simple.
>
>It's ludicrous on the face of it to say all that matters is making a
>decision, not the content of the decision itself.  That's like saying it's
>more important that we all decided to poison ourselves, rather than
>questioning the whole decision.

What on earth has poisoning ourselves got to do with the
matter at hand, and what on earth makes you think I was
suggesting that the majority decision is right for all
things. If you must bring in totally irrelevant details
like this, one can only assume you have no real argument!

The issue I was raising was purely with respect to style
issues. I find most arguments about style pretty silly.
They are typically one person who is sure they are right
but have no data to back up their opinions arguing with
another person who argues something else and is sure they
are right, but also has no data.

I will repeat that what I *really* find important is
consistency. When a team writes a program, it should be
impossible to tell one person's style from another. This
has many advantages, it means that it is much easier to
read the code, since you only have to adjust to one style,
and that code is more interchangable because people don't
feel they own pieces of the code. Egotistical code
ownership is definitely a negative factor in achieving
high and reliable productivity from a programming group.

That being said, to achieve consistency, you need to discuss
various issues for sure, a majority decision taken without
discussion is an uninformed decision, but after that decision
using a majority vote is just fine, and everyone needs to
agree in advance to be bound by this decision. This means
that everyone has to agree in advance that consistency is
more important than their pet programming style.

This is particularly useful when the argument is about a
totally idiotic issue like what style of {} to use in C
code, or how many characters to indent. Of course some of
these simple things can be handled by tools (and most
certainly can be checked by a tool), but more complex
style rules are not always susceptible to tool checking,
because all but the simplest kind of rules tend to have
legitimate exceptions.

It is dealing with these exceptions that often causes trouble.
For example, people know that gotos and spaghetti code are
a bad thing, but they wouldn't recognize what is and what
is not spaghetti code if it was wound around their fork, so
they have to fall back on an absolute rule of no gotos.

In any case the important thing for any project, really just
a *starting* point towards achieving a well managed project,
is to agree on a complete set of style guidelines/rules for
coding. I am always amazed to find serious mission critical
projects being coded in an anarchic style in environments
where programmers would not be willing to touch code written
by their colleages. I find that completely untenable.


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-12  0:00                                                                   ` dewarr
@ 1998-09-12  0:00                                                                     ` Charles Hixson
  1998-09-13  0:00                                                                       ` dewarr
  1998-09-14  0:00                                                                     ` Ell
  1 sibling, 1 reply; 510+ messages in thread
From: Charles Hixson @ 1998-09-12  0:00 UTC (permalink / raw)


dewarr@my-dejanews.com wrote:
> 
> In article <X4tK1.6$VP3.188022798@newsreader.digex.net>,
>   Ell <ell@access1.digex.net> wrote:
> >
> >: For me, the reason it makes sense to simply take majority
> >: votes on style issues is that consistency is THE most
> >: important issue, much more important than the actual
> >: decisions (it's like driving, it really doesn't matter if
> >: you drive on the left or right, but it is really important
> >: to agree>>>
> >
> >Wrong headed pragmatism, pure and simple.
> >
> >It's ludicrous on the face of it to say all that matters is making a
> >decision, not the content of the decision itself.  That's like saying it's
> >more important that we all decided to poison ourselves, rather than
> >questioning the whole decision.
> 
> What on earth has poisoning ourselves got to do with the
> matter at hand, and what on earth makes you think I was
> suggesting that the majority decision is right for all
> things. If you must bring in totally irrelevant details
> like this, one can only assume you have no real argument!
> 
Some style choices ARE important, but in most agreement is more
important than which style, and in some agreement is the only matter of
importance (and in some, even that isn't important).
I haven't seen anybody defending spaghetti code recently.  This is a
(practically universal) style (different things were being optimised),
but agreement wasn't sufficient to maintain it.  Whether or not the
names of constants were written in all-caps is a style (actually, it's
one that I, personally, don't like).  It is the majority style in some
camps of the computer community (C descendant languages, particularly). 
I don't think that it's important as long as that form is not used by
anything else.  Any good text editor do a set of global transforms on
the code to match the style of the person who is using it, with NO
IMPACT on anything else (actually, if the header files are shared with
people using differing coding styles, then one set of the constant's
names would need to be defined in terms of the other set of the
constant's names (e.g. #define stdIn STDIN ), but this would only be
needed in languages where the case of the variable name is a semantic
marker, so Ada, for example, wouldn't need a comparable statement
change).




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-11  0:00                                                                 ` alan walkington
@ 1998-09-12  0:00                                                                   ` Loryn Jenkins
  0 siblings, 0 replies; 510+ messages in thread
From: Loryn Jenkins @ 1998-09-12  0:00 UTC (permalink / raw)


> ANY terms you use will be organized withing the semiotic system which is
> used to construe them, and as such will carry their own inevitible
> linguistic baggage.
> 
> Ain't  this fun?

Yes: That's why I studied linguistics! And I do agree with your
estimation; that was my point exactly.

Loryn Jenkins




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-12  0:00                                                                     ` Charles Hixson
@ 1998-09-13  0:00                                                                       ` dewarr
  0 siblings, 0 replies; 510+ messages in thread
From: dewarr @ 1998-09-13  0:00 UTC (permalink / raw)


In article <35FB19F8.D3AAEC2D@earthlink.net>,
  Charles Hixson <charleshixsn@earthlink.net> wrote:
> dewarr@my-dejanews.com wrote:
> >
> Some style choices ARE important, but in most agreement is more
> important than which style, and in some agreement is the only matter of
> importance (and in some, even that isn't important).
> I haven't seen anybody defending spaghetti code recently.  This is a
> (practically universal) style (different things were being optimised),
> but agreement wasn't sufficient to maintain it.  Whether or not the
> names of constants were written in all-caps is a style (actually, it's
> one that I, personally, don't like).  It is the majority style in some
> camps of the computer community (C descendant languages, particularly).
> I don't think that it's important as long as that form is not used by
> anything else.  Any good text editor do a set of global transforms on
> the code to match the style of the person who is using it, with NO
> IMPACT on anything else (actually, if the header files are shared with
> people using differing coding styles, then one set of the constant's
> names would need to be defined in terms of the other set of the
> constant's names (e.g. #define stdIn STDIN ), but this would only be
> needed in languages where the case of the variable name is a semantic
> marker, so Ada, for example, wouldn't need a comparable statement
> change).
>

It is incorrect in my view to think that automatic
reformatters can solve the problem.

First, there are many style rules that are very difficult
to automate, especially if they all have an implied "but
this does not apply in special cases, and you need human
intelligence to determine those cases".

Second, if people continue to use their own styles, you
still have the phenomenon of balkanization of the coding
effort, and people prefer to use their own style. Even if
you have a totally invertible transformer, which is in fact
difficult to do, for example, the all CAPS style is not
automatically convertible to mixed case:

It is easy to go from UNIX_Package_Interface
to UNIX_PACKAGE_INTERFACE.

But it is harder work to go in the opposite direction, you
need dictionaries etc.

even if you have a totally invertible transformer, people do
not feel happy working that way. They tend to maintain
private copies of their own code in their own style, and
grudgingly convert them to the offical style, feeling that
they are destroying them

Third, automatic transformers are definitely not good at
dealing with conventions for the layout of comments, since
these particularly, being natural language dependent have
lots of exceptions.

Fourth, since so many style rules do have exceptions, unless
everyone understands and internalizes the style rules, they
do not gather the understanding that is necessary to know
when exceptions apply.

All in all, between the two models:

 1. Everyone in the team uses the same style, and that is
    what everyone becomes familiar with (it is amazing when
    you switch styles, how easy it is to get used to a new
    style -- when I started on the GNAT project, I preferred
    the Ada 83 style of ALL_UPPER_CASE with underscores,
    primarily because of the nice automatic separation of
    identifier names in comments, but the clear majority of
    programmers on the GNAT project was opposed to this style
    and now I cannot imagine ever liking it, compared to
    All_Upper_Case (postscript, I can't imagine every getting
    to like AllUpperCase, but I expect I would get used to
    it if I had to).

2.  Everyone uses their own style, and automatic tools are
    used to get some semblance of consistency in the official
    checked in sources.

I think 1 is FAR preferable. Not only does 2 result in real
technical problems, e.g. preparing a quick patch to solve a
particular bug, but it results in a far less effective level
of social cooperation and team cohesion, important factors
for the production of quality software.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-12  0:00                                                                   ` dewarr
  1998-09-12  0:00                                                                     ` Charles Hixson
@ 1998-09-14  0:00                                                                     ` Ell
  1 sibling, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-14  0:00 UTC (permalink / raw)


Ell <ell@access1.digex.net> wrote:

>: For me, the reason it makes sense to simply take majority
>: votes on style issues is that consistency is THE most
>: important issue, much more important than the actual
>: decisions (it's like driving, it really doesn't matter if
>: you drive on the left or right, but it is really important
>: to agree

>Wrong headed pragmatism, pure and simple.
>
>It's ludicrous on the face of it to say all that matters is making a
>decision, not the content of the decision itself.  That's like saying
>it's more important that we all decided to poison ourselves, rather than
>questioning the whole decision. 
>
> -- this observation thanks to Tarski :-)
>
>I'm not surprised.  I would be ashamed of this not happy.

Whoops sorry folks.  I hadn't read that this was referring to "style".
While I very much do think there are style basics that should be adhered
to, I see where wide latitude should often be given style decisions - as
long as for any given decision it applies project wide.  There is the much
vaunted "consistency"  in this area.    :-}

Elliott
 -- 
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
         "The domain object model is the foundation of OOD."
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                 ` <gio+van+no+ni+8-0309982225160001@dialup62.tlh.talstar.com>
@ 1998-09-15  0:00                                                   ` mfinney
  0 siblings, 0 replies; 510+ messages in thread
From: mfinney @ 1998-09-15  0:00 UTC (permalink / raw)


In <gio+van+no+ni+8-0309982225160001@dialup62.tlh.talstar.com>, gio+van+no+ni+8@tal+star+spam.com (Giovanni 8) writes:

>"[T]he air force estimates that it will require 25% of the
> country's entire 18-25 year old population to maintain all
> its software systems by the year 2000.  [H]igh-quality
> software is difficult to develop... most software efforts
> of any magnitude are fraught with problems & failures &
> that software projects usually take longer to complete &
> cost more than planned." --- Carma McClure 1992
> _The 3 Rs of Software Automation_ pg 5 (citing Eric Bush
> 1988 "A CASE for Existing Systems" _Language Technology
> White Paper_ pg 27)

Clearly the only solution is to abolish the air force! <g>


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                       ` <gio+van+no+ni+8-1609980026290001@dialup26.tlh.talstar.com>
@ 1998-09-16  0:00                                                         ` Nick Leaton
  0 siblings, 0 replies; 510+ messages in thread
From: Nick Leaton @ 1998-09-16  0:00 UTC (permalink / raw)


Giovanni 8 wrote:
> 
> > nickle wrote:
> > So lets say the loop calculates a square root.  What should
> > "do this" and "do that" do?...  Do you want to rewrite square
> > root for each case?
> 
> Try for a less simplistic example, please.
> 
> Part of my point is that the called function (Get, in the
> example I was following-up to) does its job well, has one
> or 2 different kinds of error values, & n "successful" return
> values.  Get, however, "knows" little of the environment, the
> context, from which it is called.  That's fine, but it means
> that there are things it cannot handle with an eye to that
> context.  The instant routine, which calls Get, does "know"
> that context, and needs to do a number of different things
> depending on the results of the Get, some having to do with
> error conditions of one sort or another, and others having
> to do with "normal" conditions, all to be dealt with in
> the context of the current context, in the current function,
> in the current loop.

But again what if I don't want to know all of the different things?
The Get routine assumes that you do want to know all. Design by
contract  and command query separation makes life much simpler. First,
any query doesn't modify the external view of an object. The procedure
in your 'get' feature is modifying the object, its doing some work.
Splitting it into a procedure to do the work, and a set of queries to
examine the results makes life simple. Then you can add preconditions,
such as not less than zero in the square root case to make sure that the
caller behaves. If they don't then behaviour is undefined, but would
raise an exception. Its a bug after all. Sounds hard, but would you
expect your program to fix itself?

Nick

-- 

Nick




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                                   ` <gio+van+no+ni+8-1609980034390001@dialup26.tlh.talstar.com>
@ 1998-09-16  0:00                                                                     ` Biju Thomas
  1998-09-17  0:00                                                                       ` dewarr
  1998-09-17  0:00                                                                       ` Gerry Quinn
  0 siblings, 2 replies; 510+ messages in thread
From: Biju Thomas @ 1998-09-16  0:00 UTC (permalink / raw)


Giovanni 8 wrote:
> 
> > Gerry Quinn wrote:
> >> adam wrote:
> >> Sigh... does anyone *try* to write spaghetti code?
> >> The thing is, someone who's inexperienced and hasn't read
> >> enough code to know whether code is readable or not, is
> >> certainly capable of writing unreadable, convoluted code
> >> without using GOTO.
> 
> > I agree - in fact I would argue that if you are carrying a
> > flag for deciding when to exit, the flag is part of the
> > flow of control - with all the potential pasta that entails.
> 
> Spaghetti code is in the eye of the beholder.
> 
> Some people find jumps or gotos, written in their own
> particular style, to be much more elegant and clear
> than the so-called control structures.  Others really
> like flags popping up in one place & then not being
> seen through vast piles of listing until, layers removed,
> they are used again (even in a different context with
> different conceptual significance for the values of
> the flag).  I've seen people, brows furrowed, puzzled
> over code that was the epitome of structured design,
> who could follow the jumps of assembly language with
> ease.

Reminds me of what Dijkstra told about the effect of COBOL and BASIC on
minds:

"The use of COBOL cripples the mind; its teaching should, therefore, be
regarded as a criminal offense."

"It is practically impossible to teach good programming style to
students that have had prior exposure to BASIC; as potential programmers
they are mentally mutilated beyond hope of regeneration"

Biju Thomas




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00             ` duncan
@ 1998-09-16  0:00               ` Matthew Heaney
  1998-09-17  0:00                 ` Reimer Behrends
  0 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-16  0:00 UTC (permalink / raw)


duncan@yc.estec.esa.nlx writes:

> One issue which I haven't yet seen addressed in this thread (but then
> our news feed is particularly patchy) is abnormal flow of control.
> 
> As far as I can see, the single entry/single exit paradigm assumes
> that there is a simple flow of control, through the code as you can
> see it. So far, nobody has made any comment on "abnormal" flow of
> control, such as interrupts, multi-threading, and what might be more
> interesting in these news groups, exceptions.

This has been discussed wrt resource management.

Robert Martin argued against early returns (or middle-exit loops) by
stating that you might forget to release a resource, if you return
early.  

I gave the counter-example that the resource management problem should
be solved another way, by using a deconstructor (C++) or a controlled
type (Ada95).  I based my arguement on the fact that this is what you
should do no matter what, because of the presence of exceptions.

Stroustrup calls this idiom "resource acquistion is initialization."





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-17  0:00                                                                         ` Matthew Heaney
@ 1998-09-16  0:00                                                                           ` Tim Ottinger
  0 siblings, 0 replies; 510+ messages in thread
From: Tim Ottinger @ 1998-09-16  0:00 UTC (permalink / raw)


Matthew Heaney wrote:
> I just got back from a business trip, and got about halfway through that
> other classic, A Discipline of Programming (Prentice-Hall, 1976).  Great
> stuff, although I recommend that those unfamiliar with the predicate
> transformer technique start with David Gries' Science Of Programming.

Maybe we should have a regular feature here called 'what are you
reading
this week'? 

Thanks for the recommendation. I may follow up on that one.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-17  0:00                                                                       ` Gerry Quinn
@ 1998-09-17  0:00                                                                         ` dewarr
  1998-09-18  0:00                                                                           ` Gerry Quinn
  0 siblings, 1 reply; 510+ messages in thread
From: dewarr @ 1998-09-17  0:00 UTC (permalink / raw)


In article <6tqvji$f0k$2@news.indigo.ie>,
  gerryq@indigo.ie (Gerry Quinn) wrote:
> In article <35FFE58C.5727@ibm.net>, bijuthom@ibm.net wrote:
>
> >Reminds me of what Dijkstra told about the effect of COBOL and BASIC on
> >minds:
> >
> >"The use of COBOL cripples the mind; its teaching should, therefore, be
> >regarded as a criminal offense."
> >
> >"It is practically impossible to teach good programming style to
> >students that have had prior exposure to BASIC; as potential programmers
> >they are mentally mutilated beyond hope of regeneration"
> >
>
> One suspects Dijkstra was a poor teacher.
>


Oh goodness, if "one" suspects that, one sure does not know
what one is talking about :-)

EWD is a brilliant teacher. I well remember a great evening
in Amsterdam, when he met my wife for the first time, and
gave a quite marvelous demonstration with her of how to
teach about trans-Cantorian infinities in a clear way to
a non-mathematical person.


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                                                                         ` Tim McDermott
  1998-09-08  0:00                                                                           ` Patrick Doyle
@ 1998-09-17  0:00                                                                           ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-17  0:00 UTC (permalink / raw)


Tim McDermott <mcdermott@draper.com> writes:

> Matthew Heaney wrote:
> 
> > (start of quote)
> > The dowhiledo structure has general form
> >
> >   do1
> >     dopart1
> >   while
> >     whiletest
> >   do2
> >     dopart2
> >   od
> 
> snip
> 
> > Conclusion: Feel free to exit from the middle of a loop.
> 
> As defined, you can exit from the middle of a dowhiledo, but not from the top
> or bottom.  This is still a se/se structure.  You can't use this structure to
> justify multiple returns.

But if dopart1 or dopart2 is just a "skip" statement, then it reduces to
a top or bottom exit.  For example, making the dopart2 part a "skip" is
just our old friend dountil (except for the sense of the predicate).

Remember: the goal is to satisfy the postcondition, and to be able to
prove that you do.  I can and do justify multiple returns, by proving
that the postcondition is indeed satisfied.






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-08  0:00                   ` Tim McDermott
@ 1998-09-17  0:00                     ` Matthew Heaney
  1998-09-17  0:00                       ` Reimer Behrends
  1998-09-18  0:00                       ` Robert I. Eachus
  0 siblings, 2 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-17  0:00 UTC (permalink / raw)


Tim McDermott <mcdermott@draper.com> writes:

> Matthew Heaney wrote:
> 
> > By separating the array iteration from the item comparison, I can reason
> > about the two different termination conditions independently.  So
> > instead of one (larger) problem with two terms, I have two (smaller)
> > problems, with one term each.
> 
> But here you are assuming that the termination conditions are
> disjoint!  In the general case they are not.  Have you never had the
> experience of writing something of the form
> 
> while (A) {
> 
> if (B) return b;
> ...
> if (C) return c;
> ...
> if (D) return d;
> 
> }
> 
> only to discover some time later that A&!B&!C (the path predicate of
> the if(D) statement forces the value of D?  Worse yet, that the
> evaluation of the loop predicate interacts with the evaluation of the
> if predicates.  My experience tells me that distributing complexity is
> a Bad Idea.
> 
> That is not to say that I always use se/se.  But I know that se/se is better
> form, and I have a real good idea of the risks of multiple return coding.

Let's consider a real-life problem that I had to solve last week.

I have a string that was padded on the right with blanks.  What I need
to do is strip off the blanks, and return the index of the last
non-blank character.

Let's analyze this problem first using Dijkstra's predicate transformer,
and then using Ada.

S is a string of length n.  It is indexed starting from 0, and therefore
ending with index n-1.

The Linear Search theorem tells us to search backwards from the maximum
index value, since we want to find the maximum index with a character
that is not blank.

If the string is all blanks, then we return -1.

Here's the postcondition:

R: -1 <= i < n and 
   Aj: i+1 <= j < n: S[j] = ' ' and 
   i /= -1 => S[i] /= ' '

Let's derive the invariant by weakening the postcondition, which in this
case means just removing some conjuncts.  Studying the postcondition for
things always true means that the postcondition is

P: -1 <= i < n and Aj: i+1 <= j < n: S[j] = ' '

We know that 

   P and not B => R

where B is the loop predicate.  So our loop predicate is the negation of
that last conjunct of the postcondition:

not B is: i /= -1 => S[i] /= ' '

Getting rid of the implication:

  i /= -1 => S[i] /= ' ' is same as

  i = -1 cor S[i] /= ' ' 

Now negate this to give us the loop predicate:

  i /= -1 cand S[i] = ' '

Initialization means making the invariant true, so just initialize i to
the value n-1.  (The universal quantifier is true by virtue of the fact
that a null range is defined to have the value True.)

Here is the result of our efforts:

i := n-1;
do i /= -1 cand S[i] = ' ' -> i := i - 1 od

QED

As Benjamin Whorf is want to remind us, the language we use has a
profound effect on how we think.  The Ada language provides loop
constructs to traverse an array, and so the Ada programmer will
"naturally" use a for loop, not a while loop, to index into the string.

This doesn't mean you can't use a while loop to do the job.  But if you
do, you'll force readers of your code to ask why you didn't just use a
for loop.  They'll ask, because you violated the Principle of Least
Astonishment.

What if the string is all blanks?  In a real program, the bounds of a
non-null string can be any positive integer (starting with 1).  Let's
therefore return the value 0 if there are all blanks in the string.  (We
could have easily decided to return S'First - 1, or indeed any number
less than S'First.)

The Ada programmer first tackles the job of setting up the loop.  We use
a for loop, iterating in reverse (because we're searching for the
largest index that's not a blank):

procedure Op (S : in String) is 
   Last : Natural := ???;
begin
   for Index in reverse S'Range loop
      ???
   end loop;


We have to give Last the value of the largest index that's not a blank.

   for Index in reverse S'Range loop
      if S (Index) /= ' ' then
         Last := Index;
...


If the string comprises all blanks, then we'll iterate over the entire
string without the if-test ever being true, and so we have to give Last
a default value to handle that case:

   Last : Natural := 0;
begin
   for Index in reverse S'Range loop
...


If we do find a value that's not blank, then we just bail out of the
loop, because we're done:

   Last : Natural := 0;
begin
   for Index in reverse S'Range loop
      if S (Index) /= ' ' then
         Last := Index;
         exit;
      end if;
   end loop;

   {R: Last = 0 or else S (Last) /= ' '}

QED

That's how an Ada programmer thinks.  Just think of a for loop as an
array iterator.  We terminate the loop early, via an exit, because we
don't need to visit all components of the array.

This is an example of reasoning by using the programming language
itself, instead of Dijkstra's formalism.  The point is that the
algorithm above can be reasoned about, in spite of the presence of an
exit from the middle of the loop.

The examples above illustrate two modes of thinking: top-down and
bottom-up.  Dijkstra is clearly a top-down thinker - and a very, very
good one.  He likes to reason about correctness in the abstract, using
the predicate calculus, independently of any specific programming
language.  (Indeed, he seems almost proud of the fact the none of his
programs are executable.)

The rest of us are bottom-up thinkers.  We reason about correctness
using constructs of the target language, and using idioms that have
greater "cognitive fit" to the human programmer.  

That's what the ACM paper I cited earlier was all about: how rules about
programming derived via top-down thinking clash with cognitive models
(bottom-up reality) used by ordinary programmers.

You tell the programmer how it "should" be done by (ie "don't terminate
a loop by exiting from the middle"), but such a solution doesn't always
match what a human programmer feels is a more "natural" solution to the
problem.

So he makes mistakes trying to reason about what he has been told is the
"right" way to do it.  Worse, he may even reason less, or not at all,
thinking that "this must be OK because I don't exit the loop from the
middle."





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00               ` Charles Hixson
  1998-09-10  0:00                 ` Loryn Jenkins
@ 1998-09-17  0:00                 ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-17  0:00 UTC (permalink / raw)


Charles Hixson <charleshixsn@earthlink.net> writes:

> It has been claimed that Design By Contract (DBC) can be done entirely
> by comments and documentation.  I, personally, don't believe it.  It is
> my expectation that the routines with explicit pre-conditions and
> post-conditions would work as desired in the Eiffel environment, where
> the developer could have pre-conditions enabled while developing it, and
> only remove them (IN LAYERS!) when the final code was produced.  I don't
> think that this would work at all as well without support from the IDE.
> 
> Now it is true, that the failures of DBC in an environment that doesn't
> support it can be traced to the contract not being lived up to, but
> ENFORCEABILITY IS A PART OF THE CONTRACT.  In an environment that
> doesn't enforce the contract, violations will not be detected, and I
> don't know about you, but my programs always need to have the bugs
> cleaned out of them before they are ready for delivery.

Use assertions to check preconditions.  When you're satisfied everyone
is obeying them, then recompile the body with assertions turned off:

function Get_Top (Stack : Stack_Type) return Stack_Item is
begin
   pragma Assert (Stack.Top /= 0);
...
end Get_Top;

You can even use a controlled type to check that a representation
invariant is being satisfied on procedure entry and exit.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                                       ` Tim Ottinger
@ 1998-09-17  0:00                                                                         ` Matthew Heaney
  1998-09-16  0:00                                                                           ` Tim Ottinger
  0 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-09-17  0:00 UTC (permalink / raw)


Tim Ottinger <ottinger@oma.com> writes:

> Matthew Heaney wrote a very fine, well-researched note
> here. I think it was great, except that he took "reason
> about..." to mean "understand...". To understand a code
> fragment is not the same as to reason about it. 

I treat them as essentially the same.  I can reason about a code
fragment implemented in a real programming language, or I can reason
about a code fragment using Dijkstra's abstract programming language.

I can make mistakes in reasoning using either language.  So formalism is
great, but is not a panacea.  It's just another tool that should be in
every programmer's toolbox.

It may be time to cite another couple of papers on this very topic:

Program Verification: The Very Idea
James H. Fetzer
CACM, Sep 1988, Vol 31, No 9, p1048-1063

Social Processes and Proofs of Theorems and Programs
Richard A. De Millo
Richard J. Lipton 
Alan J. Perlis
CACM, May 1979, Vol 22, No 5, p271-280


> That said, I have to plan to go restructure a little 
> code, and catch up on reading /Structured Programming/
> (Dahl, Dijkstra, Hoare, academic press "computer
> science classics" series, ISBN 0-12-200550-3). 

I just got back from a business trip, and got about halfway through that
other classic, A Discipline of Programming (Prentice-Hall, 1976).  Great
stuff, although I recommend that those unfamiliar with the predicate
transformer technique start with David Gries' Science Of Programming.





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-09  0:00                                                               ` sureshvv
  1998-09-10  0:00                                                                 ` prochak
@ 1998-09-17  0:00                                                                 ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-17  0:00 UTC (permalink / raw)


sureshvv@hotmail.com writes:

> Well said. The multi-return structure enables you to separate
> code in small  independent blocks, each of which may be examined
> and understood with less interference from surrounding blocks.
> The se-se structure creates large blocks, requiring more
> context information.

Not only that, but prohibiting early returns from a subprogram means you
have to figure how to navigate to the end of the subprogram without
doing anything else.  This is mental work that you wouldn't have to do
otherwise.  






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                     ` <35f51e53.48044143@ <6t6l4n$rep@jbm.nada.kth.se>
  1998-09-10  0:00                                       ` Mats Weber
@ 1998-09-17  0:00                                       ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-09-17  0:00 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1637 bytes --]

jbm@jbm.nada.kth.se (Jonas M�ls�) writes:

> 	Also, I have never encountered a real situation
> 	where I have needed an extra flag in the predicate.
> 	One can actually do fine without them. As an example,
> 	I hereby present to you three variations of str_index.
> 
> 	The first one strictly exits at the top. The other two
> 	in the middle. The first one is much easier to reason 
> 	about, and to understan, IMHO. Anyway, introducing an
> 	extra flag in the predicate is very often a sign of
> 	"patching the loop". Done right, one does not need it.
> 
> 
> 
> /** str_index
>  *
>  * str_index returns a pointer to the first occurrence of
>  * the given character in the given string.
>  * If the given character does not occur in the given
>  * string, str_index returns NULL.
>  * 
>  * If the given pointer is NULL, the result is undefined.
>  * 
>  */
> 
> 

Here's another idea:

char *
str_index (
    char   *s,			/* string to search           */
    char    c)			/* character to search for    */
{
    for (;;)
        if (*s == c)
           return s;
        
        else if (*s == '\0')
           return NULL;

        else
           s++;
}

I don't know if this is typical C code, however.  I suspect one would
move some of the work up into the for loop declaration:

   for (; *s != '\0'; s++)
      if (*s == c) 
         return s;

   return NULL;


An Ada programmer has an easier go of it:

function Get_Position (S : String; C : Character) return Natural is
begin
   for Index in S'Range loop
      if S(Index) = C then
         return Index;
      end if;
   end loop;
  
   return 0;
end Get_Position;





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                                               ` <gio+van+no+ni+8-1609981736190001@dialup47.tlh.talstar.com>
@ 1998-09-17  0:00                                                                 ` mfinney
  0 siblings, 0 replies; 510+ messages in thread
From: mfinney @ 1998-09-17  0:00 UTC (permalink / raw)


In <gio+van+no+ni+8-1609981736190001@dialup47.tlh.talstar.com>, gio+van+no+ni+8@tal+star+spam.com (Giovanni 8) writes:
>> Michael Lee Finney wrote:
>> I have made a study of many control structures for years
>> as a hobby and virtually all of them are tree-structured,
>> but they are not structured.
>
>Virtually all of them are tree-structured but not structured?
>
>Virtually all of them are 4-wheeled vehicles but not wheeled
>vehicles?
>
>Since tree-structures are a sub-set of all possible structures,
>then they must be structures.

You misunderstand.  You are applying general analogy to the
situation, but it is invalid because these terms have specific
technical meanings.

Code which is structured only allows a single entry, single exit
with some possible argument as to exactly which control structures
are valid.  Traditionalists will argue, for example, that a mid-loop
exit is not acceptable and others will disagree.

Code which is tree-structured essentially allows any control
structure which does not contain a jump into the middle of a
block.  Or, another way of expressing the concept, you may
exit or repeat any block any number of times at any depth of
block nesting.  Neither structured code nor tree-structured code
allows unrestricted use of the GOTO statement.  Under these
definitions, all structured code is tree-structured, but not vice-
versa.


Michael Lee Finney





^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-17  0:00                     ` Matthew Heaney
@ 1998-09-17  0:00                       ` Reimer Behrends
  1998-09-18  0:00                       ` Robert I. Eachus
  1 sibling, 0 replies; 510+ messages in thread
From: Reimer Behrends @ 1998-09-17  0:00 UTC (permalink / raw)


Matthew Heaney (matthew_heaney@acm.org) wrote:
[...]
>    Last : Natural := 0;
> begin
>    for Index in reverse S'Range loop
>       if S (Index) /= ' ' then
>          Last := Index;
>          exit;
>       end if;
>    end loop;
> 
>    {R: Last = 0 or else S (Last) /= ' '}

feature { ANY }

  last_non_blank(s: STRING): INTEGER is
  local
    pos: INTEGER
  do
    from
      pos := s.count
    until pos = 0 or else s @ pos /= ' ' loop
      pos := pos - 1
    end
    Result := pos
  ensure
    Result = 0 or else s @ Result /= ' '
  end

			Reimer Behrends




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-16  0:00               ` Matthew Heaney
@ 1998-09-17  0:00                 ` Reimer Behrends
  1998-09-17  0:00                   ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Reimer Behrends @ 1998-09-17  0:00 UTC (permalink / raw)


Anybody got a suggestion what a reasonable value for Followup-To would
be for this?

Matthew Heaney (matthew_heaney@acm.org) wrote:
[...]
> Robert Martin argued against early returns (or middle-exit loops) by
> stating that you might forget to release a resource, if you return
> early.  

Or more generally, to reestablish a predicate that has been temporarily
violated.

> I gave the counter-example that the resource management problem should
> be solved another way, by using a deconstructor (C++) or a controlled
> type (Ada95).  I based my arguement on the fact that this is what you
> should do no matter what, because of the presence of exceptions.
> 
> Stroustrup calls this idiom "resource acquistion is initialization."

It should, however, be noted that there are those who as a general rule
don't use exceptions at all, with the obvious benefits alluded to by
Robert Martin.  Also, using single-entry/single-exit in such a strict
fashion allows you to view _any_ code block as an abstract unit, with
the added benefit that you can decompose and restructure complex code
almost at will.

				Reimer Behrends




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-17  0:00                 ` Reimer Behrends
@ 1998-09-17  0:00                   ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-17  0:00 UTC (permalink / raw)


In comp.object Reimer Behrends <behrends@cse.msu.edu> wrote:

: It should, however, be noted that there are those who as a general rule
: don't use exceptions at all, with the obvious benefits alluded to by
: Robert Martin.  Also, using single-entry/single-exit in such a strict
: fashion allows you to view _any_ code block as an abstract unit, with
: the added benefit that you can decompose and restructure complex code
: almost at will.

At the point of each one of the mutiple exits the post-conditions for the
code block as a whole can be checked.  "Multiple exits" do not mean that
each exit must immediately leave the code block without some form of
checking.

Elliott
-- 
:=***=:  VOTE NO TO MODERATION!  ALL IDEAS SHOULD BE CRITICIZABLE! :=***=:
             MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-16  0:00                                                                     ` Biju Thomas
  1998-09-17  0:00                                                                       ` dewarr
@ 1998-09-17  0:00                                                                       ` Gerry Quinn
  1998-09-17  0:00                                                                         ` dewarr
  1 sibling, 1 reply; 510+ messages in thread
From: Gerry Quinn @ 1998-09-17  0:00 UTC (permalink / raw)


In article <35FFE58C.5727@ibm.net>, bijuthom@ibm.net wrote:

>Reminds me of what Dijkstra told about the effect of COBOL and BASIC on
>minds:
>
>"The use of COBOL cripples the mind; its teaching should, therefore, be
>regarded as a criminal offense."
>
>"It is practically impossible to teach good programming style to
>students that have had prior exposure to BASIC; as potential programmers
>they are mentally mutilated beyond hope of regeneration"
>

One suspects Dijkstra was a poor teacher.

- Gerry

----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-16  0:00                                                                     ` Biju Thomas
@ 1998-09-17  0:00                                                                       ` dewarr
  1998-09-18  0:00                                                                         ` Ell
  1998-09-17  0:00                                                                       ` Gerry Quinn
  1 sibling, 1 reply; 510+ messages in thread
From: dewarr @ 1998-09-17  0:00 UTC (permalink / raw)


In article <35FFE58C.5727@ibm.net>,
  bijuthom@ibm.net wrote:
> Giovanni 8 wrote:
> >
> > > Gerry Quinn wrote:
> > >> adam wrote:
> > >> Sigh... does anyone *try* to write spaghetti code?
> > >> The thing is, someone who's inexperienced and hasn't read
> > >> enough code to know whether code is readable or not, is
> > >> certainly capable of writing unreadable, convoluted code
> > >> without using GOTO.
> >
> > > I agree - in fact I would argue that if you are carrying a
> > > flag for deciding when to exit, the flag is part of the
> > > flow of control - with all the potential pasta that entails.
> >
> > Spaghetti code is in the eye of the beholder.
> >
> > Some people find jumps or gotos, written in their own
> > particular style, to be much more elegant and clear
> > than the so-called control structures.  Others really
> > like flags popping up in one place & then not being
> > seen through vast piles of listing until, layers removed,
> > they are used again (even in a different context with
> > different conceptual significance for the values of
> > the flag).  I've seen people, brows furrowed, puzzled
> > over code that was the epitome of structured design,
> > who could follow the jumps of assembly language with
> > ease.
>
> Reminds me of what Dijkstra told about the effect of COBOL and BASIC on
> minds:
>
> "The use of COBOL cripples the mind; its teaching should, therefore, be
> regarded as a criminal offense."
>
> "It is practically impossible to teach good programming style to
> students that have had prior exposure to BASIC; as potential programmers
> they are mentally mutilated beyond hope of regeneration"
>
> Biju Thomas
>


I would be willing to be that EWD simply does not know COBOL,
or that if he does know it, he knows some ancient version
that bears no relationship to modern COBOL. In fact this
must be the case, or he would not make a patently absurd
statement like this.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-17  0:00                                                                       ` dewarr
@ 1998-09-18  0:00                                                                         ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-18  0:00 UTC (permalink / raw)


dewarr@my-dejanews.com wrote:

> Biju Thomas wrote:
>>
>> Reminds me of what Dijkstra told about the effect of COBOL and BASIC on
>> minds:
>>
>> "The use of COBOL cripples the mind; its teaching should, therefore, be
>> regarded as a criminal offense."
>>
>> "It is practically impossible to teach good programming style to
>> students that have had prior exposure to BASIC; as potential
>> programmers they are mentally mutilated beyond hope of regeneration"

>I would be willing to be that EWD simply does not know COBOL,
>or that if he does know it, he knows some ancient version
>that bears no relationship to modern COBOL. In fact this
>must be the case, or he would not make a patently absurd
>statement like this.

COBOL, modern day at least, is great for teaching modularity,
hierarchically layered architecture, procedures to enhance loose
coupling and high cohesion, and procedure calls to avoid pasta.

Myself and many others learned BASIC and were able to develop good
programming styles despite that.  And then with Darmouth and True BASIC,
'goto' was discouraged and a modular, loosely coupled, and highly cohesive
routine call style was supported and encouraged.

While I really like Dijkstra's comment that *abstraction* is the first
thing he thinks of when the term "structured programming" is mentioned*,
his above statements are typical craftite, elitist comments. *[Art of
Literate Programmimg, CLSC, D. Knuth, pg 72]

He is the supposed all-knowing master craftsman who looks down his nose at
the work and practices of any but his own and that of a small circle of
cohorts. 

Elliott
-- 
:=***=:  VOTE NO TO MODERATION!  ALL IDEAS SHOULD BE CRITICIZABLE! :=***=:
             MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-17  0:00                     ` Matthew Heaney
  1998-09-17  0:00                       ` Reimer Behrends
@ 1998-09-18  0:00                       ` Robert I. Eachus
  1998-09-18  0:00                         ` Jeffrey C. Dege
  1 sibling, 1 reply; 510+ messages in thread
From: Robert I. Eachus @ 1998-09-18  0:00 UTC (permalink / raw)


In article <m3pvcv6cr5.fsf@mheaney.ni.net> Matthew Heaney <matthew_heaney@acm.org> writes:

  > I have a string that was padded on the right with blanks.  What I need
  > to do is strip off the blanks, and return the index of the last
  > non-blank character.

  > Let's analyze this problem first using Dijkstra's predicate transformer,
  > and then using Ada...

    Not to disagree with Matt, because he is trying to give an example
of how to reason about a problem, but there is a better approach:

    Ada.Strings.Fixed.Trim(S,Right)'Last

    Of course, you probably want to use the value returned from Trim
instead of just the index of the last non-blank character.
(Technically, if you want to insure that the value returned for a null
string is zero, you need to do:

 function Last_Non_Blank_Index(S: String) return Natural is
   Temp : constant Natural := Ada.Strings.Fixed.Trim(S,Right)'Last;
 begin
   if Temp = S'First then return 0; else return Temp; end if;
 end Last_Non_Blank_Index;

 but the convention of returning 0 in this case was not part of the
original problem statement: 

  > I have a string that was padded on the right with blanks.  What I
  > need to do is strip off the blanks, and return the index of the
  > last non-blank character.

    Why bring this up?  Because when doing ANY kind of engineering,
the first approach to try should be to ask, "Is there something in the
standard catalog that is available off-the-shelf?"  It is so easy and
enjoyable to solve these problems in Ada, that we often lose sight of
how much grief using the library function will save later.  For
example:

    If you need to truncate from both ends?  Change "Right" to "Both".

    If you need to truncate spaces and horizontal tabs from both ends,
and commas and periods from the right:

    with Ada.Strings.Maps, Ada.Characters.Latin_1;
    use Ada.Strings.Maps, Ada.Characters.Latin_1;
    ...
       Ada.Strings.Fixed.Trim(S, To_Set(Space & HT),
             To_Set(Space & HT & Comma & Full_Stop); 

    -- Although I would probably declare the Character_Sets as
    -- constants in some package.

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-18  0:00                       ` Robert I. Eachus
@ 1998-09-18  0:00                         ` Jeffrey C. Dege
  0 siblings, 0 replies; 510+ messages in thread
From: Jeffrey C. Dege @ 1998-09-18  0:00 UTC (permalink / raw)


On 18 Sep 1998 02:11:42 GMT, Robert I. Eachus <eachus@spectre.mitre.org> wrote:
>In article <m3pvcv6cr5.fsf@mheaney.ni.net> Matthew Heaney <matthew_heaney@acm.org> writes:
>
>  > I have a string that was padded on the right with blanks.  What I need
>  > to do is strip off the blanks, and return the index of the last
>  > non-blank character.
>
>    Not to disagree with Matt, because he is trying to give an example
>of how to reason about a problem, but there is a better approach:
>
>    Ada.Strings.Fixed.Trim(S,Right)'Last
>   if Temp = S'First then return 0; else return Temp; end if;
> end Last_Non_Blank_Index;
>
>    Why bring this up?  Because when doing ANY kind of engineering,
>the first approach to try should be to ask, "Is there something in the
>standard catalog that is available off-the-shelf?"  It is so easy and
>enjoyable to solve these problems in Ada, that we often lose sight of
>how much grief using the library function will save later.  

And if you don't have a a catalog, off-the-shelf tool to solve the
problem, create a tool and put it on the shelf...

-- 
Personally, I think my choice in the mostest-superlative-computer wars has to
be the HP-48 series of calculators.  They'll run almost anything.  And if they
can't, while I'll just plug a Linux box into the serial port and load up the
HP-48 VT-100 emulator.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-17  0:00                                                                         ` dewarr
@ 1998-09-18  0:00                                                                           ` Gerry Quinn
  1998-09-18  0:00                                                                             ` Biju Thomas
  1998-09-19  0:00                                                                             ` dewarr
  0 siblings, 2 replies; 510+ messages in thread
From: Gerry Quinn @ 1998-09-18  0:00 UTC (permalink / raw)


In article <6ts4d0$2gk$1@nnrp1.dejanews.com>, dewarr@my-dejanews.com wrote:
>In article <6tqvji$f0k$2@news.indigo.ie>,
>  gerryq@indigo.ie (Gerry Quinn) wrote:
>> In article <35FFE58C.5727@ibm.net>, bijuthom@ibm.net wrote:
>>
>> >Reminds me of what Dijkstra told about the effect of COBOL and BASIC on
>> >minds:
>> >
>> >"The use of COBOL cripples the mind; its teaching should, therefore, be
>> >regarded as a criminal offense."
>> >
>> >"It is practically impossible to teach good programming style to
>> >students that have had prior exposure to BASIC; as potential programmers
>> >they are mentally mutilated beyond hope of regeneration"
>> >
>>
>> One suspects Dijkstra was a poor teacher.

>Oh goodness, if "one" suspects that, one sure does not know
>what one is talking about :-)
>
>EWD is a brilliant teacher. I well remember a great evening
>in Amsterdam, when he met my wife for the first time, and
>gave a quite marvelous demonstration with her of how to
>teach about trans-Cantorian infinities in a clear way to
>a non-mathematical person.
>

I don't quite understand how a non-mathematical person would 
understand trans-Cantorian infinities.  It sounds like a 
non-programming person understanding Cobol.

- Gerry



----------------------------------------------------------
  gerryq@indigo.ie  (Gerry Quinn)
----------------------------------------------------------




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-18  0:00                                                                           ` Gerry Quinn
@ 1998-09-18  0:00                                                                             ` Biju Thomas
  1998-09-18  0:00                                                                               ` Robert C. Martin
                                                                                                 ` (2 more replies)
  1998-09-19  0:00                                                                             ` dewarr
  1 sibling, 3 replies; 510+ messages in thread
From: Biju Thomas @ 1998-09-18  0:00 UTC (permalink / raw)


Gerry Quinn wrote:
> 
> I don't quite understand how a non-mathematical person would
> understand trans-Cantorian infinities.  It sounds like a
> non-programming person understanding Cobol.
> 

Wasn't COBOL designed to enable no-programmer's to write programs? 

Biju Thomas




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-18  0:00                                                                             ` Biju Thomas
@ 1998-09-18  0:00                                                                               ` Robert C. Martin
  1998-09-19  0:00                                                                                 ` Rick Smith
  1998-09-19  0:00                                                                               ` Ell
  1998-09-19  0:00                                                                               ` dewarr
  2 siblings, 1 reply; 510+ messages in thread
From: Robert C. Martin @ 1998-09-18  0:00 UTC (permalink / raw)



Biju Thomas <"Biju Thomas"> > wrote in message <3602983C.62B1@ibm.net>...
>Gerry Quinn wrote:
>>
>> I don't quite understand how a non-mathematical person would
>> understand trans-Cantorian infinities.  It sounds like a
>> non-programming person understanding Cobol.
>>
>
>Wasn't COBOL designed to enable no-programmer's to write programs?
>


Yes, that was the idea...  But it failed since, clearly, some programmers
*are* writing programs in COBOL.

(Snicker)

Actually the idea was not to allow non-programmers to *write* the programs.
It was to allow non-programmers to be able to read the programs to some
extent.  The programs were supposed to be self-documenting.  In the end,
this failed too.  COBOL, like every other computer language, is loaded with
arcanities which are critical for the understanding of the program.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"If you've ever left double-letters out of a person's name,
 then you might be a craftite." -- Tim Ottinger







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-18  0:00                                                                             ` Biju Thomas
  1998-09-18  0:00                                                                               ` Robert C. Martin
@ 1998-09-19  0:00                                                                               ` Ell
  1998-09-19  0:00                                                                               ` dewarr
  2 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-09-19  0:00 UTC (permalink / raw)


In comp.object Biju Thomas <"Biju Thomas"> wrote:
:
: Gerry Quinn wrote:
:> 
:> I don't quite understand how a non-mathematical person would
:> understand trans-Cantorian infinities.  It sounds like a
:> non-programming person understanding Cobol.
:> 

: Wasn't COBOL designed to enable no-programmer's to write programs? 

Grace Hopper the creator of COBOL, who I saw once and who I've heard speak
a number of times, said that she wanted to formulate a language well
suited to the heavy record and regular math calculation intensive demands
of large business and organizational processing.  In that, I find that she
succeded quite admirably.

I find the "look and feel" of a COBOL program which adheres to proper
structured guidelines to be a joy to behold (ie. when I look at my own
COBOL code :-)  I know people who are great assembler, C and C++
programmers who also excel at and enjoy COBOL programming.

Elliott
--
:=***=:  VOTE NO TO MODERATION!  ALL IDEAS SHOULD BE CRITICIZABLE! :=***=:
             MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
   :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                 Hallmarks of the best SW Engineering
 Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
   Copyright 1998 Elliott. exclusive of others' writing. may be copied
     without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-18  0:00                                                                           ` Gerry Quinn
  1998-09-18  0:00                                                                             ` Biju Thomas
@ 1998-09-19  0:00                                                                             ` dewarr
  1 sibling, 0 replies; 510+ messages in thread
From: dewarr @ 1998-09-19  0:00 UTC (permalink / raw)


In article <6ttg0o$9kb$2@news.indigo.ie>,
  gerryq@indigo.ie (Gerry Quinn) wrote:

> I don't quite understand how a non-mathematical person would
> understand trans-Cantorian infinities.  It sounds like a
> non-programming person understanding Cobol.


Well that's the point! It takes a good teacher to adjust to
the right level. I certainly would expect to be able to give
a non-programming person an understanding of what COBOL is
all about. In fact if you act as an expert witness with a
jury, you are most definitely expected to be able to do this.
It is not easy, teaching like anything else is an expertise
where the experts can amaze you :-)


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-18  0:00                                                                             ` Biju Thomas
  1998-09-18  0:00                                                                               ` Robert C. Martin
  1998-09-19  0:00                                                                               ` Ell
@ 1998-09-19  0:00                                                                               ` dewarr
  1998-09-21  0:00                                                                                 ` Richard D Riehle
  2 siblings, 1 reply; 510+ messages in thread
From: dewarr @ 1998-09-19  0:00 UTC (permalink / raw)


In article <3602983C.62B1@ibm.net>,
  bijuthom@ibm.net wrote:
> Gerry Quinn wrote:
> >
> > I don't quite understand how a non-mathematical person would
> > understand trans-Cantorian infinities.  It sounds like a
> > non-programming person understanding Cobol.
> >
>
> Wasn't COBOL designed to enable no-programmer's to write programs?
>
> Biju Thomas


No. It wasn't, and this idea is obviously absurd on the face
of it (just read what you read, at the very least you must
have forgotten a smiley, no?)

What it was designed for was to make it easier for a
non-programmer to *read* a COBOL program, and a well
written COBOL program can do a good job of that (remember
that the competition at the time was Fortran with 6
character identifier length limit). A sequence like

  IF BALANCE IS NEGATIVE THEN
     PERFORM SEND-BILL
  ELSE
     PERFORM REGISTER-CREDIT
  END-IF.

Does not require a computer expert to figure out!
Note here incidentally (always happy to take the chance
to teach the ignorant a little bit about COBOL :-) :-)
that the very light local refinement syntax is very
attractive. Let's look at the above example in more
detail and let's use upper/lower case as now permitted
since that's more familiar.

Process_Balance
  if balance is negative then
     perform Send-Bill
  else
     peform Register-Credit
  end-if.

Send-Bill.
  ...

Register-Credit.
  ...

The only syntax required for a little refinement like this
is the name of the procedure and a period. Furthermore, as
you prefer for this kind of refinement, the definition of
the procedure is AFTER the use.

Many modern procedural languages don't compete well with
COBOL in this respect, and the style in languages like Ada
or C is instead to nest conditionals and let the code
wander off to the right side of the page.

COBOL programmers tend to find nested conditionals
confusing (not such a suprising attitude, how many
complex nested conditionals do you use in everyday
speach :-)

Does COBOL achieve its aim of allowing complex programs
to be understood by non-programmers? Only partially, but
at the time, it was definitely nearer to this goal than
the competition, and it still is one of the languages in
which it is possible to create the most readable code if
you know what you are doing.


SEND

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-18  0:00                                                                               ` Robert C. Martin
@ 1998-09-19  0:00                                                                                 ` Rick Smith
  0 siblings, 0 replies; 510+ messages in thread
From: Rick Smith @ 1998-09-19  0:00 UTC (permalink / raw)



Robert C. Martin wrote in message <6tvcf9$jqt$1@hirame.wwa.com>...
>
>Biju Thomas <"Biju Thomas"> > wrote in message <3602983C.62B1@ibm.net>...
>>Gerry Quinn wrote:
>>>
>>> I don't quite understand how a non-mathematical person would
>>> understand trans-Cantorian infinities.  It sounds like a
>>> non-programming person understanding Cobol.
>>>
>>
>>Wasn't COBOL designed to enable no-programmer's to write programs?
>>
>
>
>Yes, that was the idea...  But it failed since, clearly, some programmers
>*are* writing programs in COBOL.
>
>(Snicker)
>
>Actually the idea was not to allow non-programmers to *write* the programs.
>It was to allow non-programmers to be able to read the programs to some
>extent.  The programs were supposed to be self-documenting.  In the end,
>this failed too.  COBOL, like every other computer language, is loaded with
>arcanities which are critical for the understanding of the program.
>
I think the supposition that COBOL programs are "self-documenting"
is folklore! Since it was not intended, it cannot have failed!

In the quote below, note the subtle, yet distinct, difference between
readability as documentation and program as documentation.

Quote from
  Gerald M. Weinberg, The Psychology of Computer Programming,
  Van Nostrand Reinhold, 1971

"People have lost sight of the original intention of COBOL's designers.
To quote one of them, Jean Sammet:

    The users for whom COBOL was designed were actually two
    subclasses of those people concerned with business data
    processing problems. One is the relatively inexperienced
    programmer for whom the naturalness of COBOL would be an
    asset, while the other type of user would be essentially anybody
    who had not written the program initially. In other words, the
    readability of COBOL programs would provide documentation
    to all who might wish to examine the programs, including the
    supervisory or management personnel. Little attempt was made
    to cater to professional programmers. ...

The COBOL designers went to considerable trouble to see that these
objectives were met."

As I see it, the readability of COBOL allows others to examine the
programs to see that they conform to other documents, such as
requirements and specifications. For the individual who is changing
the program, the readability of COBOL makes it easier to understand
where and how to implement a change in the specification or to
correct a deviation from the specification ("bug").

I do believe that the designers never intended that COBOL programs
should be self-documenting; that is, existing without other documents.
-------------------------------
Rick Smith
e-mail: < ricksmith@aiservices.com >






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-19  0:00                                                                               ` dewarr
@ 1998-09-21  0:00                                                                                 ` Richard D Riehle
  0 siblings, 0 replies; 510+ messages in thread
From: Richard D Riehle @ 1998-09-21  0:00 UTC (permalink / raw)


In article <6u0ck4$f08$1@nnrp1.dejanews.com>,
	dewarr@my-dejanews.com wrote:

>In article <3602983C.62B1@ibm.net>,
>  bijuthom@ibm.net wrote:

>> Wasn't COBOL designed to enable no-programmer's to write programs?
>
>No. It wasn't, and this idea is obviously absurd on the face
>of it ...

 When considered from the viewpoint of COBOL's design objectives,
 Robert is correct.  However, it turned out that one of COBOL's  
 virtues was just as Mr. Biju asserts.  During the 1960's and
 1970's many large companies (banks, insurance companies, etc.)
 discovered it was easier to train accounting personnel to write 
 programs in COBOL than it was to train programmers to understand  
 accounting. Many of those accounting personnel went on to become
 real programmers. This resulted in all sorts of interesting problems, 
 some of which are still with us today.  

 COBOL gets a "bad rap" from those who favor other languages.  The fact
 is that it continues to evolve and improve.  The example given in 
 Robert's posting was an illustration of changes to the language that
 first appeared in ANSI-85 COBOL standard.  A COBOL programmer of an
 earlier time would not recognize the code as valid.  Many COBOL 
 shops are still using COBOL 68 and COBOL 74 quite regularly and 
 creating successful data processing systems.  

 The currently emerging COBOL standard is an Object COBOL in which
 this presumably outdated and obsolete language continues to amaze
 its detractors by being resilient enough to evolve to encompass the
 current fad in software development.  

 Richard Riehle
 richard@adaworks.com
 www.adaworks.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-08-31  0:00                                           ` Robert Martin
                                                               ` (2 preceding siblings ...)
  1998-09-01  0:00                                             ` Matthew Heaney
@ 1998-10-01  0:00                                             ` Charles H. Sampson
  1998-10-02  0:00                                               ` Ell
  1998-10-02  0:00                                               ` Robert C. Martin
  3 siblings, 2 replies; 510+ messages in thread
From: Charles H. Sampson @ 1998-10-01  0:00 UTC (permalink / raw)


Robert Martin <rmartin@oma.com> wrote:

> Stephen Leake wrote in message ...
> >If there is only one 'exit' statement, why is this bad?
> >
> >loop
> >    ... stuff
> >    exit when ;
> >    ... stuff
> >end loop;
> >
> >One entry, one exit. Perfectly clear. There's nothing magic about
> >putting the exit statement at the top or the bottom!
> 
> In fact there is.  If the exit condition is at the top or the bottom, then
> the body of the loop will always be excuted an exact integral number of
> times.  However if the loop condition is in the middle, then the loop body
> will be executed a fractional number of times.

     Well, this is certainly a twist to me.  I was taught the n-and-a-
half loop as an example of the inadequacy of loop structures in most 
programming languages.  Now it seems that everything has been turned 
around 180 degrees and there is some sort of software principle (in some
peoples' minds) that the entire body of a loop must execute "an exact 
integral number of times."  As another responder has pointed out (not in
these words), in the presence of conditional statements it's not clear 
what this condition means.  My guess is that it's this: Every statement
immediately in the loop body executes on every iteration of the loop.  
If this is an accurate statement of this new principle, my immediate re-
sponse is: So what?  Why should we care?

     I apologize for responding to a post that's 31 days old.  I got in
on this long thread very late and I'm running very hard to catch up.

                                Charlie

-- 
     To get my correct email address, replace the "claveman" by
"csampson" in my fake (anti-spam) address.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                                 ` John I. Moore, Jr.
@ 1998-10-02  0:00                                                   ` Ell
  1998-10-03  0:00                                                   ` John Goodsen
  1998-10-03  0:00                                                   ` Robert C. Martin
  2 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-02  0:00 UTC (permalink / raw)


"John I. Moore, Jr." <70672.1744@compuserve.com> wrote:

>Robert C. Martin wrote in message <6v2nr9$t8l$1@hirame.wwa.com>...
>>
>>The question that the post was addressing had to do with the definition of
>>structured programming.  A mid exit loop does not fall within the bounds
>>defined by structured programming because the loop body does not then have
>> a single entry and a single exit.

>... Whose definition are you using for structured
>programming?  Some of the earliest articles and books on structured
>programming were written by Harlan Mills of IBM, and he always
>defined a loop with a middle exit as an integral part of structured
>programming.  He called it a do-while-do loop.

I've seen no structured programming literature which said that a code
module must only a single entry and a single exit (se/se).  

I've seen quotes from structured literature about flowchart pages
having a single entry and single exit point, but nothing about for
example about having to navigate a loop using se/se.

Very significantly, according to Dijkstra, one of chief creators of
structured programming, the definition of structured programming has a
modelling aspect which is even more important than any maxims about
code control flow navigation.  Or rather the navigation issue was
resolved in terms of a new more productive modelling paradigm.

This is evidenced by Dijkstra's remark that the first thing he thinks
of when structured programming is mentioned is "abstraction"--in
particular hierarchies of abstraction. (Art of Literate Programming, D
Knuth, CLSC, pg 72).  

"Abstraction" meaning as Webster says:
	The act of separating the inherit qualities or properties of
	something from the actual physical object or concept to which they
	belong.

Ie. separating the contextually essential, logical aspect of an object
from the physical object itself.

This indicates that to cure the spaghetti ills of programming at the
time, Dijkstra, went beyond mere matters of navigation to modelling.

Dijkstra advocated disciplined navigation between well designed
(loosely coupled, highly cohesive) abstractions--with the abstractions
being our present day functions/routines/procedures.

Here we have another advance in software engineering based on
modelling, just as modelling is the key benefit of OO to present day
software engineering.  Dijkstra took a "giant's" step into modelling
rather than advocate a technocratic, navigation maxim of questionable
value (single entrance/single exit), 

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                               ` Robert C. Martin
  1998-10-02  0:00                                                 ` John I. Moore, Jr.
@ 1998-10-02  0:00                                                 ` Ell
  1998-10-03  0:00                                                   ` Ell
  1998-10-02  0:00                                                 ` Charles H. Sampson
                                                                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-10-02  0:00 UTC (permalink / raw)


"Robert C. Martin" <rmartin@oma.com> wrote:

>The question that the post was addressing had to do with the definition of
>structured programming.  A mid exit loop does not fall within the bounds
>defined by structured programming because the loop body does not then have a
>single entry and a single exit.
>
>This has nothing to do with whether mid exit loops are good or bad.  It only
>has to do with whether mid exit loops conform to structured programming or
>not.

Correction, I should have said "end-exit" rather that "single
entry/single exit (se/se)" in my last post in this thread.

Both "end-exit" and "mid-exit" loops may adhere to the principles of
structured programming.  

There is no structured literature which argues against loop (or other
entity) "mid-exit" in structured coding.  There is literature which
stipulates using single entry to and single exit from flowcharts
pages, but that is not the same thing.

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                               ` Robert C. Martin
  1998-10-02  0:00                                                 ` John I. Moore, Jr.
  1998-10-02  0:00                                                 ` Ell
@ 1998-10-02  0:00                                                 ` Charles H. Sampson
  1998-10-03  0:00                                                   ` Reimer Behrends
  1998-10-05  0:00                                                 ` Graham Perkins
  1998-10-09  0:00                                                 ` Matthew Heaney
  4 siblings, 1 reply; 510+ messages in thread
From: Charles H. Sampson @ 1998-10-02  0:00 UTC (permalink / raw)


Robert C. Martin <rmartin@oma.com> wrote:

> Charles H. Sampson wrote in message
> <1dg8p3r.vfredh1aou58iN@n207167116191.inetworld.net>...
> >Robert Martin <rmartin@oma.com> wrote:
> >
> >> Stephen Leake wrote in message ...
> >> >If there is only one 'exit' statement, why is this bad?
> >> >
> >> >loop
> >> >    ... stuff
> >> >    exit when ;
> >> >    ... stuff
> >> >end loop;
> >> >
> >> >One entry, one exit. Perfectly clear. There's nothing magic about
> >> >putting the exit statement at the top or the bottom!
> >>
> >> In fact there is.  If the exit condition is at the top or the bottom,
> then
> >> the body of the loop will always be excuted an exact integral number of
> >> times.  However if the loop condition is in the middle, then the loop
> body
> >> will be executed a fractional number of times.
> >
> >     Well, this is certainly a twist to me.  I was taught the n-and-a-
> >half loop as an example of the inadequacy of loop structures in most
> >programming languages.  Now it seems that everything has been turned
> >around 180 degrees and there is some sort of software principle (in some
> >peoples' minds) that the entire body of a loop must execute "an exact
> >integral number of times."  As another responder has pointed out (not in
> >these words), in the presence of conditional statements it's not clear
> >what this condition means.  My guess is that it's this: Every statement
> >immediately in the loop body executes on every iteration of the loop.
> >If this is an accurate statement of this new principle, my immediate re-
> >sponse is: So what?  Why should we care?
> 
> The question that the post was addressing had to do with the definition of
> structured programming.  A mid exit loop does not fall within the bounds
> defined by structured programming because the loop body does not then have a
> single entry and a single exit.

     But it does.  Just look.  That's not a for-loop or a while-loop.  
It's a loop that can only be executed with an exit statement and it has
just one.  (Yes, an exception can cause it to exit too, but gimme a 
break.)

    The problem everybody is chewing on has from time to time led me to
propose an Ada programming style:  No exit statements in for-loops and 
while-loops.  (The precise statement is a little more complicated.)  
With this restriction, the termination conditions of for-loops and 
while-loops are clear.  Any loop that can't reasonably be expressed that
way is to be written as an "infinite" loop with exit statement(s).  Un-
fortunately, the neatness of the loop index in Ada, self-declaring with
its scope being the loop itself, is a siren song that I haven't been 
able fully to resist.

    Incidentally, my meaning of "can't reasonably be expressed" in the 
previous paragraph uses the maintenance programmer as a frame of refer-
ence.  There have been a number of charges of "You're only interested in
what makes writing the code easy for you" thrown around in this thread.
I always program for the maintenance programmer, even when that mainte-
nance programmer is going to be me.

                                Charlie

-- 
     To get my correct email address, replace the "claveman" by
"csampson" in my fake (anti-spam) address.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-01  0:00                                             ` Charles H. Sampson
@ 1998-10-02  0:00                                               ` Ell
  1998-10-02  0:00                                               ` Robert C. Martin
  1 sibling, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-02  0:00 UTC (permalink / raw)


claveman@inetworld.net (Charles H. Sampson) wrote:

>     I apologize for responding to a post that's 31 days old.  I got in
>on this long thread very late and I'm running very hard to catch up.

You shouldn't drag the group back down a road we just traveled the
whole distance of for your benefit.  What do you expect, for all of us
to  hop back on board and relive the journey until you catch up?
We've dealt with loop and half and moved on far beyond that.  If you
must, you should contact those you have questions for off-line.

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-01  0:00                                             ` Charles H. Sampson
  1998-10-02  0:00                                               ` Ell
@ 1998-10-02  0:00                                               ` Robert C. Martin
  1998-10-02  0:00                                                 ` John I. Moore, Jr.
                                                                   ` (4 more replies)
  1 sibling, 5 replies; 510+ messages in thread
From: Robert C. Martin @ 1998-10-02  0:00 UTC (permalink / raw)



Charles H. Sampson wrote in message
<1dg8p3r.vfredh1aou58iN@n207167116191.inetworld.net>...
>Robert Martin <rmartin@oma.com> wrote:
>
>> Stephen Leake wrote in message ...
>> >If there is only one 'exit' statement, why is this bad?
>> >
>> >loop
>> >    ... stuff
>> >    exit when ;
>> >    ... stuff
>> >end loop;
>> >
>> >One entry, one exit. Perfectly clear. There's nothing magic about
>> >putting the exit statement at the top or the bottom!
>>
>> In fact there is.  If the exit condition is at the top or the bottom,
then
>> the body of the loop will always be excuted an exact integral number of
>> times.  However if the loop condition is in the middle, then the loop
body
>> will be executed a fractional number of times.
>
>     Well, this is certainly a twist to me.  I was taught the n-and-a-
>half loop as an example of the inadequacy of loop structures in most
>programming languages.  Now it seems that everything has been turned
>around 180 degrees and there is some sort of software principle (in some
>peoples' minds) that the entire body of a loop must execute "an exact
>integral number of times."  As another responder has pointed out (not in
>these words), in the presence of conditional statements it's not clear
>what this condition means.  My guess is that it's this: Every statement
>immediately in the loop body executes on every iteration of the loop.
>If this is an accurate statement of this new principle, my immediate re-
>sponse is: So what?  Why should we care?
>
>     I apologize for responding to a post that's 31 days old.  I got in
>on this long thread very late and I'm running very hard to catch up.
>


The question that the post was addressing had to do with the definition of
structured programming.  A mid exit loop does not fall within the bounds
defined by structured programming because the loop body does not then have a
single entry and a single exit.

This has nothing to do with whether mid exit loops are good or bad.  It only
has to do with whether mid exit loops conform to structured programming or
not.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                               ` Robert C. Martin
@ 1998-10-02  0:00                                                 ` John I. Moore, Jr.
  1998-10-02  0:00                                                   ` Ell
                                                                     ` (2 more replies)
  1998-10-02  0:00                                                 ` Ell
                                                                   ` (3 subsequent siblings)
  4 siblings, 3 replies; 510+ messages in thread
From: John I. Moore, Jr. @ 1998-10-02  0:00 UTC (permalink / raw)


Robert C. Martin wrote in message <6v2nr9$t8l$1@hirame.wwa.com>...
>The question that the post was addressing had to do with the definition of
>structured programming.  A mid exit loop does not fall within the bounds
>defined by structured programming because the loop body does not then have
> a single entry and a single exit.


I'm sorry, Martin.  I usually agree with your posts, but I will have to
object to this one.  Whose definition are you using for structured
programming?  Some of the earliest articles and books on structured
programming were written by Harlan Mills of IBM, and he always
defined a loop with a middle exit as an integral part of structured
programming.  He called it a do-while-do loop.

_____________________________________________________________

John I. Moore, Jr.
SoftMoore Consulting
16233 Monty Court
Rockville, MD  20853-1344

phone:  (301) 924-0680
email:  softmoore@compuserve.com










^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                                 ` Ell
@ 1998-10-03  0:00                                                   ` Ell
  1998-10-03  0:00                                                     ` Ell
  0 siblings, 1 reply; 510+ messages in thread
From: Ell @ 1998-10-03  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:

>Correction, I should have said "end-exit" rather that "single
>entry/single exit (se/se)" in my last post in this thread.

Actually, I guess there are some who strongly and wrongly argue for
general adherence to "end-exit" and against "multiple-exit" for some
alleged dependency management (DM) benefit.  The 2 concepts are of
course easily related because none "end-exit" might include
"multiple-exit".

Anyone who looks at a fair amount of non-OO, procedural code made by
knowledgeable, and experienced programmers will see the quite generous
and proper use of "non end-exits" and "multiple-exists".  Of course
the code is usually squeakingly correct with respect to DM, intuitive
key domain entity expression, overall conceptual readability.

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                                 ` John I. Moore, Jr.
  1998-10-02  0:00                                                   ` Ell
@ 1998-10-03  0:00                                                   ` John Goodsen
  1998-10-03  0:00                                                   ` Robert C. Martin
  2 siblings, 0 replies; 510+ messages in thread
From: John Goodsen @ 1998-10-03  0:00 UTC (permalink / raw)




--


John I. Moore, Jr. <70672.1744@compuserve.com> wrote in message
<6v39i0$fte$1@winter.news.erols.com>...
>Robert C. Martin wrote in message <6v2nr9$t8l$1@hirame.wwa.com>...
>>The question that the post was addressing had to do with the definition of
>>structured programming.  A mid exit loop does not fall within the bounds
>>defined by structured programming because the loop body does not then have
>> a single entry and a single exit.
>
>
>I'm sorry, Martin.  I usually agree with your posts, but I will have to
>object to this one.  Whose definition are you using for structured
>programming?  Some of the earliest articles and books on structured
>programming were written by Harlan Mills of IBM, and he always
>defined a loop with a middle exit as an integral part of structured
>programming.  He called it a do-while-do loop.
>

I read "mid exit loop" to mean an unnatural exit from the current
scope - like a goto or a return that is put inside a loop structure.

--
John Goodsen       RADSoft / Training, Mentoring and Consulting in:
jgoodsen@radsoft.com       - UML modeling and OOA/D principles
http://www.radsoft.com     - Use Centered Object-Oriented Design
602.283.0142               - Rapid Incremental S/W Delivery Process

"Example isn't another way to teach, it is the only way to teach. "
- Albert Einstein






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                                 ` John I. Moore, Jr.
  1998-10-02  0:00                                                   ` Ell
  1998-10-03  0:00                                                   ` John Goodsen
@ 1998-10-03  0:00                                                   ` Robert C. Martin
  1998-10-03  0:00                                                     ` Richard D Riehle
                                                                       ` (4 more replies)
  2 siblings, 5 replies; 510+ messages in thread
From: Robert C. Martin @ 1998-10-03  0:00 UTC (permalink / raw)



John I. Moore, Jr. <70672.1744@compuserve.com> wrote in message
<6v39i0$fte$1@winter.news.erols.com>...
>Robert C. Martin wrote in message <6v2nr9$t8l$1@hirame.wwa.com>...
>>The question that the post was addressing had to do with the definition of
>>structured programming.  A mid exit loop does not fall within the bounds
>>defined by structured programming because the loop body does not then have
>> a single entry and a single exit.
>
>
>I'm sorry, Martin.  I usually agree with your posts, but I will have to
>object to this one.  Whose definition are you using for structured
>programming?  Some of the earliest articles and books on structured
>programming were written by Harlan Mills of IBM, and he always
>defined a loop with a middle exit as an integral part of structured
>programming.  He called it a do-while-do loop.


Yes, Mills did make this definition.  However, I am referring to the work of
Dijkstra in the late 60's and early 70's.  Dijkstra was very clear about the
notion of single entry and single exit within the body of a loop.  I believe
that Mills' do-while-do loop is an unauthorized addition to Dijkstra's work.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                   ` Ell
@ 1998-10-03  0:00                                                     ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-03  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:

>Anyone who looks at a fair amount of non-OO, procedural code made by
>knowledgeable, and experienced programmers will see the quite generous
>and proper use of "non end-exits" and "multiple-exists".  Of course
>the code is usually squeakingly correct with respect to DM, intuitive
>key domain entity expression, overall conceptual readability.

rather:

>Anyone who looks at a fair amount of non-OO, procedural code made by
>knowledgeable, and experienced programmers will see the quite generous
>and proper use of "non end-exits" and "multiple-exits".  Of course
>the code is usually squeakingly correct with respect to DM, intuitive
>key domain entity expression, 
[as well as]
>overall conceptual readability.

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                   ` Robert C. Martin
  1998-10-03  0:00                                                     ` Richard D Riehle
  1998-10-03  0:00                                                     ` John I. Moore, Jr.
@ 1998-10-03  0:00                                                     ` Ell
  1998-10-05  0:00                                                     ` dewarr
  1998-10-09  0:00                                                     ` Matthew Heaney
  4 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-03  0:00 UTC (permalink / raw)


"Robert C. Martin" <rmartin@oma.com> wrote:

>John I. Moore, Jr. <70672.1744@compuserve.com> wrote in message
>>
>>Robert C. Martin wrote in message <6v2nr9$t8l$1@hirame.wwa.com>...
>>>
>>>The question that the post was addressing had to do with the definition of
>>>structured programming.  A mid exit loop does not fall within the bounds
>>>defined by structured programming because the loop body does not then have
>>> a single entry and a single exit.

>>I'm sorry, Martin.  I usually agree with your posts, but I will have to
>>object to this one.  Whose definition are you using for structured
>>programming?  Some of the earliest articles and books on structured
>>programming were written by Harlan Mills of IBM, and he always
>>defined a loop with a middle exit as an integral part of structured
>>programming.  He called it a do-while-do loop.

>Yes, Mills did make this definition.  However, I am referring to the work of
>Dijkstra in the late 60's and early 70's.  Dijkstra was very clear about the
>notion of single entry and single exit within the body of a loop.  I believe
>that Mills' do-while-do loop is an unauthorized addition to Dijkstra's work.

I hope you are not referring to the Dijkstra quotes on how to properly
create flowcharts.

And I hope you are not alleging that structured programming boils down
to exiting from a loop.

Another thing to remember is that while a procedure may return to its
caller from multiple places the flow of control always returns to the
same place in the caller.

Either way, it was abstraction and not simple navigation which came to
Dijkstra's mind when structured programming was mentioned.  We
holistic, pre-code modellers will always have that, I'm happy to say.

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                                 ` Charles H. Sampson
@ 1998-10-03  0:00                                                   ` Reimer Behrends
  1998-10-04  0:00                                                     ` Charles H. Sampson
  0 siblings, 1 reply; 510+ messages in thread
From: Reimer Behrends @ 1998-10-03  0:00 UTC (permalink / raw)


Charles H. Sampson (claveman@inetworld.net) wrote:
[...]
>      But it does.  Just look.  That's not a for-loop or a while-loop.  
> It's a loop that can only be executed with an exit statement and it has
> just one.  (Yes, an exception can cause it to exit too, but gimme a 
> break.)

You may notice, however, that the loop _body_ has two different exits
for a mid-exit loop.

[...]

				Reimer Behrends




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                   ` Robert C. Martin
  1998-10-03  0:00                                                     ` Richard D Riehle
@ 1998-10-03  0:00                                                     ` John I. Moore, Jr.
  1998-10-05  0:00                                                       ` Robert C. Martin
  1998-10-06  0:00                                                       ` Matt Kennel
  1998-10-03  0:00                                                     ` Ell
                                                                       ` (2 subsequent siblings)
  4 siblings, 2 replies; 510+ messages in thread
From: John I. Moore, Jr. @ 1998-10-03  0:00 UTC (permalink / raw)


Robert C. Martin wrote in message <6v4d5l$blb$1@hirame.wwa.com>...
>Yes, Mills did make this definition.  However, I am referring to the
>work of Dijkstra in the late 60's and early 70's.  Dijkstra was very
>clear about the notion of single entry and single exit within the
>body of a loop.  I believe that Mills' do-while-do loop is an
>unauthorized addition to Dijkstra's work.


Two points:

1.  Mills also wrote about structured programming in the 60's and 70's.
    He was a pioneer and champion of the ideas in the same sense as
    Dijkstra.

2.  Mills construct of do-while-do has a single entry and single exit,
    as do all of the other structured programming constructs.  Using
    an Ada-like syntax, consider the following:

    loop
       get x;
       exit when x satisfies some condition;
       process x;
    end loop;

    I contend that this logic is natural, that the loop has only a
    single entry and exit, and that it doesn't violate any of the
    structured programming guidelines.  Of course, one can rewrite
    it by using a standard while-loop, just as one can rewrite any
    repeat-until loop using a while-loop, but in order to do so you
    must repeat some part of the logic outside of the loop.

_____________________________________________________________

John I. Moore, Jr.
SoftMoore Consulting
16233 Monty Court
Rockville, MD  20853-1344

phone:  (301) 924-0680
email:  softmoore@compuserve.com








^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                   ` Robert C. Martin
@ 1998-10-03  0:00                                                     ` Richard D Riehle
  1998-10-03  0:00                                                     ` John I. Moore, Jr.
                                                                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 510+ messages in thread
From: Richard D Riehle @ 1998-10-03  0:00 UTC (permalink / raw)


In article <6v4d5l$blb$1@hirame.wwa.com>,
	"Robert C. Martin" <rmartin@oma.com> wrote:

  in response to a note by John I Moore, Jr. about the do-while-do
  loop suggested by Harlan Mills,

>
>Yes, Mills did make this definition. However, I am referring to the work of
>Dijkstra in the late 60's and early 70's. Dijkstra was very clear about the
>notion of single entry and single exit within the body of a loop. I believe
>that Mills'do-while-do loop is an unauthorized addition to Dijkstra's work.

Is every pronouncement by Dijkstra the equivalent of Holy writ?  Software is
a fledgling discipline even today.  It was certainly an immature practice in
the 1960's. I seem to recall that Albert Einstein once said that we should
try to make everything as simple as possible but not  simpler.  

The notion of "single-entry/single-exit" is obsolete.  It has been for a
long time.  Instead, rational programmers understand the need for control
structures that are readable, understandable, and maintainable. This
requires them to make the code as simple as possible "but not simpler." 
Single-entry/single-exit has the disadvantage of sometimes making the code
not only as simple as possible, but also simpler.  

Perhaps we should also disallow discontinuous mathematical functions.  
 
Richard Riehle
richard@adaworks.com
http://www.adaworks.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-05  0:00                                                     ` dewarr
@ 1998-10-04  0:00                                                       ` Robert C. Martin
  1998-10-05  0:00                                                         ` Ell
  1998-10-05  0:00                                                         ` Ell
  0 siblings, 2 replies; 510+ messages in thread
From: Robert C. Martin @ 1998-10-04  0:00 UTC (permalink / raw)



dewarr@my-dejanews.com wrote in message <6v9eg5$b55$1@nnrp1.dejanews.com>...
>In article <6v4d5l$blb$1@hirame.wwa.com>,
>  "Robert C. Martin" <rmartin@oma.com> wrote:
>
>> Yes, Mills did make this definition.  However, I am referring to the work
of
>> Dijkstra in the late 60's and early 70's.  Dijkstra was very clear about
the
>> notion of single entry and single exit within the body of a loop.  I
believe
>> that Mills' do-while-do loop is an unauthorized addition to Dijkstra's
work.
>
>
>What a hilarious post. I am sure that HM would be very amused by the idea
>that he had to get "authorization" from EWD for stating what he (very
>reasonably) defined as his notion of structured programming :-)


For your entertainment, below my signature I have included a post which
appeared about a month ago.  It was initially sent by Ray Gardner.  It gives
us some insight into how Dijkstra felt regarding Harland Mills and his
additions to Structured Programming.

As for Mills' notions regarding SM, he is entitled to have them.  And you
are entitled to consider that mid-exit loops are part of SP because Mills
said so.  And I, I am entitled to conclude that mid-exit loops are not part
of SP because Dijkstra unambiguously excluded them.  And, in this matter, I
think Dijkstra has priority.

Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com


======================================================================
Here's a clue, maybe.  Don't read too much into it.  From
"EWD494: Trip Report E.W. Dijkstra 16th April/7th May, 1975,
U.S.A. and Canada", reprinted in _Selected Writings on Computing:
A Personal Perspective_, E.W. Dijkstra, Springer-Verlag, 1982 (a
_really_ neat sample of Dijkstra's EWD papers, which I think were
mostly circulated only to colleagues by a sort of samizdat):
[Dijkstra stays with A. Wasserman, lectures at Berkeley, speaks
at ACM Pacific 75, lectures at Stanford, stays at Knuth's house.
Parties back at Wasserman's, meeting Karp, Floyd, and Backus.
Goes to LA for the International Conference on Software
Reliability.  Acerbic remarks.  Goes to ISI (?) to meet with
Manna, Ershov, Burstall, Randell, Turski, Wulf, and others, sees
an unconvincing demonstration of automatic program-proving.  Goes
to Phoenix for an ACM Chapter meeting [damn, why didn't we ever
get him to Denver when we had a viable chapter?], goes to Mission
Viejo to visit the Burroughs Large Systems Plant.  Flies to
Montreal to attend an IBM conference on Software Engineering Education.]
"... in my innocence I had expected an audience of computer
scientists.  My driver, however, was a manager, who opened the
conversation with something like 'so you are the world expert on
structured programming and chief programmer teams.'.  Then I knew
that I was out in the wilderness and politely refused to be
associated with Harlan D. Mills."
[More very acerbic remarks: "The ... conference was very
instructive for me, although I learned a lot without which I
would have been happier.  At most fify percent of the partcipants
were computing scientists; the rest were either IBM officials or
managers of the [DP] departments of large IBM customers.  I had
full opportunity to observe all the intricate love/hate relations
between the angles of the triangle 'university-manufacturer-
customer'.  It was all very frightening and I wish that I had a
mastery of my pen like Arthur Koestler, for then I could have
written a companion volume to his 'The Call Girls'."
"The central victims in this drama are the [MBAs] and the firms
dependent on their services ... They really have painted
themselves into a corner with very sticky molasses!  They have
made a number of unforgiveable mistakes.  One mistake is that
they have based their full automation upon the IBM/360.  When
that machine was announced, it was immediately clear to many --
even inside IBM!-- that it would be practically impossible to
write decent software for it... You cannot program a crooked
machine to go straight ... The next mistake is that they decided
to program in COBOL. ... OS/360 is no longer 'logical spaghetti',
but 'logical barbed wire'. ... on the whole it was ghastly;
unreal.  I was severely shocked by the cultural level of the
business participants. ..."]
"Later I heard Harlan Mills give a summing up of some of the
things I had said --together with some Harlanesk additions-- for
that business audience.  It was terrible, a misuse of language to
which to the best of my powers I could not give a meaning.  So,
every third phrase I interrupted Harlan 'please could you explain
or restate what you tried to say', but it was hopeless.  Tom Hull
helped me and I was very grateful to him.  Later, when it was all
over, our eyes met, and Tom gasped 'Jezus!'.  It was the first
time that I had heard him use strong language.  How to sell empty
but impressive slogans under the cloak of academic respectibility... ."
"Turski's comments were short: 'They don't want computer
scientists, nor software engineers, they want brainwashed mental
cripples.'.  It is too true... ."
"On the last morning, Harlan Mills gave the summing up talk.  It
was again very much of the same, but, remarkably enough, I
learned something from him, viz. the expression 'entry level
jobs'.  His argument was that the university should not train
experts --as an aside: training and education were constantly
confused-- because the jobs those experts should get were not
'entry level jobs'.  This may be a profound difference between
the academic community and (at least some of) the business
community: there is not the slightest objection to giving the
most responible university function, viz. a full professorship,
to a youngster who has just got his Ph.D.  It does not happen so
very often, because really brilliant people are rare; but nothing
in the university environment forbids it ... But to the business
communities represented it was unthinkable to give a youngster
any real responsibility... ."







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                   ` Reimer Behrends
@ 1998-10-04  0:00                                                     ` Charles H. Sampson
  1998-10-05  0:00                                                       ` Reimer Behrends
  0 siblings, 1 reply; 510+ messages in thread
From: Charles H. Sampson @ 1998-10-04  0:00 UTC (permalink / raw)


Reimer Behrends <behrends@cse.msu.edu> wrote:

> Charles H. Sampson (claveman@inetworld.net) wrote:
> [...]
> >      But it does.  Just look.  That's not a for-loop or a while-loop.
> > It's a loop that can only be executed with an exit statement and it has
> > just one.  (Yes, an exception can cause it to exit too, but gimme a
> > break.)
> 
> You may notice, however, that the loop _body_ has two different exits
> for a mid-exit loop.

     I don't know about others, but I don't notice any such thing.  Here
is a cut down version of the loop we were discussing.

               loop
                  <first part>
                  exit
                  <second part>
               end loop

Please point out the two exits (neither <first part> nor <second part> 
has one) or give the definition of <loop body> that you're using.

                                Charlie


-- 
     To get my correct email address, replace the "claveman" by
"csampson" in my fake (anti-spam) address.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                   ` Robert C. Martin
                                                                       ` (2 preceding siblings ...)
  1998-10-03  0:00                                                     ` Ell
@ 1998-10-05  0:00                                                     ` dewarr
  1998-10-04  0:00                                                       ` Robert C. Martin
  1998-10-09  0:00                                                     ` Matthew Heaney
  4 siblings, 1 reply; 510+ messages in thread
From: dewarr @ 1998-10-05  0:00 UTC (permalink / raw)


In article <6v4d5l$blb$1@hirame.wwa.com>,
  "Robert C. Martin" <rmartin@oma.com> wrote:

> Yes, Mills did make this definition.  However, I am referring to the work of
> Dijkstra in the late 60's and early 70's.  Dijkstra was very clear about the
> notion of single entry and single exit within the body of a loop.  I believe
> that Mills' do-while-do loop is an unauthorized addition to Dijkstra's work.


What a hilarious post. I am sure that HM would be very amused by the idea
that he had to get "authorization" from EWD for stating what he (very
reasonably) defined as his notion of structured programming :-)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-04  0:00                                                     ` Charles H. Sampson
@ 1998-10-05  0:00                                                       ` Reimer Behrends
  1998-10-05  0:00                                                         ` Patrick Logan
  1998-10-06  0:00                                                         ` Charles H. Sampson
  0 siblings, 2 replies; 510+ messages in thread
From: Reimer Behrends @ 1998-10-05  0:00 UTC (permalink / raw)


Charles H. Sampson (claveman@inetworld.net) wrote:
> Reimer Behrends <behrends@cse.msu.edu> wrote:
[Mid-exit loops.]
> > You may notice, however, that the loop _body_ has two different exits
> > for a mid-exit loop.
> 
>      I don't know about others, but I don't notice any such thing.  Here
> is a cut down version of the loop we were discussing.
> 
>                loop
>                   <first part>
>                   exit
>                   <second part>
>                end loop
> 
> Please point out the two exits (neither <first part> nor <second part> 
> has one) or give the definition of <loop body> that you're using.

The loop body is of course the following part of the code:

		<first part>
		exit
		<second part>

It has an exit at the "exit" statement, and one at the end of <second
part>, where control flow leaves the body to reenter at the top.  And
I'm not kidding you. Try to put the loop body into a procedure of its
own, and this becomes very visible. (Ease of procedural decomposition is
usually one of the benefits of strict single-entry, single-exit
structures.)

			Reimer Behrends




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-05  0:00                                                       ` Reimer Behrends
@ 1998-10-05  0:00                                                         ` Patrick Logan
  1998-10-06  0:00                                                         ` Charles H. Sampson
  1 sibling, 0 replies; 510+ messages in thread
From: Patrick Logan @ 1998-10-05  0:00 UTC (permalink / raw)


In comp.object Reimer Behrends <behrends@cse.msu.edu> wrote:
: > 
: >                loop
: >                   <first part>
: >                   exit
: >                   <second part>
: >                end loop
: > 
: > Please point out the two exits...

: 		<first part>
: 		exit
: 		<second part>

: It has an exit at the "exit" statement, and one at the end of <second
: part>, where control flow leaves the body to reenter at the top.  And
: I'm not kidding you. Try to put the loop body into a procedure of its
: own, and this becomes very visible. (Ease of procedural decomposition is
: usually one of the benefits of strict single-entry, single-exit
: structures.)

Well, you can easily put this into *two* procedures and end up with a
"structured program"...

void first_part()
  {
    <first part>
    if (!condition)
       second_part();
  }

void second_part()
  {
    <second part>
    first_part();
  }

...maybe a measure of the degree of "structuredness" of a loop is *how
many* well structured procedures result from the conversion?

-- 
Patrick Logan    (H) mailto:plogan@teleport.com 
                 (W) mailto:patrickl@gemstone.com 
                 http://www.gemstone.com




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-04  0:00                                                       ` Robert C. Martin
@ 1998-10-05  0:00                                                         ` Ell
  1998-10-05  0:00                                                           ` Ell
  1998-10-05  0:00                                                         ` Ell
  1 sibling, 1 reply; 510+ messages in thread
From: Ell @ 1998-10-05  0:00 UTC (permalink / raw)


"Robert C. Martin" <rmartin@oma.com> wrote:

>... And I, I am entitled to conclude that mid-exit loops are not part
>of SP because Dijkstra unambiguously excluded them.

Where?

> And, in this matter, I think Dijkstra has priority.

Why?

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-04  0:00                                                       ` Robert C. Martin
  1998-10-05  0:00                                                         ` Ell
@ 1998-10-05  0:00                                                         ` Ell
  1 sibling, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-05  0:00 UTC (permalink / raw)


"Robert C. Martin" <rmartin@oma.com> wrote:

>For your entertainment, below my signature I have included a post which
>appeared about a month ago.  It was initially sent by Ray Gardner.  It gives
>us some insight into how Dijkstra felt regarding Harland Mills and his
>additions to Structured Programming.
>
>[elided post]

I can see nothing in it that makes a reasoned and meaningful case
against Mills with regard to anything, including software engineering.

Perhaps it was due to how he was quoted, but on the whole the quote is
fuzzy, mildly incoherent and hard to get anything out of.  It seems he
had some problem with IBM, the 360, and universities and that Mills
was somehow involved in with them in ways he did not like.  But it is
really not clear.

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-05  0:00                                                         ` Ell
@ 1998-10-05  0:00                                                           ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-05  0:00 UTC (permalink / raw)


ell@access.digex.net (Ell) wrote:

>"Robert C. Martin" <rmartin@oma.com> wrote:
>
>>... And I, I am entitled to conclude that mid-exit loops are not part
>>of SP because Dijkstra unambiguously excluded them.

>Where?

And even if he did it isn't the essence of SP.  Abstraction is.
Modelling is!   :-}  

And I can show you where Dijkstra said that himself.  ("Art of
Literate Programming",  D. Knuth,  CLSC, pg 72)

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                     ` John I. Moore, Jr.
@ 1998-10-05  0:00                                                       ` Robert C. Martin
  1998-10-06  0:00                                                       ` Matt Kennel
  1 sibling, 0 replies; 510+ messages in thread
From: Robert C. Martin @ 1998-10-05  0:00 UTC (permalink / raw)



John I. Moore, Jr. <70672.1744@compuserve.com> wrote in message <6v5en9$d46

>2.  Mills construct of do-while-do has a single entry and single exit,
>    as do all of the other structured programming constructs.  Using
>    an Ada-like syntax, consider the following:
>
>    loop
>       get x;
>       exit when x satisfies some condition;
>       process x;
>    end loop;
>
>    I contend that this logic is natural, that the loop has only a
>    single entry and exit, and that it doesn't violate any of the
>    structured programming guidelines.  Of course, one can rewrite
>    it by using a standard while-loop, just as one can rewrite any
>    repeat-until loop using a while-loop, but in order to do so you
>    must repeat some part of the logic outside of the loop.



Ooops.  Sorry, I was mistaking mid-exit loops for loops with extra exits in
them.

Yes, a pure mid-exit loop (e.g. Mills' do-while-do *is* compatible with
structured programming.  Sorry for the fuss.  You were right and I was
wrong.


Robert C. Martin    | Design Consulting   | Training courses offered:
Object Mentor       | rmartin@oma.com     |   Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 |   C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com











^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                               ` Robert C. Martin
                                                                   ` (2 preceding siblings ...)
  1998-10-02  0:00                                                 ` Charles H. Sampson
@ 1998-10-05  0:00                                                 ` Graham Perkins
  1998-10-08  0:00                                                   ` s350817
  1998-10-09  0:00                                                 ` Matthew Heaney
  4 siblings, 1 reply; 510+ messages in thread
From: Graham Perkins @ 1998-10-05  0:00 UTC (permalink / raw)


Robert C. Martin wrote:
> >> >loop
> >> >    ... stuff
> >> >    exit when ;
> >> >    ... stuff
> >> >end loop;
> ...
> The question that the post was addressing had to do with the definition of
> structured programming.  A mid exit loop does not fall within the bounds
> defined by structured programming because the loop body does not then have a
> single entry and a single exit.

I beg to differ.

The construct as a whole has single entry and exit points.  So I
think we could be entitled to regard it as a structured programming
construct.  Try slicing a CASE flowchart across the middle .. you
get more than one flow line crossing the cut!

Crucially, other parts of the program may not transfer control
to any intermediate point between LOOP-EXIT, nor gain control
from any such point.

----------------------------------------------------------------
Graham Perkins, De Montfort University, Milton Keynes
http://www.mk.dmu.ac.uk/~gperkins/




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-06  0:00                                                       ` Matt Kennel
@ 1998-10-06  0:00                                                         ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-06  0:00 UTC (permalink / raw)


NOSPAMmbkennelNOSPAM@yahoo.com (Matt Kennel) wrote:

>On Sat, 3 Oct 1998 11:02:08 -0400, John I. Moore, Jr. wrote:
>:2.  Mills construct of do-while-do has a single entry and single exit,
>:    as do all of the other structured programming constructs.  Using
>:    an Ada-like syntax, consider the following:
>:
>:    loop
>:       get x;
>:       exit when x satisfies some condition;
>:       process x;
>:    end loop;
>:
>:    I contend that this logic is natural, that the loop has only a
>:    single entry and exit, and that it doesn't violate any of the
>:    structured programming guidelines.  Of course, one can rewrite
>:    it by using a standard while-loop, just as one can rewrite any
>:    repeat-until loop using a while-loop, but in order to do so you
>:    must repeat some part of the logic outside of the loop.
>
>Why is that loop morally superior to one like
>
>    loop
>       get x;
>       exit when x satisfies some condition;
>       partially process x;
>       exit if the preliminary processing shows something wrong
>       continue to process x;
>    end loop;
>
>Which does not have a single exit? 

This one:

>:   loop
>:       get x;
>:       exit when x satisfies some condition;
>:       process x;
>:    end loop;

based on discussion I think should really be:

    loop
       get x;
       exit when x satisfies some condition;
       process x;
    reloop;

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-05  0:00                                                       ` Reimer Behrends
  1998-10-05  0:00                                                         ` Patrick Logan
@ 1998-10-06  0:00                                                         ` Charles H. Sampson
  1998-10-11  0:00                                                           ` Reimer Behrends
  1 sibling, 1 reply; 510+ messages in thread
From: Charles H. Sampson @ 1998-10-06  0:00 UTC (permalink / raw)


Reimer Behrends <behrends@cse.msu.edu> wrote:

> Charles H. Sampson (claveman@inetworld.net) wrote:
> > Reimer Behrends <behrends@cse.msu.edu> wrote:
> [Mid-exit loops.]
> > > You may notice, however, that the loop _body_ has two different exits
> > > for a mid-exit loop.
> > 
> >      I don't know about others, but I don't notice any such thing.  Here
> > is a cut down version of the loop we were discussing.
> > 
> >                loop
> >                   <first part>
> >                   exit
> >                   <second part>
> >                end loop
> > 
> > Please point out the two exits (neither <first part> nor <second part>
> > has one) or give the definition of <loop body> that you're using.
> 
> The loop body is of course the following part of the code:
> 
>               <first part>
>               exit
>               <second part>
> 
> It has an exit at the "exit" statement, and one at the end of <second
> part>, where control flow leaves the body to reenter at the top.  And
> I'm not kidding you. Try to put the loop body into a procedure of its
> own, and this becomes very visible. (Ease of procedural decomposition is
> usually one of the benefits of strict single-entry, single-exit
> structures.)
> 

     O. k., I might grudgingly grant you a half score on that one.  You
pretty clearly said "loop body", but I was so fixed on "loop" that I 
didn't notice that you had changed the frame of reference.  I think I 
can be forgiven for my mistake; this whole subthread has been about 
exits from loops, not exits from loop bodies.

     Furthermore, it's not clear why that transfer of control is consid-
ered an exit from the loop body.  Prior to the transfer a statement of 
the body is executing.  After the transfer a statement of the body is 
executing.  Where is the exit part?

     Then there's the concept of transfer of control itself.  I'm sur-
prised about that.  Is that still taught in CS departments?  Certainly I
was taught it (I'm a VERY old programmer) and I still have to think 
about it in the rare cases when I'm mucking about among the 0s and 1s, 
but when I'm working in as good a high-level language as Ada I don't 
think in terms of control at all any more.  For example, a loop body for
me is simply a sequence of statement that is repeatedly executed until 
some condition arises.  (In case anyone wants to say, "Well, and exit 
statement contradicts that concept," an implicit effect of the execution
of an exit statement is to abort the execution of the rest of the loop 
body.)  For an if-then-else, there are two sequences of statements, of 
which one will execute depending on the value of a Boolean expression; I
don't think of transferring control from the evaluation code to the else
part if the expression evaluates to false.  I don't even think in terms
of transfer of control when an exception is raised; raising an exception
simply causes a certain dynamically determined exception handler to exe-
cute.

     Without thinking about it too hard, I'll grant your claim about 
ease of decomposition.  I don't want to think too hard about it because
I have the strong impression that this is another "who cares?" issue.  
In my entire career I have rarely written the following construct:

                    <loop head>
                       <procedure call>
                    end loop

Actually, I can't remember ever doing it, but I assume that I must have
at least a few times.

                                Charlie


-- 
     To get my correct email address, replace the "claveman" by
"csampson" in my fake (anti-spam) address.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                     ` John I. Moore, Jr.
  1998-10-05  0:00                                                       ` Robert C. Martin
@ 1998-10-06  0:00                                                       ` Matt Kennel
  1998-10-06  0:00                                                         ` Ell
  1 sibling, 1 reply; 510+ messages in thread
From: Matt Kennel @ 1998-10-06  0:00 UTC (permalink / raw)


On Sat, 3 Oct 1998 11:02:08 -0400, John I. Moore, Jr. wrote:
:2.  Mills construct of do-while-do has a single entry and single exit,
:    as do all of the other structured programming constructs.  Using
:    an Ada-like syntax, consider the following:
:
:    loop
:       get x;
:       exit when x satisfies some condition;
:       process x;
:    end loop;
:
:    I contend that this logic is natural, that the loop has only a
:    single entry and exit, and that it doesn't violate any of the
:    structured programming guidelines.  Of course, one can rewrite
:    it by using a standard while-loop, just as one can rewrite any
:    repeat-until loop using a while-loop, but in order to do so you
:    must repeat some part of the logic outside of the loop.

Why is that loop morally superior to one like

    loop
       get x;
       exit when x satisfies some condition;
       partially process x;
       exit if the preliminary processing shows something wrong
       continue to process x;
    end loop;

Which does not have a single exit? 

-- 
*        Matthew B. Kennel/Institute for Nonlinear Science, UCSD           
*
*      "To chill, or to pop a cap in my dome, whoomp! there it is."
*                 Hamlet, Fresh Prince of Denmark.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-05  0:00                                                 ` Graham Perkins
@ 1998-10-08  0:00                                                   ` s350817
  0 siblings, 0 replies; 510+ messages in thread
From: s350817 @ 1998-10-08  0:00 UTC (permalink / raw)


Graham Perkins wrote:
> 
> Robert C. Martin wrote:
> > >> >loop
> > >> >    ... stuff
> > >> >    exit when ;
> > >> >    ... stuff
> > >> >end loop;
> > ...
> > The question that the post was addressing had to do with the definition of
> > structured programming.  A mid exit loop does not fall within the bounds
> > defined by structured programming because the loop body does not then have a
> > single entry and a single exit.
> 
> I beg to differ.
> 
> The construct as a whole has single entry and exit points.  So I
> think we could be entitled to regard it as a structured programming
> construct.  Try slicing a CASE flowchart across the middle .. you
> get more than one flow line crossing the cut!
> 
> Crucially, other parts of the program may not transfer control
> to any intermediate point between LOOP-EXIT, nor gain control
> from any such point.
> 
> ----------------------------------------------------------------
> Graham Perkins, De Montfort University, Milton Keynes
> http://www.mk.dmu.ac.uk/~gperkins/

Assignment 1. Q 11




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-09-07  0:00                                                   ` Ray Gardner
  1998-09-07  0:00                                                     ` Ell
@ 1998-10-09  0:00                                                     ` Matthew Heaney
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


rgardner@nyx.net (Ray Gardner) writes:

> Matthew Heaney <matthew_heaney@acm.org> wrote:
> > rgardner@nyx.net (Ray Gardner) writes:
> > 
> > > RCM had responded with a direct quote from Dijkstra, but Ell But the
> > > original idea, as expounded by Dijkstra, Mills, Wirth, Ledgard, and
> > > others does indeed restrict you to single- entry/single-exit control
> > > structures, and they don't exit loops in the middle.
> > 
> > Oh!  You were doing well up to that last line.  Read about the
> > dowhiledo structure, in section 3.3.3, Iteration Structures, of
> > Structured Programming, by Linger, Mills, and Witt.
> > 
> Thanks for the correction, Matt.  Of course my main point was 
> that the founder(s) of SP did limit the control structures to 
> single-entry / single-exit structures, and that still stands.  
> The middle-exit loop (with single exit) is still such a structure 
> whether Dijkstra used it or not.  (He didn't).

I still say we're splitting hairs, here.

As Mills points out, the sequence of actions is:

read N
test N
process N
read N
test N
process N
read N
test N

There are two ways to turn this into a loop.  The most natural way
(according to me, and Soloway et al) is like this:

loop
   read N
   exit when N = 0
   process N
end loop

This describes the enumerated list of actions above.  The "classic" way
is like this:

read N

while N /= 0 loop
   process N
   read N
end loop


I recently read Dijkstra's structured programming monograph.  He
explicates his philosophy in the section 7 (p. 16), titled "On
Understanding Programs."  His argument is that the static program text
should be close to what happens dynamically, or, more simply, that
programs be understandable.

I argue that the middle-exit construction shown above satisfies
Dijkstra's "restricted topology" in the sense that a reader of the
(static) program text can easily understand what happens at run-time.

His philosophy is "to make a program in such a way that its correctness
[can] be proved without undue intellectual labor." [p. 39] Even though
Dijkstra doesn't specifically mention the middle-exit construction in
his monograph, I would argue that that construction satisfies his
ultimate goal, which easy-to-understand, provably-correct programs.











^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-02  0:00                                               ` Robert C. Martin
                                                                   ` (3 preceding siblings ...)
  1998-10-05  0:00                                                 ` Graham Perkins
@ 1998-10-09  0:00                                                 ` Matthew Heaney
  4 siblings, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


"Robert C. Martin" <rmartin@oma.com> writes:

> The question that the post was addressing had to do with the definition of
> structured programming.  A mid exit loop does not fall within the bounds
> defined by structured programming because the loop body does not then have a
> single entry and a single exit.
> 
> This has nothing to do with whether mid exit loops are good or bad.  It only
> has to do with whether mid exit loops conform to structured programming or
> not.

The specific text of what Dijkstra said is (from section 7, "On
Understanding Programs"):

<<These flowcharts share the property that they have a single entry at
the top and a single exit at the bottom: as indicated by the dotted
block they can again be interpreted (by disregarding what is inside the
dotted lines) as a single action in a sequential computation.>> [p. 19]

He says later that:

<<Alternatively: restricting ourselves to the three mentioned types of
decomposition leads to flowcharts of a restricted topology compared with
the flowcharts one can make when arrows can be drawn from any block
leading into any other.>> [p. 20]

I think the last part is very significant.  As Bob Eachus pointed out, a
subprogram with an early return really does have "single exit," because
all returns lead to the same place, to the POINT OF CALL.  

Dijkstra's complaint was that you can't tell what the program does at
run-time by reading the program text.  One cause is the unbridled use of
the goto statement, when you can jump out of a sequential abstraction
(the block to which Dijkstra refers) into any other.

By returning early from a subprogram, you are not "jumping into another
abstraction."  You are merely tracing another edge that leads to the
SAME NODE (the point of call) in the graph of the program.

He sums up that section by noting that:

<<The moral of the story is that when we acknowledge our duty to control
the computations (intellectually!) via the program text evoking them,
that then we should restrict ourselves in all humility to the most
systematic sequencing mechanisms, ensuring that "progress through the
computation" is mapped on "progress through the text" in the most
straightforward manner.>> [p. 23]

I argue that an early return (appropriately used, of course) meets his
criterion of understanding the mapping of static program text to dynamic
program behavior.  

The whole point of structured programming is NOT to "use only these
three control flow constructs."  It is as he states in that last summary
paragraph: that programs should be intellectually manageable.  If a
mid-loop exit simplifies a loop, or an early return simplifies a 
subprogram, then by all means use it.







^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-03  0:00                                                   ` Robert C. Martin
                                                                       ` (3 preceding siblings ...)
  1998-10-05  0:00                                                     ` dewarr
@ 1998-10-09  0:00                                                     ` Matthew Heaney
  1998-10-09  0:00                                                       ` Ell
  4 siblings, 1 reply; 510+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


"Robert C. Martin" <rmartin@oma.com> writes:

> Yes, Mills did make this definition.  However, I am referring to the work of
> Dijkstra in the late 60's and early 70's.  Dijkstra was very clear about the
> notion of single entry and single exit within the body of a loop.

I think it's debateable whether Dijkstra was "very clear" about the a
single exit means, given the popularity of this thread.

Dijkstra's argument was to avoid constructions in which you could jump
out of one abstraction directly into another, and to restrict oneself to
"systematic sequencing mechanisms."  

Based on my own reading of his monograph, I would interpret "single exit"
to include early returns (or loop exits), because all returns go to a
single point - the point of call.

> I believe that Mills' do-while-do loop is an unauthorized addition to
> Dijkstra's work.

I don't think Dijkstra is in the business of "authorizing" what
loop constructs are allowed.  Indeed, as David Gries has pointed out, in
his monograph, Dijkstra nowhere defines what "structured programming"
actually means.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-09  0:00                                                     ` Matthew Heaney
@ 1998-10-09  0:00                                                       ` Ell
  0 siblings, 0 replies; 510+ messages in thread
From: Ell @ 1998-10-09  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> wrote:

>I don't think Dijkstra is in the business of "authorizing" what
>loop constructs are allowed.  Indeed, as David Gries has pointed out, in
>his monograph, Dijkstra nowhere defines what "structured programming"
>actually means.

In a quote close to an overall view he said that the first thing he
thought of when someone mentioned structured programming was
"abstraction".  ("The Art of Literate Programming",  D. Knuth, CLSC,
page 72)

This tends to back up the point I (and I think Heaney) have made in
previous articles that it seems Dijkstra was emphasizing that
navigation should mainly take place between coherent abstractions as
opposed navigating between free standing entities.

It also makes me think that modelling was a key aspect of the
structured paradigm because the essential act of abstraction, "the act
or process of separating the inherent qualities or properties of
something from the actual physical object or concept to which they
belong" is also the essence of modelling and simulation in software
engineering generally.

Elliott
--
                :=***=:   VOTE  NO  TO  MODERATION!   :=***=: 
CRAFTISM SHOULD NOT USE USENET RESOURCES TO AVOID CRITICISM!
              MODERATORS SHOULD NOT HAVE LIFETIME TERMS!
        :=***=:  Objective  *  Pre-code Modelling  *  Holistic  :=***=:
                      Hallmarks of the best SW Engineering
  Study Phony Crafite OO vs. Genuine OO: http://www.access.digex.net/~ell
    Copyright 1998 Elliott. exclusive of others' writing. may be copied
      without permission only in the comp.* usenet and bitnet groups.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                 ` <m3ogt3qgca.fsf@mheaney.ni.n <1dghyt5.oik1lzhxzf2N@n207167116176.inetworld.net>
@ 1998-10-10  0:00                                   ` Patrick Doyle
  1998-10-12  0:00                                     ` Charles H. Sampson
  0 siblings, 1 reply; 510+ messages in thread
From: Patrick Doyle @ 1998-10-10  0:00 UTC (permalink / raw)


In article <1dghyt5.oik1lzhxzf2N@n207167116176.inetworld.net>,
Charles H. Sampson <claveman@inetworld.net> wrote:
>
>In my entire career I have rarely written the following construct:
>
>                    <loop head>
>                       <procedure call>
>                    end loop
>
>Actually, I can't remember ever doing it, but I assume that I must have
>at least a few times.

Eh?  How can you write a serious loop without calling a procedure
from inside it?

Do I misunderstand what you wrote?

 -PD

-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-06  0:00                                                         ` Charles H. Sampson
@ 1998-10-11  0:00                                                           ` Reimer Behrends
  0 siblings, 0 replies; 510+ messages in thread
From: Reimer Behrends @ 1998-10-11  0:00 UTC (permalink / raw)


Charles H. Sampson (claveman@inetworld.net) wrote:
> Reimer Behrends <behrends@cse.msu.edu> wrote:
[...]
> > The loop body is of course the following part of the code:
> > 
> >               <first part>
> >               exit
> >               <second part>
> > 
> > It has an exit at the "exit" statement, and one at the end of <second
> > part>, where control flow leaves the body to reenter at the top.  And
> > I'm not kidding you. Try to put the loop body into a procedure of its
> > own, and this becomes very visible. (Ease of procedural decomposition is
> > usually one of the benefits of strict single-entry, single-exit
> > structures.)
> 
>      O. k., I might grudgingly grant you a half score on that one.  You
> pretty clearly said "loop body", but I was so fixed on "loop" that I 
> didn't notice that you had changed the frame of reference.

Hmm. I was under the impression that I had phrased my reply with
sufficient precision to not confuse the non-casual reader. My apologies
if this wasn't the case.

In any event, I didn't intend to "score". I just wished to point out an
aspect that had apparently been overlooked in the discussion.

[...]

>      Furthermore, it's not clear why that transfer of control is consid-
> ered an exit from the loop body.  Prior to the transfer a statement of 
> the body is executing.  After the transfer a statement of the body is 
> executing.  Where is the exit part?

I have very little interest in abstractly discussing whether any
particular control structure can be construed as having a single entry
and/or single exit.

Rather, there are certain advantages commonly associated with classical
single-entry/single-exit control structures (ease of decomposition,
clear control flow, etc.). I am arguing that these advantages are not
present in a mid-exit loop, no matter whether you can technically say
that a mid-exit loop has a single exit, and I was pointing out the
reason why.

[...]

>      Without thinking about it too hard, I'll grant your claim about 
> ease of decomposition.  I don't want to think too hard about it because
> I have the strong impression that this is another "who cares?" issue.  
> In my entire career I have rarely written the following construct:
> 
>                     <loop head>
>                        <procedure call>
>                     end loop
> 
> Actually, I can't remember ever doing it, but I assume that I must have
> at least a few times.

I am perfectly aware that using abstractions on a regular basis is not a
popular notion; mostly, I think, because some people still believe that
using a procedure/class/etc. instead of inserting code directly will
invariably slow their code down to a crawl. Of course, they tend to
forgot about things like maintenance cost. Personally, I am pretty sick
of code that spans several pages without any apparent benefit.

[...]

				Reimer Behrends




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
       [not found]                                               ` <m31zpq4pim.fsf@mheaney.ni.ne <m3af36wtwh.fsf@mheaney.ni.net>
@ 1998-10-11  0:00                                                 ` Patrick Doyle
  0 siblings, 0 replies; 510+ messages in thread
From: Patrick Doyle @ 1998-10-11  0:00 UTC (permalink / raw)


In article <m3af36wtwh.fsf@mheaney.ni.net>,
Matthew Heaney  <matthew_heaney@acm.org> wrote:
>
>There are two ways to turn this into a loop.  The most natural way
>(according to me, and Soloway et al) is like this:
>
>loop
>   read N
>   exit when N = 0
>   process N
>end loop
>
>This describes the enumerated list of actions above.  The "classic" way
>is like this:
>
>read N
>
>while N /= 0 loop
>   process N
>   read N
>end loop
>
> [...]
>
>I argue that the middle-exit construction shown above satisfies
>Dijkstra's "restricted topology" in the sense that a reader of the
>(static) program text can easily understand what happens at run-time.

You make some good points.

I'd just like to add that another desirable property of a loop is
that all exit conditions are concentrated in one place.  This,
in combination with my own preference for the first form (above)
rather than the second (which repeats the "read N" part), led
me, a while back, to propose a loop syntax like this:

until exit{end_of_file} loop
  read N
  if N = 0 then exit(end_of_file);
  process N
end loop

This has the advantages of your first method with the added benefit
that the exit conditions are concentrated in one place, for easy
comprehension.  

Clearly, this could already be done without special syntax simply by
declaring a boolean flag and then, perhaps, relying on the compiler
to optimize it away.  However, it would be nice to be able to express
to the compiler that you don't want a flag; you are simply trying
to describe the flow of control through the loop.

Another point is that it is important for the program to be able to 
discern the reason for loop termination.  You should be able to say "if
end_of_file" after executing the loop.  However, again, this should
not be translated into a boolean flag test.  Again it's just
describing the flow of control.

What I'm trying to say is that we should be guaranteed that
the compiler will turn this:

	loop
	  A;
	  if B then exit(condition1);
	  C;
	until 
	  exit{condition1} or condition2 
	end loop

	if condition1 then
	  D;
	end if
	E;


...into something like this:

top:	A
	if !B then goto after
	D
	goto bottom
after:	C
	if !condition2 then goto top
bottom:	E

See what I'm getting at?  The source code is not trying to
express how the loop should be implemented.  It's trying to
express the flow control in a human-friendly form, and the
programmer should be confident that it will be implemented
in a machine-friendly form.  After all, isn't that the
point of a compiled language?  :-)

I know that most compilers do simple optimizations like this
anyway.  I'm just trying to differentiate between my mental image
of exit conditions and simple boolean flags.

 -PD
-- 
--
Patrick Doyle
doylep@ecf.toronto.edu




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-10  0:00                                   ` Patrick Doyle
@ 1998-10-12  0:00                                     ` Charles H. Sampson
  1998-10-13  0:00                                       ` Matthew Heaney
  1998-10-14  0:00                                       ` Graham Perkins
  0 siblings, 2 replies; 510+ messages in thread
From: Charles H. Sampson @ 1998-10-12  0:00 UTC (permalink / raw)


Patrick Doyle <doylep@ecf.toronto.edu> wrote:

> In article <1dghyt5.oik1lzhxzf2N@n207167116176.inetworld.net>,
> Charles H. Sampson <claveman@inetworld.net> wrote:
> >
> >In my entire career I have rarely written the following construct:
> >
> >                    <loop head>
> >                       <procedure call>
> >                    end loop
> >
> >Actually, I can't remember ever doing it, but I assume that I must have
> >at least a few times.
> 
> Eh?  How can you write a serious loop without calling a procedure
> from inside it?
> 
> Do I misunderstand what you wrote?

     I suspect that we're each misunderstanding the other, because your
response has surely puzzled me.  Before the confusion gets worse, maybe
you should define the term "serious loop".

     The above structure, that I don't remember writing, is not a loop 
that fails to contain a procedure call in its body.  It's a loop whose 
body consists entirely of a single procedure call.

                                Charlie

-- 
     To get my correct email address, replace the "claveman" by
"csampson" in my fake (anti-spam) address.




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-12  0:00                                     ` Charles H. Sampson
@ 1998-10-13  0:00                                       ` Matthew Heaney
  1998-10-14  0:00                                       ` Graham Perkins
  1 sibling, 0 replies; 510+ messages in thread
From: Matthew Heaney @ 1998-10-13  0:00 UTC (permalink / raw)


claveman@inetworld.net (Charles H. Sampson) writes:

>In my entire career I have rarely written the following construct:
>
>                    <loop head>
>                       <procedure call>
>                    end loop
>
>Actually, I can't remember ever doing it, but I assume that I must have
>at least a few times.

>      The above structure, that I don't remember writing, is not a loop
> that fails to contain a procedure call in its body.  It's a loop whose
> body consists entirely of a single procedure call.


I do this from time-to-time, for a for loop body that's getting a long.
Instead of:

   for Index in Index_Type loop
      declare
         <decl's that depend on Index>
      begin
         <lots of stuff here>
      end;
   end loop;


I prefer to do this:
 
   procedure Do_Something (Index : in Index_Type);

   for Index in Index_Type loop
      Do_Something (Index);
   end loop;






^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-12  0:00                                     ` Charles H. Sampson
  1998-10-13  0:00                                       ` Matthew Heaney
@ 1998-10-14  0:00                                       ` Graham Perkins
  1998-10-15  0:00                                         ` Reimer Behrends
  1 sibling, 1 reply; 510+ messages in thread
From: Graham Perkins @ 1998-10-14  0:00 UTC (permalink / raw)


Charles H. Sampson wrote:
...
>      The above structure, that I don't remember writing, is not a loop
> that fails to contain a procedure call in its body.  It's a loop whose
> body consists entirely of a single procedure call.

A very frequent construct in student programs!

Also we often find "main program" which consists of a single procedure
call, and many individual procedures which consist of nothing but
two or three parameter-less procedure calls.

We try to reform such people before they graduate!!  But many
slip through.

Now someone please tell me that *all* of these student are
kept away from real programming once they get jobs !

----------------------------------------------------------------
Graham Perkins, De Montfort University, Milton Keynes
http://www.mk.dmu.ac.uk/~gperkins/




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-14  0:00                                       ` Graham Perkins
@ 1998-10-15  0:00                                         ` Reimer Behrends
  1998-10-15  0:00                                           ` dewarr
  0 siblings, 1 reply; 510+ messages in thread
From: Reimer Behrends @ 1998-10-15  0:00 UTC (permalink / raw)


Graham Perkins (gperkins@dmu.ac.uk) wrote:
[...]
> Also we often find "main program" which consists of a single procedure
> call, and many individual procedures which consist of nothing but
> two or three parameter-less procedure calls.
> 
> We try to reform such people before they graduate!!  But many
> slip through.

Well, I hope so. :) An abstraction (procedure or class) is a good
abstraction because it embodies a useful concept, not because it saves
space.

	void f() { g(); }

is a perfectly legitimate construct, with the obvious benefit that
you can at any time change the implementation of f() from g() to h()
without affecting the code that uses it.

Imagine for instance the case of writing an anonymous mailer, where
you want to eliminate all uses of the "From" address and replace it
by a dummy. (Say, for anonymous feedback in a class.) Now, if there
is a uniform function

	string from_address() { return user_name(); }

then you can just change this single function. However, if user_name()
were used all over the place, making the change is anything but
pleasant.

(Extra points for spotting the reference and noticing that it is
anything but fictitious.)

[...]

				Reimer Behrends




^ permalink raw reply	[flat|nested] 510+ messages in thread

* Re: Software landmines (loops)
  1998-10-15  0:00                                         ` Reimer Behrends
@ 1998-10-15  0:00                                           ` dewarr
  0 siblings, 0 replies; 510+ messages in thread
From: dewarr @ 1998-10-15  0:00 UTC (permalink / raw)


In article <slrn72bafc.16n.behrends@allegro.cse.msu.edu>,
  behrends@cse.msu.edu (Reimer Behrends) wrote:
> Graham Perkins (gperkins@dmu.ac.uk) wrote:
> [...]
> > Also we often find "main program" which consists of a single procedure
> > call, and many individual procedures which consist of nothing but
> > two or three parameter-less procedure calls.
> >
> > We try to reform such people before they graduate!!  But many
> > slip through.
>
> Well, I hope so. :) An abstraction (procedure or class) is a good
> abstraction because it embodies a useful concept, not because it saves
> space.

I often tell students that if I see a large program which does NOT contain
instances of subprograms called only once, it is misstructured.

Indeed I find it annoying that many modern programming languages make it
harder than necessary to introduce simple "refinement" procedures in two
ways:

1. They require the declaration before the call, which is annoying in this
case, since the program then is written "upside down".

2. They require a lot of syntax

One of the most attractive features of COBOL is its economical syntax for
this kind of refinement:

   check-balance.
      if balance > 0 then
        perform record-credit
      else
        perform send-bill
      end-if.

   record-credit.
      ...

   send-bill.
      ...

Lambert Meertens ABC language provides a similar functionality as did
Koster's CDL. But many modern Algol-derived languages are lacking in this
area, and as a result one often sees conditionals nested annoyingly deep
in an effort to avoid clarifying refinements.

Robert Dewar

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 510+ messages in thread

end of thread, other threads:[~1998-10-15  0:00 UTC | newest]

Thread overview: 510+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-09-07  0:00 Software landmines (loops) Robert Martin
1998-09-08  0:00 ` Mike Spille
  -- strict thread matches above, loose matches on Subject: below --
1998-08-06  0:00 Why C++ is successful Robert Dewar
1998-08-07  0:00 ` harald.mueller
1998-08-07  0:00   ` Brian Rogoff
1998-08-07  0:00     ` Timothy Welch
1998-08-08  0:00       ` Robert Dewar
1998-08-08  0:00         ` Jeffrey C. Dege
1998-08-10  0:00           ` Laurent GUERBY
1998-08-12  0:00             ` Andy Ward
1998-08-14  0:00               ` Robert Dewar
1998-08-14  0:00                 ` Software landmines (was: Why C++ is successful) dennison
1998-08-16  0:00                   ` Robert Dewar
1998-08-17  0:00                     ` dennison
1998-08-19  0:00                       ` ell
1998-08-19  0:00                         ` adam
1998-08-19  0:00                           ` Dan Higdon
1998-08-20  0:00                             ` adam
1998-08-20  0:00                               ` Software landmines (loops) Nick Leaton
1998-08-30  0:00                                 ` Matthew Heaney
1998-08-30  0:00                                   ` Robert Martin
1998-08-30  0:00                                     ` Charles Hixson
1998-08-31  0:00                                       ` Robert I. Eachus
1998-08-31  0:00                                     ` Ell
1998-08-31  0:00                                       ` Robert Martin
1998-08-31  0:00                                         ` Jeffrey C. Dege
1998-08-31  0:00                                           ` Ell
1998-08-31  0:00                                             ` Gene Gajewski
1998-08-31  0:00                                           ` Ell
1998-08-31  0:00                                             ` Jeffrey C. Dege
1998-08-31  0:00                                         ` Stephen Leake
1998-08-31  0:00                                           ` Robert Martin
1998-08-31  0:00                                             ` Agent
1998-09-01  0:00                                               ` Ell
1998-08-31  0:00                                                 ` Robert Martin
1998-09-01  0:00                                                   ` Tim Ottinger
1998-09-01  0:00                                                     ` Robert Martin
1998-09-01  0:00                                                   ` dennison
1998-09-01  0:00                                                     ` Robert Martin
1998-09-02  0:00                                                       ` Andrew Reilly
1998-09-01  0:00                                                         ` Robert Martin
1998-09-02  0:00                                                           ` dennison
     [not found]                                                 ` <6sfqul$ggg$1@hirame. <6sidsq$e6c$1@hirame.wwa.com>
1998-09-03  0:00                                                   ` Patrick Doyle
1998-09-03  0:00                                                     ` Charles Hixson
1998-09-03  0:00                                                       ` John G. Volan
1998-09-01  0:00                                             ` Phil Goodwin
1998-09-01  0:00                                               ` Robert Martin
1998-09-02  0:00                                                 ` Ell
1998-09-01  0:00                                                   ` Robert Martin
1998-09-02  0:00                                                     ` Richard MacDonald (dogmat)
1998-09-03  0:00                                                       ` Matthew Heaney
1998-09-02  0:00                                                     ` Richard Melvin
1998-09-02  0:00                                                     ` dennison
1998-09-02  0:00                                                     ` Matthew Heaney
1998-09-02  0:00                                                       ` Robert Martin
1998-09-02  0:00                                                         ` Richard Melvin
1998-09-02  0:00                                                           ` Tim Ottinger
1998-09-02  0:00                                                         ` Matthew Heaney
1998-09-03  0:00                                                     ` mfinney
     [not found]                                                     ` <gio+van+no+ni+8-0309982244140001@dialup62.tlh.talstar.com>
1998-09-04  0:00                                                       ` Ell
     [not found]                                                 ` <gio+van+no+ni+8-0309982225160001@dialup62.tlh.talstar.com>
1998-09-15  0:00                                                   ` mfinney
1998-09-01  0:00                                             ` Matthew Heaney
1998-10-01  0:00                                             ` Charles H. Sampson
1998-10-02  0:00                                               ` Ell
1998-10-02  0:00                                               ` Robert C. Martin
1998-10-02  0:00                                                 ` John I. Moore, Jr.
1998-10-02  0:00                                                   ` Ell
1998-10-03  0:00                                                   ` John Goodsen
1998-10-03  0:00                                                   ` Robert C. Martin
1998-10-03  0:00                                                     ` Richard D Riehle
1998-10-03  0:00                                                     ` John I. Moore, Jr.
1998-10-05  0:00                                                       ` Robert C. Martin
1998-10-06  0:00                                                       ` Matt Kennel
1998-10-06  0:00                                                         ` Ell
1998-10-03  0:00                                                     ` Ell
1998-10-05  0:00                                                     ` dewarr
1998-10-04  0:00                                                       ` Robert C. Martin
1998-10-05  0:00                                                         ` Ell
1998-10-05  0:00                                                           ` Ell
1998-10-05  0:00                                                         ` Ell
1998-10-09  0:00                                                     ` Matthew Heaney
1998-10-09  0:00                                                       ` Ell
1998-10-02  0:00                                                 ` Ell
1998-10-03  0:00                                                   ` Ell
1998-10-03  0:00                                                     ` Ell
1998-10-02  0:00                                                 ` Charles H. Sampson
1998-10-03  0:00                                                   ` Reimer Behrends
1998-10-04  0:00                                                     ` Charles H. Sampson
1998-10-05  0:00                                                       ` Reimer Behrends
1998-10-05  0:00                                                         ` Patrick Logan
1998-10-06  0:00                                                         ` Charles H. Sampson
1998-10-11  0:00                                                           ` Reimer Behrends
1998-10-05  0:00                                                 ` Graham Perkins
1998-10-08  0:00                                                   ` s350817
1998-10-09  0:00                                                 ` Matthew Heaney
1998-08-31  0:00                                         ` Matthew Heaney
1998-08-31  0:00                                           ` Gene Gajewski
1998-08-31  0:00                                           ` Ell
1998-08-31  0:00                                             ` Robert Martin
1998-08-31  0:00                                               ` Ell
1998-08-31  0:00                                                 ` Robert Martin
1998-09-03  0:00                                                   ` Steven Perryman
1998-09-01  0:00                                                 ` Charles Hixson
1998-08-31  0:00                                             ` Phlip
1998-08-31  0:00                                               ` Robert Martin
1998-08-31  0:00                                           ` Patrick Logan
1998-09-01  0:00                                             ` dewarr
1998-09-01  0:00                                       ` Charles Hixson
     [not found]                                     ` <35f51e53.48044143@ <m3af4mq7f4.fsf@mheaney.ni.net>
1998-08-31  0:00                                       ` Andrew Hussey
1998-08-31  0:00                                         ` Mattias Lundstr�m
1998-08-31  0:00                                           ` Robert Martin
1998-08-31  0:00                                             ` Robert I. Eachus
1998-08-31  0:00                                               ` Robert Martin
1998-09-01  0:00                                                 ` Matthew Heaney
1998-09-01  0:00                                                   ` Stephen Leake
1998-09-01  0:00                                                     ` Robert Martin
1998-09-01  0:00                                               ` Matthew Heaney
1998-09-01  0:00                                             ` Mattias Lundstr�m
1998-09-01  0:00                                               ` Robert Martin
1998-09-01  0:00                                                 ` Robert I. Eachus
1998-09-01  0:00                                                   ` Robert Martin
1998-09-02  0:00                                                 ` Mattias Lundstr�m
1998-09-02  0:00                                                   ` Robert Martin
1998-09-02  0:00                                                 ` Mattias Lundstr�m
1998-09-01  0:00                                             ` Richard Jones
1998-09-02  0:00                                               ` Mattias Lundstr�m
1998-09-02  0:00                                                 ` Patrick Logan
1998-09-02  0:00                                                   ` Robert Martin
1998-09-02  0:00                                               ` Mattias Lundstr�m
1998-09-02  0:00                                               ` Mattias Lundstr�m
1998-09-02  0:00                                               ` Mattias Lundstr�m
1998-09-01  0:00                                           ` Tim Ottinger
1998-08-31  0:00                                         ` Matthew Heaney
1998-08-31  0:00                                           ` Tim McDermott
1998-08-31  0:00                                             ` Larry Brasfield
1998-09-01  0:00                                               ` Matthew Heaney
1998-09-01  0:00                                             ` dewar
1998-09-01  0:00                                             ` Matthew Heaney
1998-08-31  0:00                                           ` Robert Martin
1998-08-31  0:00                                             ` Gene Gajewski
1998-09-01  0:00                                             ` sureshvv
1998-09-01  0:00                                               ` Robert Martin
1998-09-02  0:00                                                 ` sureshvv
1998-09-02  0:00                                                   ` Robert Martin
1998-09-02  0:00                                                   ` Robert Martin
1998-09-03  0:00                                                     ` Charles Hixson
1998-09-04  0:00                                                       ` adam
1998-09-06  0:00                                                         ` Gerry Quinn
1998-09-04  0:00                                                       ` Patrick Logan
1998-09-04  0:00                                                     ` Rick Smith
1998-09-04  0:00                                                       ` Robert Martin
1998-09-04  0:00                                                       ` Charles Hixson
     [not found]                                                       ` <gio+van+no+ni+8-0809981818260001@dialup75.tlh.talstar.com>
1998-09-08  0:00                                                         ` Mark A Biggar
1998-09-08  0:00                                                         ` Rick Smith
1998-09-08  0:00                                                       ` adam
1998-09-08  0:00                                                         ` Rick Smith
1998-09-01  0:00                                             ` Robert I. Eachus
1998-09-01  0:00                                             ` Matthew Heaney
1998-08-31  0:00                                               ` Robert Martin
1998-09-01  0:00                                                 ` Gerhard Menzl
1998-09-02  0:00                                                 ` Tres Seaver
1998-09-02  0:00                                                   ` Robert Martin
1998-09-03  0:00                                                     ` sureshvv
1998-09-03  0:00                                                   ` Patrick Logan
1998-09-01  0:00                                             ` Phil Goodwin
1998-09-01  0:00                                               ` Biju Thomas
1998-09-02  0:00                                                 ` Phil Goodwin
1998-09-02  0:00                                                   ` Robert Martin
1998-09-03  0:00                                                     ` Phil Goodwin
1998-09-03  0:00                                                       ` Robert Martin
1998-09-03  0:00                                               ` Ole-Hjalmar Kristensen
1998-09-01  0:00                                             ` Richard Melvin
1998-09-01  0:00                                               ` Robert Martin
1998-09-02  0:00                                               ` Jim Cochrane
1998-09-02  0:00                                                 ` Richard Melvin
1998-09-02  0:00                                                   ` Jim Cochrane
1998-09-03  0:00                                                     ` Matthew Heaney
1998-09-03  0:00                                                       ` Loryn Jenkins
1998-09-03  0:00                                                       ` Jim Cochrane
1998-09-01  0:00                                             ` Chris Brand
1998-09-01  0:00                                               ` Robert Martin
1998-09-01  0:00                                                 ` Biju Thomas
1998-09-01  0:00                                                   ` Robert Martin
1998-09-01  0:00                                           ` Loryn Jenkins
1998-09-01  0:00                                             ` Matthew Heaney
1998-09-01  0:00                                               ` Loryn Jenkins
1998-09-01  0:00                                                 ` Matthew Heaney
1998-09-01  0:00                                                   ` James Weirich
1998-09-01  0:00                                                     ` Mike Spille
1998-09-02  0:00                                                       ` Nick Leaton
1998-09-02  0:00                                                   ` Loryn Jenkins
1998-09-01  0:00                                                     ` John Volan
1998-09-01  0:00                                                     ` John Volan
1998-09-01  0:00                                                       ` Robert Martin
1998-09-02  0:00                                                       ` Nick Leaton
1998-09-02  0:00                                                       ` Chris Saunders
1998-09-01  0:00                                                     ` Darren New
1998-09-02  0:00                                                       ` Loryn Jenkins
1998-09-02  0:00                                                         ` Matthew Heaney
1998-09-02  0:00                                                           ` Loryn Jenkins
1998-09-02  0:00                                                     ` Matthew Heaney
1998-09-02  0:00                                                       ` Loryn Jenkins
1998-09-02  0:00                                                       ` Tim McDermott
1998-09-03  0:00                                                         ` Matthew Heaney
1998-09-03  0:00                                                       ` Joe Gamache
1998-09-04  0:00                                                         ` Charles Hixson
1998-09-05  0:00                                                           ` Patrick Logan
1998-09-05  0:00                                                             ` Charles Hixson
1998-09-04  0:00                                                 ` Charles Hixson
1998-09-05  0:00                                                   ` Loryn Jenkins
1998-09-01  0:00                                               ` dewarr
1998-09-04  0:00                                               ` Jean-Marc Jezequel
1998-09-04  0:00                                                 ` Richard Melvin
1998-09-07  0:00                                                   ` Jean-Marc Jezequel
1998-09-01  0:00                                           ` Don Harrison
1998-09-01  0:00                                         ` dewarr
1998-08-31  0:00                                     ` dennison
1998-08-31  0:00                                       ` Robert Martin
1998-09-01  0:00                                         ` Matthew Heaney
1998-09-06  0:00                                           ` Charles Hixson
1998-09-06  0:00                                             ` Matthew Heaney
1998-09-01  0:00                                       ` Andrew Reilly
1998-09-01  0:00                                         ` Matthew Heaney
1998-09-01  0:00                                         ` dennison
1998-09-01  0:00                                         ` dewarr
     [not found]                                     ` <35f51e53.48044143@news.erols.c <m3af4mq7f4.fsf@mheaney.ni.net>
1998-08-31  0:00                                       ` Patrick Doyle
1998-08-31  0:00                                         ` Gene Gajewski
1998-08-31  0:00                                         ` Richard D Riehle
1998-09-01  0:00                                           ` Simon Wright
1998-09-02  0:00                                           ` adam
1998-09-01  0:00                                         ` Matthew Heaney
     [not found]                                     ` <35f51e53.48044143@ <904556531.666222@miso.it.uq.edu.au>
1998-09-01  0:00                                       ` Gerry Quinn
1998-09-01  0:00                                         ` Robert Martin
1998-09-01  0:00                                           ` Gerry Quinn
1998-09-01  0:00                                             ` Robert Martin
1998-09-02  0:00                                               ` Gerry Quinn
1998-09-02  0:00                                                 ` Robert Martin
1998-09-02  0:00                                                   ` Ell
1998-09-04  0:00                                                     ` Andre Tibben
1998-09-04  0:00                                                       ` Patrick Doyle
1998-09-02  0:00                                                   ` Gerry Quinn
1998-09-02  0:00                                                     ` Robert Martin
1998-09-03  0:00                                                       ` Ell
1998-09-04  0:00                                                         ` Ell
1998-09-03  0:00                                                           ` Robert Martin
1998-09-04  0:00                                                             ` Ell
1998-09-04  0:00                                                               ` Robert Martin
1998-09-05  0:00                                                                 ` Loryn Jenkins
1998-09-04  0:00                                                                   ` Ell
1998-09-05  0:00                                                                     ` Loryn Jenkins
1998-09-04  0:00                                                               ` Patrick Doyle
1998-09-05  0:00                                                                 ` Ell
1998-09-05  0:00                                                                   ` Jeffrey C. Dege
1998-09-05  0:00                                                                     ` Matthew Heaney
1998-09-05  0:00                                                                       ` Robert Martin
1998-09-05  0:00                                                                       ` Matthew Heaney
1998-09-05  0:00                                                                         ` Robert Martin
1998-09-06  0:00                                                                           ` Loryn Jenkins
1998-09-05  0:00                                                                             ` Robert Martin
1998-09-06  0:00                                                                               ` Loryn Jenkins
1998-09-06  0:00                                                                                 ` Charles Hixson
1998-09-06  0:00                                                                                   ` Patrick Doyle
1998-09-07  0:00                                                                                 ` Ray Gardner
1998-09-07  0:00                                                                                   ` Patrick Logan
1998-09-08  0:00                                                                         ` Tim McDermott
1998-09-08  0:00                                                                           ` Patrick Doyle
1998-09-08  0:00                                                                             ` Patrick Logan
1998-09-17  0:00                                                                           ` Matthew Heaney
1998-09-09  0:00                                                                       ` Tim Ottinger
1998-09-17  0:00                                                                         ` Matthew Heaney
1998-09-16  0:00                                                                           ` Tim Ottinger
1998-09-05  0:00                                                                   ` Loryn Jenkins
1998-09-05  0:00                                                                     ` Robert Martin
1998-09-06  0:00                                                                       ` Loryn Jenkins
1998-09-05  0:00                                                                         ` Robert Martin
1998-09-06  0:00                                                                           ` Loryn Jenkins
1998-09-03  0:00                                                       ` sureshvv
1998-09-03  0:00                                                         ` Patrick Logan
1998-09-04  0:00                                                           ` Matthew Heaney
1998-09-03  0:00                                                         ` Robert Martin
1998-09-03  0:00                                                           ` Mike Spille
1998-09-03  0:00                                                             ` Robert Martin
1998-09-03  0:00                                                               ` Mike Spille
1998-09-03  0:00                                                                 ` Robert Martin
1998-09-04  0:00                                                                 ` sureshvv
1998-09-04  0:00                                                                   ` Robert Martin
1998-09-04  0:00                                                                     ` Mike Spille
1998-09-05  0:00                                                                       ` Ell
1998-09-04  0:00                                                               ` Ray Blaak
1998-09-06  0:00                                                                 ` Charles Hixson
1998-09-06  0:00                                                                   ` Robert Martin
1998-09-07  0:00                                                                     ` Patrick Logan
1998-09-04  0:00                                                               ` Gerry Quinn
     [not found]                                                               ` <EyyLos.2nx@yc.estec.esa.nl>
1998-09-08  0:00                                                                 ` Robert Martin
1998-09-08  0:00                                                                 ` John G. Volan
1998-09-08  0:00                                                                   ` duncan
1998-09-08  0:00                                                                     ` Patrick Doyle
1998-09-06  0:00                                                           ` Charles Hixson
1998-09-06  0:00                                                             ` Robert Martin
1998-09-06  0:00                                                               ` Charles Hixson
1998-09-09  0:00                                                               ` sureshvv
     [not found]                                                     ` <6skqf3$ <35F0B5B0.8E2D0166@s054.aone.net.au>
1998-09-06  0:00                                                       ` Will Rose
1998-09-06  0:00                                                         ` Ell
1998-09-06  0:00                                                           ` Jeffrey C. Dege
1998-09-01  0:00                                           ` Mike Spille
1998-09-01  0:00                                             ` Robert Martin
     [not found]                                               ` <gio+van+no+ni+8-0309982212300001@dialup62.tlh.talstar.com>
1998-09-04  0:00                                                 ` Robert I. Eachus
     [not found]                                                   ` <gio+van+no+ni+8-0809981840170001@dialup75.tlh.talstar.com>
1998-09-09  0:00                                                     ` Nick Leaton
     [not found]                                                       ` <gio+van+no+ni+8-1609980026290001@dialup26.tlh.talstar.com>
1998-09-16  0:00                                                         ` Nick Leaton
1998-09-02  0:00                                           ` mfinney
1998-09-02  0:00                                             ` Ell
1998-09-02  0:00                                               ` Robert Oliver
1998-09-02  0:00                                                 ` Ell
1998-09-02  0:00                                                   ` Robert Oliver
1998-09-02  0:00                                                     ` Robert Martin
1998-09-03  0:00                                                       ` sureshvv
1998-09-03  0:00                                                         ` Patrick Logan
1998-09-06  0:00                                                       ` Charles Hixson
1998-09-07  0:00                                                         ` Loryn Jenkins
1998-09-03  0:00                                                     ` Ell
1998-09-03  0:00                                                       ` Jeffrey C. Dege
1998-09-02  0:00                                                 ` Matthew Heaney
1998-09-02  0:00                                                 ` john-clonts
1998-09-02  0:00                                                   ` Robert Martin
1998-09-02  0:00                                                   ` Darren New
1998-09-05  0:00                                               ` Ray Gardner
1998-09-05  0:00                                                 ` Matthew Heaney
1998-09-07  0:00                                                   ` Ray Gardner
1998-09-07  0:00                                                     ` Ell
1998-09-07  0:00                                                       ` Ell
1998-09-09  0:00                                                         ` Adrian P. Morgan
1998-09-09  0:00                                                           ` Charles Hixson
1998-09-10  0:00                                                             ` mfinney
     [not found]                                                               ` <gio+van+no+ni+8-1609981736190001@dialup47.tlh.talstar.com>
1998-09-17  0:00                                                                 ` mfinney
1998-09-07  0:00                                                       ` Patrick Doyle
1998-09-07  0:00                                                         ` dewarr
1998-09-07  0:00                                                       ` dewarr
1998-09-09  0:00                                                         ` Ray Gardner
1998-09-11  0:00                                                           ` Robert I. Eachus
1998-09-07  0:00                                                       ` Ray Gardner
1998-09-07  0:00                                                         ` Ell
1998-09-07  0:00                                                           ` Ell
1998-09-09  0:00                                                           ` Ray Gardner
1998-10-09  0:00                                                     ` Matthew Heaney
     [not found]                                               ` <m31zpq4pim.fsf@mheaney.ni.ne <m3af36wtwh.fsf@mheaney.ni.net>
1998-10-11  0:00                                                 ` Patrick Doyle
1998-09-02  0:00                                             ` Ell
1998-09-02  0:00                                             ` john-clonts
1998-09-03  0:00                                               ` mfinney
1998-09-06  0:00                                                 ` Charles Hixson
1998-09-06  0:00                                                   ` mfinney
1998-09-02  0:00                                             ` Robert Martin
1998-09-02  0:00                                               ` Phil Goodwin
1998-09-02  0:00                                               ` adam
1998-09-02  0:00                                               ` adam
1998-09-02  0:00                                                 ` Robert Martin
1998-09-02  0:00                                                   ` Mike Spille
1998-09-03  0:00                                                   ` Richard MacDonald
1998-09-03  0:00                                                   ` Gerry Quinn
1998-09-06  0:00                                                 ` Charles Hixson
1998-09-02  0:00                                               ` Matthew Heaney
1998-09-02  0:00                                                 ` Robert Martin
1998-09-02  0:00                                                   ` dennison
1998-09-02  0:00                                                   ` Dan Higdon
1998-09-02  0:00                                                   ` Matthew Heaney
1998-09-02  0:00                                                     ` Robert Martin
1998-09-03  0:00                                                       ` Matthew Heaney
1998-09-03  0:00                                                         ` Patrick Logan
1998-09-03  0:00                                                         ` Robert Martin
1998-09-03  0:00                                                           ` Biju Thomas
1998-09-03  0:00                                                           ` Phil Goodwin
1998-09-04  0:00                                                             ` Matthew Heaney
1998-09-04  0:00                                                               ` Jeffrey C. Dege
1998-09-04  0:00                                                                 ` Ell
1998-09-04  0:00                                                                 ` Patrick Logan
1998-09-04  0:00                                                           ` Ell
1998-09-04  0:00                                                             ` Ell
1998-09-05  0:00                                                             ` Loryn Jenkins
1998-09-06  0:00                                                               ` Charles Hixson
1998-09-07  0:00                                                                 ` Loryn Jenkins
     [not found]                                                             ` <35F074C9.E10C <35F2E907.594CD023@earthlink.net>
1998-09-07  0:00                                                               ` Patrick Doyle
1998-09-10  0:00                                                             ` Tim Ottinger
1998-09-10  0:00                                                               ` dewarr
1998-09-11  0:00                                                                 ` prochak
1998-09-12  0:00                                                                 ` Ell
1998-09-12  0:00                                                                   ` dewarr
1998-09-12  0:00                                                                     ` Charles Hixson
1998-09-13  0:00                                                                       ` dewarr
1998-09-14  0:00                                                                     ` Ell
1998-09-03  0:00                                                         ` Robert Martin
1998-09-02  0:00                                                     ` Patrick Logan
1998-09-03  0:00                                                       ` Matthew Heaney
1998-09-03  0:00                                                         ` Patrick Logan
1998-09-03  0:00                                                       ` Ole-Hjalmar Kristensen
1998-09-03  0:00                                                         ` Patrick Logan
1998-09-02  0:00                                               ` Ell
1998-09-02  0:00                                                 ` Rick Smith
1998-09-02  0:00                                                   ` Robert I. Eachus
1998-09-02  0:00                                                     ` Patrick Logan
1998-09-03  0:00                                                       ` Robert I. Eachus
1998-09-02  0:00                                                 ` Patrick Doyle
1998-09-02  0:00                                                 ` adam
1998-09-02  0:00                                                 ` Robert Martin
1998-09-02  0:00                                                   ` Ell
1998-09-03  0:00                                                     ` Ole-Hjalmar Kristensen
1998-09-03  0:00                                                       ` Ell
1998-09-03  0:00                                                         ` Martin Tom Brown
1998-09-03  0:00                                                         ` Patrick Doyle
1998-09-02  0:00                                                   ` Ell
1998-09-02  0:00                                                     ` Robert Martin
1998-09-02  0:00                                                       ` Ell
1998-09-02  0:00                                                         ` Robert Martin
1998-09-03  0:00                                                           ` Joe Gwinn
1998-09-03  0:00                                                             ` Robert Martin
1998-09-04  0:00                                                               ` sureshvv
1998-09-04  0:00                                                               ` Ell
1998-09-04  0:00                                                                 ` Robert Martin
1998-09-04  0:00                                                                   ` Ell
1998-09-06  0:00                                                             ` Charles Hixson
1998-09-06  0:00                                                               ` Matthew Heaney
1998-09-06  0:00                                                                 ` Robert Martin
1998-09-06  0:00                                                                   ` Ell
1998-09-06  0:00                                                                     ` Jeffrey C. Dege
1998-09-11  0:00                                                                   ` Robert I. Eachus
1998-09-12  0:00                                                                     ` Patrick Logan
1998-09-06  0:00                                                               ` Robert Martin
1998-09-06  0:00                                                                 ` Jeffrey C. Dege
1998-09-06  0:00                                                                   ` Robert Martin
1998-09-08  0:00                                                               ` adam
1998-09-09  0:00                                                                 ` Gerry Quinn
     [not found]                                                                   ` <gio+van+no+ni+8-1609980034390001@dialup26.tlh.talstar.com>
1998-09-16  0:00                                                                     ` Biju Thomas
1998-09-17  0:00                                                                       ` dewarr
1998-09-18  0:00                                                                         ` Ell
1998-09-17  0:00                                                                       ` Gerry Quinn
1998-09-17  0:00                                                                         ` dewarr
1998-09-18  0:00                                                                           ` Gerry Quinn
1998-09-18  0:00                                                                             ` Biju Thomas
1998-09-18  0:00                                                                               ` Robert C. Martin
1998-09-19  0:00                                                                                 ` Rick Smith
1998-09-19  0:00                                                                               ` Ell
1998-09-19  0:00                                                                               ` dewarr
1998-09-21  0:00                                                                                 ` Richard D Riehle
1998-09-19  0:00                                                                             ` dewarr
1998-09-03  0:00                                                       ` Malcolm Steel
     [not found]                                                       ` <o1fH1.543$495.1 <gwinn-0309982042490001@d8.dial-4.cmb.ma.ultra.net>
1998-09-04  0:00                                                         ` Samuel Mize
1998-09-04  0:00                                                           ` Ell
1998-09-05  0:00                                                           ` Loryn Jenkins
1998-09-09  0:00                                                             ` Samuel Mize
1998-09-09  0:00                                                               ` sureshvv
1998-09-10  0:00                                                                 ` prochak
1998-09-11  0:00                                                                   ` Patrick Doyle
1998-09-17  0:00                                                                 ` Matthew Heaney
1998-09-10  0:00                                                               ` Tim Ottinger
     [not found]                                                                 ` <01bddccc$98b2dda0$ca3aea9e@tom>
1998-09-10  0:00                                                                   ` Tim Ottinger
1998-09-11  0:00                                                             ` Robert I. Eachus
1998-09-12  0:00                                                               ` Loryn Jenkins
1998-09-11  0:00                                                                 ` alan walkington
1998-09-12  0:00                                                                   ` Loryn Jenkins
1998-09-02  0:00                                                     ` Robert Martin
1998-09-02  0:00                                                       ` Ell
     [not found]                                                     ` <6sjnlu$83l$1@hirame.wwa.c <35EE5F67.80D@gecm.com>
1998-09-03  0:00                                                       ` Patrick Doyle
     [not found]                                               ` <gio+van+no+ni+8-0309982311220001@dialup62.tlh.talstar.com>
1998-09-03  0:00                                                 ` Robert Martin
1998-09-03  0:00                                               ` mfinney
1998-09-03  0:00                                                 ` Robert Martin
1998-09-02  0:00                                           ` Gene Gajewski
1998-09-09  0:00                                     ` Jonas M�ls�
     [not found]                                     ` <35f51e53.48044143@ <6t6l4n$rep@jbm.nada.kth.se>
1998-09-10  0:00                                       ` Mats Weber
1998-09-17  0:00                                       ` Matthew Heaney
     [not found]                                 ` <m3ogt3qgca.fsf@mheaney.ni.n <1dghyt5.oik1lzhxzf2N@n207167116176.inetworld.net>
1998-10-10  0:00                                   ` Patrick Doyle
1998-10-12  0:00                                     ` Charles H. Sampson
1998-10-13  0:00                                       ` Matthew Heaney
1998-10-14  0:00                                       ` Graham Perkins
1998-10-15  0:00                                         ` Reimer Behrends
1998-10-15  0:00                                           ` dewarr
     [not found]                           ` <l5HC1.6840$wN.18 <35F238F7.F57D3EC7@earthlink.net>
1998-09-06  0:00                             ` Patrick Doyle
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <m31zpxqutn.fsf@mheaney.ni.net>
1998-08-31  0:00             ` Jim Cochrane
1998-09-01  0:00               ` Matthew Heaney
1998-09-01  0:00               ` Matthew Heaney
1998-09-02  0:00                 ` Jim Cochrane
1998-09-02  0:00                   ` Richard Melvin
1998-09-03  0:00                     ` Jim Cochrane
1998-09-03  0:00                   ` Robert I. Eachus
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <35EC1590.D50DB8F6@tisny.com>
1998-09-01  0:00             ` Patrick Doyle
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <m3zpck79xp.fsf@mheaney.ni.net>
1998-09-02  0:00             ` Patrick Doyle
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <6shunm$47g$1@hirame.wwa.com>
1998-09-02  0:00             ` David E. Wallace
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <6shhg4$llp$1@hirame.wwa.com>
1998-09-02  0:00             ` Jim Cochrane
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <6sjms6$7c4$1@hirame.wwa.com>
1998-09-02  0:00             ` Patrick Doyle
1998-09-02  0:00               ` Patrick Logan
1998-09-02  0:00                 ` Patrick Doyle
1998-09-02  0:00                   ` Robert Martin
1998-09-03  0:00                   ` Patrick Logan
1998-09-02  0:00               ` Robert Martin
1998-09-02  0:00                 ` Patrick Logan
1998-09-02  0:00                   ` Robert Martin
1998-09-04  0:00                     ` Patrick Logan
1998-09-03  0:00               ` mfinney
1998-09-03  0:00                 ` Patrick Doyle
1998-09-03  0:00               ` Matthew Heaney
1998-09-03  0:00                 ` Robert Martin
1998-09-03  0:00                   ` Patrick Logan
     [not found]           ` <35f51e53.48044143@ <904556531. <m3lno372be.fsf@mheaney.ni.net>
1998-09-03  0:00             ` Patrick Doyle
1998-09-03  0:00             ` Patrick Doyle
1998-09-03  0:00               ` Loryn Jenkins
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <35EDC648.76F03F32@draper.com>
1998-09-03  0:00             ` Patrick Doyle
1998-09-03  0:00               ` Martin Tom Brown
1998-09-03  0:00               ` Tim McDermott
1998-09-04  0:00                 ` Patrick Doyle
1998-09-04  0:00                 ` Matthew Heaney
1998-09-04  0:00                   ` Patrick Doyle
1998-09-08  0:00                   ` Tim McDermott
1998-09-17  0:00                     ` Matthew Heaney
1998-09-17  0:00                       ` Reimer Behrends
1998-09-18  0:00                       ` Robert I. Eachus
1998-09-18  0:00                         ` Jeffrey C. Dege
     [not found]           ` <35f51e53.48044143@ <m3af4mq7f4 <35EC937F.94420C51@ibm.net>
1998-09-07  0:00             ` Michael F Brenner
     [not found]           ` <35f51e53.480 <904556531.66622 <EyyLos.2nx@yc.estec.esa.nl>
1998-09-08  0:00             ` duncan
1998-09-16  0:00               ` Matthew Heaney
1998-09-17  0:00                 ` Reimer Behrends
1998-09-17  0:00                   ` Ell
1998-09-08  0:00             ` Jim Cochrane
1998-09-09  0:00               ` duncan
1998-09-11  0:00                 ` Jim Cochrane
1998-09-11  0:00                   ` duncan
1998-09-09  0:00               ` Charles Hixson
1998-09-10  0:00                 ` Loryn Jenkins
1998-09-17  0:00                 ` Matthew Heaney
     [not found]           ` <35f51e53.480<904556531.666222@ <6t42kg$son$1@hirame.wwa.com>
1998-09-08  0:00             ` Patrick Doyle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox