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,7d3cb5920e882220 X-Google-Attributes: gid103376,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!feeder3.cambrium.nl!feeder1.cambrium.nl!feed.tweaknews.nl!news.netcologne.de!newsfeed-hp2.netcologne.de!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Exceptions Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.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: <5947aa62-2547-4fbb-bc46-1111b4a0dcc9@x69g2000hsx.googlegroups.com> <475a8d6d$0$30677$4d3efbfe@news.sover.net> <145gsya555jlt$.8mvve9nqja9n$.dlg@40tude.net> <475adbe8$0$30689$4d3efbfe@news.sover.net> <1qbsb1u76vyrk.3n8oov6aevw3$.dlg@40tude.net> <475be24c$0$30661$4d3efbfe@news.sover.net> Date: Sun, 9 Dec 2007 15:31:18 +0100 Message-ID: <1t9vga1zec55e.advo17w5as02.dlg@40tude.net> NNTP-Posting-Date: 09 Dec 2007 15:31:20 CET NNTP-Posting-Host: 742ccb37.newsspool4.arcor-online.net X-Trace: DXC=JW:DbIVRAF?T2Rfi6`PGja[TFeF0D@\`>7`cUn6 X-Complaints-To: usenet-abuse@arcor.de Xref: g2news1.google.com comp.lang.ada:18811 Date: 2007-12-09T15:31:20+01:00 List-Id: On Sun, 09 Dec 2007 07:40:45 -0500, Peter C. Chapin wrote: > Dmitry A. Kazakov wrote: > >>> if Has_Acceptable_Value(X) then >>> P1(X); >>> end if; >>> >>> What if Has_Acceptable_Value(X) returns true if X is prime... or a >>> positive power of two? I don't believe you can use Ada subtypes to >>> express conditions like that---or indeed many other possibilities. >> >> Yes, but it that case very design of P1 is in question. Why the set of >> values where P1 is defined does not constitute some semantically integral >> body (like a subtype)? > > Well, my example above is a bit contrived. Let's consider a couple of > more realistic examples: > > 1. X is a string. Has_Acceptable_Value returns true if X is the name > field of some record in a database. The procedure P1 executes some > string handling algorithm that happens to not be meaningful for empty > strings. Thus P1 raises an exception if given such a string. Yet, due to > database constraints (let's say), any X that causes Has_Acceptable_Value > to return true won't be empty so the exception never arises. Then I would propose: begin P1 (X); exception when Empty_String_Error => -- do something else end; If the point is that exception propagation is too expensive for the caller of P1 then again, why wasn't it for P1? Bad design? > 2. X is an abstract type representing an XML document. > Has_Acceptable_Value returns true if X is valid according to its > declared schema. P1 does some XML processing but it assumes the document > given to it is well formed and raises exceptions if that is not the > case. Since valid documents are also well formed, those exceptions won't > occur once Has_Acceptable_Value has signed off on X. Indeed, this is one > of the main reasons why validating documents before processing them is > desirable: it simplifies later error handling. Isn't this indeed a waste of resources? Validation is performed twice, once in Has_Acceptable_Value and once in P1! Isn't this design actually based on a presumption that P1 does something wrong, while Has_Acceptable_Value would do it right? Wouldn't it better just to fix P1? And for all, I bet that exception propagation in most cases will be far more efficient than an extra document parsing. > If I understand what you are saying, one would need to define a subtype > of strings that contains all strings but the empty string (for #1) or a > subtype of my abstract type that contains all valid XML documents (for > #2). Can those things be expressed using Ada subtypes? I suppose it > could be done using type derivation, but is invoking that machinery > really better than just ignoring the possibility that P1 will raise and > letting any unexpected exceptions propagate in the usual way? My point is that if there exist problems then they lie by possible weaknesses of the language subtyping system rather than by contracts for exceptions. > The issue is particularly acute when there is an else clause on the if. > > if Is_Valid_XML(X) then > Process_Document(X); > else > Log_Bad_Document(X); > end if; > > Suppose the above is inside a loop that runs over a collection of > documents. Do we really want to include a handler for > Not_Well_Formed_Exception in this procedure just because the contract on > Process_Document says it might raise such an exception? Do we really > want to claim that we propagate that exception when we clearly don't? I want to propagate it. If the design foresaw exception propagation (and contract says so), then I just handle that exception explicitly. To me begin Process_Document (X); exception when Reason : Format_Error => Log_Bad_Document (Reason); end; is much cleaner and also more efficient. If some extra analysis of X has to done then I would do it in the exception handler after the problem has manifested itself. The universal principle is never run ahead of the locomotive... (:-)) > You might say that in a careful program (for example in a high integrity > program) unexpected exceptions should not be treated in such a cavalier > manner. I would agree with that. The question is should the language > attempt to force that degree of care on all programs? YES! Otherwise I would use Visual Basic. (:-)) > It's a balance > between usability and safety. As with all things related to security, > overly aggressive policies can backfire when people feel the need to do > silly things to work around them. I suppose at the end of the day it's > really just a matter of taste... which is what makes debates like this > possible. :-) Talking about balance. It is not about high integrity applications. In recent times I have been using a lot of GTK+ (under GtkAda). I cannot tell for AdaCore people developing GPS, but as for me, GTK+ makes me sick. Roughly 90% of all errors I spent the debugging time on was about exceptions propagating from Ada into GTK and then crashing it. It is a mess, and there is no any way to deal with that, because GTK+ is not Ada and its design contradicts to very foundations of. Analysis of these cases clearly shows that these bugs could be caught at compile time if we had exception contracts. I don't see how lacking it could add any usability. It does otherwise. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de