1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

add when, unless

* module/ice-9/boot-9.scm (when, unless): New forms.

* doc/ref/api-control.texi (Conditionals): Add docs.  Rename this
  node from "if cond case".

* doc/ref/r6rs.texi:
* doc/ref/scheme-ideas.texi:
* doc/ref/srfi-modules.texi: Update referrers.
This commit is contained in:
Andy Wingo 2012-01-20 19:47:02 +01:00
parent 7d02e25661
commit 9accf3d98f
6 changed files with 55 additions and 17 deletions

View file

@ -12,7 +12,7 @@ flow of Scheme affects C code.
@menu @menu
* begin:: Sequencing and splicing. * begin:: Sequencing and splicing.
* if cond case:: Simple conditional evaluation. * Conditionals:: If, when, unless, case, and cond.
* and or:: Conditional evaluation of a sequence. * and or:: Conditional evaluation of a sequence.
* while do:: Iteration mechanisms. * while do:: Iteration mechanisms.
* Prompts:: Composable, delimited continuations. * Prompts:: Composable, delimited continuations.
@ -103,11 +103,13 @@ good idea. But it is useful to be able to write macros that expand out
to multiple definitions, as in @code{define-sealant} above, so Scheme to multiple definitions, as in @code{define-sealant} above, so Scheme
abuses the @code{begin} form for these two tasks. abuses the @code{begin} form for these two tasks.
@node if cond case @node Conditionals
@subsection Simple Conditional Evaluation @subsection Simple Conditional Evaluation
@cindex conditional evaluation @cindex conditional evaluation
@cindex if @cindex if
@cindex when
@cindex unless
@cindex case @cindex case
@cindex cond @cindex cond
@ -121,14 +123,44 @@ values.
All arguments may be arbitrary expressions. First, @var{test} is All arguments may be arbitrary expressions. First, @var{test} is
evaluated. If it returns a true value, the expression @var{consequent} evaluated. If it returns a true value, the expression @var{consequent}
is evaluated and @var{alternate} is ignored. If @var{test} evaluates to is evaluated and @var{alternate} is ignored. If @var{test} evaluates to
@code{#f}, @var{alternate} is evaluated instead. The value of the @code{#f}, @var{alternate} is evaluated instead. The values of the
evaluated branch (@var{consequent} or @var{alternate}) is returned as evaluated branch (@var{consequent} or @var{alternate}) are returned as
the value of the @code{if} expression. the values of the @code{if} expression.
When @var{alternate} is omitted and the @var{test} evaluates to When @var{alternate} is omitted and the @var{test} evaluates to
@code{#f}, the value of the expression is not specified. @code{#f}, the value of the expression is not specified.
@end deffn @end deffn
When you go to write an @code{if} without an alternate (a @dfn{one-armed
@code{if}}), part of what you are expressing is that you don't care
about the return value (or values) of the expression. As such, you are
more interested in the @emph{effect} of evaluating the consequent
expression. (By convention, we use the word @dfn{statement} to refer to
an expression that is evaluated for effect, not for value).
In such a case, it is considered more clear to express these intentions
with these special forms, @code{when} and @code{unless}. As an added
bonus, these forms accept multiple statements to evaluate, which are
implicitly wrapped in a @code{begin}.
@deffn {Scheme Syntax} when test statement1 statement2 ...
@deffnx {Scheme Syntax} unless test statement1 statement2 ...
The actual definitions of these forms are in many ways their most clear
documentation:
@example
(define-syntax-rule (when test stmt stmt* ...)
(if test (begin stmt stmt* ...)))
(define-syntax-rule (unless condition stmt stmt* ...)
(if (not test) (begin stmt stmt* ...)))
@end example
That is to say, @code{when} evaluates its consequent statements in order
if @var{test} is true. @code{unless} is the opposite: it evaluates the
statements if @var{test} is false.
@end deffn
@deffn syntax cond clause1 clause2 @dots{} @deffn syntax cond clause1 clause2 @dots{}
Each @code{cond}-clause must look like this: Each @code{cond}-clause must look like this:

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*- @c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual. @c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012
@c Free Software Foundation, Inc. @c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions. @c See the file guile.texi for copying conditions.
@ -78,10 +78,10 @@ equality predicates @code{eq?}, @code{eqv?} and @code{equal?}
#t #t
@end lisp @end lisp
In test condition contexts like @code{if} and @code{cond} (@pxref{if In test condition contexts like @code{if} and @code{cond}
cond case}), where a group of subexpressions will be evaluated only if a (@pxref{Conditionals}), where a group of subexpressions will be
@var{condition} expression evaluates to ``true'', ``true'' means any evaluated only if a @var{condition} expression evaluates to ``true'',
value at all except @code{#f}. ``true'' means any value at all except @code{#f}.
@lisp @lisp
(if #t "yes" "no") (if #t "yes" "no")

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*- @c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual. @c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 2010, 2011 @c Copyright (C) 2010, 2011, 2012
@c Free Software Foundation, Inc. @c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions. @c See the file guile.texi for copying conditions.
@ -316,7 +316,7 @@ grouped below by the existing manual sections to which they correspond.
@deffn {Scheme Syntax} if test consequence [alternate] @deffn {Scheme Syntax} if test consequence [alternate]
@deffnx {Scheme Syntax} cond clause1 clause2 ... @deffnx {Scheme Syntax} cond clause1 clause2 ...
@deffnx {Scheme Syntax} case key clause1 clause2 ... @deffnx {Scheme Syntax} case key clause1 clause2 ...
@xref{if cond case}, for documentation. @xref{Conditionals}, for documentation.
@end deffn @end deffn
@deffn {Scheme Syntax} and expr ... @deffn {Scheme Syntax} and expr ...
@ -1146,7 +1146,7 @@ exception handler that binds a raised exception to @var{variable} and
then evaluates the specified @var{clause}s as if they were part of a then evaluates the specified @var{clause}s as if they were part of a
@code{cond} expression, with the value of the first matching clause @code{cond} expression, with the value of the first matching clause
becoming the value of the @code{guard} expression becoming the value of the @code{guard} expression
(@pxref{if cond case}). If none of the clause's test expressions (@pxref{Conditionals}). If none of the clause's test expressions
evaluates to @code{#t}, the exception is re-raised, with the exception evaluates to @code{#t}, the exception is re-raised, with the exception
handler that was current before the evaluation of the @code{guard} form. handler that was current before the evaluation of the @code{guard} form.

View file

@ -1,6 +1,6 @@
@c -*-texinfo-*- @c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual. @c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005 @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2012
@c Free Software Foundation, Inc. @c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions. @c See the file guile.texi for copying conditions.
@ -964,11 +964,11 @@ same as a procedure which returns its last argument, because the
evaluation of a procedure invocation expression does not guarantee to evaluation of a procedure invocation expression does not guarantee to
evaluate the arguments in order. evaluate the arguments in order.
@code{if} and @code{cond} (@pxref{if cond case}) provide conditional @code{if} and @code{cond} (@pxref{Conditionals}) provide conditional
evaluation of argument expressions depending on whether one or more evaluation of argument expressions depending on whether one or more
conditions evaluate to ``true'' or ``false''. conditions evaluate to ``true'' or ``false''.
@code{case} (@pxref{if cond case}) provides conditional evaluation of @code{case} (@pxref{Conditionals}) provides conditional evaluation of
argument expressions depending on whether a variable has one of a argument expressions depending on whether a variable has one of a
specified group of values. specified group of values.

View file

@ -4193,7 +4193,7 @@ This SRFI extends RnRS @code{cond} to support test expressions that
return multiple values, as well as arbitrary definitions of test return multiple values, as well as arbitrary definitions of test
success. SRFI 61 is implemented in the Guile core; there's no module success. SRFI 61 is implemented in the Guile core; there's no module
needed to get SRFI-61 itself. Extended @code{cond} is documented in needed to get SRFI-61 itself. Extended @code{cond} is documented in
@ref{if cond case,, Simple Conditional Evaluation}. @ref{Conditionals,, Simple Conditional Evaluation}.
@node SRFI-67 @node SRFI-67
@subsection SRFI-67 - Compare procedures @subsection SRFI-67 - Compare procedures

View file

@ -412,6 +412,12 @@ If there is no handler at all, Guile prints an error and then exits."
((_ x) x) ((_ x) x)
((_ x y ...) (let ((t x)) (if t t (or y ...)))))) ((_ x y ...) (let ((t x)) (if t t (or y ...))))))
(define-syntax-rule (when test stmt stmt* ...)
(if test (begin stmt stmt* ...)))
(define-syntax-rule (unless test stmt stmt* ...)
(if (not test) (begin stmt stmt* ...)))
;; The "maybe-more" bits are something of a hack, so that we can support ;; The "maybe-more" bits are something of a hack, so that we can support
;; SRFI-61. Rewrites into a standalone syntax-case macro would be ;; SRFI-61. Rewrites into a standalone syntax-case macro would be
;; appreciated. ;; appreciated.