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=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,d4b13594b8779b99,start X-Google-Attributes: gid103376,public From: blaak@infomatch.com (Ray Blaak) Subject: Improving Ada Exceptions Date: 1997/10/26 Message-ID: <63072n$q6r$1@berlin.infomatch.com>#1/1 X-Deja-AN: 285827362 Summary: Why can't Ada's raise be like C++'s throw? Keywords: exceptions X-Complaints-To: usenet@berlin.infomatch.com X-Trace: berlin.infomatch.com 877895575 26843 (None) 199.60.99.1 Organization: InfoMatch Internet - Vancouver BC Newsgroups: comp.lang.ada Date: 1997-10-26T00:00:00+00:00 List-Id: Hello all. I am an Ada fanatic who has just started his first C++ project. Being thoroughly ingrained against the evils of C++ I was quite surprised to find it not as bad as I expected. There are many horrible aspects about it, to be sure, but one thing I find very cool is C++'s exception mechanism. It is a very powerful thing to be able to throw and catch arbitrary objects, since one can cleanly place whatever appropriate information is relevant to the error. By catching objects of a base class, one can handle whole classes of errors at once. The Ada 83 exception method is clean and simple but suffers from the inability to pass data with the exception. Ada 95 adds the ability to pass strings with the exception, but in an inelegant way, in my opinion. One now has the Ada.Exceptions library package, exception ids, exception occurrences, and mutiple ways to raise on exception (i.e. the raise keyword and Ada.Exceptions.Raise_Exception). Part of the complexity comes from the fact that Ada exceptions are just names, not data objects, but the result seems a kind of hack. Surely there can be a conceptually simpler way. So how About extending the semantics of raise to simply allow arbitrary objects to be raised, as in C++? To handle an arbitrary thrown object, the "when" branches of an exception handle could look like a good-old-fashioned variable declaration (there is already a precedent syntactically with "when e : others =>""). Consider this simple example: type Out_Of_Range is record Hi : Integer; Low : Integer; Value : Integer; end record; ... if (...Some Failure...) raise Out_Of_Range'(Hi => 0, Low => 99, Value => Input_Value); end if; ... exception when Error : Out_Of_Range => Text_Io.Put_Line ("out of range. " & Integer'Image(Error.Value) & " not in" & Integer'Image(Error.Low) & " .." & Integer'Image(Error.Hi)); end; Consider a heirarchy of exception types: package Math_Exception is type Math_Error is tagged record with private; function Message_Of (Error : in Math_Error) return String; type Integer_Divide_By_Zero_Error is new Math_Error with private; -- Message_Of is inherited. function Bad_Denominator_Of (Error : in Integer_Divide_By_Zero_Error) return Integer; -- other error types... private -- whatever... end Math_Exception; Now fielding a heirarchy of errors: begin -- some bogus calculation exception when Error : Math_Exception.Integer_Divide_By_Zero_Error => Text_Io.Put_Line ("divide by zero with " & Integer'Image(Math_Exception.Bad_Denominator_Of(Error))); when Error : Math_Exception.Math_Exception'Class => -- handle any other math errors Text_Io.Put_Line (Math_Exception.Message_Of(Error)); end; It seems to me that this proposal fits fairly cleanly and orthogonally with the existing language design. Of course, I could be missing something fundamental. I would like to see a discussion on the merits and disadvantages of this approach. Some things I am interested in: 01. Implementation complexity: Is this hard to do? Given that this is already implemented in C++, and GNAT especially can take advantage of gcc's implementation, is there something specific to Ada that would make it more difficult? What about throwing controlled types? 02. Safety issues: Will this violate anything? Throwing objects containing pointers to static objects comes to mind. 03. Conceptual coolness: I think that this approach makes use of existing syntax pretty simply and cleanly. It also, I think, does not preturb the existing exception mechanism. What are some problems? One might be that "raise" is typeless. One either has to raise a variable, or a type qualified literal or aggregate. 04. Anything else? -- 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.