update.
[chise/xemacs-chise.git-] / man / lispref / control.texi
index 5ea470f..5860ca5 100644 (file)
@@ -1,6 +1,6 @@
 @c -*-texinfo-*-
 @c This is part of the XEmacs Lisp Reference Manual.
 @c -*-texinfo-*-
 @c This is part of the XEmacs Lisp Reference Manual.
-@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 
+@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
 @c See the file lispref.texi for copying conditions.
 @setfilename ../../info/control.info
 @node Control Structures, Variables, Evaluation, Top
 @c See the file lispref.texi for copying conditions.
 @setfilename ../../info/control.info
 @node Control Structures, Variables, Evaluation, Top
@@ -152,7 +152,7 @@ based on the value of @var{condition}.  If the evaluated @var{condition} is
 non-@code{nil}, @var{then-form} is evaluated and the result returned.
 Otherwise, the @var{else-forms} are evaluated in textual order, and the
 value of the last one is returned.  (The @var{else} part of @code{if} is
 non-@code{nil}, @var{then-form} is evaluated and the result returned.
 Otherwise, the @var{else-forms} are evaluated in textual order, and the
 value of the last one is returned.  (The @var{else} part of @code{if} is
-an example of an implicit @code{progn}.  @xref{Sequencing}.) 
+an example of an implicit @code{progn}.  @xref{Sequencing}.)
 
 If @var{condition} has the value @code{nil}, and no @var{else-forms} are
 given, @code{if} returns @code{nil}.
 
 If @var{condition} has the value @code{nil}, and no @var{else-forms} are
 given, @code{if} returns @code{nil}.
@@ -163,8 +163,8 @@ never evaluated---it is ignored.  Thus, in the example below,
 
 @example
 @group
 
 @example
 @group
-(if nil 
-    (print 'true) 
+(if nil
+    (print 'true)
   'very-false)
 @result{} very-false
 @end group
   'very-false)
 @result{} very-false
 @end group
@@ -226,7 +226,7 @@ clauses was successful.  To do this, we use @code{t} as the
 never @code{nil}, so this clause never fails, provided the @code{cond}
 gets to it at all.
 
 never @code{nil}, so this clause never fails, provided the @code{cond}
 gets to it at all.
 
-For example, 
+For example,
 
 @example
 @group
 
 @example
 @group
@@ -360,7 +360,7 @@ You could almost write @code{or} in terms of @code{if}, but not quite:
 @example
 @group
 (if @var{arg1} @var{arg1}
 @example
 @group
 (if @var{arg1} @var{arg1}
-  (if @var{arg2} @var{arg2} 
+  (if @var{arg2} @var{arg2}
     @var{arg3}))
 @end group
 @end example
     @var{arg3}))
 @end group
 @end example
@@ -581,7 +581,7 @@ return points at once.  First, two return points with the same tag,
 @end group
 
 @group
 @end group
 
 @group
-(catch 'hack 
+(catch 'hack
   (print (catch2 'hack))
   'no)
 @print{} yes
   (print (catch2 'hack))
   'no)
 @print{} yes
@@ -662,47 +662,172 @@ instead.  @xref{Catch and Throw}.
 which you call for other purposes, such as if you try to take the
 @sc{car} of an integer or move forward a character at the end of the
 buffer; you can also signal errors explicitly with the functions
 which you call for other purposes, such as if you try to take the
 @sc{car} of an integer or move forward a character at the end of the
 buffer; you can also signal errors explicitly with the functions
-@code{error} and @code{signal}.
+@code{error}, @code{signal}, and others.
 
 
-  Quitting, which happens when the user types @kbd{C-g}, is not 
+  Quitting, which happens when the user types @kbd{C-g}, is not
 considered an error, but it is handled almost like an error.
 @xref{Quitting}.
 
 considered an error, but it is handled almost like an error.
 @xref{Quitting}.
 
-@defun error format-string &rest args
-This function signals an error with an error message constructed by
-applying @code{format} (@pxref{String Conversion}) to
-@var{format-string} and @var{args}.
+XEmacs has a rich hierarchy of error symbols predefined via @code{deferror}.
+
+@example
+error
+  syntax-error
+    invalid-read-syntax
+    list-formation-error
+      malformed-list
+        malformed-property-list
+      circular-list
+        circular-property-list
+
+  invalid-argument
+    wrong-type-argument
+    args-out-of-range
+    wrong-number-of-arguments
+    invalid-function
+    no-catch
+
+  invalid-state
+    void-function
+    cyclic-function-indirection
+    void-variable
+    cyclic-variable-indirection
+
+  invalid-operation
+    invalid-change
+      setting-constant
+    editing-error
+      beginning-of-buffer
+      end-of-buffer
+      buffer-read-only
+    io-error
+      end-of-file
+    arith-error
+      range-error
+      domain-error
+      singularity-error
+      overflow-error
+      underflow-error
+@end example
+
+The five most common errors you will probably use or base your new
+errors off of are @code{syntax-error}, @code{invalid-argument},
+@code{invalid-state}, @code{invalid-operation}, and
+@code{invalid-change}.  Note the semantic differences:
+
+@itemize @bullet
+@item
+@code{syntax-error} is for errors in complex structures: parsed strings,
+lists, and the like.
+
+@item
+@code{invalid-argument} is for errors in a simple value.  Typically, the
+entire value, not just one part of it, is wrong.
+
+@item
+@code{invalid-state} means that some settings have been changed in such
+a way that their current state is unallowable.  More and more, code is
+being written more carefully, and catches the error when the settings
+are being changed, rather than afterwards.  This leads us to the next
+error:
+
+@item
+@code{invalid-change} means that an attempt is being made to change some
+settings into an invalid state.  @code{invalid-change} is a type of
+@code{invalid-operation}.
+
+@item
+@code{invalid-operation} refers to all cases where code is trying to do
+something that's disallowed.  This includes file errors, buffer errors
+(e.g. running off the end of a buffer), @code{invalid-change} as just
+mentioned, and arithmetic errors.
+@end itemize
+
+@defun error datum &rest args
+This function signals a non-continuable error.
+
+@var{datum} should normally be an error symbol, i.e. a symbol defined
+using @code{define-error}.  @var{args} will be made into a list, and
+@var{datum} and @var{args} passed as the two arguments to @code{signal},
+the most basic error handling function.
+
+This error is not continuable: you cannot continue execution after the
+error using the debugger @kbd{r} command.  See also @code{cerror}.
+
+The correct semantics of @var{args} varies from error to error, but for
+most errors that need to be generated in Lisp code, the first argument
+should be a string describing the *context* of the error (i.e. the exact
+operation being performed and what went wrong), and the remaining
+arguments or \"frobs\" (most often, there is one) specify the offending
+object(s) and/or provide additional details such as the exact error when
+a file error occurred, e.g.:
+
+@itemize @bullet
+@item
+the buffer in which an editing error occurred.
+@item
+an invalid value that was encountered. (In such cases, the string
+should describe the purpose or \"semantics\" of the value [e.g. if the
+value is an argument to a function, the name of the argument; if the value
+is the value corresponding to a keyword, the name of the keyword; if the
+value is supposed to be a list length, say this and say what the purpose
+of the list is; etc.] as well as specifying why the value is invalid, if
+that's not self-evident.)
+@item
+the file in which an error occurred. (In such cases, there should be a
+second frob, probably a string, specifying the exact error that occurred.
+This does not occur in the string that precedes the first frob, because
+that frob describes the exact operation that was happening.
+@end itemize
+
+For historical compatibility, DATUM can also be a string.  In this case,
+@var{datum} and @var{args} are passed together as the arguments to
+@code{format}, and then an error is signalled using the error symbol
+@code{error} and formatted string.  Although this usage of @code{error}
+is very common, it is deprecated because it totally defeats the purpose
+of having structured errors.  There is now a rich set of defined errors
+to use.
+
+See also @code{cerror}, @code{signal}, and @code{signal-error}."
 
 These examples show typical uses of @code{error}:
 
 @example
 @group
 
 These examples show typical uses of @code{error}:
 
 @example
 @group
-(error "You have committed an error.  
+(error 'syntax-error
+       "Dialog descriptor must supply at least one button"
+       descriptor)
+@end group
+
+@group
+(error "You have committed an error.
         Try something else.")
         Try something else.")
-     @error{} You have committed an error.  
+     @error{} You have committed an error.
         Try something else.
 @end group
 
 @group
 (error "You have committed %d errors." 10)
         Try something else.
 @end group
 
 @group
 (error "You have committed %d errors." 10)
-     @error{} You have committed 10 errors.  
+     @error{} You have committed 10 errors.
 @end group
 @end example
 
 @end group
 @end example
 
-@code{error} works by calling @code{signal} with two arguments: the
-error symbol @code{error}, and a list containing the string returned by
-@code{format}.
-
 If you want to use your own string as an error message verbatim, don't
 just write @code{(error @var{string})}.  If @var{string} contains
 @samp{%}, it will be interpreted as a format specifier, with undesirable
 results.  Instead, use @code{(error "%s" @var{string})}.
 @end defun
 
 If you want to use your own string as an error message verbatim, don't
 just write @code{(error @var{string})}.  If @var{string} contains
 @samp{%}, it will be interpreted as a format specifier, with undesirable
 results.  Instead, use @code{(error "%s" @var{string})}.
 @end defun
 
+@defun cerror datum &rest args
+This function behaves like @code{error}, except that the error it
+signals is continuable.  That means that debugger commands @kbd{c} and
+@kbd{r} can resume execution.
+@end defun
+
 @defun signal error-symbol data
 @defun signal error-symbol data
-This function signals an error named by @var{error-symbol}.  The
-argument @var{data} is a list of additional Lisp objects relevant to the
-circumstances of the error.
+This function signals a continuable error named by @var{error-symbol}.
+The argument @var{data} is a list of additional Lisp objects relevant to
+the circumstances of the error.
 
 The argument @var{error-symbol} must be an @dfn{error symbol}---a symbol
 bearing a property @code{error-conditions} whose value is a list of
 
 The argument @var{error-symbol} must be an @dfn{error symbol}---a symbol
 bearing a property @code{error-conditions} whose value is a list of
@@ -710,9 +835,9 @@ condition names.  This is how XEmacs Lisp classifies different sorts of
 errors.
 
 The number and significance of the objects in @var{data} depends on
 errors.
 
 The number and significance of the objects in @var{data} depends on
-@var{error-symbol}.  For example, with a @code{wrong-type-arg} error,
-there are two objects in the list: a predicate that describes the type
-that was expected, and the object that failed to fit that type.
+@var{error-symbol}.  For example, with a @code{wrong-type-argument}
+error, there are two objects in the list: a predicate that describes the
+type that was expected, and the object that failed to fit that type.
 @xref{Error Symbols}, for a description of error symbols.
 
 Both @var{error-symbol} and @var{data} are available to any error
 @xref{Error Symbols}, for a description of error symbols.
 
 Both @var{error-symbol} and @var{data} are available to any error
@@ -721,8 +846,10 @@ variable to a list of the form @code{(@var{error-symbol} .@:
 @var{data})} (@pxref{Handling Errors}).  If the error is not handled,
 these two values are used in printing the error message.
 
 @var{data})} (@pxref{Handling Errors}).  If the error is not handled,
 these two values are used in printing the error message.
 
-The function @code{signal} never returns (though in older Emacs versions
-it could sometimes return).
+The function @code{signal} can return, if the debugger is invoked and
+the user invokes the ``return from signal'' option.  If you want the
+error not to be continuable, use @code{signal-error} instead.  Note that
+in FSF Emacs @code{signal} never returns.
 
 @smallexample
 @group
 
 @smallexample
 @group
@@ -731,17 +858,42 @@ it could sometimes return).
 @end group
 
 @group
 @end group
 
 @group
-(signal 'no-such-error '("My unknown error condition."))
-     @error{} peculiar error: "My unknown error condition."
+(signal 'no-such-error '("My unknown error condition"))
+     @error{} Peculiar error (no-such-error "My unknown error condition")
 @end group
 @end smallexample
 @end defun
 
 @end group
 @end smallexample
 @end defun
 
-@cindex CL note---no continuable errors
-@quotation
-@b{Common Lisp note:} XEmacs Lisp has nothing like the Common Lisp
-concept of continuable errors.
-@end quotation
+@defun signal-error error-symbol data
+This function behaves like @code{signal}, except that the error it
+signals is not continuable.
+@end defun
+
+@defmac check-argument-type predicate argument
+This macro checks that @var{argument} satisfies @var{predicate}.  If
+that is not the case, it signals a continuable
+@code{wrong-type-argument} error until the returned value satisfies
+@var{predicate}, and assigns the returned value to @var{argument}.  In
+other words, execution of the program will not continue until
+@var{predicate} is met.
+
+@var{argument} is not evaluated, and should be a symbol.
+@var{predicate} is evaluated, and should name a function.
+
+As shown in the following example, @code{check-argument-type} is useful
+in low-level code that attempts to ensure the sanity of its data before
+proceeding.
+
+@example
+@group
+(defun cache-object-internal (object wlist)
+  ;; @r{Before doing anything, make sure that @var{wlist} is indeed}
+  ;; @r{a weak list, which is what we expect.}
+  (check-argument-type 'weak-list-p wlist)
+  @dots{})
+@end group
+@end example
+@end defmac
 
 @node Processing of Errors
 @subsubsection How XEmacs Processes Errors
 
 @node Processing of Errors
 @subsubsection How XEmacs Processes Errors
@@ -761,6 +913,27 @@ command loop has an implicit handler for all kinds of errors.  The
 command loop's handler uses the error symbol and associated data to
 print an error message.
 
 command loop's handler uses the error symbol and associated data to
 print an error message.
 
+Errors in command loop are processed using the @code{command-error}
+function, which takes care of some necessary cleanup, and prints a
+formatted error message to the echo area.  The functions that do the
+formatting are explained below.
+
+@defun display-error error-object stream
+This function displays @var{error-object} on @var{stream}.
+@var{error-object} is a cons of error type, a symbol, and error
+arguments, a list.  If the error type symbol of one of its error
+condition superclasses has a @code{display-error} property, that
+function is invoked for printing the actual error message.  Otherwise,
+the error is printed as @samp{Error: arg1, arg2, ...}.
+@end defun
+
+@defun error-message-string error-object
+This function converts @var{error-object} to an error message string,
+and returns it.  The message is equivalent to the one that would be
+printed by @code{display-error}, except that it is conveniently returned
+in string form.
+@end defun
+
 @cindex @code{debug-on-error} use
 An error that has no explicit handler may call the Lisp debugger.  The
 debugger is enabled if the variable @code{debug-on-error} (@pxref{Error
 @cindex @code{debug-on-error} use
 An error that has no explicit handler may call the Lisp debugger.  The
 debugger is enabled if the variable @code{debug-on-error} (@pxref{Error
@@ -834,6 +1007,13 @@ predictable, such as failure to open a file in a call to
 totally unpredictable, such as when the program evaluates an expression
 read from the user.
 
 totally unpredictable, such as when the program evaluates an expression
 read from the user.
 
+@cindex @code{debug-on-signal} use
+  Even when an error is handled, the debugger may still be called if the
+variable @code{debug-on-signal} (@pxref{Error Debugging}) is
+non-@code{nil}.  Note that this may yield unpredictable results with
+code that traps expected errors as normal part of its operation.  Do not
+set @code{debug-on-signal} unless you know what you are doing.
+
   Error signaling and handling have some resemblance to @code{throw} and
 @code{catch}, but they are entirely separate facilities.  An error
 cannot be caught by a @code{catch}, and a @code{throw} cannot be handled
   Error signaling and handling have some resemblance to @code{throw} and
 @code{catch}, but they are entirely separate facilities.  An error
 cannot be caught by a @code{catch}, and a @code{throw} cannot be handled
@@ -899,9 +1079,9 @@ message and returns a very large number.
 @smallexample
 @group
 (defun safe-divide (dividend divisor)
 @smallexample
 @group
 (defun safe-divide (dividend divisor)
-  (condition-case err                
+  (condition-case err
       ;; @r{Protected form.}
       ;; @r{Protected form.}
-      (/ dividend divisor)              
+      (/ dividend divisor)
     ;; @r{The handler.}
     (arith-error                        ; @r{Condition.}
      (princ (format "Arithmetic error: %s" err))
     ;; @r{The handler.}
     (arith-error                        ; @r{Condition.}
      (princ (format "Arithmetic error: %s" err))
@@ -917,7 +1097,9 @@ message and returns a very large number.
 @end smallexample
 
 @noindent
 @end smallexample
 
 @noindent
-The handler specifies condition name @code{arith-error} so that it will handle only division-by-zero errors.  Other kinds of errors will not be handled, at least not by this @code{condition-case}.  Thus,
+The handler specifies condition name @code{arith-error} so that it will
+handle only division-by-zero errors.  Other kinds of errors will not be
+handled, at least not by this @code{condition-case}.  Thus,
 
 @smallexample
 @group
 
 @smallexample
 @group
@@ -942,7 +1124,7 @@ including those signaled with @code{error}:
       ;; @r{This is a call to the function @code{error}.}
       (error "Rats!  The variable %s was %s, not 35" 'baz baz))
   ;; @r{This is the handler; it is not a form.}
       ;; @r{This is a call to the function @code{error}.}
       (error "Rats!  The variable %s was %s, not 35" 'baz baz))
   ;; @r{This is the handler; it is not a form.}
-  (error (princ (format "The error was: %s" err)) 
+  (error (princ (format "The error was: %s" err))
          2))
 @print{} The error was: (error "Rats!  The variable baz was 34, not 35")
 @result{} 2
          2))
 @print{} The error was: (error "Rats!  The variable baz was 34, not 35")
 @result{} 2
@@ -972,43 +1154,49 @@ one or more condition names: @code{error}, the error symbol if that
 is distinct from @code{error}, and perhaps some intermediate
 classifications.
 
 is distinct from @code{error}, and perhaps some intermediate
 classifications.
 
-  In order for a symbol to be an error symbol, it must have an
-@code{error-conditions} property which gives a list of condition names.
-This list defines the conditions that this kind of error belongs to.
-(The error symbol itself, and the symbol @code{error}, should always be
-members of this list.)  Thus, the hierarchy of condition names is
-defined by the @code{error-conditions} properties of the error symbols.
-
-  In addition to the @code{error-conditions} list, the error symbol
-should have an @code{error-message} property whose value is a string to
-be printed when that error is signaled but not handled.  If the
-@code{error-message} property exists, but is not a string, the error
-message @samp{peculiar error} is used.
-@cindex peculiar error
+  In other words, each error condition @dfn{inherits} from another error
+condition, with @code{error} sitting at the top of the inheritance
+hierarchy.
+
+@defun define-error error-symbol error-message &optional inherits-from
+  This function defines a new error, denoted by @var{error-symbol}.
+@var{error-message} is an informative message explaining the error, and
+will be printed out when an unhandled error occurs.  @var{error-symbol}
+is a sub-error of @var{inherits-from} (which defaults to @code{error}).
+
+  @code{define-error} internally works by putting on @var{error-symbol}
+an @code{error-message} property whose value is @var{error-message}, and
+an @code{error-conditions} property that is a list of @var{error-symbol}
+followed by each of its super-errors, up to and including @code{error}.
+You will sometimes see code that sets this up directly rather than
+calling @code{define-error}, but you should @emph{not} do this yourself,
+unless you wish to maintain compatibility with FSF Emacs, which does not
+provide @code{define-error}.
+@end defun
 
 
-  Here is how we define a new error symbol, @code{new-error}:
+  Here is how we define a new error symbol, @code{new-error}, that
+belongs to a range of errors called @code{my-own-errors}:
 
 @example
 @group
 
 @example
 @group
-(put 'new-error
-     'error-conditions
-     '(error my-own-errors new-error))       
-@result{} (error my-own-errors new-error)
-@end group
-@group
-(put 'new-error 'error-message "A new error")
-@result{} "A new error"
+(define-error 'my-own-errors "A whole range of errors" 'error)
+(define-error 'new-error "A new error" 'my-own-errors)
 @end group
 @end example
 
 @noindent
 @end group
 @end example
 
 @noindent
-This error has three condition names: @code{new-error}, the narrowest
-classification; @code{my-own-errors}, which we imagine is a wider
-classification; and @code{error}, which is the widest of all.
+@code{new-error} has three condition names: @code{new-error}, the
+narrowest classification; @code{my-own-errors}, which we imagine is a
+wider classification; and @code{error}, which is the widest of all.
+
+  Note that it is not legal to try to define an error unless its
+super-error is also defined.  For instance, attempting to define
+@code{new-error} before @code{my-own-errors} are defined will signal an
+error.
 
   The error string should start with a capital letter but it should
 not end with a period.  This is for consistency with the rest of Emacs.
 
   The error string should start with a capital letter but it should
 not end with a period.  This is for consistency with the rest of Emacs.
+
   Naturally, XEmacs will never signal @code{new-error} on its own; only
 an explicit call to @code{signal} (@pxref{Signaling Errors}) in your
 code can do this:
   Naturally, XEmacs will never signal @code{new-error} on its own; only
 an explicit call to @code{signal} (@pxref{Signaling Errors}) in your
 code can do this:
@@ -1044,6 +1232,8 @@ make it possible to categorize errors at various levels of generality
 when you write an error handler.  Using error symbols alone would
 eliminate all but the narrowest level of classification.
 
 when you write an error handler.  Using error symbols alone would
 eliminate all but the narrowest level of classification.
 
+
+
   @xref{Standard Errors}, for a list of all the standard error symbols
 and their conditions.
 
   @xref{Standard Errors}, for a list of all the standard error symbols
 and their conditions.