1
0
Fork 0
cl-sites/guile.html_node/Conditionals.html
2024-12-17 12:49:28 +01:00

220 lines
12 KiB
HTML

<!DOCTYPE html>
<html>
<!-- Created by GNU Texinfo 7.1, https://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- This manual documents Guile version 3.0.10.
Copyright (C) 1996-1997, 2000-2005, 2009-2023 Free Software Foundation,
Inc.
Copyright (C) 2021 Maxime Devos
Copyright (C) 2024 Tomas Volf
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license is included in the section entitled "GNU Free
Documentation License." -->
<title>Conditionals (Guile Reference Manual)</title>
<meta name="description" content="Conditionals (Guile Reference Manual)">
<meta name="keywords" content="Conditionals (Guile Reference Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content=".texi2any-real">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="index.html" rel="start" title="Top">
<link href="Concept-Index.html" rel="index" title="Concept Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Control-Mechanisms.html" rel="up" title="Control Mechanisms">
<link href="and-or.html" rel="next" title="and or">
<link href="begin.html" rel="prev" title="begin">
<style type="text/css">
<!--
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
div.example {margin-left: 3.2em}
span:hover a.copiable-link {visibility: visible}
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
-->
</style>
<link rel="stylesheet" type="text/css" href="https://www.gnu.org/software/gnulib/manual.css">
</head>
<body lang="en">
<div class="subsection-level-extent" id="Conditionals">
<div class="nav-panel">
<p>
Next: <a href="and-or.html" accesskey="n" rel="next">Conditional Evaluation of a Sequence of Expressions</a>, Previous: <a href="begin.html" accesskey="p" rel="prev">Sequencing and Splicing</a>, Up: <a href="Control-Mechanisms.html" accesskey="u" rel="up">Controlling the Flow of Program Execution</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<h4 class="subsection" id="Simple-Conditional-Evaluation"><span>6.11.2 Simple Conditional Evaluation<a class="copiable-link" href="#Simple-Conditional-Evaluation"> &para;</a></span></h4>
<a class="index-entry-id" id="index-conditional-evaluation"></a>
<a class="index-entry-id" id="index-if"></a>
<a class="index-entry-id" id="index-when"></a>
<a class="index-entry-id" id="index-unless"></a>
<a class="index-entry-id" id="index-case"></a>
<a class="index-entry-id" id="index-cond"></a>
<p>Guile provides three syntactic constructs for conditional evaluation.
<code class="code">if</code> is the normal if-then-else expression (with an optional else
branch), <code class="code">cond</code> is a conditional expression with multiple branches,
and <code class="code">case</code> branches if an expression has one of a set of constant
values.
</p>
<dl class="first-deffn">
<dt class="deffn" id="index-if-1"><span class="category-def">syntax: </span><span><strong class="def-name">if</strong> <var class="def-var-arguments">test consequent [alternate]</var><a class="copiable-link" href="#index-if-1"> &para;</a></span></dt>
<dd><p>All arguments may be arbitrary expressions. First, <var class="var">test</var> is
evaluated. If it returns a true value, the expression <var class="var">consequent</var>
is evaluated and <var class="var">alternate</var> is ignored. If <var class="var">test</var> evaluates to
<code class="code">#f</code>, <var class="var">alternate</var> is evaluated instead. The values of the
evaluated branch (<var class="var">consequent</var> or <var class="var">alternate</var>) are returned as
the values of the <code class="code">if</code> expression.
</p>
<p>When <var class="var">alternate</var> is omitted and the <var class="var">test</var> evaluates to
<code class="code">#f</code>, the value of the expression is not specified.
</p></dd></dl>
<p>When you go to write an <code class="code">if</code> without an alternate (a <em class="dfn">one-armed
<code class="code">if</code></em>), part of what you are expressing is that you don&rsquo;t care
about the return value (or values) of the expression. As such, you are
more interested in the <em class="emph">effect</em> of evaluating the consequent
expression. (By convention, we use the word <em class="dfn">statement</em> to refer to
an expression that is evaluated for effect, not for value).
</p>
<p>In such a case, it is considered more clear to express these intentions
with the special forms <code class="code">when</code> and <code class="code">unless</code>. As an added
bonus, these forms take a <em class="emph">body</em> like in a <code class="code">let</code> expression,
which can contain internal definitions and multiple statements to
evaluate (see <a class="pxref" href="Local-Bindings.html">Local Variable Bindings</a>).
</p>
<dl class="first-deffn">
<dt class="deffn" id="index-when-1"><span class="category-def">Scheme Syntax: </span><span><strong class="def-name">when</strong> <var class="def-var-arguments">test body</var><a class="copiable-link" href="#index-when-1"> &para;</a></span></dt>
<dt class="deffnx def-cmd-deffn" id="index-unless-1"><span class="category-def">Scheme Syntax: </span><span><strong class="def-name">unless</strong> <var class="def-var-arguments">test body</var><a class="copiable-link" href="#index-unless-1"> &para;</a></span></dt>
<dd><p>The actual definitions of these forms may be their most clear documentation:
</p>
<div class="example">
<pre class="example-preformatted">(define-syntax-rule (when test stmt stmt* ...)
(if test (let () stmt stmt* ...)))
(define-syntax-rule (unless test stmt stmt* ...)
(if (not test) (let () stmt stmt* ...)))
</pre></div>
<p>That is to say, <code class="code">when</code> evaluates its consequent statements in order
if <var class="var">test</var> is true. <code class="code">unless</code> is the opposite: it evaluates the
statements if <var class="var">test</var> is false.
</p></dd></dl>
<dl class="first-deffn">
<dt class="deffn" id="index-cond-1"><span class="category-def">syntax: </span><span><strong class="def-name">cond</strong> <var class="def-var-arguments">clause1 clause2 &hellip;</var><a class="copiable-link" href="#index-cond-1"> &para;</a></span></dt>
<dd><p>Each <code class="code">cond</code>-clause must look like this:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(<var class="var">test</var> <var class="var">body</var>)
</pre></div>
<p>where <var class="var">test</var> is an arbitrary expression, or like this
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(<var class="var">test</var> =&gt; <var class="var">expression</var>)
</pre></div>
<p>where <var class="var">expression</var> must evaluate to a procedure.
</p>
<p>The <var class="var">test</var>s of the clauses are evaluated in order and as soon as one
of them evaluates to a true value, the corresponding <var class="var">body</var> is
evaluated to produce the result of the <code class="code">cond</code>-expression. For the
<code class="code">=&gt;</code> clause type,
<var class="var">expression</var> is evaluated and the resulting procedure is applied to
the value of <var class="var">test</var>. The result of this procedure application is
then the result of the <code class="code">cond</code>-expression.
</p>
<a class="index-entry-id" id="index-SRFI_002d61"></a>
<a class="index-entry-id" id="index-general-cond-clause"></a>
<a class="index-entry-id" id="index-multiple-values-and-cond"></a>
<p>One additional <code class="code">cond</code>-clause is available as an extension to
standard Scheme:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(<var class="var">test</var> <var class="var">guard</var> =&gt; <var class="var">expression</var>)
</pre></div>
<p>where <var class="var">guard</var> and <var class="var">expression</var> must evaluate to procedures.
For this clause type, <var class="var">test</var> may return multiple values, and
<code class="code">cond</code> ignores its boolean state; instead, <code class="code">cond</code> evaluates
<var class="var">guard</var> and applies the resulting procedure to the value(s) of
<var class="var">test</var>, as if <var class="var">guard</var> were the <var class="var">consumer</var> argument of
<code class="code">call-with-values</code>. If the result of that procedure call is a
true value, it evaluates <var class="var">expression</var> and applies the resulting
procedure to the value(s) of <var class="var">test</var>, in the same manner as the
<var class="var">guard</var> was called.
</p>
<p>The <var class="var">test</var> of the last <var class="var">clause</var> may be the symbol <code class="code">else</code>.
Then, if none of the preceding <var class="var">test</var>s is true, the
<var class="var">body</var> following the <code class="code">else</code> is evaluated to produce the
result of the <code class="code">cond</code>-expression.
</p></dd></dl>
<dl class="first-deffn">
<dt class="deffn" id="index-case-1"><span class="category-def">syntax: </span><span><strong class="def-name">case</strong> <var class="def-var-arguments">key clause1 clause2 &hellip;</var><a class="copiable-link" href="#index-case-1"> &para;</a></span></dt>
<dd><p><var class="var">key</var> may be any expression, and the <var class="var">clause</var>s must have the form
</p>
<div class="example lisp">
<pre class="lisp-preformatted">((<var class="var">datum1</var> ...) <var class="var">body</var>)
</pre></div>
<p>or
</p>
<div class="example lisp">
<pre class="lisp-preformatted">((<var class="var">datum1</var> ...) =&gt; <var class="var">expression</var>)
</pre></div>
<p>and the last <var class="var">clause</var> may have the form
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(else <var class="var">body</var>)
</pre></div>
<p>or
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(else =&gt; <var class="var">expression</var>)
</pre></div>
<p>All <var class="var">datum</var>s must be distinct. First, <var class="var">key</var> is evaluated. The
result of this evaluation is compared against all <var class="var">datum</var> values
using <code class="code">eqv?</code>. When this comparison succeeds, the <var class="var">body</var>
following the <var class="var">datum</var> is evaluated to produce the result of the
<code class="code">case</code> expression.
</p>
<p>If the <var class="var">key</var> matches no <var class="var">datum</var> and there is an
<code class="code">else</code>-clause, the <var class="var">body</var> following the <code class="code">else</code> is
evaluated to produce the result of the <code class="code">case</code> expression. If there
is no such clause, the result of the expression is unspecified.
</p>
<p>For the <code class="code">=&gt;</code> clause types, <var class="var">expression</var> is evaluated and the
resulting procedure is applied to the value of <var class="var">key</var>. The result of
this procedure application is then the result of the
<code class="code">case</code>-expression.
</p></dd></dl>
</div>
<hr>
<div class="nav-panel">
<p>
Next: <a href="and-or.html">Conditional Evaluation of a Sequence of Expressions</a>, Previous: <a href="begin.html">Sequencing and Splicing</a>, Up: <a href="Control-Mechanisms.html">Controlling the Flow of Program Execution</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>