From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,ec21c3c7cdc7ff3e X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!atl-c05.usenetserver.com!news.usenetserver.com!cycny01.gnilink.net!bigfeed3.bellsouth.net!news.bellsouth.net!news-in.ntli.net!newsrout1-win.ntli.net!ntli.net!news.highwinds-media.com!border2.nntp.ams.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!npeer.de.kpn-eurorings.net!newsfeed.arcor.de!news.arcor.de!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Handling invalid objects Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.14.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <3pKdnRGO2eWjQr3ZnZ2dneKdnZydnZ2d@comcast.com> <1peyefbqozdml.afdrxqiuyi0b$.dlg@40tude.net> <1c2j4h3onbhmk.p3uisoojg34b$.dlg@40tude.net> Date: Thu, 23 Mar 2006 14:20:24 +0100 Message-ID: NNTP-Posting-Date: 23 Mar 2006 14:20:24 MET NNTP-Posting-Host: c312e46d.newsread2.arcor-online.net X-Trace: DXC=]NV4OkSX On Wed, 22 Mar 2006 17:42:53 +0100, Maciej Sobczak wrote: > Dmitry A. Kazakov wrote: > >>>If by exception contracts you mean embedding the exception specification >>>in the "signature" of the procedure/function, then it was already >>>exercised by the Java community with rather disappointing effects. >> >> If Java did it wrong, let's do it right in Ada. > > Do what exactly? This is important question. Sure. > - We use exceptions when we want to *DECOUPLE* error reporting from > error handling. We find it especially good in those situations, where > error reporting site and error handling site are separated by more than > one level of subroutine calls (otherwise returning error codes is good > enough). Yes, though also see below. > - We embed contract information in subroutine signatures to *COUPLE* the > caller with the callee with respect to what they provide to each other > and what they expect from each other. No, we are decoupling using contracts. Instead of presenting any concrete caller, we do a contract. The callee is coupled only to its contract. It does not to any caller, because it hopes that any caller will respect the contract. > Now, "coupling" and "decoupling" are hardly compatible. Let's see where > it breaks in so-called practice. > > First, there is a cascading effect when someone on one end of the chain > adds a new exception type. Just let's say that the project evolved and > for example a database got involved in something that was previously > managed with the use of files. This is not specific to exceptions. It is "fragile class" design. You cannot add a new exception type [better to say a class of], this breaks the contract. You have to stay within the class. In Ada model, where exceptions are values, this means that the exception contracts should specify ranges of values [subtype] and a new exception [value] should be chosen from that range. It is doable. > Second, the problem is that the error reporting and handling might be > stated as a contract not between immediate caller and callee, but > between some entities that operate across some other entity. [...] > The real problem is that languages based on simple subroutine calls are > not appropriate for expressing these kind of relationships. Something > fundamentally different would be needed to ensure that myFun handles > exceptions from myComparator without involving sort in this process, but > I don't see what that thing would look like. I think it was Robert Duff, who proposed a nice solution for this. When you have some procedure composed out of another procedure, in this example, you pass it as a parameter, you could say something like: A raises this plus anything what B does. Because B has a defined subroutine type, its contract is statically known. One could also bind exceptions to types of primitive subprograms. For example: type File is tagged ...; subtype File_Error is File'Exception; -- The range of exceptions bound to File procedure Read (X : File) exception File_Error; type DB is new File with ...; DB_Error : File_Error := some sugar; -- Declares a new exception in the range procedure Read (X : DB); -- This is allowed to raise DB_Error > Anyway. The whole purpose of exceptions is to provide a kind of > "out-of-band" channel which is *decoupled* from the main chain of > subroutine calls. This is a control-flow view. But there is another, more general view. Exceptions allow us to weaken preconditions. Without exceptions, a real-valued sqrt should specify x >= 0.0 as a precondition. This is unacceptable when x is statically unknown. Exceptions relax the precondition and bring things back to static. The price is that you leave the realm of real numbers. You have to this way or another. Either you make it complex-valued or you say that the result is "Real or Constraint_Error." Who will deal with this result is the question for another day. But when exceptions are not contracted, then the gain of static preconditions gets lost. So in my view, Java's is undoubtedly right here. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de