\begin{describe}{mac}
{with-gensyms (@{ @<var> @! (@<var> @[@<name>@]) @}^*) \\ \ind
@<declaration>^* \\
- @<form>^*}
+ @<form>^*
+ \-\nlret @<value>^*}
Bind each @<var> (a symbol, not evaluated) to a freshly made gensym whose
name is based on the corresponding @<name> (a string, evaluated), and
evaluate the @<form>s as an implicit @|progn| in the resulting environment.
@{ @<var> @! (@<var> @[@<value-form>@]) @}^*) \\ \ind
@<declaration>^* \\
@<form>^*
- \nlret @<result-form>}
+ \-\nlret @<result-form>}
This is a helper to ensure that macro expansions evaluate their arguments
exactly once each, in the correct order.
true locatives, such that two locatives compare equal if and only if they
refer to the same place; but that doesn't work for these locatives.
-\begin{describe}{cls}{loc}
+\begin{describe}{cls}{locative}
The type of locative objects.
\end{describe}
-\begin{describe}{fun}{locp @<object> @> @<generalized-boolean>}
+\begin{describe}{fun}{locativep @<object> @> @<generalized-boolean>}
Return non-nil if and only if @<object> is a locative.
\end{describe}
@{ @<var> @! (@{ @<var> @!
(@<var> @[@<locative>@]) @}^*) @} \\ \ind
@<declaration>^* \\
- @<form>^*}
+ @<form>^*
+ \-\nlret @<values>^*}
This is a macro which hides the use of locatives from its caller using
symbol-macros.
An anaphoric macro implicitly binds a well-known name to a value of interest,
in the course of doing something else. The concept was popularized by Paul
-Graham \cite{FIXME:OnLisp}.
+Graham \cite{graham-1993:on-lisp}.
The macros described here all bind the variable @|it|.
The symbol @|it| is exported by the @|sod-utilities| package.
\end{describe}
-\begin{describe}{mac}{aif @<condition> @<consequent> @[@<alt>@]}
+\begin{describe}{mac}{aif @<condition> @<consequent> @[@<alt>@] @> @<value>^*}
Evaluate the @<condition>. If @<condition> is non-nil, then bind @|it| to
the resulting value and evaluate the @<consequent>, returning all of its
values. Otherwise, evaluate @<alt>, returning all of its values.
\end{describe}
-\begin{describe}{mac}{aand @<form>^*}
+\begin{describe}{mac}{aand @<form>^* @> @<value>^*}
Evaluate each @<form> in turn. If any @<form> evaluates to nil, then stop
and return nil. Each form except the first is evaluated with @|it| bound
to the (necessarily non-nil) value of the previous form. If all but the
(No @|aor| is provided, since @|it| would necessarily be bound to nil.)
-\begin{describe}{mac}{awhen @<condition> @<form>^*}
+\begin{describe}{mac}{awhen @<condition> @<form>^* @> nil}
If @<condition> evaluates to a non-nil value, bind @|it| to that value, and
evaluate the @<form>s as an implicit @|progn|. Otherwise, return nil.
\end{describe}
-\begin{describe}{mac}{acond @{ (@<condition> @<form>^*) @}^*}
+\begin{describe}{mac}{acond @{ (@<condition> @<form>^*) @}^* @> @<value>^*}
Evaluate each @<condition> in turn, until one of them produces a non-nil
value. If the @<condition> is followed by one or more @<form>s, then bind
@|it| to the non-nil value of the @<condition> and evaluate the @<form>s as
\end{describe}
\begin{describe*}
- {\dhead{mac}
- {acase @<scrutinee> @{ (@{ @<case> @! (@<case>^*) @} @<form>^*) @}^*}
- \dhead{mac}
- {aecase @<scrutinee> @{ (@{ @<case> @! (@<case>^*) @} @<form>^*) @}^*}
- \dhead{mac}{atypecase @<scrutinee> @{ (@<type> @<form>^*) @}^*}
- \dhead{mac}{aetypecase @<scrutinee> @{ (@<type> @<form>^*) @}^*}}
+ {\dhead{mac}{acase @<scrutinee>
+ @{ (@{ @<case> @! (@<case>^*) @} @<form>^*) @}^*
+ @> @<value>^*}
+ \dhead{mac}{aecase @<scrutinee>
+ @{ (@{ @<case> @! (@<case>^*) @} @<form>^*) @}^*
+ @> @<value>^*}
+ \dhead{mac}{atypecase @<scrutinee> @{ (@<type> @<form>^*) @}^*
+ @> @<value>^*}
+ \dhead{mac}{aetypecase @<scrutinee> @{ (@<type> @<form>^*) @}^*
+ @> @<value>^*}}
These are like the Common Lisp macros @|case|, @|ecase|, @|typecase|, and
@|etypecase|, except that @|it| is bound to the value of the @<scrutinee>
while evaluating the matching @<form>s.
\end{describe*}
-\begin{describe}{mac}{asetf @{ @<place> @<value> @}^*}
+\begin{describe}{mac}{asetf @{ @<place> @<value> @}^* @> @<value>^*}
For each @<place> and @<value> in turn: bind @|it| to the current value of
the @<place>, evaluate the @<value> expression, and store the resulting
- value back in the @<place>.
+ value back in the @<place>. Return the @<value>(s) stored by the final
+ pair: there may be more than one value, e.g., if @<place> is a @|values|
+ form.
For example, @|(asetf @<place> (1+ it))| is almost equivalent to @|(incf
@<place>)|, even if evaluating @<place> has side-effects.
The following utilities make use of the introspection features of the CLOS
metaobject protocol.
-\begin{describe}{gf}{instance-initargs @<instance>}
+\begin{describe}{gf}{instance-initargs @<instance> @> @<initargs-list>}
Return a fresh list of plausible initargs for the given @<instance>.
This is done by digging through the instance's class's slot definitions and
the partial order.
\end{describe}
+\begin{describe}{fun}{cross-product \&rest @<pieces>}
+ Return the cross product of the @<pieces>.
+
+ Each arguments may be a list, or a (non-nil) atom, which is equivalent to a
+ singleton list containing just that atom. Return a list of all possible
+ lists which can be constructed by taking one item from each argument list
+ in turn, in an arbitrary order.
+\end{describe}
+
\begin{describe}{fun}
{find-duplicates @<report> @<sequence> \&key :key :test}
Call @<report> on each pair of duplicate items in a @<sequence>.
and $y$ are considered equal if and only if @|(funcall @<test> (funcall
@<key> $x$) (funcall @<key> $y$))| returns non-nil.
+ The @<report> function is called as @|(funcall @<report> @<duplicate>
+ @<previous>)|. Duplicates are reported in order; the @<previous> item is
+ always the first matching item in the sequence.
+
This function will work for arbitrary @<test> functions, but it will run
- much more efficiently if @<test> is @|eq|, @|eql|, @|equal|, or @|equalp|
- (because it can use hash-tables).
+ much more efficiently if @<test> is @|eq|, @|eql|, @|equal|, or @|equalp|,
+ because it can use hash-tables. (The generic implementation for lists is
+ especially inefficient.)
\end{describe}
\begin{describe}{fun}
{frob-identifier @<string> \&key :swap-case :swap-hyphen
@> @<frobbed-string>}
+ Return a `frobbed' version of the identifier @<string>. Two different
+ transformations can be applied.
+
+ \begin{itemize}
+
+ \item If @<swap-case> is non-nil (the default), and the letters in
+ @<string> are either all uppercase or all lowercase, then switch the case
+ of all of the letters.
+
+ \item If @<swap-hyphen> is non-nil (the default), and @<string> contains
+ either hyphens @`--' or underscores @`_', but not both, then replace the
+ hyphens by underscores or \emph{vice-versa}.
+
+ \end{itemize}
+
+ (These are the `obvious' transformations to convert a C identifier into a
+ Lisp symbol.)
+
+ Some examples:
+ \begin{itemize}
+ \item @|(frob-identifier "foo")| $\Longrightarrow$ @|"FOO"|
+ \item @|(frob-identifier "FOO")| $\Longrightarrow$ @|"foo"|
+ \item @|(frob-identifier "FooBar")| $\Longrightarrow$ @|"FooBar"|
+ \item @|(frob-identifier "Foo-Bar")| $\Longrightarrow$ @|"Foo_Bar"|
+ \item @|(frob-identifier "Foo_Bar")| $\Longrightarrow$ @|"Foo-Bar"|
+ \item @|(frob-identifier "foo_bar")| $\Longrightarrow$ @|"FOO-BAR"|
+ \item @|(frob-identifier "foo_bar" :swap-hyphen nil)| $\Longrightarrow$
+ @|"FOO_BAR"|
+ \item @|(frob-identifier "foo_bar" :swap-case nil)| $\Longrightarrow$
+ @|"foo-bar"|
+ \item @|(frob-identifier "foo_bar" :swap-case nil :swap-hyphen nil)|
+ $\Longrightarrow$ @|"foo_bar"|
+ \end{itemize}
\end{describe}
\begin{describe}{fun}
- {compose @<function> \&rest @<more-functions> @> @<function>}
+ {compose @<functions> @> @<function>}
+ Return the left-to-right composition zero or more @<functions>.
+
+ Let $f_1$, $f_2$, \ldots, $f_n$ be functions, and let $g = @|(compose $f_1$
+ $f_2$ $\cdots$ $f_n$)|$ is their composition. If $g$ is applied to
+ arguments, the effect is as follows: first, $f_1$ is applied to the
+ arguments, yielding some value; $f_2$ is applied to this value, yielding a
+ second value; and so on, until finally the value yielded by $f_n$ is
+ returned as the result of $g$. Note that this is the reverse of the usual
+ mathematician's convention, but the author finds this ordering
+ significantly easier to work with:
+ \[ g = f_n \circ \cdots \circ f_2 \circ f_1 \]
+
+ If any of the input functions return multiple values then \emph{all} of the
+ values are passed on to the next function in the list. (If the last
+ function returns multiple values then all of the values are returned from
+ the composition.
+
+ The result of composing no functions is a function which simply returns all
+ of its arguments as values; essentially, $@|(compose)| \equiv
+ @|\#'values|$.
\end{describe}
\begin{describe}{mac}{defvar-unbound @<name> @<documentation> @> @<name>}
+ Define a variable called @<name>, with a @<documentation> string.
+
+ The Common Lisp @|defvar| macro accepts both an initial value and a
+ doc-string as optional arguments, in that order, with the result that it's
+ not possible to define a variable and establish a documentation string for
+ it without also giving it an initial value. The @|defvar-unbound| macro,
+ on the other hand, never changes the symbol's variable-value.
\end{describe}
\begin{describe}{mac}
{dosequence (@<var> @<sequence>
@[[ :start @<start> @! :end @<end> @!
- :indexvar @<var> @]]) \\ \ind
+ :indexvar @<index-var> @]]) \\ \ind
@<declaration>^* \\
@{ @<tag> @! @<statement> @}^*}
+ Iterate over a @<sequence>. Common Lisp has a rich collection of iteration
+ primitives, and a rich collection of functions for working with sequences,
+ but no macro for iterating over the items of a sequence.
+
+ First, the @<sequence> is evaluated. If @<start> and/or @<end> are
+ provided, they are also evaluated (in that order), which should produce
+ integers; @<end> may be also be nil. If not provided, or nil (in the case
+ of @<end>), @<start> and @<end> default respectively to zero and the length
+ of the @<sequence>. For each item in the sequence between the @<start> and
+ @<end> positions (i.e., each item in @|(subseq @<sequence> @<start>
+ @<end>)|, in order, the body is evaluated as an implicit @|tagbody|, with
+ @<var> bound to the item and, if provided, @<index-var> bound to the item's
+ index. It is not specified whether the @<var> and @<index-var> are
+ let-bound or mutated in each iteration.
+
+ Unlike other Common Lisp @|do|\dots\ forms, there is no `result' form.
\end{describe}
\begin{describe}{mac}
{define-access-wrapper @<from> @<to>
@[[ :read-only @<read-only-flag> @]]}
+ Define @<from> as a function of one argument, so that @|(@<from> @<thing>)|
+ is equivalent to @|(@<to> @<thing>)|. If @<read-only-flag> is nil (the
+ default), then also define @|(setf @<from>)| so that @|(setf (@<from>
+ @<thing>) @<value>)| is equivalent to @|(setf (@<to> @<thing>) @<value>)|.
+
+ In a @|defstruct| form, the accessor function names are constructed based
+ on the structure name and slot names. The structure name and accessor
+ names are part of the exported interface, but the slot names ideally
+ shouldn't be. This causes a problem when the slot name which will lead to
+ the right accessor is already an external symbol in some package. You can
+ solve this problem by choosing an internal name for the symbol, and then
+ using this macro to define an accessor function with the name that you
+ want, in terms of the accessor that @|defstruct| made.
\end{describe}
\begin{describe}{fun}
{distinguished-point-shortest-paths @<root> @<neighbours-func>
@> @<list>}
+ Calculate the shortest path from the @<root> to each node reachable from it
+ in a directed graph. The nodes of the graph can be any kind of object;
+ they will be compared using @|eql|.
+
+ The @<neighbours-func> should be a function which, given a node~$v$ as its
+ only argument, returns a list of cons cells @|($v'$ . $c'$)|, one for each
+ node~$v'$ adjacent to $v$, indicating the cost $c'$ of traversing the arc
+ from $v$ to $v'$.
+
+ The return value is a list of cons cells @|($c$ . $p$)|, where $p$ is list
+ of nodes, in reverse order, along a path from the @<root> to some other
+ node, and $c$ is the total cost of traversing this path. (Therefore @|(car
+ $p$)| is the destination node, and @|(car (last $p$))| is always the
+ @<root> itself.)
+
+ The function runs in $O(n^2)$ time, where $n$ is the number of nodes
+ reachable from the @<root>. Currently, it uses an algorithm due to Edsger
+ Dijkstra.
+\end{describe}
+
+
+\subsection{Other exported symbols}
+
+\begin{describe}{sym}{int}
+ The symbol @|int| is exported by the @|sod-utilities| package, without
+ giving it any particular meaning. This is done because it's given
+ non-conflicting meanings by two different packages, and it's more
+ convenient for user code not to have to deal with an unnecessary symbol
+ conflict. Specifically, the @|sod| package wants to define it as a C type
+ specifier, see \descref{cls}{simple-c-type}; and @|optparse| wants to
+ define it as an option handler, see \descref{opt}{int}.
\end{describe}
%%%--------------------------------------------------------------------------
\section{Option parser} \label{sec:misc.optparse}
-These symbols are defined in the @|optparse| package.
+Most of these symbols are defined in the @|optparse| package.
\begin{describe}{fun}{exit \&optional (@<code> 0) \&key :abrupt}
\end{describe}
\dhead{fun}{setf (opt-negated-tag @<option>) @<tag>}
\dhead{fun}{opt-arg-name @<option> @> @<string-or-null>}
\dhead{fun}{setf (opt-arg-name @<option>) @<string-or-null>}
- \dhead{fun}{opt-optional-p @<option> @> @<generalized-boolean>}
- \dhead{fun}{setf (opt-optional-p @<option>) @<generalized-boolean>}
+ \dhead{fun}{opt-arg-optional-p @<option> @> @<generalized-boolean>}
+ \dhead{fun}{setf (opt-arg-optional-p @<option>) @<generalized-boolean>}
\dhead{fun}{opt-documentation @<option> @> @<string-or-null>}
\dhead{fun}{setf (opt-documentation @<option>) @<string-or-null>}}
\end{describe*}
\&key :format-control :format-arguments}
\end{describe}
+\begin{describe}{fun}{option-parse-error @<msg> \&optional @<args>}
+\end{describe}
+
\begin{describe}{fun}{option-parse-remainder @<option-parser>}
\end{describe}
@<form>^*) @}^*}
\end{describe}
+\begin{describe}{fun}{sod-frontend:augment-options @<options-list>}
+\end{describe}
+
%%%--------------------------------------------------------------------------
\section{Property sets} \label{sec:misc.pset}
\begin{describe*}
{\dhead{fun}{p-name @<property> @> @<name>}
+ \dhead{meth}{property}{file-location (@<property> property) @> @<floc>}
\dhead{fun}{p-value @<property> @> @<value>}
\dhead{fun}{p-type @<property> @> @<type>}
\dhead{fun}{p-key @<property> @> @<symbol>}