manis@UBC.CSNET (Vincent Manis) (02/04/86)
I'm personally strongly opposed to hardwiring exception handling into programming languages. In part, this is because one wants to discourage routine use of exceptions for other than error handling; in part, because one of the major virtues of Modula-2 is its small size. Exceptions, by their very nature, are global. One signals an exception, and any module in the system (or at least in the dynamic execution history of the program) can catch them. As a result, two modules may have different ideas on what to do with a given exception. Thus, there are very good program structuring arguments against extensive use of exceptions. What many people have missed is that Modula-2 gives the programmer ''local exceptions'', in the form of procedure variables. Rather than exporting an exception, a module may export a procedure variable (or a procedure which accepts a procedure parameter). The client module can assign this variable a value; when an exceptional condition occurs, the procedure is invoked, and does whatever the client deems appropriate. It should be noted that this possibility is not present in Ada(TM), as procedure variables and procedural parameters are not provided (the Steelman specification explicitly ruled them out; I never understood why). There are, however, a number of situations in which exception handling (or more precisely non-local jumps) are necessary. Jeffrey McArthur's proposals are quite reasonable (though I'd prefer to represent exception names by integers rather than character strings, for efficiency's sake). The C setjmp/longjmp facility, which McArthur references, is quite good enough by itself, though, and very easy to implement.
lsr@apple.UUCP (Larry Rosenstein) (02/13/86)
In article <913:manis@cs.ubc.cdn> writes: > >Exceptions, by their very nature, are global. One signals an exception, and >any module in the system (or at least in the dynamic execution history of >the program) can catch them. As a result, two modules may have different >ideas on what to do with a given exception. Thus, there are very good >program structuring arguments against extensive use of exceptions. > Not necessarily true. The CLU exception mechanism is local; if a procedure raises an exception, only its caller can handle it. If the caller does not handle it, the exception is converted into a generic 'failure' exception, which will be propagated up another level (and so on). The reason for this is modularity; a routine should not have to know about exceptions that could be generated several levels of calls deep. This is in keeping with the CLU programming methodology that the internals of a module are hidden from users of the module. The language provided a convenient way to pass an exception up a level, but you had to explicitly write this. Non-local exception mechanisms are convenient because you do not have to explicitly pass exceptions on to your caller if you don't care about them. I have implemented a setjmp/longjmp kind of mechanism for the Pascal we use (on top ofthe language), and found it to be very useful in handling errors. -- Larry Rosenstein Apple Computer UUCP: {voder, nsc, ios, mtxinu, dual}!apple!lsr CSNET: lsr@Apple.CSNET
wyant@apollo.UUCP (Geoffrey Wyant) (04/22/86)
One problem I see with implementing exceptions outside the language comes in the following form: VAR fileOpened: BOOLEAN ; Exceptions.SetHandler(status) ; IF status <> ok THEN IF fileOpened THEN FileSystem.Close(...); END ; END ; fileOpened := FALSE ; FileSystem.Open(...) ; fileOpened := TRUE ; Now a smart optimizing complier will notice that the first assignment to fileOpened is never used. It then thinks that it is free to delete that expression. This is clearly wrong. The fact is that either the compiler has to know about stack unwinders (exception handling) or there must be some way to declare that a variable is "volitale" and the compiler not optimize assignments to it. Similiar things can happen when dealing with IO devices (don't want optimize away those control register assignments !) Now I think that it's a bad idea to stick exception handling into the language, but the ability to specify attributes in a declaration, such as "volatile" seems to me to be usefull. Then one could write the above example as VAR fileOpened: [VOLITALE] BOOLEAN ; .... I think that the notion of attributes could be generalized to allow specifying field sizes for dealing with device registers: VAR mythicalCSR: [VOLITALE] RECORD [BITS] commands: SET OF (go, halt, catchFire) ; [BITS] status: SET OF (broken, flaming, toasting, running) ; END (* record *); What do other people think of this ? I think it provides usefull functionality without warping the language too much. Geoff Wyant -------
bobc@tikal.UUCP (Bob Campbell) (05/01/86)
In article <8604240042.AA13982@uw-beaver.arpa> wyant@apollo.UUCP (Geoffrey Wyant) writes: > >register assignments !) Now I think that it's a >bad idea to stick exception handling into the >language, but the ability to specify attributes >in a declaration, such as "volatile" seems to me >to be usefull. Then one could write the above >example as > > VAR > fileOpened: [VOLITALE] BOOLEAN ; > .... > >I think that the notion of attributes could be >generalized to allow specifying field sizes >for dealing with device registers: > > VAR > mythicalCSR: [VOLITALE] RECORD > [BITS] commands: > SET OF (go, halt, catchFire) ; > [BITS] status: > SET OF (broken, flaming, toasting, running) ; > END (* record *); > >What do other people think of this ? I think it provides usefull >functionality without warping the language too much. > > > Geoff Wyant >------- Well what I think is that these should be handled as compiler options ie: VAR fileOpened: (*$VOLITALE*) BOOLEAN ; .... VAR mythicalCSR: (*$VOLITALE*) RECORD (*$BITS*) commands: SET OF (go, halt, catchFire) ; (*$BITS*) status: SET OF (broken, flaming, toasting, running) ; END (* record *); At this point I must admit that I don't under stand what BITS means. Does this mean size of BITSET or is BITS to be replaced by a number indicating the size of the element. (Is this Record to also be packed? ie how many words it this record). To continue and expand functionality one would add the compiler option "PACKED". Therefore a one word of 16 bits records containing two bit fields (as above) would become: VAR mythicalCSR: (*$VOLITALE*) RECORD (*$PACKED*) (*$BITS:3*) commands: SET OF (go, halt, catchFire); (*$BITS:4*) status: SET OF (broken, flaming, toasting, running); END (* record *); This interpretation of the original intent feels wrong to me as the size of the SETS (and subranges etc.) and be determined by the number of elements (or the size of the subrange) dummy feilds can be inserted to fill out for unused bits. (* Assuming that PACKED maximizes use of bits in the record *) This is my 2+ cents, Bob Campbell {fluke,dataio,hplsla,sunup,uw-beaver}!tikal!bobc