comp.lang.ada
 help / color / mirror / Atom feed
From: "Joachim Durchholz" <joachim dot durchholz@halstenbach.com>
Subject: Re: Design by Contract (was Re: Interesting thread in comp.lang.eiffel)
Date: 2000/07/19
Date: 2000-07-19T00:00:00+00:00	[thread overview]
Message-ID: <8l4v6n$3mph1$1@ID-9852.news.cis.dfn.de> (raw)
In-Reply-To: 01HW.B59822A20005ECF4078EC70C@news.pacbell.net

David Kristola <David95037@See-My.Sig> wrote:
> On Sun, 16 Jul 2000 12:12:10 -0700, Joachim Durchholz wrote
> (in message <8kt1eb$34jh1$1@ID-9852.news.cis.dfn.de>):
>
> > David Kristola <David95037@See-My.Sig> wrote:
> >> On Thu, 13 Jul 2000 11:12:53 -0700, Joachim Durchholz wrote:
> >>
> >>> or
> >>> find_minimum_in (h: HEAP)
> >>> require
> >>> not h.is_empty
> >>
> >> Depending on the implementation of the heap, this too would
> >> probably cause some sort of exception to be raised if the
> >> heap were empty.
> >
> > The difference is that the exception will happen before the routine
> > is even called. The responsibility for the exception will clearly
> > be the caller's.
> > If the exception happens somewhere inside the routine, you need
> > another analysis step to find out which part of the code is really
> > responsible for the problem.
>
> Perhaps it is my coding style, but (in this limited case) i would
> consider it the responsibility of the caller to handle the exception.

Oh, this is not a limited case. The vast majority of failed assertions
is in precondition checks (well, at least during debugging.)
In nearly all cases, the caller needs to be fixed. (There is the rare
occurrence that a precondition was needlessly strict. If we own the
library with the callee, we take the opportunity to weaken the
precondition in this situation.)

> There is nothing find_minimum_in can do if the heap is empty.  To me,
> that is even an unstated but obvious contract.

The difference is that the contract is explicit.
Besides, the contract isn't obvious. The routine could reasonably return
some minimum value if the heap is empty. In that case, we'd have one
precondition less and one postcondition more.

> This is not to say
> that it is not worth stating obviously and in a way that can be
> checked by a compiler.  This particular example is perhaps a little
> simple.  Certainly there are plenty of others that are not so
> obvious, where a formally stated precondition adds to the
understanding.

It's usually the other way round: Writing preconditions can relieve you
of verbiage in the description. Say you have a routine like this in
FILE:

  read (offset, number_of_bytes: INTEGER; target: BUFFER)
    -- Read 'number_of_bytes' bytes into 'target', starting at file
    -- offset 'offset'.
    -- File must be open.
    -- Do not try to read past end-of-file.

This can be rewritten in a more concise and formal way as

  read (offset, number_of_bytes: INTEGER; target: BUFFER)
    -- Read 'number_of_bytes' bytes into 'target', starting at file
    -- offset 'offset'.
  require
    must_be_open: open
    dont_read_past_eof: offset + number_of_bytes <= file_size + 1

where 'open' and 'file_size' are other functions of FILE.

The first interface is what you usually read in some software
description. It leaves much to desire: there is no indication what will
happen if the preconditions aren't fulfilled, and it doesn't tell the
programmer what exactly has to be done to make sure that the call will
not fail.

The second interface is clearer. The reaction to a failed precondition
will always be an exception, or unspecified behaviour if checking is
switched off. This is quite harsh, but people tend to write short
preconditions; if clients of 'read' want a less strict contract (say,
reading past EOF fills the rest of 'buffer' with null bytes or whatever)
then bugger the routine author.
It's also *much* more precise: the preconditions leave no question open.
The caller must make sure that the 'open' query on the FILE returns
True, and he must fulfill some precisely defined numeric inequation on
'offset' and 'number_of_bytes'. The caller can then republish the same
contract on its own interface (if the caller has such a things as
'offset' and 'number_of_bytes'), or it can translate the preconditions
to some higher abstraction. For example, a class that embodies a file
with fixed-length records might have this routine:

  read (record_number: INTEGER; target: FIXED_LENGTH_RECORD)
  require
    must_be_open: open
    dont_read_past_eof: record_number <= number_of_records
  do
    internal_file.read (record_number * record_size, target.size,
target)
  end

  open: BOOLEAN
  do
    Result := internal_file.open
  end

  number_of_records
  require
    must_be_open: open
  do
    Result := internal_file.number_of_bytes div record_size
  end

I'm leaving out details like checking that the file size is an integral
multiple of record_size, a check that will probably be done in the
'open' routine; to ensure that this is always true, we can write this:

  invariant
    integral_records:
      internal_file.number_of_bytes mod record_size = 0

Together, these specifications make sure that FILE's 'read' routine will
never be called with inappropriate parameters.
Well, unless I overlooked something - it's a bit late right now and I
don't have the time to check that the preconditions percolated up
precisely. In a real-life situation, I'd make sure that this really
holds up, either by extensive testing, or by code review; in an ideal
world, I'd ask an inference engine whether the 'read' call guarantees
all its preconditions.

> Ada also does not provide for the inheritance of contracts.  That is
> a very interesting aspect of Eiffel.

Actually this is the main concept in Design by Contract.
It's essentially the Liskov Substitutability Principle applied to
preconditions and postconditions: If you have a variable of type PARENT,
and assign to it an object of type CHILD, then everything should work as
expected - in other words, all routines in CHILD must honor all
contracts that the precursor routines in PARENT offered. (CHILD may
offer more value: its routines may require less of the caller, i.e.
loosen up the precondition, or they may guarantee more, i.e. specify a
stricter postcondition.)

Regards,
Joachim
--
This is not an official statement from my employer or from NICE.
Reply-to address changed to discourage unsolicited advertisements.






  reply	other threads:[~2000-07-19  0:00 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <8ipvnj$inc$1@wanadoo.fr>
     [not found] ` <8j67p8$afd$1@nnrp1.deja.com>
     [not found]   ` <39573CAB.BB90DF92@gecm.com>
     [not found]     ` <8j8ek0$24la$3@ID-9852.news.cis.dfn.de>
     [not found]       ` <3957ED3E.E64E7390@lmco.com>
     [not found]         ` <8k8orn$1tlh9$1@ID-9852.news.cis.dfn.de>
     [not found]           ` <94S95.9936$7%3.667320@news.flash.net>
2000-07-13  0:00             ` Interresting thread in comp.lang.eiffel Joachim Durchholz
2000-07-14  0:00               ` Ken Garlington
2000-07-16  0:00                 ` Joachim Durchholz
2000-07-16  0:00                   ` Ken Garlington
     [not found]   ` <slrn8leffq.ebq.gisle@spurv.ii.uib.no>
     [not found]     ` <395886DA.CCE008D2@deepthought.com.au>
     [not found]       ` <3958B07B.18A5BB8C@acm.com>
     [not found]         ` <y1d65.620$7%3.33446@news.flash.net>
     [not found]           ` <395A0ECA.940560D1@acm.com>
     [not found]             ` <8jd4bb$na7$1@toralf.uib.no>
     [not found]               ` <8jfabb$1d8$1@nnrp1.deja.com>
     [not found]                 ` <SVH65.1596$7%3.129344@news.flash.net>
     [not found]                   ` <8jt4i0$18ec7$1@ID-9852.news.cis.dfn.de>
     [not found]                     ` <nSt85.5388$7%3.424540@news.flash.net>
     [not found]                       ` <8k5a31$1p61t$1@ID-9852.news.cis.dfn.de>
     [not found]                         ` <qlt95.7824$7%3.596314@news.flash.net>
     [not found]                           ` <3966D7B0.5D6475E4@earthlink.net>
     [not found]                             ` <A5J95.9237$7%3.638838@news.flash.net>
2000-07-12  0:00                               ` Robert I. Eachus
2000-07-13  0:00                                 ` Ken Garlington
2000-07-23  0:00                                   ` Robert I. Eachus
2000-07-23  0:00                                     ` Ken Garlington
2000-07-24  0:00                                       ` swhalen
2000-07-24  0:00                                       ` David Gillon
2000-07-24  0:00                                         ` Ken Garlington
2000-07-24  0:00                                     ` David Gillon
     [not found]                             ` <39688CA2.31B2A7EF@acm.com>
2000-07-13  0:00                               ` Joachim Durchholz
2000-07-13  0:00                                 ` Marin D. Condic
     [not found]                           ` <8k8p8m$1upjk$1@ID-9852.news.cis.dfn.de>
     [not found]                             ` <0cS95.9944$7%3.667682@news.flash.net>
2000-07-13  0:00                               ` Joachim Durchholz
2000-07-14  0:00                                 ` Ken Garlington
     [not found]                 ` <8jhq0m$30u5$1@toralf.uib.no>
     [not found]                   ` <8jt4j7$19hpk$1@ID-9852.news.cis.dfn.de>
     [not found]                     ` <3963CDDE.3E8FB644@earthlink.net>
     [not found]                       ` <8k5alv$1oogm$1@ID-9852.news.cis.dfn.de>
     [not found]                         ` <Rmt95.7825$7%3.595826@news.flash.net>
2000-07-13  0:00                           ` Joachim Durchholz
2000-07-13  0:00                             ` Marin D. Condic
2000-07-14  0:00                             ` Ken Garlington
2000-07-16  0:00                               ` Joachim Durchholz
2000-07-16  0:00                                 ` Ken Garlington
2000-07-19  0:00                                   ` Joachim Durchholz
2000-07-19  0:00                                     ` Ken Garlington
2000-07-14  0:00                             ` Ken Garlington
2000-07-14  0:00                               ` Marin D. Condic
2000-07-14  0:00                                 ` Ken Garlington
     [not found]                       ` <3963DEBF.79C40BF1@eiffel.com>
     [not found]                         ` <2LS85.6100$7%3.493920@news.flash.net>
     [not found]                           ` <8k5aru$1odtq$1@ID-9852.news.cis.dfn.de>
     [not found]                             ` <Rnt95.7826$7%3.596208@news.flash.net>
     [not found]                               ` <8k8pk2$20cab$1@ID-9852.news.cis.dfn.de>
     [not found]                                 ` <_dS95.9945$7%3.666180@news.flash.net>
2000-07-12  0:00                                   ` David K Allen
2000-07-12  0:00                                     ` Ken Garlington
2000-07-12  0:00                                       ` David K Allen
2000-07-12  0:00                                       ` David K Allen
2000-07-13  0:00                                         ` Howard W. LUDWIG
2000-07-13  0:00                                           ` Joachim Durchholz
2000-07-14  0:00                                           ` Ken Garlington
2000-07-14  0:00                                         ` Ken Garlington
2000-07-18  0:00                                           ` Veli-Pekka Nousiainen
2000-07-19  0:00                                             ` Ken Garlington
2000-07-19  0:00                                               ` Bob Allen
2000-07-12  0:00                                     ` Bob Allen
2000-07-12  0:00                                       ` Ken Garlington
2000-07-13  0:00                                         ` Bob Allen
2000-07-14  0:00                                           ` Ken Garlington
2000-07-14  0:00                                             ` Marin D. Condic
2000-07-14  0:00                                             ` carr_tom
2000-07-18  0:00                                               ` Veli-Pekka Nousiainen
2000-07-12  0:00                                     ` David Gillon
2000-07-13  0:00                                       ` David Gillon
2000-07-13  0:00                                         ` David K Allen
2000-07-13  0:00                                           ` Bob Allen
2000-07-13  0:00                                             ` Joachim Durchholz
2000-07-18  0:00                                               ` Veli-Pekka Nousiainen
2000-07-19  0:00                                                 ` Joachim Durchholz
2000-07-14  0:00                                         ` Ken Garlington
2000-07-13  0:00                                       ` Joachim Durchholz
2000-07-18  0:00                                       ` Veli-Pekka Nousiainen
2000-07-19  0:00                                         ` David Gillon
     [not found]                             ` <Rnt95.78 <L6vb5.16117$7%3.988701@news.flash.net>
2000-07-14  0:00                               ` Nick Williams
     [not found]                         ` <396502D2.BD8A42E7@earthlink.net>
     [not found]                           ` <RSsa5.11075$7%3.784507@news.flash.net>
     [not found]                             ` <6aHa5.113$6E.23141@ptah.visi.com>
     [not found]                               ` <396B4A68.458FA3BC@maths.unine.ch>
     [not found]                                 ` <u6hp4i16$GA.283@cpmsnbbsa07>
2000-07-11  0:00                                   ` cropt
2000-07-11  0:00                                   ` Ken Garlington
2000-07-12  0:00                                     ` Bob Allen
2000-07-12  0:00                                       ` Ken Garlington
2000-07-12  0:00                                       ` David Starner
2000-07-12  0:00                                     ` Peter Amey
2000-07-12  0:00                                       ` Peter Amey
2000-07-13  0:00                                       ` Joachim Durchholz
     [not found]                           ` <39654639.B3760EF2@eiffel.com>
     [not found]                             ` <i4k95.7512$7%3.571616@news.flash.net>
     [not found]                               ` <oqog45g1j0.fsf@premise.demon.co.uk>
     [not found]                                 ` <85Fa5.11419$7%3.818927@news.flash.net>
2000-07-11  0:00                                   ` Aspects (Re: Interesting thread in comp.lang.eiffel) tom
2000-07-12  0:00                                     ` Steve Merrick
2000-07-12  0:00                                       ` Frank Mitchell
2000-07-14  0:00                                         ` Jubilation
2000-07-14  0:00                                           ` Frank Mitchell
2000-07-15  0:00                                             ` Jubilation
2000-07-12  0:00                                     ` Veli-Pekka Nousiainen
2000-07-12  0:00                                       ` tom
2000-07-12  0:00                                   ` Design by Contract (was " David Kristola
2000-07-12  0:00                                     ` Howard W. LUDWIG
2000-07-12  0:00                                       ` Greg
2000-07-12  0:00                                         ` Eirik Mangseth
2000-07-13  0:00                                       ` Joachim Durchholz
2000-07-14  0:00                                         ` David Kristola
2000-07-14  0:00                                           ` Matthew J Heaney
2000-07-16  0:00                                           ` Joachim Durchholz
2000-07-17  0:00                                             ` David Kristola
2000-07-19  0:00                                               ` Joachim Durchholz [this message]
2000-07-25  0:00                                                 ` Richard Riehle
2000-07-12  0:00                                     ` Greg
2000-07-12  0:00                                       ` Matthew J Heaney
2000-07-13  0:00                                         ` Eirik Mangseth
2000-07-18  0:00                               ` Interesting thread in comp.lang.eiffel Veli-Pekka Nousiainen
2000-07-19  0:00                                 ` Ken Garlington
     [not found]                             ` <i4k95.7512$7%3.571616@n <397D8CC3.BB0C9001@ix.netcom.com>
2000-07-29  0:00                               ` Writing better software was: Design by Contract (was Re: Interesting thread in comp.lang.eiffel) Kent Paul Dolan
2000-07-29  0:00                                 ` Ken Garlington
2000-07-31  0:00                                   ` Stefan Skoglund
2000-08-01  0:00                                     ` Ken Garlington
2000-08-01  0:00                                   ` Kent Paul Dolan
2000-08-01  0:00                                     ` Ken Garlington
2000-07-31  0:00                                 ` Simon Brady
2000-07-30  0:00                                   ` John Magness
2000-08-01  0:00                                     ` Simon Brady
2000-08-01  0:00                                       ` Ken Garlington
2000-08-01  0:00                                       ` Simon Brady
2000-08-04  0:00                                         ` Robert I. Eachus
2000-08-04  0:00                                           ` Simon Brady
     [not found]   ` <8j7i54$j7d5@news.kvaerner.com>
     [not found]     ` <395887EB.8D612FC7@deepthought.com.au>
     [not found]       ` <395A190E.FD4D8978@easystreet.com>
     [not found]         ` <6Yt65.3417$MS3.72586@news1.online.no>
     [not found]           ` <395A7E7E.FE57E036@easystreet.com>
     [not found]             ` <8jermi$5cb2@news.kvaerner.com>
     [not found]               ` <395BCE66.2BE8EE0A@eiffel.com>
     [not found]                 ` <wccaeg3gj61.fsf@world.std.com>
     [not found]                   ` <395D113D.1F654A68@eiffel.com>
     [not found]                     ` <dus75.5086$MS3.105182@news1.online.no>
     [not found]                       ` <395E5D16.C4D109F1@eiffel.com>
2000-07-18  0:00                         ` Interesting thread in comp.lang.eiffel Veli-Pekka Nousiainen
replies disabled

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