summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2012-01-20 19:47:02 +0100
committerAndy Wingo <wingo@pobox.com>2012-01-20 19:51:45 +0100
commit9accf3d98ffd1d9d484e5214a9dd9e4054204557 (patch)
tree8aa53e7eabc6bc4ca6a3a8adafac94d9b0a2da09
parent7d02e256610e37c0ab0e8c55623d6f6c6eacab82 (diff)
downloadguile-9accf3d98ffd1d9d484e5214a9dd9e4054204557.tar.gz
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.
-rw-r--r--doc/ref/api-control.texi42
-rw-r--r--doc/ref/api-data.texi10
-rw-r--r--doc/ref/r6rs.texi6
-rw-r--r--doc/ref/scheme-ideas.texi6
-rw-r--r--doc/ref/srfi-modules.texi2
-rw-r--r--module/ice-9/boot-9.scm6
6 files changed, 55 insertions, 17 deletions
diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi
index 559677874..7935d5633 100644
--- a/doc/ref/api-control.texi
+++ b/doc/ref/api-control.texi
@@ -12,7 +12,7 @@ flow of Scheme affects C code.
@menu
* begin:: Sequencing and splicing.
-* if cond case:: Simple conditional evaluation.
+* Conditionals:: If, when, unless, case, and cond.
* and or:: Conditional evaluation of a sequence.
* while do:: Iteration mechanisms.
* 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
abuses the @code{begin} form for these two tasks.
-@node if cond case
+@node Conditionals
@subsection Simple Conditional Evaluation
@cindex conditional evaluation
@cindex if
+@cindex when
+@cindex unless
@cindex case
@cindex cond
@@ -121,14 +123,44 @@ values.
All arguments may be arbitrary expressions. First, @var{test} is
evaluated. If it returns a true value, the expression @var{consequent}
is evaluated and @var{alternate} is ignored. If @var{test} evaluates to
-@code{#f}, @var{alternate} is evaluated instead. The value of the
-evaluated branch (@var{consequent} or @var{alternate}) is returned as
-the value of the @code{if} expression.
+@code{#f}, @var{alternate} is evaluated instead. The values of the
+evaluated branch (@var{consequent} or @var{alternate}) are returned as
+the values of the @code{if} expression.
When @var{alternate} is omitted and the @var{test} evaluates to
@code{#f}, the value of the expression is not specified.
@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{}
Each @code{cond}-clause must look like this:
diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi
index f2450cea2..60a214872 100644
--- a/doc/ref/api-data.texi
+++ b/doc/ref/api-data.texi
@@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 See the file guile.texi for copying conditions.
@@ -78,10 +78,10 @@ equality predicates @code{eq?}, @code{eqv?} and @code{equal?}
#t
@end lisp
-In test condition contexts like @code{if} and @code{cond} (@pxref{if
-cond case}), where a group of subexpressions will be evaluated only if a
-@var{condition} expression evaluates to ``true'', ``true'' means any
-value at all except @code{#f}.
+In test condition contexts like @code{if} and @code{cond}
+(@pxref{Conditionals}), where a group of subexpressions will be
+evaluated only if a @var{condition} expression evaluates to ``true'',
+``true'' means any value at all except @code{#f}.
@lisp
(if #t "yes" "no")
diff --git a/doc/ref/r6rs.texi b/doc/ref/r6rs.texi
index d054bd39e..df14cc050 100644
--- a/doc/ref/r6rs.texi
+++ b/doc/ref/r6rs.texi
@@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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]
@deffnx {Scheme Syntax} cond clause1 clause2 ...
@deffnx {Scheme Syntax} case key clause1 clause2 ...
-@xref{if cond case}, for documentation.
+@xref{Conditionals}, for documentation.
@end deffn
@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
@code{cond} expression, with the value of the first matching clause
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
handler that was current before the evaluation of the @code{guard} form.
diff --git a/doc/ref/scheme-ideas.texi b/doc/ref/scheme-ideas.texi
index 99c07b9c4..53f7b6132 100644
--- a/doc/ref/scheme-ideas.texi
+++ b/doc/ref/scheme-ideas.texi
@@ -1,6 +1,6 @@
@c -*-texinfo-*-
@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 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
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
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
specified group of values.
diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi
index c2b19fd9c..2ab9c7a63 100644
--- a/doc/ref/srfi-modules.texi
+++ b/doc/ref/srfi-modules.texi
@@ -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
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
-@ref{if cond case,, Simple Conditional Evaluation}.
+@ref{Conditionals,, Simple Conditional Evaluation}.
@node SRFI-67
@subsection SRFI-67 - Compare procedures
diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm
index d006d4700..86ca875a5 100644
--- a/module/ice-9/boot-9.scm
+++ b/module/ice-9/boot-9.scm
@@ -412,6 +412,12 @@ If there is no handler at all, Guile prints an error and then exits."
((_ x) x)
((_ 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
;; SRFI-61. Rewrites into a standalone syntax-case macro would be
;; appreciated.