[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gcl-devel] condition system proposal
From: |
Camm Maguire |
Subject: |
Re: [Gcl-devel] condition system proposal |
Date: |
01 Nov 2002 00:03:20 -0500 |
Greetings, Peter, and thanks as always for your thorough ideas and
work!
1) I agree the error system is in a mess. o/error.c, lsp/serror.lsp
and clcs/kcl-cond.lisp clcs/conditions.lisp all seem to have been
added at separate times.
2) We need to find a way to smoothly transition to whatever new
structure we decide upon without breaking anything in maxima or
acl2. GCL now compiles both of these on all 11 Debian
architectures plus a few other machines, and I'd like to keep it
this way at all times if possible.
3) Many of Paul's tests have already revolved around this issue, and
many of my patches thus far have likewise addressed error
conditions. If you look through the CVS log on kcl-cond.lisp,
error.c, and package.d (for example), you can see what's been done
so far. In all of this I've attempted to take the minimal steps
necessary to fix the test without spoiling existing function
interfaces possibly in use by other code. This has not always been
possible, but has in general been achievable as far as I can tell.
While this approach unfortunately makes for poor overall design, it
does allow us to focus on getting correct behavior quickly without
breaking existing functionality, and hopefully leaving us in a
position to redesign certain items once we've consolidated a bit.
4) The error messages I've put in recently in particular need work.
I've tried to label such places with a FIXME comment in the code.
5) This having been said, I don't think your proposal is necessarily
too radical for the above goals. In fact, its quite similar to
what we've been doing in general, i.e. replacing all instances of
FEerror with something more specific. So in general I like this
proposal very much. Here are some thoughts which we might need to
discuss:
a) Do we need 'internal' error subtypes in any/all cases?
can't we throw the main type where allowed by the spec,
e.g. package-error?
b) we need to make sure the interface allows us to specify
that the error is correctable. See the 'specific-error' and
'specific-correctable-error' hacks in error.c
c) A lot of existing lisp code calls (error "foo" ...). So
does this mean we have to name a function with a fuller syntax
like (foo :internal-bar-error :correctable "asdasda" ...)(
something other than 'error'? I've made this assumption thus
far.
d) Until we standardize on the ansi image (at least), whatever
we do has to work with the traditional image as well. clcs
overwrites the function 'error' defined in error.c for the
traditional image.
e) while we're at it, we should also standardize where a given
error condition defines what data it takes. There appears to
be code to this effect both in conditions.lisp and
kcl-cond.lisp. Will every error of the same type have the
same error string? I kind of like a dual solution like "Type
error: ~S is not of type ~S: <specific instance message if
available>". Each instance could then pass clarifying
information -- see the previous error messages that were in
package.d before I truncated them to conform with the existing
package-error expectations.
f) once we agree on a system (and I'd like to hear Paul's and
hopefully Vadim's comments here), perhaps what we would then
do is to decide that no one commits any further error fixes
while you work on your implementation. Once you've verified
that all maxima and acl2 tests still pass, we can check it in
en masse to CVS. With the current state of gcl, quite a few
people appear to be using CVS, so I'd really like to not break
it if possible.
More later...
Take care,
Peter Wood <address@hidden> writes:
> Hi
>
> First of all, this is a long mail, for which I apologise. Secondly,
> this proposal entails a fair amount of work, which I am volunteering
> to do. However, I would appreciate some feedback first:
>
> Is there anything anyone sees in the following that is
> inadvisable/unworkable/misguided/stupid?
>
> The error system is not in great shape. Some ansi conditions are
> missing (eg division-by-zero), and more seriously, the conditions
> which get signalled are neither (1) identifiable as ansi conditions,
> nor (2) practically useable by a programmer because their names are
> not predictable from a knowledge of the spec.
>
> For example: In o/catch.c
>
> fr = frs_sch_catch(tag);
> if (fr == NULL)
> FEerror("~S is an undefined tag.", 1, tag);
>
> Creates #<conditions::internal-simple-error.0>
>
> Which is the identical condition type to _lots_ of quite diverse types
> including the condition signalled by (/ 1 0).
>
> This means the programmer can't distinguish between the two in a
> handler-bind or handler-case.
>
> The spec (from my reading) allows us to define new types (like
> 'internal-simple-program-error) but (1) they should be in their own
> package (2) they should be subtypes of appropriate ansi types so that
> a programmer can use them sensibly without knowing in advance what
> they are called.(3) All the standard types must be there and (4) we
> must preserve the standard type hierarchy.
>
> For eaxample:
>
> (bearing in mind that, According To The Spec (ATTS): "The type
> program-error consists of error conditions related to incorrect
> program syntax. The errors that result from naming a go tag or a block
> tag that is not lexically apparent are of type program-error.")
>
> We can define conditions::internal-simple-program-error to be a
> subtype of program-error and then change the catch.c example above to:
>
> fr = frs_sch_catch(tag);
> if (fr == NULL)
> UNDEFINED_TAG(tag)
>
> Where UNDEFINED_TAG(x) looks like this (in a new header file
> 'h/lisp-error.h') which gets #included by "include.h"
>
> EXTER object Icall_error_handler();
>
> #define UNTAGMESSAGE make_simple_string("Syntax Error: The tag ~S is
> undefined.")
> #define UNDEFINED_TAG(x)
> {Icall_error_handler(sKinternal_simple_program_error,UNTAGMESSAGE,1,(x));}
>
> We use sKinternal_simple_program_error as the error name because its a
> keyword in its own package and doesn't pollute the COMMON-LISP
> package.
>
> In clcs/condition-definitions.lisp we define the condition
> internal-simple-program-error (and _not_ export it). In
> clcs/kcl-cond.lisp we change the internal-error-hash-table to look
> something like this:
>
> (defparameter *internal-error-list*
> '((division-by-zero :operands)
> (arithmetic-error :operation :operands)
> (unbound-variable :name)
> (:internal-simple-program-error
> conditions::internal-simple-program-error :format-string
> :format-arguments))) ;;etc
>
> Where the lookup is done on the car, and if it is a keyword, we set
> the data to the cdr, otherwise it is what gets returned by the lookup.
> All the ansi-standard condition types can be referred to directly
> since the condition name can be a symbol in COMMON-LISP.
>
> Ie, in o/num_arith.c in the function number_divide():
>
> if(number_zerop(y) == TRUE)
> DIVISION_BY_ZERO(x,y)
>
> Where DIVISION_BY_ZERO is #defined in h/lisp-error.h to be
>
> #define DIVZMESSAGE make_simple_string("Division with operands ~S is an
> error")
> #define DIVISION_BY_ZERO(x,y)
> {Icall_error_handler(sLdivision_by_zero,DIVZMESSAGE,1,make_cons((x),make_cons((y),
> Cnil)));}
>
> and lisp-error.h also gets #included by num_include.h.
>
> Under this proposal, we will keep FEerror as a fallback, but most
> (all, except for some very primitive calls) calls to FEerror will be
> replaced by appropriate macros. Some/Most of the other FE<name> calls
> and functions can eventually be dumped, if this works out and proves
> robust. The ansi-standard conditions will be mostly left just as a
> template, and GCL internal-xyz-errors will inherit from them
> appropriately.
>
> I have implemented the beginnings of this proposal. Here's what it
> looks like in practice:
>
> ============================================================
> >(/ 1 0)
>
> DIVISION operation with operands (1 0) is an error
>
> Fast links are on: do (use-fast-links nil) for debugging
> Broken at /. Type :H for Help.
> 1 (Abort) Return to top level.
> dbl:>>:q
>
> Top level.
> >(go foo)
>
> Syntax Error: The tag FOO is undefined.
>
> Fast links are on: do (use-fast-links nil) for debugging
> Broken at GO. Type :H for Help.
> 1 (Abort) Return to top level.
> dbl:>>
>
> >(defmacro tec (ec ef)
> `(handler-case ,ef (,ec (c) (format t "Gotcha: ~A" c))))
>
> TEC
>
> >(tec program-error (go foo))
> Gotcha: Syntax Error: The tag FOO is undefined.
> NIL
>
> >(tec division-by-zero (/ 1 0))
> Gotcha: DIVISION operation with operands (1 0) is an error
> NIL
>
> >(tec unbound-variable (cons 1 a))
> Gotcha: The variable A is unbound.
> NIL
>
> >(tec division-by-zero (go foo))
>
> Syntax Error: The tag FOO is undefined.
>
> Fast links are on: do (use-fast-links nil) for debugging
> Broken at GO. Type :H for Help.
> 1 (Abort) Return to top level.
> dbl:>>:q
>
> ================================================= etc ===
>
> I have only tried testing one place in the compiler with a new error
> macro, and it works fine, so far.
>
> In cmpnew/cmpcatch.lsp
>
> (wt-nl "fr=frs_sch_catch(" loc ");")
> ; (wt-nl "if(fr==NULL) FEerror(\"The tag ~s is undefined.\",1," loc ");")
> (wt-nl "if(fr==NULL) UNDEFINED_TAG(" loc ")")
>
> produces c-code like this:
>
> fr=frs_sch_catch(VV[0]);
> if(fr==NULL) UNDEFINED_TAG(VV[0])
>
> The following work as expected when compiled with the changed
> compiler:
>
> (defun test-throw-code-1 ()
> (catch 'foo
> (sub)))
> => FOO
>
> (defun sub ()
> (throw 'foo 'foo))
>
> (defun test-throw-code-2 ()
> (sub))
> => Syntax Error: The tag FOO is undefined.
>
> The macros get included in cmpinclude.h via protoize.h. Is there a
> better way to do this?
>
> If noone has any objections, I will continue working along these
> lines. Of course, I won't commit any changes without agreement, but I
> wanted to ask for comments now, since there's quite a bit of work
> here, and I don't want to do it if anyone can already see an
> objection.
>
> Thanks for your patience.
>
> Regards,
> Peter
>
>
> _______________________________________________
> Gcl-devel mailing list
> address@hidden
> http://mail.gnu.org/mailman/listinfo/gcl-devel
>
>
--
Camm Maguire address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens." -- Baha'u'llah
- Re: [Gcl-devel] condition system proposal,
Camm Maguire <=