[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Issue: ERROR-CHECKING-IN-NUMBERS-CHAPTER (Version 1)
- To: CL-Cleanup@SAIL.Stanford.EDU
- Subject: Issue: ERROR-CHECKING-IN-NUMBERS-CHAPTER (Version 1)
- From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
- Date: Mon, 6 Mar 89 23:29 EST
Well, no one else beat me to it so I finally got around to writing up one
of the several needed proposals on what functions should signal what errors.
Let me emphasize that even though this covers a subset of the functions in
CLtL, it is still both meaningful and useful to vote on it separately. If
we had only proposals for handling of errors in numbers and files/streams
that would cover a very large class of cases.
This being a long proposal, please keep your comments focused. Preferrably
just requests for specific changes in wording with a brief rationale for the
change. I am not firmly wedded to any of the positions I've taken here --
I just felt it necessary to take -some- position. I patterned this pretty
directly after a document I passed out several meetings ago, but I got very
little feedback on that document, so I don't know if it was controversial.
-kmp
----
Issue: ERROR-CHECKING-IN-NUMBERS-CHAPTER
Forum: Cleanup
References: Numbers (pp193-232),
S:>kmp>cl>conditions>revision-18-notes.text.34
(formerly S:>kmp>cl-conditions.text.34),
Category: CHANGE
Edit history: 06-Mar-89, Version 1 by Pitman
Status: For Internal Discussion
Problem Description:
In many cases, CLtL specifies ``is an error'' situations for functions
in places that programmers would prefer to see an error signalled.
Reliably signalling an error accomplishes two things...
- It eases the development process by making it easier to notice errors
in a timely fashion.
- It makes it easier for code to reliably handle errors at runtime,
leading to greater robustness in delivered applications.
Proposal (ERROR-CHECKING-IN-NUMBERS-CHAPTER:SCARECROW): - a straw man...
ABS should signal TYPE-ERROR if its argument is not type NUMBER.
ACOS should signal TYPE-ERROR if its argument is not type NUMBER.
ACOS might signal ARITHMETIC-ERROR.
ACOSH should signal TYPE-ERROR if its argument is not type NUMBER.
ACOSH might signal ARITHMETIC-ERROR.
ASH should signal TYPE-ERROR if either argument is not type INTEGER.
ASH might signal ARITHMETIC-ERROR.
ASIN should signal TYPE-ERROR if its argument is not type NUMBER.
ASIN might signal ARITHMETIC-ERROR.
ASINH should signal TYPE-ERROR if its argument is not type NUMBER.
ASINH might signal ARITHMETIC-ERROR.
ATAN should signal TYPE-ERROR if exactly one argument is given and that
argument is not type NUMBER.
ATAN should signal TYPE-ERROR if exactly two arguments are given and
either argument is not type (AND NUMBER (NOT COMPLEX)).
ATAN might signal ARITHMETIC-ERROR.
ATANH should signal TYPE-ERROR if its argument is not type NUMBER.
ATANH might signal ARITHMETIC-ERROR.
BOOLE should signal TYPE-ERROR if its first argument is not type
(MEMBER #.BOOLE-CLR #.BOOLE-SET #.BOOLE-1 #.BOOLE-2
#.BOOLE-C1 #.BOOLE-C2 #.BOOLE-AND #.BOOLE-IOR
#.BOOLE-XOR #.BOOLE-EQV #.BOOLE-NAND #.BOOLE-NOR
#.BOOLE-ANDC1 #.BOOLE-ANDC2 #.BOOLE-ORC1 #.BOOLE-ORC2)
BOOLE should signal TYPE-ERROR if either its second or third
argument is not type INTEGER.
BYTE should signal TYPE-ERROR if either argument is not type INTEGER.
BYTE-POSITION might signal TYPE-ERROR if its argument is not a byte
specifier (something that was returned by the BYTE
function). Note that byte specifiers are not required
to be disjoint from other types, so this error checking
is only heuristic.
BYTE-SIZE might signal TYPE-ERROR if its argument is not a byte
specifier (something that was returned by the BYTE
function). Note that byte specifiers are not required
to be disjoint from other types, so this error checking
is only heuristic.
CEILING should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
CEILING should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
CEILING should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
CEILING might signal ARITHMETIC-ERROR.
COMPLEX should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
COMPLEX should signal TYPE-ERROR if its second argument is provided
but is not type (AND NUMBER (NOT COMPLEX)).
CONJUGATE should signal TYPE-ERROR if its argument is not type NUMBER.
CIS should signal TYPE-ERROR if its argument is not type
(AND NUMBERP (NOT COMPLEX)).
CIS might signal ARITHMETIC-ERROR.
COS should signal TYPE-ERROR if its argument is not type NUMBER.
COS might signal ARITHMETIC-ERROR.
COSH should signal TYPE-ERROR if its argument is not type NUMBER.
COSH might signal ARITHMETIC-ERROR.
DECF might signal SYNTAX-ERROR at semantic processing time.
DECF should signal TYPE-ERROR at runtime if the variable to be
incremented does not have a value of type NUMBER.
DECF might signal ARITHMETIC-ERROR at runtime.
DECODE-FLOAT should signal TYPE-ERROR if its argument is not type FLOAT.
DENOMINATOR should signal TYPE-ERROR if its argument is not type RATIONAL.
DEPOSIT-FIELD should signal TYPE-ERROR if its first argument is not type
INTEGER.
DEPOSIT-FIELD might signal TYPE-ERROR if its second argument is not a
bytespec (something returned by BYTE). Note that byte
specifiers are not required to be disjoint from other types,
so this error checking is only heuristic.
DEPOSIT-FIELD should signal TYPE-ERROR if its third argument is not type
INTEGER.
DPB should signal TYPE-ERROR if its first argument is not type INTEGER.
DPB might signal TYPE-ERROR if its second argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
DPB should signal TYPE-ERROR if its third argument is not type INTEGER.
EVENP should signal TYPE-ERROR if its argument is not type INTEGER.
FCEILING should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FCEILING should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FCEILING should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FCEILING might signal ARITHMETIC-ERROR.
FFLOOR should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FFLOOR should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FFLOOR should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FFLOOR might signal ARITHMETIC-ERROR.
FLOOR should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FLOOR should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FLOOR should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FLOOR might signal ARITHMETIC-ERROR.
FROUND should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FROUND should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FROUND should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FROUND might signal ARITHMETIC-ERROR.
FTRUNCATE should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FTRUNCATE should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
FTRUNCATE should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
FTRUNCATE might signal ARITHMETIC-ERROR.
GCD should signal TYPE-ERROR if any argument is not type INTEGER.
GCD might signal ARITHMETIC-ERROR.
EXP should signal TYPE-ERROR if its argument is not type NUMBER.
EXP might signal ARITHMETIC-ERROR.
EXPT should signal TYPE-ERROR if either argument is not type NUMBER.
EXPT might signal ARITHMETIC-ERROR. e.g., (EXPT 0 0.0)
FLOAT should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
FLOAT should signal TYPE-ERROR if its second argument is supplied
but is not type FLOAT.
FLOAT might signal ARITHMETIC-ERROR.
FLOAT-DIGITS should signal TYPE-ERROR if its argument is not type FLOAT.
FLOAT-PRECISION should signal TYPE-ERROR if its argument is not type FLOAT.
FLOAT-RADIX should signal TYPE-ERROR if its argument is not type FLOAT.
FLOAT-SIGN should signal TYPE-ERROR if its first argument is not type
FLOAT.
FLOAT-SIGN should signal TYPE-ERROR if its second argument is supplied
but is not type FLOAT.
INCF might signal SYNTAX-ERROR at semantic processing time.
INCF should signal TYPE-ERROR at runtime if the variable to be
incremented does not have a value of type NUMBER.
INCF might signal ARITHMETIC-ERROR at runtime.
INTEGER-DECODE-FLOAT should signal TYPE-ERROR if its argument is not
type FLOAT.
INTEGER-LENGTH should signal TYPE-ERROR if its argument is not type INTEGER.
IMAGPART should signal TYPE-ERROR if its argument is not type NUMBER.
ISQRT should signal TYPE-ERROR if its argument is not type (INTEGER 0).
ISQRT might signal ARITHMETIC-ERROR.
LCM should signal TYPE-ERROR if any argument is not type INTEGER.
LCM might signal ARITHMETIC-ERROR.
LDB might signal TYPE-ERROR if its first argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
LDB should signal TYPE-ERROR if its second argument is not type INTEGER.
LDB-TEST might signal TYPE-ERROR if its first argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
LDB-TEST should signal TYPE-ERROR if its second argument is not type INTEGER.
LOG should signal TYPE-ERROR if either argument is not type NUMBER.
LOG might signal ARITHMETIC-ERROR.
LOGAND should signal TYPE-ERROR if any argument is not type INTEGER.
LOGANDC1 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGANDC2 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGBITP should signal TYPE-ERROR if its first argument is not type
(INTEGER 0).
LOGBITP should signal TYPE-ERROR if its second argument is not type
INTEGER.
LOGCOUNT should signal TYPE-ERROR error if its argument is not type INTEGER.
LOGEQV should signal TYPE-ERROR if any argument is not type INTEGER.
LOGIOR should signal TYPE-ERROR if any argument is not type INTEGER.
LOGNAND should signal TYPE-ERROR if either argument is not type INTEGER.
LOGNOR should signal TYPE-ERROR if either argument is not type INTEGER.
LOGNOT should signal TYPE-ERROR error if its argument is not type INTEGER.
LOGORC1 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGORC2 should signal TYPE-ERROR if either argument is not type INTEGER.
LOGTEST should signal TYPE-ERROR if either argument is not type INTEGER.
LOGXOR should signal TYPE-ERROR if any argument is not type INTEGER.
MAKE-RANDOM-STATE should signal TYPE-ERROR if an argument is supplied
but is not type (OR (MEMBER NIL T) RANDOM-STATE).
MASK-FIELD might signal TYPE-ERROR if its first argument is not a bytespec
(something returned by BYTE). Note that byte specifiers are not
required to be disjoint from other types, so this error checking
is only heuristic.
MASK-FIELD should signal TYPE-ERROR if its second argument is not type
INTEGER.
MAX should signal TYPE-ERROR if any argument is not type
(AND NUMBERP (NOT COMPLEX)).
MAX might signal ARITHMETIC-ERROR.
MIN should signal TYPE-ERROR if any argument is not type
(AND NUMBERP (NOT COMPLEX)).
MIN might signal ARITHMETIC-ERROR.
MINUSP should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
MOD should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
MOD should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
MOD should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
MOD might signal ARITHMETIC-ERROR.
NUMERATOR should signal TYPE-ERROR if its argument is not type RATIONAL.
ODDP should signal TYPE-ERROR if its argument is not type INTEGER.
PHASE should signal TYPE-ERROR if its argument is not type NUMBER.
PHASE might signal ARITHMETIC-ERROR.
PLUSP should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
RANDOM should signal TYPE-ERROR if its first argument is not
type (INTEGER 1).
RANDOM should signal TYPE-ERROR if its second argument is supplied
but is not type RANDOM-STATE.
RANDOM-STATE-P will never signal an error.
RATIONAL should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
RATIONAL might signal ARITHMETIC-ERROR.
RATIONALIZE should signal TYPE-ERROR if its argument is not type
(AND NUMBER (NOT COMPLEX)).
RATIONALIZE might signal ARITHMETIC-ERROR.
REALPART should signal TYPE-ERROR if its argument is not type NUMBER.
REM should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
REM should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
REM should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
REM might signal ARITHMETIC-ERROR.
ROUND should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
ROUND should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
ROUND should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
ROUND might signal ARITHMETIC-ERROR.
SCALE-FLOAT should signal TYPE-ERROR if its first argument is not
type FLOAT.
SCALE-FLOAT should signal TYPE-ERROR if its second argument is not
type INTEGER.
SIGNUM should signal TYPE-ERROR if its argument is not type NUMBER.
SIN should signal TYPE-ERROR if its argument is not type NUMBER.
SIN might signal ARITHMETIC-ERROR.
SINH should signal TYPE-ERROR if its argument is not type NUMBER.
SINH might signal ARITHMETIC-ERROR.
SQRT should signal TYPE-ERROR if its argument is not type NUMBER.
SQRT might signal ARITHMETIC-ERROR.
TAN should signal TYPE-ERROR if its argument is not type NUMBER.
TAN might signal ARITHMETIC-ERROR.
TANH should signal TYPE-ERROR if its argument is not type NUMBER.
TANH might signal ARITHMETIC-ERROR.
TRUNCATE should signal TYPE-ERROR if its first argument is not type
(AND NUMBER (NOT COMPLEX)).
TRUNCATE should signal TYPE-ERROR if its second argument is supplied
but is not type (AND NUMBER (NOT COMPLEX)).
TRUNCATE should signal DIVISION-BY-ZERO if its second argument is
supplied and is zero.
TRUNCATE might signal ARITHMETIC-ERROR.
ZEROP should signal TYPE-ERROR if its argument is not type NUMBER.
* should signal TYPE-ERROR if any argument is not type NUMBER.
* might signal ARITHMETIC-ERROR.
+ should signal TYPE-ERROR if any argument is not type NUMBER.
+ should signal TYPE-ERROR if any argument is not type NUMBER.
+ might signal ARITHMETIC-ERROR.
- should signal TYPE-ERROR if any argument is not type NUMBER.
- might signal ARITHMETIC-ERROR.
/ should signal TYPE-ERROR if any argument is not type NUMBER.
/ should signal DIVISION-BY-ZERO if any divisor argument is zero.
/ might signal ARITHMETIC-ERROR.
/= should signal type-error if any argument is not type NUMBER.
/= might signal ARITHMETIC-ERROR.
1+ should signal TYPE-ERROR if any argument is not type NUMBER.
1+ might signal ARITHMETIC-ERROR.
1- should signal TYPE-ERROR if any argument is not type NUMBER.
1- might signal ARITHMETIC-ERROR.
< should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
< might signal ARITHMETIC-ERROR.
<= should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
<= might signal ARITHMETIC-ERROR.
= should signal TYPE-ERROR if any argument is not type NUMBER.
= might signal ARITHMETIC-ERROR.
> should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
> might signal ARITHMETIC-ERROR.
>= should signal TYPE-ERROR if any argument is not type
(AND NUMBER (NOT COMPLEX)).
>= might signal ARITHMETIC-ERROR.
Rationale:
This addresses the development and delivery concerns mentioned in the
Problem Description.
Current Practice:
Most implementations probably do not reliably signal the indicated
errors in safe code.
Cost to Implementors:
In implementations not providing the indicated error checking,
considerable work might need to be done.
The alternative is to identify the implementation as an "unsafe" subset.
However, while it is a "subset" in the sense that code that was developed
in it will run in the superset, it is important to understand that such
implementations are not simply "places you can run code that's been
thoroughly debugged in the full language" since such debugged code may
still depend on the reliable detection and handling of certain kinds of
errors.
Cost to Users:
Technically none. These are supposedly already all `is an error'
cases that people can't depend on.
Some users might be relying on an implementation not to signal a particular
error in compiled code. Such code is already not portable, however.
In some cases, where an implementation adds error checking that they
consider unnecessary, the user will need to add some OPTIMIZE proclamations.
Some users will see this as a bug fix.
Cost of Non-Adoption:
The error handling facilities will be a lot less useful.
Code that uses error handling will not port well.
Benefits:
Better development environments. More robust delivered applications.
Aesthetics:
Hopefully improved.
Discussion:
Pitman getting this level of detail is a good idea. He's ammenable to
specific changes if they improve the overall level of receptiveness to
the proposal.
Notes about how to proceed on this issue
(to be removed prior to final vote):
- Is anyone uncomfortable about the name ARITHMETIC-ERROR?
If so, can someone mathematically inclined suggest a better name?
`MATH-ERROR' or `NUMBER-ERROR' come to mind.
- In some of the cases of "might signal", it might be the case that
no signal should ever occur. Someone who's actually implemented these
functions might want to suggest that in some cases we can remove
this verbiage, or give examples of the circumstances under which the
condition might be signalled?