@c -*-texinfo-*-
@c This is part of the GNU Emacs Lisp Reference Manual.
-@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998 Free Software Foundation, Inc.
@c See the file elisp.texi for copying conditions.
@setfilename ../info/control
@node Control Structures, Variables, Evaluation, Top
@menu
* Sequencing:: Evaluation in textual order.
-* Conditionals:: @code{if}, @code{cond}.
+* Conditionals:: @code{if}, @code{cond}, @code{when}, @code{unless}.
* Combining Conditions:: @code{and}, @code{or}, @code{not}.
* Iteration:: @code{while} loops.
* Nonlocal Exits:: Jumping out of a sequence.
@cindex conditional evaluation
Conditional control structures choose among alternatives. Emacs Lisp
-has two conditional forms: @code{if}, which is much the same as in other
-languages, and @code{cond}, which is a generalized case statement.
+has four conditional forms: @code{if}, which is much the same as in
+other languages; @code{when} and @code{unless}, which are variants of
+@code{if}; and @code{cond}, which is a generalized case statement.
@defspec if condition then-form else-forms@dots{}
@code{if} chooses between the @var{then-form} and the @var{else-forms}
@end example
@end defspec
+@tindex when
+@defmac when condition then-forms@dots{}
+This is a variant of @code{if} where there are no @var{else-forms},
+and possibly several @var{then-forms}. In particular,
+
+@example
+(when @var{condition} @var{a} @var{b} @var{c})
+@end example
+
+@noindent
+is entirely equivalent to
+
+@example
+(if @var{condition} (progn @var{a} @var{b} @var{c}) nil)
+@end example
+@end defmac
+
+@tindex condition
+@defmac unless condition forms@dots{}
+This is a variant of @code{if} where there is no @var{then-form}:
+
+@example
+(unless @var{condition} @var{a} @var{b} @var{c})
+@end example
+
+@noindent
+is entirely equivalent to
+
+@example
+(if @var{condition} nil
+ @var{a} @var{b} @var{c})
+@end example
+@end defmac
+
@defspec cond clause@dots{}
@code{cond} chooses among an arbitrary number of alternatives. Each
@var{clause} in the @code{cond} must be a list. The @sc{car} of this
@noindent
This expression is a @code{cond} which returns @code{foo} if the value
-of @code{a} is 1, and returns the string @code{"default"} otherwise.
+of @code{a} is @code{hack}, and returns the string @code{"default"} otherwise.
@end defspec
Any conditional construct can be expressed with @code{cond} or with
@noindent
This moves forward one line and continues moving by lines until it
-reaches an empty. It is unusual in that the @code{while} has no body,
-just the end test (which also does the real work of moving point).
+reaches an empty line. It is peculiar in that the @code{while} has no
+body, just the end test (which also does the real work of moving point).
@end defspec
@node Nonlocal Exits
@example
@group
-(catch 'foo
- (progn
- @dots{}
- (throw 'foo t)
- @dots{}))
+(defun foo-outer ()
+ (catch 'foo
+ (foo-inner)))
+
+(defun foo-inner ()
+ @dots{}
+ (if x
+ (throw 'foo t))
+ @dots{})
@end group
@end example
@noindent
-The @code{throw} transfers control straight back to the corresponding
-@code{catch}, which returns immediately. The code following the
-@code{throw} is not executed. The second argument of @code{throw} is used
-as the return value of the @code{catch}.
-
- The @code{throw} and the @code{catch} are matched through the first
-argument: @code{throw} searches for a @code{catch} whose first argument
-is @code{eq} to the one specified. Thus, in the above example, the
-@code{throw} specifies @code{foo}, and the @code{catch} specifies the
-same symbol, so that @code{catch} is applicable. If there is more than
-one applicable @code{catch}, the innermost one takes precedence.
+The @code{throw} form, if executed, transfers control straight back to
+the corresponding @code{catch}, which returns immediately. The code
+following the @code{throw} is not executed. The second argument of
+@code{throw} is used as the return value of the @code{catch}.
+
+ The function @code{throw} finds the matching @code{catch} based on the
+first argument: it searches for a @code{catch} whose first argument is
+@code{eq} to the one specified in the @code{throw}. If there is more
+than one applicable @code{catch}, the innermost one takes precedence.
+Thus, in the above example, the @code{throw} specifies @code{foo}, and
+the @code{catch} in @code{foo-outer} specifies the same symbol, so that
+@code{catch} is the applicable one (assuming there is no other matching
+@code{catch} in between).
Executing @code{throw} exits all Lisp constructs up to the matching
@code{catch}, including function calls. When binding constructs such as
@example
@group
-(error "You have committed an error.
- Try something else.")
- @error{} You have committed an error.
- Try something else.
+(error "That is an error -- try something else")
+ @error{} That is an error -- try something else
@end group
@group
-(error "You have committed %d errors." 10)
- @error{} You have committed 10 errors.
+(error "You have committed %d errors" 10)
+ @error{} You have committed 10 errors
@end group
@end example
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})}.
+@strong{Warning:} 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 signal error-symbol data
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
+there should be 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.
@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: "My unknown error condition"
@end group
@end smallexample
@end defun
@code{condition-case} forms offer to handle the same error, the inner of
the two will actually handle it.
+ If an error is handled by some @code{condition-case} form, this
+ordinarily prevents the debugger from being run, even if
+@code{debug-on-error} says this error should invoke the debugger.
+@xref{Error Debugging}. If you want to be able to debug errors that are
+caught by a @code{condition-case}, set the variable
+@code{debug-on-signal} to a non-@code{nil} value.
+
When an error is handled, control returns to the handler. Before this
happens, Emacs unbinds all variable bindings made by binding constructs
that are being exited and executes the cleanups of all
bindings that were made within the protected form. All it can do is
clean up and proceed.
- @code{condition-case} is often used to trap errors that are
-predictable, such as failure to open a file in a call to
+ The @code{condition-case} construct is often used to trap errors that
+are predictable, such as failure to open a file in a call to
@code{insert-file-contents}. It is also used to trap errors that are
totally unpredictable, such as when the program evaluates an expression
read from the user.
@smallexample
@group
(safe-divide nil 3)
- @error{} Wrong type argument: integer-or-marker-p, nil
+ @error{} Wrong type argument: number-or-marker-p, nil
@end group
@end smallexample
The @code{unwind-protect} construct is essential whenever you
temporarily put a data structure in an inconsistent state; it permits
-you to ensure the data are consistent in the event of an error or throw.
+you to make the data consistent again in the event of an error or throw.
@defspec unwind-protect body cleanup-forms@dots{}
@cindex cleanup forms
However, the way shown above is safer, if @var{body} happens to get an
error after switching to a different buffer! (Alternatively, you could
write another @code{save-excursion} around the body, to ensure that the
-temporary buffer becomes current in time to kill it.)
+temporary buffer becomes current again in time to kill it.)
+
+ Emacs includes a standard macro called @code{with-temp-buffer} which
+expands into more or less the code shown above (@pxref{Current Buffer}).
+Several of the macros defined in this manual use @code{unwind-protect}
+in this way.
@findex ftp-login
Here is an actual example taken from the file @file{ftp.el}. It
@code{ftp-setup-buffer} returns but before the variable @code{process} is
set, the process will not be killed. There is no easy way to fix this bug,
but at least it is very unlikely.
-
- Here is another example which uses @code{unwind-protect} to make sure
-to kill a temporary buffer. In this example, the value returned by
-@code{unwind-protect} is used.
-
-@smallexample
-(defun shell-command-string (cmd)
- "Return the output of the shell command CMD, as a string."
- (save-excursion
- (set-buffer (generate-new-buffer " OS*cmd"))
- (shell-command cmd t)
- (unwind-protect
- (buffer-string)
- (kill-buffer (current-buffer)))))
-@end smallexample