<!DOCTYPE Book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" >
<!-- $Id: core-exp.sgm,v 1.5 1998/03/25 16:39:33 tkg Exp $ -->
<book>

<bookinfo>
<title>Core Expression Language</title>
<subtitle>Revision 1</subtitle>
<subtitle>March 25, 1998</subtitle>
<legalnotice>
<title>Proprietary Rights Notice</title>
<para>
All rights reserved by Mulberry Technologies, Inc.  No part of
this material may be reproduced, translated, or transmitted in
any form or by any means, electronic, mechanical, or otherwise,
including photocopying and recording, without the permission in
writing from Mulberry Technologies, Inc.</para>
</legalnotice>
<legalnotice>
<title>Disclaimer</title>
<para>
Mulberry Technologies, Inc. makes no representation or warranty,
express or implied with respect to this publication or the programs
or information described in this publication.  In no event shall
Mulberry Technologies, Inc., its employees, or contractors be
liable for specific, indirect, or consequential damage.</para>
</legalnotice>
<legalnotice>
<para>
&copy; 1997, 1998 Mulberry Technologies, Inc.</para>
<para>All rights reserved.</para>
</legalnotice>
</bookinfo>

<chapter>
<title>Introduction</title>

<Para>
DSSSL's expression language is defined in Section 8, Expression
Language, of the Standard.  As the minimum necessary to support if not
life then stylesheets, Section 8.6 defines a subset of the expression
language as the &ldquo;Core Expression Language&rdquo;.</para>

<para>
This discussion presents the elements of the Core Expression Language
in a different order to that of the standard.  The discussion begins
by defining the different types of objects in the Core Expression
Language.  Included with the discussion of each object type is the
description of the object's <firstterm>type predicate</firstterm>
procedure &ndash; a procedure that returns a true value only if its argument
is of the matching type or possesses the quality being tested.  The
advantages of this discussion over that in the standard are that more
examples are presented and that the discussion occasionally strays
into observations about how to use the objects or how they are
implemented in Jade.</para>

<para>
Following the discussion of the types is a listing, with numerous
examples, of the remaining syntax expressions and procedures defined
in the Core Expression Language.  Again, the order differs from that
of the standard: variable definition and the test for equivalence are
presented first, then the procedures for quantity, list, character,
string, and procedure objects (plus some procedures not related to
Core Expression Language object types) are described and numerous
examples are given, before the logical operators and the
<function>if</function>, <function>cond</function>, and
<function>case</function> expressions are presented.</para>

<para>
The discussion ends with a copy of the Core Expression Language
syntax productions and procedure prototypes and, of course, an
exercise.
</para>

<sect1>
<title>Format of Procedure or Expression Definition</title>

<para>
An example of a procedure or expression definition is shown below.
 The title of the definition is usually the same as that in the
DSSSL standard, and the corresponding section number from the
standard is in square brackets follows the title.  Following the
title is the prototype or prototypes of the procedures or expressions
being defined and a discussion of the operation of the procedures
or expressions plus examples of the procedures or expressions.


<graphic fileref="core-exp-sample.GIF"></graphic>

<para>
The left hand side of each example (before the &ldquo;&rArr;&rdquo;)
is one or more expressions, and the right hand side of the example is
the result of evaluating the expression on the left hand side.  In the
three examples above, one expression returned <LITERAL>#t</LITERAL>,
and the other two returned <literal>#f</LITERAL>.</para>

<sect1>
<title>About This Tutorial</title>

<para>
This tutorial is derived from tutorial material produced for use at
Mulberry Technologies, Inc. and is made available to the DSSSL
Documentation Project by Mulberry Technologies, Inc.</para>

</chapter>
<chapter>
<title>Object Types</title>

<sect1>
<title>Numerical Types [8.5.7.1]</title>

<para>
DSSSL provides a quantity data type that represents lengths and
quantities, such as areas and volumes, that derive from lengths.
Lengths have dimension 1; areas, 2; and plain old numbers, dimension
0, making them <firstterm>dimensionless</firstterm>.</para>

<para>
The base unit for lengths is the meter, with symbol
<LITERAL>m</LITERAL>.
</para>

<sect2>
<title>Syntax of Numerical Constants [8.5.7.4]</title>

<para>
A quantity may be written in binary, octal, decimal, or hexadecimal by the use of a radix prefix:

<informaltable frame="topbot" colsep="0" rowsep="1">
<tgroup cols="2">
<colspec colnum="1" colwidth="1*">
<colspec colnum="2" colwidth="4*">
<thead>
<row>
<entry>Radix</entry>
<entry>Base</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>#b</literal></entry>
<entry>Binary (base 2)</entry>
</row>
<row>
<entry><literal>#o</literal></entry>
<entry>Octal (base 8)</entry>
</row>
<row>
<entry><literal>#d</literal></entry>
<entry>Decimal (base 10)</entry>
</row>
<row>
<entry><literal>#x</literal></entry>
<entry>Hexadecimal (base 10)</entry>
</row>
</tbody>
</tgroup>
</informaltable>

<para>
If no radix, a quantity is assumed to be decimal.
</para>

<para>
A decimal number may have a decimal <firstterm>exponent</firstterm>; for
example, <literal>1e0</literal>.
</para>

<para>
A numerical constant may have a <firstterm>unit</firstterm> suffix,
possibly with a multiplier raising (or lowering) the power of the
quantity associated with the unit; for example, <literal>1m</literal>,
<literal>1.0m</literal>, <literal>1m2</literal>,
<literal>1m+2</literal>, or <literal>1m-2</literal>.
</para>

<sect2>
<title>Number Type Predicates [8.5.7.5]</title>

<synopsis>
(quantity? <replaceable>obj</replaceable>)
(number? <replaceable>obj</replaceable>)
(real? <replaceable>obj</replaceable>)
(integer? <replaceable>obj</replaceable>)
</synopsis>

<para>
These return <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is of the named type, otherwise they return <literal>#f</LITERAL>.
The predicates are listed in order of decreasing abstractness.  In
general, if a predicate is true for a given
<replaceable>obj</replaceable>, then the more abstract predicates also
evaluate to <literal>#t</LITERAL>.
</para>

<programlisting>
(quantity? 1m)              &rArr;    #t
(number? 1m)                &rArr;    #f
(real? 1m)                  &rArr;    #f
(integer? 1m)               &rArr;    #f
</programlisting>

<programlisting>
(quantity? 1.2)             &rArr;    #t
(number? 1.2)               &rArr;    #t
(real? 1.2)                 &rArr;    #t
(integer? 1.2)              &rArr;    #f
</programlisting>

<programlisting>
(quantity? 9)               &rArr;    #t
(number? 9)                 &rArr;    #t
(real? 9)                   &rArr;    #t
(integer? 9)                &rArr;    #t
</programlisting>

<sect2>
<title>Length</title>

<para>
Lengths are explicitly covered in the core expression language,
but a length is a quantity of dimension 1.  There is no type predicate
for length defined in the standard.
</para>

<sect2>
<title>Exact and Inexact Numbers [8.5.7.2]</title>

<para>
DSSSL, and Scheme before it, distinguishes between quantities that can
or should be represented exactly and those that may not.  For example,
an index into a data structure should be known exactly; an index would
be &ldquo;4&rdquo;, not &ldquo;4.0&rdquo;, &ldquo;4.00001&rdquo;, or
&ldquo;4e0&rdquo;.</para>

<para>
A numeric constant is inexact if it contains a decimal point,
an exponent, or a unit.</para>

<para>
The exactness or inexactness of a quantity is independent of its
dimension.</para>

<para>
In general, rational operators such as <LITERAL>+</LITERAL>
return exact results when given exact arguments, and, with the
exception of <function>inexact->exact</function>,
the procedures defined in the standard return inexact results
when given inexact arguments.  Inexactness is contagious;  a quantity
will be inexact if it is declared as an inexact value, if it is
derived from expressions returning inexact values, or it is derived
from inexact arguments.</para>

<sect2>
<title>Exactness Predicates [8.5.7.5]</title>

<synopsis>
(exact? <replaceable>q</replaceable>)
(inexact? <replaceable>q)</replaceable>
</synopsis>

<para>
<function>exact?</function> returns <literal>#t</LITERAL>
if <replaceable>q</replaceable> is an exact
quantity, otherwise returns <literal>#f</LITERAL>.</para>

<para>
<function>inexact?</function> returns <literal>#t</LITERAL>
is <replaceable>q</replaceable> is an
inexact quantity, otherwise returns <literal>#f</LITERAL>.</para>

<para>
For any quantity, only one of these predicates will return
<literal>#t</LITERAL>.
</para>

<programlisting>
(exact? 4)                  &rArr;    #t
(exact? 4.0)                &rArr;    #f
(exact? 4.00001)            &rArr;    #f
(exact? 4e0)                &rArr;    #f
(exact? 4m)                 &rArr;    #f
</programlisting>

<programlisting>
(inexact? 4)                &rArr;    #f
(inexact? 4.0)              &rArr;    #t
(inexact? 4.00001)          &rArr;    #t
(inexact? 4e0)              &rArr;    #t
(inexact? 4m)               &rArr;    #t
</programlisting>

<sect1>
<title>List [8.5.3]</title>

<para>
Lists are slippery things to define, enough so that they should be the
topic of a tutorial of their own.  Lists should not be confused with
node-lists, which are what many of the style language procedures
operate on.</para>

<para>
Lists are written as a sequence of objects surrounded by parentheses.
The list may need to be quoted by a leading single quote
(<LITERAL>'</LITERAL>) in some contexts.  The empty list, which the a
special case of a list with no members, is written
<literal>()</LITERAL>.</para>

<para>
There is a <firstterm>dotted pair</firstterm> notation for
representing pairs of items.  The list representation is actually a
shorthand form of representing dotted pairs, but since the pair type
predicate is not part of the core expression language, pairs will be
ignored for now.</para>

<sect2>
<title>List Type Predicate [8.5.3.7]</title>

<synopsis>
(list? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is a list, otherwise returns <literal>#f</LITERAL>.</para>

<programlisting>
(list? '())                 &rArr;    #t
(list? '(Mulberry))         &rArr;    #t
(list? '(a b c))            &rArr;    #t
(list? "Mulberry")          &rArr;    #f
(list? '("Mulberry"))       &rArr;    #t
(list? 3)                   &rArr;    #f
(list? '(3 4 5))            &rArr;    #t
(list? #\M)                 &rArr;    #f
(list? '(#\M #\T #\I))      &rArr;    #t
</programlisting>

<sect2>
<title>Empty List Type Predicate [8.5.3.6]</title>

<synopsis>
(null? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is the empty list, otherwise returns <literal>#f</LITERAL>.</para>

<programlisting>
(null? '())                 &rArr;    #t
(null? '(Mulberry))         &rArr;    #f
(null? '(a b c))            &rArr;    #f
</programlisting>

<sect1>
<title>Character [8.5.8]</title>

<para>
The character object represents a character.</para>

<para>
Outside of strings, characters are written as
&ldquo;<LITERAL>#\<replaceable>any-character</replaceable></LITERAL>&rdquo;
or as
&ldquo;<literal>#\<replaceable>character-name</replaceable></LITERAL>&rdquo;.
Within strings, only the <replaceable>character-name</replaceable>
form is allowed, but without the leading
&ldquo;<literal>#</LITERAL>&rdquo;.  Within strings,
<replaceable>character-name</replaceable> should be followed by
&ldquo;<literal>;</LITERAL>&rdquo; unless the following character
cannot be interpreted as part of
<replaceable>character-name</replaceable>.</para>

<para>
Jade supports Unicode character names.  The character name used in the
stylesheet should be all lowercase, and any spaces in the official
Unicode name should be replaced by hyphens.  For example, the Unicode
character named &ldquo;<literal>EN DASH</LITERAL>&rdquo; is represented
as &ldquo;<literal>#\en-dash</LITERAL>&rdquo; in a
stylesheet.</para>

<informaltable frame="topbot" colsep="0" rowsep="1">
<tgroup cols="2">
<colspec colnum="1" colwidth="1*">
<colspec colnum="2" colwidth="4*">
<tbody>
<row>
<entry><literal>#\M</literal></entry>
<entry>Uppercase character &ldquo;M&rdquo;</entry>
</row>
<row>
<entry><literal>#\u</literal></entry>
<entry>Lowercase character &ldquo;u&rdquo;</entry>
</row>
<row>
<entry><literal>#\-</literal></entry>
<entry>Dash character</entry>
</row>
<row>
<entry><literal>#\en-dash</literal></entry>
<entry>EN DASH character</entry>
</row>
<row>
<entry><literal>#\</literal></entry>
<entry>Space character (though you can't see the space after &ldquo;#\&rdquo;)</entry>
</row>
<row>
<entry><literal>#\space</literal></entry>
<entry>The preferred way to write a space</entry>
</row>
<row>
<entry><literal>"\en-dash"</literal></entry>
<entry>A string containing the EN DASH character</entry>
</row>
<row>
<entry><literal>"\en-dash;M"</literal></entry>
<entry>A string containing the EN DASH character followed by &ldquo;M&rdquo;</entry>
</row>
</tbody>
</informaltable>

<sect2>
<title>Character Type Predicate [8.5.8.3]</title>

<synopsis>
(character? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is a character, otherwise returns <literal>#f</LITERAL>.</para>

<programlisting>
(character? #f)             &rArr;    #f
(character? #\M)            &rArr;    #t
(character? "Mulberry")     &rArr;    #f
(character? 'Mulberry)      &rArr;    #f
</programlisting>

<sect1>
<title>String [8.5.9]</title>

<para>
A sequence of characters.  Strings are written as a sequence of
characters enclosed in double quotes, (<literal>"</LITERAL>).
Double quote characters within a string are escaped by a backslash
(<LITERAL>\</LITERAL>), and backslash characters are escaped by
another backslash:

<programlisting>
"The \"backslash\" is written as \\."
</programlisting>
</para>


<sect2>
<title>String Type Predicate [8.5.9.1]</title>

<synopsis>
(string? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is a string, otherwise returns <literal>#f</LITERAL>.</para>

<programlisting>
(string? #f)                &rArr;    #f
(string? #\M)               &rArr;    #f
(string? "Mulberry")        &rArr;    #t
(string? 'Mulberry)         &rArr;    #f
</programlisting>


<sect1>
<title>Symbol [8.5.4]</title>

<para>
Objects that are identical if and only if their names are spelled
the same way.  Symbols are written with a leading single quote
(<LITERAL>'</LITERAL>), although the quote
is not part of the name of the symbol.  Any constant string that
can be supplied as the value of a characteristic is a symbol.</para>

<sect2>
<title>Symbol Type Predicate [8.5.4.1]</title>

<synopsis>
(symbol? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is a symbol, otherwise returns <literal>#f</LITERAL>.</para>

<programlisting>
(symbol? #f)                &rArr;    #f
(symbol? #\M)               &rArr;    #f
(symbol? "Mulberry")        &rArr;    #f
(symbol? 'Mulberry)         &rArr;    #t
</programlisting>


<sect1>
<title>Keyword [8.5.5]</title>

<para>
Keywords are similar to symbols.  Keywords are written with a trailing
colon (<LITERAL>:</LITERAL>), although the colon is not part of the
name of the keyword.  The characteristic names in a make expression
are keywords.</para>

<sect2>
<title>Keyword Type Predicate [8.5.5.1]</title>

<synopsis>
(keyword? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is a string, otherwise returns <literal>#f</LITERAL>.</para>

<programlisting>
(keyword? start-indent:)    &rArr;    #t
(keyword? Mulberry:)        &rArr;    #t
(keyword? "start-indent:")  &rArr;    #f
(keyword? 'Mulberry)        &rArr;    #f
</programlisting>


<sect1>
<title>Boolean [8.5.1]</title>

<para>
The standard objects are <LITERAL>#t</LITERAL>
and <literal>#f</LITERAL>, but anything except
<literal>#f</LITERAL> evaluates as a true
value in a conditional expression.  <literal>#f</LITERAL>,
therefore, is the only object that evaluates as a false value.</para>

<sect2>
<title>Boolean Type Predicate [8.5.1.2]</title>

<synopsis>
(boolean? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is a boolean object, and returns <literal>#f</LITERAL>
otherwise.</para>

<programlisting>
(boolean? #f)               &rArr;    #t
(boolean? 3)                &rArr;    #f
(boolean? '())              &rArr;    #f
(boolean? 0)                &rArr;    #f
</programlisting>


<sect1>
<title>Procedure [8.5.10]</title>

<para>
DSSSL doesn't seem to define what a procedure is.  &ldquo;The Scheme
Programming Language&rdquo; by Dybvig describes a procedure as
&ldquo;simply the association of a name with a block of code&rdquo;.</para>

<sect2>
<title>Procedure Call</title>

<synopsis>
(<replaceable>operator</replaceable> <replaceable>operand</replaceable>*)
</synopsis>

<para>
Calls procedure <replaceable>operator</replaceable>
with arguments <replaceable>operand</replaceable>*.</para>

<sect2>
<title>Procedure Type Predicate [8.5.10.1]</title>

<synopsis>
(procedure? <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>obj</replaceable>
is a procedure, and returns <literal>#f</LITERAL>
otherwise.</para>

<programlisting>
(procedure? procedure?)     &rArr;    #t
(procedure? 'procedure?)    &rArr;    #f
(procedure? "procedure?")   &rArr;    #f
(procedure? #\en-dash)      &rArr;    #f
</programlisting>

<sect1>
<title>Quick Reference</title>

<sect2>
<title>Quantity</title>


<informaltable frame="topbot" colsep="0" rowsep="1">
<tgroup cols="2">
<colspec colnum="1" colwidth="1*">
<colspec colnum="2" colwidth="4*">
<tbody>
<row>
<entry><literal>4</literal></entry>
<entry>Exact number</entry>
</row>
<row>
<entry><literal>4.0</literal></entry>
<entry>Inexact number</entry>
</row>
<row>
<entry><literal>4e2</literal></entry>
<entry>Inexact number</entry>
</row>
<row>
<entry><literal>4e-1</literal></entry>
<entry>Inexact number</entry>
</row>
<row>
<entry><literal>4m</literal></entry>
<entry>Length (dimension 1)</entry>
</row>
<row>
<entry><literal>#b1000</literal></entry>
<entry>Binary representation of decimal 16</entry>
</row>
<row>
<entry><literal>#o20</literal></entry>
<entry>Octal representation of decimal 16</entry>
</row>
<row>
<entry><literal>#x10</literal></entry>
<entry>Hexadecimal representation of decimal 16</entry>
</row>
</tbody>
</informaltable>

<sect2>
<title>Identifier</title>

<informaltable frame="topbot" colsep="0" rowsep="1">
<tgroup cols="2">
<colspec colnum="1" colwidth="1*">
<colspec colnum="2" colwidth="4*">
<tbody>
<row>
<entry><literal>var</literal></entry>
<entry>Variable</entry>
</row>
<row>
<entry><literal>var:</literal></entry>
<entry>Keyword</entry>
</row>
<row>
<entry><literal>'var</literal></entry>
<entry>Symbol</entry>
</row>
<row>
<entry><literal>(proc var)</literal></entry>
<entry>Procedure</entry>
</row>
<row>
<entry><literal>'(var1 var2)</literal></entry>
<entry>Quoted list</entry>
</row>
<row>
<entry><literal>(quote (var1 var2))</literal></entry>
<entry>Quoted list</entry>
</row>
<row>
<entry><literal>#\v</literal></entry>
<entry>Character &ldquo;v&rdquo;</entry>
</row>
<row>
<entry><literal>#\var</literal></entry>
<entry>Character named &ldquo;var&rdquo;</entry>
</row>
<row>
<entry><literal>"var"</literal></entry>
<entry>String</entry>
</row>
<row>
<entry><literal>"\var"</literal></entry>
<entry>Character named &ldquo;var&rdquo; within a string</entry>
</row>
<row>
<entry><literal>"\var;iable"</literal></entry>
<entry>Character named &ldquo;var&rdquo; within
a string plus &ldquo;iable&rdquo;</entry>
</row>
</tbody>
</informaltable>

<chapter>
<title>Variable Definition [8.4]</title>

<synopsis>
(define <replaceable>variable</replaceable> <replaceable>expression</replaceable>)
</synopsis>

<para>
This is a primitive of the expression language syntax.</para>

<programlisting>
(define var "Mulberry")
var                         &rArr;    "Mulberry"
</programlisting>

<para>
The core expression language does not include the syntax production
for defining your own procedures.
</para>

<chapter>
<title>Equivalence [8.5.2]</title>

<synopsis>
(equal? <replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> of
<replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT> and
<replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT> should be
regarded as the same object.  The conditions for equivalence vary with
the type of the objects.  <function>equal?</function> returns
<literal>#t</LITERAL> if and only if:
<itemizedlist>
<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT>
and <replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>
are both <literal>#t</LITERAL> or both <literal>#f</LITERAL>;
</PARA>
</LISTITEM>
<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT>
and <replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>
are both symbols and

<PROGRAMLISTING>
(string=? (symbol->string obj1)
          (symbol->string obj2))
                           &rArr;    #t
</PROGRAMLISTING>
</para>
</listitem>

<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT> and
<replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT> are both
numbers, are numerically equal in the sense of <function>=</function>,
and are either both exact or inexact;
</PARA>
</LISTITEM>
<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT> and
<replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT> are both
strings and are the same string according to the
<function>string=?</function> procedure;
</PARA>
</LISTITEM>
<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT>
and <replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>
are both characters and are the same character according to the
<function>char=?</function> procedure;
</PARA>
</LISTITEM>
<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT>
and <replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>
are both the empty list;
</PARA>
</LISTITEM>
<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT>
and <replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>
are both <literal>#t</LITERAL> or both <literal>#f</LITERAL>;
</PARA>
</LISTITEM>
<LISTITEM>
<PARA><replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT> and
<replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT> are both pairs
and the car of <replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT>
is <function>equal?</function> to the car of
<replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT> and the cdr of
<replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT> is
<function>equal?</function> to the cdr
<replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>.</para>
</ITEMIZEDLIST>
</para>

<para>
Equality for procedures is not well defined.  See the standard
for details.</para>


<chapter>
<title>Numerical Expressions</title>

<sect1>
<title>Comparison Predicates [8.5.7.7]</title>

<synopsis>
(= <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(&lt; <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(> <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(&lt;= <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(>= <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
</synopsis>

<para>
These return <LITERAL>#t</literal> if
their arguments match the following conditions:

<informaltable frame="topbot" colsep="0" rowsep="1">
<tgroup cols="2">
<colspec colnum="1" colwidth="1*">
<colspec colnum="2" colwidth="4*">
<tbody>
<row>
<entry><literal>=</literal></entry>
<entry>equal</entry>
</row>
<row>
<entry><literal>&lt;</literal></entry>
<entry>monotonically increasing</entry>
</row>
<row>
<entry><literal>></literal></entry>
<entry>monotonically decreasing</entry>
</row>
<row>
<entry><literal>&lt;=</literal></entry>
<entry>monotonically nondecreasing</entry>
</row>
<row>
<entry><literal>>=</literal></entry>
<entry>monotonically nonincreasing</entry>
</row>
</tbody>
</informaltable>


<programlisting>
(= 2 2)                     &rArr;    #t
(= 2 2 2)                   &rArr;    #t
(= 2 2 3)                   &rArr;    #f
(= 1 2 3)                   &rArr;    #f
(= 9 7 5 3)                 &rArr;    #f
(= 6 6 3)                   &rArr;    #f
</programlisting>

<programlisting>
(&lt; 2 2)                     &rArr;    #f
(&lt; 2 2 2)                   &rArr;    #f
(&lt; 2 2 3)                   &rArr;    #f
(&lt; 1 2 3)                   &rArr;    #t
(&lt; 9 7 5 3)                 &rArr;    #f
(&lt; 6 6 3)                   &rArr;    #f
</programlisting>

<programlisting>
(> 2 2)                     &rArr;    #f
(> 2 2 2)                   &rArr;    #f
(> 2 2 3)                   &rArr;    #f
(> 1 2 3)                   &rArr;    #f
(> 9 7 5 3)                 &rArr;    #t
(> 6 6 3)                   &rArr;    #f
</programlisting>

<programlisting>
(&lt;= 2 2)                    &rArr;    #t
(&lt;= 2 2 2)                  &rArr;    #t
(&lt;= 2 2 3)                  &rArr;    #t
(&lt;= 1 2 3)                  &rArr;    #t
(&lt;= 9 7 5 3)                &rArr;    #f
(&lt;= 6 6 3)                  &rArr;    #f
</programlisting>

<programlisting>
(>= 2 2)                    &rArr;    #t
(>= 2 2 2)                  &rArr;    #t
(>= 2 2 3)                  &rArr;    #f
(>= 1 2 3)                  &rArr;    #f
(>= 9 7 5 3)                &rArr;    #t
(>= 6 6 3)                  &rArr;    #t
</programlisting>

<sect1>
<title>Maximum and Minimum [8.5.7.9]</title>

<synopsis>
(max <replaceable>q1</replaceable> <replaceable>q2</replaceable> &hellip;)
(min <replaceable>q1</replaceable> <replaceable>q2</replaceable> &hellip;)
</synopsis>

<para>
Returns the maximum or minimum, respectively, of their arguments.  The
arguments must all have the same dimension, and the result will have
the same dimension as the arguments.</para>

<programlisting>
(max 1 2 3)                 &rArr;    3
(max 1.0 2 3)               &rArr;    3.0
(max 4pt 2pt 6pi)           &rArr;    6pi
</programlisting>

<programlisting>
(min 1 2 3)                 &rArr;    1
(min 1.0 2 3)               &rArr;    3.0
(min 4pt 2pt 6pi)           &rArr;    2pt
</programlisting>

<sect1>
<title>Addition [8.5.7.10]</title>

<synopsis>
(+ <replaceable>q1</replaceable> &hellip;)
</synopsis>

<para>
Returns the sum of its arguments.  The arguments should all have
the same dimension, and the result will have the same dimension
as the arguments.</para>

<programlisting>
(+)                         &rArr;    0
(+ 3)                       &rArr;    3
(+ 1 1)                     &rArr;    2
(+ 1 3 5 7)                 &rArr;    16
</programlisting>

<sect1>
<title>Subtraction [8.5.7.12]</title>

<synopsis>
(- <replaceable>q1</replaceable> <replaceable>q2</replaceable>)
(- <replaceable>q</replaceable>)
</synopsis>

<para>
The first case returns the difference between the two arguments.
 The second case returns the negations of the argument.  The arguments
should all have the same dimension, and the result will have the
same dimension as the arguments.</para>

<programlisting>
(- 27 3)                    &rArr;    24
(- 1)                       &rArr;    -1
</programlisting>

<sect1>
<title>Multiplication [8.5.7.11]</title>

<synopsis>
(* <replaceable>q1</replaceable> &hellip;)
</synopsis>

<para>
Returns the product of its arguments.  The dimension of the result
is the sum of the dimensions of the arguments.</para>

<programlisting>
(* 2 2)                     &rArr;    4
(* 4 2)                     &rArr;    8
(* 4 2pt)                   &rArr;    8pt
</programlisting>

<sect1>
<title>Division [8.5.7.13]</title>

<synopsis>
(/ <replaceable>q1</replaceable> <replaceable>q2</replaceable>)
(/ <replaceable>q</replaceable>)
</synopsis>

<para>
With two arguments, returns the quotient of its arguments.  With
one argument, returns the reciprocal of its argument.  The dimension
of the result is the difference of the dimensions of the arguments.
 With one argument, the dimension of the result is the negation
of the dimension of the argument since the number 1 has dimension
0.</para>

<programlisting>
(/ 27 3)                    &rArr;    9
(/ 2)                       &rArr;    1/2
</programlisting>

<sect1>
<title>Absolute Value [8.5.7.14]</title>

<synopsis>
(abs <replaceable>q</replaceable>)
</synopsis>

<para>
Returns the magnitude of its argument.</para>

<programlisting>
(abs -6)                    &rArr;    6
</programlisting>

<sect1>
<title>Number-theoretic Division [8.5.7.15]</title>

<synopsis>
(quotient <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
(remainder <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
(modulo <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
</synopsis>

<para>
These procedures perform integer division (referred to as number-theoretic
division in the standard without explaining &ldquo;number-theoretic&rdquo;).</para>

<para>
For the positive integers
<replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> and
<replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>, if are
<replaceable>n</replaceable><SUBSCRIPT>3</SUBSCRIPT> and
<replaceable>n</replaceable><SUBSCRIPT>4</SUBSCRIPT> integers such
that:</para>

<para>
<replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT>
= <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT><replaceable>n</replaceable><SUBSCRIPT>3</SUBSCRIPT>
+ <replaceable>n</replaceable><SUBSCRIPT>4</SUBSCRIPT></para>
<para>
and</para>
<para>
<LITERAL>0 &le; <replaceable>n</replaceable><SUBSCRIPT>4</SUBSCRIPT>
&le; <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT></LITERAL></para>

<para>
then the following is true:

<programlisting>
(quotient <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)             &rArr;    <replaceable>n</replaceable><SUBSCRIPT>3</SUBSCRIPT>
(remainder <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)            &rArr;    <replaceable>n</replaceable><SUBSCRIPT>4</SUBSCRIPT>
(modulo <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)               &rArr;    <replaceable>n</replaceable><SUBSCRIPT>4</SUBSCRIPT>
</programlisting>

<programlisting>
(quotient 17 5)             &rArr;    3
(remainder 17 5)            &rArr;    2
(modulo 17 5)               &rArr;    2
</programlisting>

<programlisting>
(quotient -17 5)            &rArr;    -3
(remainder -17 5)           &rArr;    -2
(modulo -17 5)              &rArr;    2
</programlisting>

<programlisting>
(quotient 17 -5)            &rArr;    -3
(remainder 17 -5)           &rArr;    2
(modulo 17 -5)              &rArr;    -2
</programlisting>

<programlisting>
(quotient -17 -5)           &rArr;    3
(remainder -17 -5)          &rArr;    -2
(modulo -17 -5)             &rArr;    -2
</programlisting>

<programlisting>
(quotient 17 5.0)           &rArr;    3
(remainder 17 5.0)          &rArr;    2.0
(modulo 17 5.0)             &rArr;    2
</programlisting>

<sect1>
<title>Real to Integer Conversion [8.5.7.16]</title>

<synopsis>
(floor <replaceable>x</replaceable>)
(ceiling <replaceable>x</replaceable>)
(truncate <replaceable>x</replaceable>)
(round <replaceable>x</replaceable>)
</synopsis>

<para>
<function>floor</function> returns the largest
integer not larger than <replaceable>x</replaceable>.</para>

<para>
<function>ceiling</function> returns the
smallest integer not smaller than <replaceable>x</replaceable>.</para>

<para>
<function>truncate</function> returns the
integer closest to <replaceable>x</replaceable>
whose absolute value is not larger than the absolute value of
<replaceable>x</replaceable>.</para>

<para>
<function>round</function> returns the closest
integer to <replaceable>x</replaceable>, rounding
to even when <replaceable>x</replaceable> is
halfway between two integers.</para>

<para>
If the argument to one of these procedures is inexact, the
result is also inexact.</para>

<programlisting>
(floor 2.5)                 &rArr;    2.0
(ceiling 2.5)               &rArr;    3.0
(truncate 2.5)              &rArr;    2.0
(round 2.5)                 &rArr;    2.0
</programlisting>

<programlisting>
(floor 3.6)                 &rArr;    3.0
(ceiling 3.6)               &rArr;    4.0
(truncate 3.6)              &rArr;    3.0
(round 3.6)                 &rArr;    4.0
</programlisting>

<programlisting>
(floor -2.5)                &rArr;    -3.0
(ceiling -2.5)              &rArr;    -2.0
(truncate -2.5)             &rArr;    -2.0
(round -2.5)                &rArr;    -2.0
</programlisting>

<programlisting>
(floor -3.6)                &rArr;    -4.0
(ceiling -3.6)              &rArr;    -3.0
(truncate -3.6)             &rArr;    -3.0
(round -3.6)                &rArr;    -4.0
</programlisting>

<sect1>
<title>Square Root [8.5.7.20]</title>

<synopsis>
(sqrt <replaceable>q</replaceable>)
</synopsis>

<para>
Returns the square root of <replaceable>q</replaceable>.
 The dimension of <replaceable>q</replaceable>
should be even, and the dimension of the result is half the dimension
of <replaceable>q</replaceable>.  The square
root of a dimensionless quantity is similarly dimensionless.</para>

<programlisting>
(sqrt 25)                   &rArr;    5
(sqrt (* 4pt 1pt))          &rArr;    2pt
</programlisting>

<sect1>
<title>Number to String Conversion [8.5.7.24]</title>

<synopsis>
(number->string <replaceable>number</replaceable>)
(number->string <replaceable>number</replaceable> <replaceable>radix</replaceable>)
</synopsis>

<para>
Returns a string representation of the given number in the given
radix, or in radix 10 if <replaceable>radix</replaceable>
is omitted.  <replaceable>radix</replaceable>
may be one of 2, 8, 10, or 16.</para>

<para>
The result never includes an explicit radix prefix.</para>

<programlisting>
(number->string 16)         &rArr;    "16"
(number->string 16 2)       &rArr;    "10000"
(number->string 16 8)       &rArr;    "20"
(number->string 16 10)      &rArr;    "16"
(number->string 16 16)      &rArr;    "10"
</programlisting>

<programlisting>
(number->string #x10)       &rArr;    "16"
(number->string #x10 2)     &rArr;    "10000"
(number->string #x10 8)     &rArr;    "20"
(number->string #x10 10)    &rArr;    "16"
(number->string #x10 16)    &rArr;    "10"
</programlisting>

<chapter>
<title>List Expressions</title>

<sect1>
<title>List Construction [8.5.3.8]</title>

<synopsis>
(list <replaceable>obj</replaceable> &hellip;)
</synopsis>

<para>
Returns a list of its arguments.</para>

<programlisting>
(list #\M 1 '(3 4) "abc" 5pt)
                            &rArr;    (#\M 1 (3 4) "abc" 5pt)
(list)                      &rArr;    ()
</programlisting>

<sect1>
<title>List Length [8.5.3.9]</title>

<synopsis>
(length <replaceable>list</replaceable>)
</synopsis>

<para>
Returns the length of <replaceable>list</replaceable>.</para>

<programlisting>
(length '(a b '(c d) e))    &rArr;    4
(length '(#\M 1 '(3 4) "abc" 5pt))
                            &rArr;    5
(length '())                &rArr;    0
</programlisting>

<sect1>
<title>List Appendance [8.5.3.10]</title>

<synopsis>
(append <replaceable>list</replaceable> &hellip;)
</synopsis>

<para>
Returns a list consisting of the members of each of the lists.</para>

<programlisting>
(append '(a b) '(c d) '(e)) &rArr;    (a b c d e)
(append '(1) '(2 3 4 5))    &rArr;    (1 2 3 4 5)
</programlisting>

<para>
The last argument doesn't have to be a list, but if it isn't, the
procedure will return an <replaceable>improper list</replaceable>, and
we wouldn't want that, would we?</para>


<sect1>
<title>List Reversal [8.5.3.11]</title>

<synopsis>
(reverse <replaceable>list</replaceable>)
</synopsis>

<para>
Returns a list consisting of the elements in <replaceable>list</replaceable>
in reverse order.</para>

<para>
The order of the elements in <replaceable>list</replaceable>
may be reversed, but the reversal does not carry through to any
lists within <replaceable>list</replaceable>.</para>

<programlisting>
(reverse '(a b '(c d) e))   &rArr;    (e (c d) b a)
(reverse '(#\M 1 '(3 4) "abc" 5pt))
                            &rArr;    (5pt "abc" (3 4) 1 #\M)
(reverse '())               &rArr;    ()
</programlisting>

<sect1>
<title>Sublist Extraction [8.5.3.12]</title>

<synopsis>
(list-tail <replaceable>list</replaceable> <replaceable>k</replaceable>)
</synopsis>

<para>
Returns a list consisting of the elements of <replaceable>list</replaceable>
omitting the first <replaceable>k</replaceable>
elements.</para>

<programlisting>
(list-tail '(a b '(c d) e) 2)
                            &rArr;    (e)
(list-tail '(#\M 1 '(3 4) "abc" 5pt) 2)
                            &rArr;    ("abc" 5pt)
</programlisting>

<sect1>
<title>List Access [8.5.3.13]</title>

<synopsis>
(list-ref <replaceable>list</replaceable> <replaceable>k</replaceable>)
</synopsis>

<para>
Returns the <replaceable>k</replaceable>th
element of <replaceable>list</replaceable>.
 The first element of <replaceable>list</replaceable>
is index 0.  The returned element, not a list containing the element,
is returned.</para>

<programlisting>
(list-ref '(a b '(c d) e) 2)
                            &rArr;    (c d)
(list-ref '(#\M 1 '(3 4) "abc" 5pt) 0)
                            &rArr;    #\M
</programlisting>

<sect1>
<title>List Membership [8.5.3.14]</title>

<synopsis>
(member obj <replaceable>list</replaceable>)
</synopsis>

<para>
Returns a sublist consisting of the elements of <replaceable>list</replaceable>
from the first occurrence of <replaceable>obj</replaceable>
to the end of the list, otherwise returns <literal>#f</LITERAL>
when <replaceable>obj</replaceable> is not
a member of <replaceable>list</replaceable>.</para>

<programlisting>
(member 'b '(a b '(c d) e)) &rArr;    (b (c d) e)
(member '(c d) '(a b '(c d) e))
                            &rArr;    ((c d) e)
(member 3.14 '(#\M 1 '(3 4) "abc" 5pt))
                            &rArr;    #f
</programlisting>

<chapter>
<title>Character Expressions</title>

<sect1>
<title>Character Comparison Predicate [8.5.8.4]</title>

<synopsis>
(char=? <replaceable>char</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>char</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if <replaceable>char</replaceable><SUBSCRIPT>1</SUBSCRIPT>
and <replaceable>char</replaceable><SUBSCRIPT>2</SUBSCRIPT>
are the same character, otherwise returns <literal>#f</LITERAL>.</para>

<para>
There are other character comparison predicates that are not
included in the core expression language.  See Sections 8.5.8.4
and 8.5.8.5 of the DSSSL standard.</para>

<programlisting>
(char=? #\A #\A)            &rArr;    #t
(char=? #\A #\a)            &rArr;    #f
</programlisting>

<sect1>
<title>Character Properties [8.5.8.7]</title>

<synopsis>
(char-property <replaceable>symbol</replaceable> <replaceable>char</replaceable>)
(char-property <replaceable>symbol</replaceable> <replaceable>char</replaceable> <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns the value of the property <replaceable>symbol</replaceable>
of <replaceable>char</replaceable>.  It is
an error if <replaceable>symbol</replaceable>
is not a character property.  If <replaceable>char</replaceable>
does not have a property <replaceable>symbol</replaceable>,
then <replaceable>obj</replaceable> is returned,
or if <replaceable>obj</replaceable> was not
specified, the default value of the property is returned.</para>

<para>
Jade does not fully support char-property, and it always returns
either #f or the default
value.</para>

<chapter>
<title>String Expressions</title>

<sect1>
<title>String Construction [8.5.9.2]</title>

<synopsis>
(string <replaceable>char</replaceable> &hellip;)
</synopsis>

<para>
Returns a string composed of the arguments</para>

<programlisting>
(string #\M #\u #\l #\b #\e #\r #\r #\y)
                            &rArr;    "Mulberry"
</programlisting>

<sect1>
<title>String Length [8.5.9.3]</title>

<synopsis>
(string-length <replaceable>string</replaceable>)
</synopsis>

<para>
Returns the number of characters in <replaceable>string</replaceable>.</para>

<programlisting>
(string-length "Mulberry")  &rArr;    8
</programlisting>

<sect1>
<title>String Access [8.5.9.4]</title>

<synopsis>
(string-ref <replaceable>string</replaceable> <replaceable>k</replaceable>)
</synopsis>

<para>
Returns character <replaceable>k</replaceable>
of <replaceable>string</replaceable>.  The
first character of <replaceable>string</replaceable>
is index 0.</para>

<programlisting>
(string-ref "Mulberry" 0)   &rArr;    #\M
</programlisting>

<sect1>
<title>String Equivalence [8.5.9.5]</title>

<synopsis>
(string=? <replaceable>string</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>string</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
</synopsis>

<para>
Returns <LITERAL>#t</LITERAL> if the two
strings are the same length and have the same characters in the
same positions, otherwise returns <LITERAL>#f</LITERAL>.</para>

<programlisting>
(string=? "Mulberry" "Mulberry")
                            &rArr;    #t
(string=? "Mulberry" "mulberry")
                            &rArr;    #f
</programlisting>

<programlisting>
(define var "Mulberry")
(string=? "Mulberry" var)   &rArr;    #t
</programlisting>

<sect1>
<title>Substring Extraction [8.5.9.7]</title>

<synopsis>
(substring <replaceable>string</replaceable> <replaceable>start</replaceable> <replaceable>end</replaceable>)
</synopsis>

<para>
Returns the string comprising the characters of
<replaceable>string</replaceable> between the
<replaceable>start</replaceable> and <replaceable>end</replaceable>
indexes inclusive, where the first character of
<replaceable>string</replaceable> is index 0.</para>

<programlisting>
(substring "Mulberry" 3 7)  &rArr;    "berry"
</programlisting>

<sect1>
<title>Appending Strings [8.5.9.8]</title>

<synopsis>
(string-append <replaceable>string</replaceable> &hellip;)
</synopsis>

<para>
Returns a string formed by concatenating the argument strings.</para>

<programlisting>
(string-append "Mul" "berry" "!")
                            &rArr;    "Mulberry!"
</programlisting>

<sect1>
<title>String to Number Conversion [8.5.7.25]</title>

<synopsis>
(string->number <replaceable>number</replaceable>)
(string->number <replaceable>number</replaceable> <replaceable>radix</replaceable>)
</synopsis>

<para>
Returns a number of the maximally precise representation expressed by
the given <replaceable>string</replaceable> in the given
<replaceable>radix</replaceable> (or in radix 10 if omitted), or
<literal>#f</literal> is <replaceable>string</replaceable> is not a
syntactically valid representation for a number.
<replaceable>radix</replaceable> may be one of 2, 8, 10, or 16.
</para>

<para>
<replaceable>radix</replaceable> may be overridden by an explicit
radix prefix in <replaceable>string</replaceable>, e.g.,
<literal>"#o37"</literal>.
</para>

<programlisting>
(string->number "17")       &rArr;    17
(string->number "17" 2)     &rArr;    #f
(string->number "17" 8)     &rArr;    15
(string->number "17" 10)    &rArr;    17
(string->number "17" 16)    &rArr;    23
</programlisting>

<programlisting>
(string->number "17.0")     &rArr;    17.0
(string->number "1e3")      &rArr;    1000.0
</programlisting>

<programlisting>
(string->number "#x17" 10)  &rArr;    23
</programlisting>

<chapter>
<title>Procedure Expressions</title>

<sect1>
<title>Procedure Application [8.5.10.2]</title>

<synopsis>
(apply <replaceable>proc</replaceable> <replaceable>args</replaceable>)
</synopsis>

<para>
<replaceable>proc</replaceable> is a procedure, and
<replaceable>args</replaceable> is a list.  <function>apply</function>
calls <replaceable>proc</replaceable> with the elements of
<replaceable>args</replaceable> as the actual arguments.</para>

<programlisting>
(apply * '(2 3))            &rArr;    6
(apply process-matching-children '("PARA" "LIST" "TABLE"))
                            &rArr;    <replaceable>sosofos</replaceable>
</programlisting>

<sect1>
<title>External Procedure [8.5.10.4]</title>

<synopsis>
(external-procedure <replaceable>string</replaceable>)
</synopsis>

<para>
Returns a procedure object which, when called, executes the external
procedure with public identifier <replaceable>string</replaceable>.
Returns <literal>#f</LITERAL> if the system cannot find the external
procedure.</para>

<para>
When the procedure object is evaluated, the arguments passed
to the object are passed to the external procedure, and the result
of the external procedure is returned as the result of the call
of the procedure object.</para>

<para>
An error may be signaled if the number or type of the arguments
passed to the procedure object do not match those expected by
the external procedure.</para>

<programlisting>
(external-procedure "UNREGISTERED::James Clark//Procedure::if-front-page")
                            &rArr;    <replaceable>procedure object</replaceable>
</programlisting>

<programlisting>
(define if-front-page
  (external-procedure "UNREGISTERED::James Clark//Procedure::if-front-page"))
(procedure? if-front-page)  &rArr;    #t
</programlisting>

<programlisting>
(define if-front-page
  (external-procedure "UNREGISTERED::James Clark//Procedure::if-front-page"))
(if-front-page a b)         &rArr;    <replaceable>Result of external procedure</replaceable>
</programlisting>

<chapter>
<title>Date and Time</title>

<sect1>
<title>Time [8.5.11]</title>

<synopsis>
(time)
</synopsis>

<para>
Returns an integer for the number of seconds since 1970-01-01
00:00:00 GMT.
</para>

<sect1>
<title>Time Conversion [8.5.11]</title>

<synopsis>
(time->string <replaceable>k</replaceable>)
(time->string <replaceable>k</replaceable> <replaceable>boolean</replaceable>)
</synopsis>

<para>
Returns a string in the format of ISO 8601 converted from an integer
representation as returned by <function>time</function>.</para>

<para>
If <replaceable>boolean</replaceable> is
present and true, the string representation is in GMT, otherwise
it is in local time.</para>

<chapter>
<title>Error Signaling [8.5.12]</title>

<synopsis>
(error <replaceable>string</replaceable>)
</synopsis>

<para>
<function>error</function> signals an error, and the argument
<replaceable>string</replaceable> describes the error.  No value is
returned from <function>error</function>.</para>


<chapter>
<title>Logical Expressions</title>

<sect1>
<title>AND [8.3.2.3]</title>

<synopsis>
(and <replaceable>test</replaceable>*)
</synopsis>


<para>
The <replaceable>test</replaceable> expressions are evaluated left to
right, and if one of them returns a false value,
<function>and</function> terminates and returns that value, otherwise
it returns the value of the last expression.  This means that
<function>and</function> will return a value other than
<literal>#t</literal> or <literal>#f</literal> if the last expression
evaluated does not return #t or <literal>#f</LITERAL>.</para>

<para>
If there are no <replaceable>test</replaceable>
expressions, <literal>#t</literal> is returned.</para>

<programlisting>
(and (= 3 3) (> 4 3))       &rArr;    #t
(and (= 3 3) (&lt; 4 3))       &rArr;    #f
(and 3 4 5 6)               &rArr;    6
(and)                       &rArr;    #t
</programlisting>

<sect1>
<title>OR [8.3.2.4]</title>

<synopsis>
(or <replaceable>test</replaceable>*)
</synopsis>

<para>
The <replaceable>test</replaceable> expressions are evaluated left to
right, and the first true value is returned.  If none of the
expressions evaluate to a true value, then the value of the last
expression is returned.  This means that <function>or</function> will
return a value other than <literal>#t</literal> if the first true
value evaluated is not actually <literal>#t</LITERAL>.</para>

<para>
If there are no <replaceable>test</replaceable> expressions,
<literal>#f</literal> is returned.</para>

<programlisting>
(or (= 3 3) (> 4 3))        &rArr;    #t
(or (= 3 3) (&lt; 4 3))        &rArr;    #t
(or #f #f #f))              &rArr;    #f
(or (= 3 4) 7pt 5.5)        &rArr;    7pt
</programlisting>

<sect1>
<title>Negation [8.5.1.1]</title>

<synopsis>
(not <replaceable>obj</replaceable>)
</synopsis>

<para>
Returns <LITERAL>#f</LITERAL> if <replaceable>obj</replaceable>
evaluates to a true value, otherwise returns <LITERAL>#t</LITERAL>.</para>

<programlisting>
(not #t)                    &rArr;    #f
(not #f)                    &rArr;    #t
(not 0)                     &rArr;    #f
(not "Mulberry")            &rArr;    #f
(not 'nil)                  &rArr;    #f
(not '())                   &rArr;    #f
(not (or (= 3 3) (> 4 3))   &rArr;    #f
</programlisting>

<chapter>
<title>if, cond, and case Expressions</title>

<sect1>
<title>if [8.3.1.5]</title>

<synopsis>
(if <replaceable>test</replaceable> <replaceable>consequent</replaceable> <replaceable>alternate</replaceable>)
</synopsis>

<para>
First, <replaceable>test</replaceable> is evaluated.  If it returns a
true value (not necessarily the <LITERAL>#t</LITERAL> value), then
<replaceable>consequent</replaceable> is evaluated and its value is
returned, otherwise <replaceable>alternate</replaceable> is evaluated
and its value is returned.</para>

<para>
Both <replaceable>consequent</replaceable> and
<replaceable>alternate</replaceable> must be provided as part of the
<function>if</function> expression.</para>

<programlisting>
(if (> 3 4) "Yes" "No")     &rArr;    "No"
(if #t (+ 3 4) -5)          &rArr;    7
(if (+ 4 5 6) 6pt "Maybe")  &rArr;    6pt
</programlisting>

<sect1>
<title>cond [8.3.2.1]</title>

<synopsis>
(cond (<replaceable>test</replaceable> <replaceable>expression</replaceable>)+)
(cond (<replaceable>test</replaceable> <replaceable>expression</replaceable>)* (else <replaceable>expression</replaceable>))
</synopsis>

<para>
The above expressions are a simplification of productions 42 and
43 in Section 8.3.2.1 of the DSSSL standard.</para>

<para>
The <function>cond</function> expression is evaluated by evaluating
each of the <replaceable>test</replaceable> expressions in turn until
one returns a true value, then the corresponding
<replaceable>expression</replaceable> is evaluated.  If all of the
<replaceable>test</replaceable> expressions evaluate to false values
and there is no <literal>else</literal> clause, then an error is
signaled.  If all of the <replaceable>test</replaceable> expressions
evaluate to false and there is an <literal>else</literal> clause, the
<replaceable>expression</replaceable> in that clause is
evaluated.</para>

<para>
The value returned from the cond expression is the result of the
<replaceable>expression</replaceable> that is
evaluated.</para>

<para>
The full expression language allows two additional forms of
the clause with the <replaceable>test</replaceable>
expression.</para>

<programlisting>
(cond ((> 3 4) 'Yes)
      ((&lt; 3 4) 'No))        &rArr;    'No(define var 4)
</programlisting>

<programlisting>
(cond ((> 3 var) 'Yes)
      ((&lt; 3 var) 'No))      &rArr;    'No
</programlisting>

<sect1>
<title>case [8.3.2.2]</title>

<synopsis>
(case <replaceable>key</replaceable> ((<replaceable>datum</replaceable>*) <replaceable>expression</replaceable>)+))
(case <replaceable>key</replaceable> ((<replaceable>datum</replaceable>*) <replaceable>expression</replaceable>)+) (else <replaceable>expression</replaceable>))
</synopsis>

<para>
The above expressions are a simplification of productions 45 to
47 in Section 8.3.2.2 of the DSSSL standard.</para>

<para>
The <replaceable>datum</replaceable> must all be distinct
values.</para>

<para>
The <replaceable>key</replaceable> expression is evaluated, and its
result is compared with each <replaceable>datum</replaceable> in turn
until a match is found.  If the result of evaluating
<replaceable>key</replaceable> is equivalent to the value of
<replaceable>datum</replaceable> (in the sense of
<function>equal?</function>), then the corresponding
<replaceable>expression</replaceable> is evaluated. If none of the
<replaceable>datum</replaceable> are equivalent to the
<replaceable>key</replaceable> and there is no <literal>else</literal>
clause, then an error is signaled.  If none of the
<replaceable>datum</replaceable> are equivalent to the
<replaceable>key</replaceable> and there is an <literal>else</literal>
clause, the <replaceable>expression</replaceable> in that clause is
evaluated.</para>

<para>
The value returned from the <function>cond</function> expression is
the result of the <replaceable>expression</replaceable> that is
evaluated.</para>

<programlisting>
(define var 6pi)
(case var
      ((1pi 3pi 5pi) "Odd")
      ((2pi 4pi 6pi) "Even")
                            &rArr;    "Even"
</programlisting>

<chapter>
<title>The Real Core Expression Language [8.6]</title>

<sect1>
<title>Syntax</title>

<para>
[120] expression = <replaceable>primitive-expression</replaceable> | <replaceable>derived-expression</replaceable></para>
<para>
[121] primitive-expression = <replaceable>variable-reference</replaceable> | <replaceable>literal</replaceable>
| <replaceable>procedure-call</replaceable> | <replaceable>conditional</replaceable></para>
<para>
[122] variable-reference = <replaceable>variable</replaceable></para>
<para>
[123] variable = <replaceable>identifier</replaceable></para>
<para>
[124] literal = <replaceable>quotation</replaceable> | <replaceable>self-evaluating</replaceable></para>
<para>
[125] quotation = <LITERAL>'<replaceable>datum</replaceable></LITERAL>
| <LITERAL>(quote <replaceable>datum</replaceable>)</LITERAL></para>
<para>
[126] datum = <replaceable>simple-datum</replaceable> | <replaceable>list</replaceable></para>
<para>
[127] simple-datum = <replaceable>boolean</replaceable> |
<replaceable>number</replaceable> |
<replaceable>character</replaceable> |
<replaceable>string</replaceable> | <replaceable>symbol</replaceable>
| <replaceable>keyword</replaceable> |
<replaceable>glyph-identifier</replaceable></para>
<para>
[128] list = <LITERAL>(<replaceable>datum</replaceable>*)</LITERAL> | <LITERAL>'<replaceable>datum</replaceable></LITERAL></para>
<para>
[129] self-evaluating = <replaceable>boolean</replaceable> | <replaceable>number</replaceable> | <replaceable>character</replaceable>
| <replaceable>string</replaceable> | <replaceable>keyword</replaceable> | <replaceable>glyph-identifier</replaceable></para>
<para>
[130] procedure-call = <LITERAL>(<replaceable>operator</replaceable> <replaceable>operand</replaceable>*)</LITERAL></para>
<para>
[131] operator = <replaceable>expression</replaceable></para>
<para>
[132] operand = <replaceable>expression</replaceable></para>
<para>
[133] conditional = <LITERAL>(if <replaceable>test</replaceable>
<replaceable>consequent</replaceable>
<replaceable>alternate</replaceable>)</LITERAL></para>
<para>
[134] test = <replaceable>expression</replaceable></para>
<para>
[135] consequent = <replaceable>expression</replaceable></para>
<para>
[136] alternate = <replaceable>expression</replaceable></para>
<para>
[137] derived-expression = <replaceable>cond-expression</replaceable> | <replaceable>case-expression</replaceable>
| <replaceable>and-expression</replaceable> | <replaceable>or-expression</replaceable></para>
<para>
[138] cond-expression = <LITERAL>(cond
<replaceable>cond-clause</replaceable>+)</LITERAL> | <LITERAL>(cond
<replaceable>cond-clause</replaceable>* (else
<replaceable>expression</replaceable>))</LITERAL></para>
<para>
[139] cond-clause = <LITERAL>(<replaceable>test</replaceable> <replaceable>expression</replaceable>)</LITERAL></para>
<para>
[140] case-expression = <LITERAL>(case <replaceable>key</replaceable>
<replaceable>case-clause</replaceable>+)</LITERAL> | <LITERAL>(case
<replaceable>key</replaceable> <replaceable>case-clause</replaceable>*
(else <replaceable>expression</replaceable>))</LITERAL></para>
<para>
[141] key = <replaceable>expression</replaceable></para>
<para>
[142] case-clause = <LITERAL>((<replaceable>datum</replaceable>*) <replaceable>expression</replaceable>)</LITERAL></para>
<para>
[143] and-expression = <LITERAL>(and
<replaceable>test</replaceable>*)</LITERAL></para>
<para>
[144] or-expression = <LITERAL>(or
<replaceable>test</replaceable>*)</LITERAL></para>
<para>
[145] definition = <LITERAL>(define
<replaceable>variable</replaceable> <replaceable>expression</replaceable>)</LITERAL></para>

<sect1>
<title>Procedures</title>

<synopsis>
(not <replaceable>obj</replaceable>)
(boolean? <replaceable>obj</replaceable>)
(equal? <replaceable>obj</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>obj</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
(null? <replaceable>obj</replaceable>)
(list? <replaceable>obj</replaceable>)
(list <replaceable>obj</replaceable> &hellip;)
(length <replaceable>list</replaceable>)
(append <replaceable>list</replaceable> &hellip;)
(reverse <replaceable>list</replaceable>)
(list-tail <replaceable>list</replaceable> <replaceable>k</replaceable>)
(list-ref <replaceable>list</replaceable> <replaceable>k</replaceable>)
(member <replaceable>obj</replaceable> <replaceable>list</replaceable>)
(symbol? <replaceable>obj</replaceable>)
(keyword? <replaceable>obj</replaceable>)
(quantity? <replaceable>obj</replaceable>)
(number? <replaceable>obj</replaceable>)
(real? <replaceable>obj</replaceable>)
(integer? <replaceable>obj</replaceable>)
(= <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(&lt; <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(> <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(&lt;= <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(>= <replaceable>q1</replaceable> <replaceable>q2</replaceable> <replaceable>q3</replaceable> &hellip;)
(max <replaceable>q1</replaceable> <replaceable>q2</replaceable> &hellip;)
(min <replaceable>q1</replaceable> <replaceable>q2</replaceable> &hellip;)
(+ <replaceable>q1</replaceable> &hellip;)
(* <replaceable>q1</replaceable> &hellip;)
(- <replaceable>q1</replaceable> <replaceable>q2</replaceable>)
(- q)
(/ <replaceable>q1</replaceable> <replaceable>q2</replaceable>)
(/ <replaceable>q</replaceable>)
(abs <replaceable>q</replaceable>)
(quotient <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
(remainder <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable>+)
(modulo <replaceable>n</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>n</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
(floor <replaceable>x</replaceable>)
(ceiling <replaceable>x</replaceable>)
(truncate <replaceable>x</replaceable>)
(round <replaceable>x</replaceable>)
(sqrt <replaceable>x</replaceable>)
(number->string <replaceable>number</replaceable>)
(number->string <replaceable>number</replaceable> <replaceable>radix</replaceable>)
(string->number <replaceable>string</replaceable>)
(string->number <replaceable>string</replaceable> <replaceable>radix</replaceable>)
(char? <replaceable>obj</replaceable>)
(char=? <replaceable>char</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>char</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
(char-property symbol <replaceable>char</replaceable>)
(char-property symbol <replaceable>char</replaceable> <replaceable>obj</replaceable>)
(string? <replaceable>obj</replaceable>)
(string <replaceable>char</replaceable> &hellip;)
(string-length <replaceable>string</replaceable>)
(string-ref <replaceable>string</replaceable> <replaceable>k</replaceable>)
(string=? <replaceable>string</replaceable><SUBSCRIPT>1</SUBSCRIPT> <replaceable>string</replaceable><SUBSCRIPT>2</SUBSCRIPT>)
(substring <replaceable>string</replaceable> <replaceable>start</replaceable> <replaceable>end</replaceable>)
(string-append <replaceable>string</replaceable> &hellip;)
(procedure? <replaceable>obj</replaceable>)
(apply proc args)
(external-procedure <replaceable>string</replaceable>)
(time)
(time->string <replaceable>k</replaceable>)
(time->string <replaceable>k</replaceable> <replaceable>boolean</replaceable>)
(error <replaceable>string</replaceable>)
</synopsis>
</chapter>

<chapter>
<title>Exercise</title>


<orderedlist>
<LISTITEM>
<PARA>Identify the type of each of the following:

<PROGRAMLISTING>
"Mulberry"                  &rArr;

'Mulberry                   &rArr;

Mulberry:                   &rArr;

#\Mulberry                  &rArr;

"\Mulberry;"                &rArr;

99999m                      &rArr;

2.4                         &rArr;

6                           &rArr;

#x23                        &rArr;

#b1010                      &rArr;

#o17                        &rArr;

3.4pi                       &rArr;

#\M                         &rArr;

'(Mul berry)                &rArr;

(mulberry 1 2 4)            &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:

<PROGRAMLISTING>
(+ 1 2 4)                   &rArr;

(+ 1 2.0 4)                 &rArr;

(- 7)                       &rArr;

(- 4 3)                     &rArr;

(* 4 3)                     &rArr;

(/ 1)                       &rArr;

(/ 7 42)                    &rArr;

(abs -7.5)                  &rArr;

(abs 6)                     &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:

<PROGRAMLISTING>
(= 1 2 4)                   &rArr;

(= 1.0 1)                   &rArr;

(define var 1.0)            &rArr;

(= var 1.0)                 &rArr;

(&lt; 2 5 5 7)              &rArr;

(> 2 5 5 7)                 &rArr;

(&lt;= 2 5 5 7)                &rArr;

(&lt;= 2 5 5 7)                &rArr;

(&lt; 9pi 4.5pi 2.25pi)        &rArr;

(> 9pi 4.5pi 2.25pi)        &rArr;

(&lt;=9pi 4.5pi 2.25pi)        &rArr;

(&lt;=9pi 4.5pi 2.25pi)        &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:

<PROGRAMLISTING>
(min 4 5.1 2)               &rArr;

(max 3pi 1pi 35pt)          &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:


<programlisting>
(quotient 15 4)             &rArr;

(remainder 15 4)            &rArr;

(modulo 15 4)               &rArr;

(quotient -15 4)            &rArr;

(remainder -15 4)           &rArr;

(modulo -15 4)              &rArr;

(quotient -15 -4)           &rArr;

(remainder -15 -4)          &rArr;

(modulo -15 -4)             &rArr;

(quotient -15 4.0)          &rArr;

(remainder -15 4.0)         &rArr;

(modulo -15 4.0)            &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:


<programlisting>
(floor -2.3)                &rArr;

(ceiling -2.3)              &rArr;

(truncate -2.3)             &rArr;

(round -2.3)                &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:


<programlisting>
(number->string 12)         &rArr;

(number->string 12 2)       &rArr;

(number->string 12 8)       &rArr;

(number->string 12 10)      &rArr;

(number->string 12 16)      &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:


<programlisting>
(list)                      &rArr;

(list "Mulberry")           &rArr;

(list 1 2 3 4 5 6)          &rArr;

(length '(1 3 5))           &rArr;

(define var '(1 2))         &rArr;

(append var var var)        &rArr;

(reverse '(z '(q m) f))     &rArr;

(list-tail '(q w e r t y) 3)
                            &rArr;

(list-ref '(q w e r t y) 3) &rArr;

(member 'r '(q w e r t y))  &rArr;

(member 'r '(q w '(e r) t y))
                            &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:


<programlisting>
(char=? #\i #\l)            &rArr;

(char=? #\t #\t)            &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:


<programlisting>
(string #\m #\t #\i)        &rArr;

(string-length "a \en-dash; z")
                            &rArr;

(string=? "blue" "red")     &rArr;

(define red "blue")         &rArr;

(string=? "blue" red)       &rArr;

(substring "Rockville" 1 4) &rArr;

(string-append "red" "white" "blue")
                            &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>Evaluate the following expressions:


<programlisting>
(apply max '(3 3.5 9))      &rArr;

(apply string-append '("the " "cat " "in " "the " "hat"))
                            &rArr;
</PROGRAMLISTING>
</listitem>

<LISTITEM>
<PARA>What is wrong with each of the following expressions?

<PROGRAMLISTING>
(max 2 2.0 2pi 2e0)         &rArr;

(sqrt 2pi)                  &rArr;

(string=? "\en-dash" #\en-dash)
                            &rArr;

(list-tail '(a 2pi 2.0 b) 2.0)
                            &rArr;
</PROGRAMLISTING>
</LISTITEM>

<LISTITEM>
<PARA>Evaluate the following expressions:

<PROGRAMLISTING>
(if (&lt;= 5 6 7 7 8.0)
    "Yes"
    "No")                   &rArr;
</PROGRAMLISTING>

<PROGRAMLISTING>
(define red "blue")
(if (not
     (string=? red "blue"))
    (max 4 5.0 6 7.0)
    (min 4 5.0 6 7.0))      &rArr;
</PROGRAMLISTING>

<PROGRAMLISTING>
(define var (/ 0.5))
(case var
      ((1 2 3 4) "Exact")
      ((1.0 2.0 3.0 4.0) "Inexact"))
                            &rArr;
</PROGRAMLISTING>

<PROGRAMLISTING>
(define seven 6)
(define six 7)
(define five 5)
(cond
 ((&lt; five six seven) 'one)
 ((max five six seven) 'two)
 (else 'three))             &rArr;
</PROGRAMLISTING>
</listitem>
</orderedlist>
</chapter>
</book>
