comp.lang.ada
 help / color / mirror / Atom feed
From: behrends@student.uni-kl.de (Reimer Behrends)
Subject: Re: Building blocks (Was: Design By Contract)
Date: 1997/10/22
Date: 1997-10-22T00:00:00+00:00	[thread overview]
Message-ID: <slrn64qhvb.2gos.behrends@alma.student.uni-kl.de> (raw)
In-Reply-To: 5w3FnzA6KRR0Iwt+@treetop.demon.co.uk


Paul Johnson (Paul@treetop.demon.co.uk) wrote:
[Discussion of exit-at-top vs. exit-anywhere.]
: Hmm.  Interesting.
: 
: I agree that the repeated read (or whatever instruction) before the loop
: and at the end is a bad idea.  Quite apart from the Soloway experiment,
: it is duplicating code.

Yes, but ... see below.

: OTOH I wonder if the situation might be reversed in real life situations
: with deeply nested structures.  I'm rather dubious of small, neat coding
: experiments such as Soloway's.  While they are the best handle we have
: on the facts, I worry that in an attempt to come up with a controllable,
: repeatable, and above all feasible experiment, they abstract out too
: much complexity.  After all, it is complexity that makes programming
: difficult.

You have a point here, I think. It is worth noting that the example
discussed not only was a toy program, but also had a couple of bugs in
it (didn't work for empty or non-numerical input). This may be perfectly
acceptable for prototyping, of course, but not for industrial-strength
code.

The general problem is that if your task cannot be suitably expressed
with one control structure, you have basically two options:

	(1) "Rewire" the control flow.
	(2) Think of suitable abstractions instead of expressing
	    something directly.

The most general approach to (1) is to use goto or one of its
watered-down variants (break, continue, Sather style iterators, etc.).
The problem with them is that if only you use them often enough you lose
the clarity of single-entry, single-exit structures. It becomes hard to
understand the code or produce test cases that provide adequate
coverage. This is (aside from general gotos) particularly extreme if you
have multi-level breaks, breaks inside deeply nested if-statements, etc.

It should be noted, however, that just removing such constructs from the
syntax of the language doesn't necessarily alleviate the problem. You
can always simulate them with boolean variables, and code that makes
ample use of this "solution" will probably be even harder to understand.
That doesn't mean that you boolean variables shouldn't be used as
convenient abbreviations for complex conditions, just not to simulate
gotos.

Using (2) appears like the cleaner solution, and it probably is. After
all, didn't structured programming teach years ago that if we have code
that is long, complex, or repeated in more than one place, we should try
to encapsulate suitable parts in subroutines? It should be noticed,
however, that writing such abstractions can be more work initially
(which hopefully pays off due to code reuse and making testing and
maintenance easier) and relies on a compiler that is capable of decent
automatic inlining of code to ensure suitable efficiency for certain
applications.

Another point is not only choosing to use abstractions, but also to
choose _suitable_ abstractions. For instance, much of the problem in the
original example (reading integers and adding them until a zero is
encountered, I think) stem from the fact that "read" is not really a
good abstraction for complex computations. Like the "x++" operator in C,
it lumps two marginally related operations together without a good
reason.  This becomes much clearer when you try to use it with more
advanced parsing methods.  For instance, with shift-reduce parsers, you
will always have to undo the read operation when doing a reduce.
Providing separate primitives for advancing the input stream and
checking the current token not only work much better for that case, they
are also easier extend if you suddenly need a lookahead > 1.

A similar case can be made for handwritten LL(k) parsers. Much of their
bad reputation (besides the fact that it _is_ easier and safer to write
a parser using a tool) stems from the fact that with the traditional
read operations grammar rules don't map as nicely to code as when you
have both an advance and a lookahead operation, because the entry
into/exit from the code for a rule often does not correspond to the
current position of the input stream.

I seem to remember that Bertrand Meyer suggested somewhere that a
routine should either query the state of an object, or change it, but
never both (i.e. function vs. procedure). I think we have a good example
here why to avoid the latter approach.

Of course, with an appropriate INTEGER_SCANNER class the code is no less
clear than the original example:

	from
	  scanner.start(...)
	  sum := 0
	until scanner.stopped or else scanner.data = 0 loop
	  sum := sum + scanner.data
	  scanner.advance
	end

This also takes care of end-of-file and error conditions that can occur.

Yes, "start" and "advance" will probably call a common routine. That's
only natural, as they both have to ensure the class invariant is right
in a similar fashion. And it doesn't duplicate code.

[...]

				Reimer Behrends





  parent reply	other threads:[~1997-10-22  0:00 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-09-09  0:00 Building blocks (Was: Design By Contract) Marc Wachowitz
1997-09-15  0:00 ` Joachim Durchholz
1997-09-17  0:00 ` Paul Johnson
1997-09-18  0:00   ` Robert Dewar
1997-09-18  0:00   ` Stephen Leake
1997-09-18  0:00     ` Mark L. Fussell
     [not found]       ` <11861963wnr@eiffel.demon.co.uk>
1997-09-19  0:00         ` Mark L. Fussell
1997-09-19  0:00       ` Robert A Duff
1997-09-20  0:00         ` Joachim Durchholz
1997-09-22  0:00           ` Matthew Heaney
1997-09-23  0:00             ` Veli-Pekka Nousiainen
1997-10-03  0:00               ` Robert I. Eachus
1997-10-04  0:00                 ` Paul Johnson
1997-10-14  0:00                   ` Robert I. Eachus
1997-09-23  0:00             ` Joachim Durchholz
1997-09-23  0:00           ` Jon S Anthony
1997-09-24  0:00           ` Richard A. O'Keefe
1997-09-24  0:00           ` Alan E & Carmel J Brain
1997-09-25  0:00             ` Anonymous
1997-09-30  0:00               ` Alan E & Carmel J Brain
1997-09-30  0:00                 ` Matthew Heaney
1997-09-30  0:00                   ` W. Wesley Groleau x4923
1997-09-30  0:00                     ` Matthew Heaney
1997-10-01  0:00                     ` Alan E & Carmel J Brain
1997-09-30  0:00                   ` Neil Wilson
1997-09-30  0:00                     ` Stephen Leake
1997-10-01  0:00                 ` Anonymous
1997-10-01  0:00                   ` Paul M Gover
1997-10-04  0:00                     ` Paul Johnson
1997-10-04  0:00                       ` Matthew Heaney
1997-10-15  0:00                         ` Paul Johnson
1997-10-15  0:00                           ` Matthew Heaney
1997-10-16  0:00                             ` Joachim Durchholz
1997-10-17  0:00                               ` Robert I. Eachus
1997-10-16  0:00                           ` Joachim Durchholz
1997-10-22  0:00                           ` Reimer Behrends [this message]
1997-10-01  0:00                   ` Joachim Durchholz
1997-10-02  0:00                   ` Robert A Duff
1997-10-02  0:00                     ` Tucker Taft
1997-10-02  0:00                       ` Matthew Heaney
1997-10-03  0:00                     ` Stephen Leake
1997-10-04  0:00                     ` Matthew Heaney
1997-10-07  0:00                       ` Robert A Duff
1997-09-19  0:00       ` Jon S Anthony
1997-09-23  0:00         ` Mark L. Fussell
1997-09-18  0:00     ` W. Wesley Groleau x4923
1997-09-21  0:00       ` Matthew Heaney
1997-09-18  0:00   ` Jon S Anthony
  -- strict thread matches above, loose matches on Subject: below --
1997-09-11  0:00 Robert Dewar
1997-09-09  0:00 Marc Wachowitz
1997-09-02  0:00 Design By Contract Jon S Anthony
     [not found] ` <JSA.97Sep3201329@alexandria.organon.com>
1997-09-04  0:00   ` Paul Johnson
     [not found]     ` <5un58u$9ih$1@gonzo.sun3.iaf.nl>
1997-09-06  0:00       ` Building blocks (Was: Design By Contract) Joachim Durchholz
1997-09-08  0:00       ` Paul Johnson
1997-09-08  0:00         ` Brian Rogoff
1997-09-09  0:00           ` Veli-Pekka Nousiainen
1997-09-09  0:00             ` Jon S Anthony
1997-09-09  0:00           ` Veli-Pekka Nousiainen
1997-09-09  0:00           ` Matthew Heaney
1997-09-09  0:00             ` W. Wesley Groleau x4923
1997-09-10  0:00               ` Robert A Duff
1997-09-12  0:00                 ` Jon S Anthony
1997-09-09  0:00             ` Brian Rogoff
1997-09-10  0:00             ` Robert Dewar
1997-09-12  0:00               ` Paul Johnson
1997-09-14  0:00                 ` Robert Dewar
1997-09-15  0:00                   ` John G. Volan
1997-09-14  0:00                 ` Robert Dewar
1997-09-14  0:00                 ` Robert Dewar
1997-09-12  0:00               ` Jon S Anthony
1997-09-12  0:00                 ` Robert Dewar
1997-09-16  0:00                   ` Brian Rogoff
1997-09-10  0:00             ` Paul Johnson
1997-09-10  0:00               ` Darren New
1997-09-10  0:00               ` Matthew Heaney
1997-09-09  0:00           ` W. Wesley Groleau x4923
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox