sbcl.sbcl/doc/manual/beyond-ansi.texinfo
2026-06-30 17:00:48 +02:00

2774 lines
120 KiB
Plaintext

@c Generated by the sb-manual contrib. Do not edit.
@node beyond the ansi standard
@cindex reader extensions
@chapter Beyond the ANSI Standard
@menu
* Reader Extensions: reader extensions.
* Package-Local Nicknames: package local nicknames.
* Package Variance: package variance.
* Garbage Collection: garbage collection.
* Generic Function Dispatch: generic function dispatch.
* Extended Slot Access: extended slot access.
* Metaobject Protocol: metaobject protocol.
* Extensible Sequences: extensible sequences.
* Support For Unix: support for unix.
* Unicode Support: unicode support.
* Customization Hooks for Users: customization hooks for users.
* Tools To Help Developers: tools to help developers.
* Resolution of Name Conflicts: resolution of name conflicts.
* Hash Table Extensions: hash table extensions.
* Random Number Generation: random number generation.
* Timeouts and Deadlines: timeouts and deadlines.
* Miscellaneous Extensions: miscellaneous extensions.
* Stale Extensions: stale extensions.
* Efficiency Hacks: efficiency hacks.
@end menu
SBCL is derived from CMUCL, which implements many extensions to the
ANSI standard. SBCL doesn't support as many extensions as CMUCL, but
it still has quite a few. See @ref{contributed modules}.
@node reader extensions
@section Reader Extensions
@menu
* Extended Package Prefix Syntax: extended package prefix syntax.
* Symbol Name Normalization: symbol name normalization.
* Decimal Syntax for Rationals: decimal syntax for rationals.
@end menu
@node extended package prefix syntax
@cindex extended package prefix syntax
@cindex package prefix syntax, extended
@subsection Extended Package Prefix Syntax
@cindex interning symbols
@cindex symbols, interning
SBCL supports extended package prefix syntax, which allows specifying
an alternate package instead of @code{*package*} for the reader to use as
the default package for interning symbols:
@example
<package-name>::<form-with-interning-into-package>
@end example
Example:
@example
'foo::(bar quux zot) == '(foo::bar foo::quux foo::zot)
@end example
@cindex package lock
@cindex lock, package
@code{*package*} is not rebound during the course of reading a form with
extended package prefix syntax; if @code{foo::bar} would cause a
read-time package lock violation, so does @code{foo::(bar)}.
@node symbol name normalization
@cindex symbol name normalization
@cindex normalization of symbol name
@subsection Symbol Name Normalization
@cindex Unicode
SBCL also extends the reader to normalize all symbols to @emph{Normalization
Form KC} in builds with Unicode enabled. Whether symbols are
normalized is controlled by
@anchor{Function sb-ext readtable-normalization}
@ffindex @sortas{readtable-normalization sb-ext} readtable-normalization [sb-ext]
@deffn{Function} sb-ext:readtable-normalization readtable
@cindex NFKC
@cindex normalization form compatibility composition
Returns @code{t} if @code{readtable} normalizes symbols to NFKC, and @code{nil}
otherwise. The @code{readtable-normalization} of the standard readtable is @code{t}.
@end deffn
Symbols created by @code{intern} and similar functions are not affected by
this setting. If @code{sb-ext:readtable-normalization} is @code{t}, symbols that
are not normalized are escaped during printing.
@node decimal syntax for rationals
@cindex decimal syntax for rationals
@cindex rational, decimal syntax
@subsection Decimal Syntax for Rationals
SBCL supports a decimal syntax for rationals, modelled after the
standard syntax for floating-point numbers. If a number with
floating-point syntax has an exponent marker of @code{r} or @code{r}
(rather than one of the standard exponent markers), it is read as
the rational with the exact value of the decimal number expressed as
a float.
In addition, setting or binding the value of
@code{*read-default-float-format*} to @code{rational} around a call to @code{read} or
@code{read-from-string} has the effect that floating-point numbers without
exponent markers are read as rational numbers, as if there had been
an explicit @code{r} or @code{r} marker.
Floating point numbers of all types are printed with an exponent
marker while the value of @code{*read-default-float-format*} is @code{rational};
however, rational numbers are printed in their standard syntax,
irrespective of the value of @code{*read-default-float-format*}.
@node package local nicknames
@cindex package-local nicknames
@cindex nicknames, package-local
@section Package-Local Nicknames
SBCL allows giving packages local nicknames: they allow short and
easy-to-use names to be used without fear of name conflict associated
with normal nicknames.
A local nickname is valid only when inside the package for which it
has been specified. Different packages can use same local nickname
for different global names, or different local nickname for same
global name.
The symbol @code{:package-local-nicknames} in @code{*features*} denotes the
support for this feature.
@code{defpackage} options are extended to include
@example
:local-nicknames (<local-nickname> <actual-package-name>)*
@end example
with the semantics of adding the package package-local nicknames
@code{<local-nickname>}s for the corresponding @code{<actual-package-name>}s.
Example:
@example
(defpackage :bar (:intern "X"))
(defpackage :foo (:intern "X"))
(defpackage :quux (:use :cl) (:local-nicknames (:bar :foo) (:foo :bar)))
(find-symbol "X" :foo) ; => FOO::X
(find-symbol "X" :bar) ; => BAR::X
(let ((*package* (find-package :quux)))
(find-symbol "X" :foo)) ; => BAR::X
(let ((*package* (find-package :quux)))
(find-symbol "X" :bar)) ; => FOO::X
@end example
@anchor{Function sb-ext package-local-nicknames}
@ffindex @sortas{package-local-nicknames sb-ext} package-local-nicknames [sb-ext]
@deffn{Function} sb-ext:package-local-nicknames package-designator
Returns an alist of @code{(local-nickname . actual-package)} describing the
nicknames local to the designated package.
When in the designated package, calls to @code{find-package} with the any of the
local-nicknames will return the corresponding actual-package instead. This
also affects all implied calls to @code{find-package}, including those performed by
the reader.
When printing a package prefix for a symbol with a package local nickname, the
local nickname is used instead of the real name in order to preserve
print-read consistency.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext package-locally-nicknamed-by-list}
@ffindex @sortas{package-locally-nicknamed-by-list sb-ext} package-locally-nicknamed-by-list [sb-ext]
@deffn{Function} sb-ext:package-locally-nicknamed-by-list package-designator
Returns a list of packages which have a local nickname for the designated
package.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext add-package-local-nickname}
@ffindex @sortas{add-package-local-nickname sb-ext} add-package-local-nickname [sb-ext]
@deffn{Function} sb-ext:add-package-local-nickname local-nickname actual-package &optional package-designator
Adds @code{local-nickname} for @code{actual-package} in the designated package, defaulting
to current package. @code{local-nickname} must be a string designator, and
@code{actual-package} must be a package designator.
Returns the designated package.
Signals a continuable error if @code{local-nickname} is already a package
local nickname for a different package, or if @code{local-nickname} is one of
@code{"CL"}, @code{"COMMON-LISP"}, @code{"KEYWORD"}, or if @code{local-nickname} is a
global name or nickname for the package to which the nickname would be
added.
When in the designated package, calls to @code{find-package} with the @code{local-nickname}
will return the package the designated @code{actual-package} instead. This also
affects all implied calls to @code{find-package}, including those performed by the
reader.
When printing a package prefix for a symbol with a package local nickname,
local nickname is used instead of the real name in order to preserve
print-read consistency.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext remove-package-local-nickname}
@ffindex @sortas{remove-package-local-nickname sb-ext} remove-package-local-nickname [sb-ext]
@deffn{Function} sb-ext:remove-package-local-nickname old-nickname &optional package-designator
If the designated package had @code{old-nickname} as a local nickname for
another package, it is removed. Returns true if the nickname existed and was
removed, and @code{nil} otherwise.
Experimental: interface subject to change.
@end deffn
@node package variance
@section Package Variance
@code{defpackage} @code{clhs} specifies that @emph{if the new definition is at
variance with the current state of that package, the consequences
are undefined}. SBCL by default signals a full warning and retains
as much of the package state as possible. This can be adjusted with
the following variable.
@anchor{Variable sb-ext *on-package-variance*}
@vvindex @sortas{on-package-variance* sb-ext} *on-package-variance* [sb-ext]
@deffn{Variable} sb-ext:*on-package-variance*
Specifies behavior when redefining a package using @code{defpackage} and the
definition is in variance with the current state of the package.
The value should be of the form:
@example
(:warn [t | packages-names] :error [t | package-names])
@end example
specifying which packages get which behaviour -- with @code{t} signifying the
default unless otherwise specified. If default is not specified, @code{:warn}
is used.
@itemize
@item @code{:warn} keeps as much state as possible and causes SBCL to signal a
full warning.
@item @code{:error} causes SBCL to signal an error when the variant @code{defpackage}
form is executed, with restarts provided for user to specify what
action should be taken.
@end itemize
Example:
@example
(setf *on-package-variance* '(:warn (:swank :swank-backend) :error t))
@end example
specifies to signal a warning if SWANK package is in variance, and an
error otherwise.
@end deffn
@node garbage collection
@cindex garbage collection
@section Garbage Collection
@menu
* Finalization: finalization.
* Weak Pointers: weak pointers.
* Introspection and Tuning: introspection and tuning.
* Tracing Live Objects Back to Roots: tracing live objects back to roots.
@end menu
SBCL provides additional garbage collection functionality not
specified by ANSI.
@anchor{Function sb-ext gc}
@ffindex @sortas{gc sb-ext} gc [sb-ext]
@deffn{Function} sb-ext:gc &key full gen &allow-other-keys
Initiate a garbage collection.
The default is to initiate a nursery collection, which may in turn
trigger a collection of one or more older generations as well. If FULL
is true, all generations are collected. If GEN is provided, it can be
used to specify the oldest generation guaranteed to be collected.
@end deffn
@anchor{Variable sb-ext *after-gc-hooks*}
@vvindex @sortas{after-gc-hooks* sb-ext} *after-gc-hooks* [sb-ext]
@deffn{Variable} sb-ext:*after-gc-hooks*
Called after each garbage collection, except for garbage collections
triggered during thread exits. In a multithreaded environment these hooks may
run in any thread.
@end deffn
@node finalization
@cindex finalization
@subsection Finalization
Finalization allows code to be executed after an object has been
garbage collected. This is useful for example for releasing foreign
memory associated with a Lisp object.
@anchor{Function sb-ext finalize}
@ffindex @sortas{finalize sb-ext} finalize [sb-ext]
@deffn{Function} sb-ext:finalize object function &key dont-save
Arrange for the designated @code{function} to be called when there
are no more references to @code{object}, including references in @code{function}
itself.
If @code{dont-save} is true, the finalizer will be cancelled when
@code{save-lisp-and-die} is called: this is useful for finalizers
deallocating system memory, which might otherwise be called with
addresses from the old image.
In a multithreaded environment @code{function} may be called in any
thread. In both single and multithreaded environments @code{function}
may be called in any dynamic scope: consequences are unspecified
if @code{function} is not fully re-entrant.
Errors from @code{function} are handled and cause a @code{warning} to be
signalled in whichever thread the @code{function} was called in.
Examples:
@example
;;; GOOD, assuming RELEASE-HANDLE is re-entrant.
(let* ((handle (get-handle))
(object (make-object handle)))
(finalize object (lambda () (release-handle handle)))
object)
@end example
@example
;;; BAD, finalizer refers to object being finalized, causing
;;; it to be retained indefinitely!
(let* ((handle (get-handle))
(object (make-object handle)))
(finalize object
(lambda ()
(release-handle (object-handle object)))))
@end example
@example
;;; BAD, not re-entrant!
(defvar *rec* nil)
(defun oops ()
(when *rec*
(error "recursive OOPS"))
(let ((*rec* t))
(gc))) ; or just cons enough to cause one
@end example
@example
(progn
(finalize "oops" #'oops)
(oops)) ; GC causes re-entry to #'oops due to the finalizer
; -> ERROR, caught, WARNING signalled
@end example
@end deffn
@anchor{Function sb-ext cancel-finalization}
@ffindex @sortas{cancel-finalization sb-ext} cancel-finalization [sb-ext]
@deffn{Function} sb-ext:cancel-finalization object
Cancel all finalizations for @code{object}, returning @code{t} if it had a finalizer.
@end deffn
@node weak pointers
@cindex weak pointers
@subsection Weak Pointers
Weak pointers allow references to objects to be maintained without
keeping them from being garbage collected: useful for building caches
among other things.
Hash tables can also have weak keys and values. See
@ref{hash table extensions}.
@anchor{Function sb-ext make-weak-pointer}
@ffindex @sortas{make-weak-pointer sb-ext} make-weak-pointer [sb-ext]
@deffn{Function} sb-ext:make-weak-pointer object
Allocate and return a weak pointer which points to @code{object}.
@end deffn
@anchor{Function sb-ext weak-pointer-value}
@ffindex @sortas{weak-pointer-value sb-ext} weak-pointer-value [sb-ext]
@deffn{Function} sb-ext:weak-pointer-value weak-pointer
If @code{weak-pointer} is valid, return the value of @code{weak-pointer} and @code{t}.
If the referent of @code{weak-pointer} has been garbage collected,
returns the values @code{nil} and @code{nil}.
@end deffn
@node introspection and tuning
@subsection Introspection and Tuning
@anchor{Variable sb-ext *gc-run-time*}
@vvindex @sortas{gc-run-time* sb-ext} *gc-run-time* [sb-ext]
@deffn{Variable} sb-ext:*gc-run-time*
Total CPU time spent doing garbage collection (as reported by
@code{get-internal-run-time}.) Initialized to zero on startup. It is safe to bind
this to zero in order to measure @code{gc} time inside a certain section of code, but
doing so may interfere with results reported by eg. @code{time}.
@end deffn
@anchor{Variable sb-ext *gc-real-time*}
@vvindex @sortas{gc-real-time* sb-ext} *gc-real-time* [sb-ext]
@deffn{Variable} sb-ext:*gc-real-time*
Total real time spent doing garbage collection (as reported by
@code{get-internal-real-time}.) Initialized to zero on startup.
@end deffn
@anchor{Function sb-ext bytes-consed-between-gcs}
@ffindex @sortas{bytes-consed-between-gcs sb-ext} bytes-consed-between-gcs [sb-ext]
@deffn{Function} sb-ext:bytes-consed-between-gcs
The amount of memory that will be allocated before the next garbage
collection is initiated. This can be set with @code{setf}.
On GENCGC platforms this is the nursery size, and defaults to 5% of dynamic
space size.
Note that currently, changes to this value are lost when saving core.
@end deffn
@anchor{Function sb-ext dynamic-space-size}
@ffindex @sortas{dynamic-space-size sb-ext} dynamic-space-size [sb-ext]
@deffn{Function} sb-ext:dynamic-space-size
Size of the dynamic space in bytes.
@end deffn
@anchor{Function sb-ext get-bytes-consed}
@ffindex @sortas{get-bytes-consed sb-ext} get-bytes-consed [sb-ext]
@deffn{Function} sb-ext:get-bytes-consed
Return the number of bytes consed since the program began. Typically
this result will be a consed bignum, so if you have an
application (e.g. profiling) which can't tolerate the overhead of
consing bignums, you'll probably want either to hack in at a lower
level (as the code in the @code{sb-profile} package does), or to design a
more microefficient interface and submit it as a patch.
@end deffn
@anchor{Function sb-ext gc-logfile}
@ffindex @sortas{gc-logfile sb-ext} gc-logfile [sb-ext]
@deffn{Function} sb-ext:gc-logfile
Return the pathname used to log garbage collections. Can be @code{setf}.
Default is @code{nil}, meaning collections are not logged. If non-null, the
designated file is opened before and after each collection, and generation
statistics are appended to it.
@end deffn
@anchor{Function sb-ext generation-average-age}
@ffindex @sortas{generation-average-age sb-ext} generation-average-age [sb-ext]
@deffn{Function} sb-ext:generation-average-age generation
Average age of memory allocated to GENERATION: average number of times
objects allocated to the generation have seen younger objects promoted to it.
Available on GENCGC platforms only.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext generation-bytes-allocated}
@ffindex @sortas{generation-bytes-allocated sb-ext} generation-bytes-allocated [sb-ext]
@deffn{Function} sb-ext:generation-bytes-allocated generation
Number of bytes allocated to GENERATION currently. Available on GENCGC
platforms only.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext generation-bytes-consed-between-gcs}
@ffindex @sortas{generation-bytes-consed-between-gcs sb-ext} generation-bytes-consed-between-gcs [sb-ext]
@deffn{Function} sb-ext:generation-bytes-consed-between-gcs generation
Number of bytes that can be allocated to GENERATION before that
generation is considered for garbage collection. This value is meaningless for
generation 0 (the nursery): see @code{bytes-consed-between-gcs} instead. Default is
5% of the dynamic space size divided by the number of non-nursery generations.
Can be assigned to using @code{setf}. Available on GENCGC platforms only.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext generation-minimum-age-before-gc}
@ffindex @sortas{generation-minimum-age-before-gc sb-ext} generation-minimum-age-before-gc [sb-ext]
@deffn{Function} sb-ext:generation-minimum-age-before-gc generation
Minimum average age of objects allocated to GENERATION before that
generation is may be garbage collected. Default is 0.75. See also
@code{generation-average-age}. Can be assigned to using @code{setf}. Available on GENCGC
platforms only.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext generation-number-of-gcs-before-promotion}
@ffindex @sortas{generation-number-of-gcs-before-promotion sb-ext} generation-number-of-gcs-before-promotion [sb-ext]
@deffn{Function} sb-ext:generation-number-of-gcs-before-promotion generation
Number of times garbage collection is done on GENERATION before
automatic promotion to the next generation is triggered. Default is 1. Can be
assigned to using @code{setf}. Available on GENCGC platforms only.
Experimental: interface subject to change.
@end deffn
@anchor{Function sb-ext generation-number-of-gcs}
@ffindex @sortas{generation-number-of-gcs sb-ext} generation-number-of-gcs [sb-ext]
@deffn{Function} sb-ext:generation-number-of-gcs generation
Number of times garbage collection has been done on GENERATION without
promotion. Available on GENCGC platforms only.
Experimental: interface subject to change.
@end deffn
@node tracing live objects back to roots
@subsection Tracing Live Objects Back to Roots
This feature is intended to help expert users diagnose rare low-level
issues and should not be needed during normal usage. On top of that,
the interface and implementation are experimental and may change at
any time without further notice.
It is sometimes important to understand why a given object is
retained in the Lisp image instead of being garbage collected. To
help with this problem, SBCL provides a mechanism that searches
through the different memory spaces, builds a path of references
from a root to the object in question and finally reports this
paths:
@anchor{Function sb-ext search-roots}
@ffindex @sortas{search-roots sb-ext} search-roots [sb-ext]
@deffn{Function} sb-ext:search-roots weak-pointers &key criterion ignore print
Find roots keeping the targets of @code{weak-pointers} alive.
@code{weak-pointers} must be a single @code{sb-ext:weak-pointer} or a list of those,
pointing to objects for which roots should be searched.
@code{criterion} determines just how rooty (how deep) a root must be in order
to be considered. Possible values are:
@itemize
@item @code{:oldest}
This says we can stop upon seeing an object in the oldest gen to
@code{gc}, or older. This is the easiest test to satisfy.
@item @code{:pseudo-static}
This is usually the same as @code{:oldest}, unless the oldest gen to @code{gc}
has been decreased.
@item @code{:static}
To find a root of an image-backed object, you want to stop only at
a truly @code{:static} object.
@end itemize
@code{ignore} is a list of objects to treat as if nonexistent in the heap.
It can often be useful for finding a path to an interned symbol other than
through its package by specifying the package as an ignored object.
@code{print} controls whether discovered paths should be returned or
printed. Possible values are
@itemize
@item @code{:verbose}
Return no values. Print discovered paths using a verbose format
with each node of each path on a separate line.
@item true (other than @code{:verbose})
Return no values. Print discovered paths using a compact format
with all nodes of each path on a single line.
@item @code{nil}
Do not print any output. Instead return the discovered paths as a
list of lists. Each list has the form
@example
(TARGET . (ROOT NODE*))
@end example
where @code{target} is one of the target of one of the @code{weak-pointers}.
@code{root} is a description of the root at which the path starts and has
one of the following forms:
@itemize
@item @code{:static}
If the root of the path is a non-collectible heap object.
@item @code{:pinned}
If an unknown thread stack pins the root of the path.
@item @code{((thread-name | thread-object) symbol currentp)}
If the path begins at a special binding of @code{symbol} in a thread.
@code{currentp} is a @code{boolean} indicating whether the value is current
or shadowed by another binding.
@item @code{((thread-name | thread-object) guessed-pc)}
If the path begins at a lexical variable in the function whose
code contains @code{guessed-pc}.
@end itemize
Each @code{node} in the remainder of the path is a cons (@code{object} . @code{slot})
indicating that the slot at index @code{slot} in @code{object} references the
next path node.
@end itemize
Experimental: subject to change without prior notice.
@end deffn
An example of using this could look like this:
@itemize
@item (defvar *my-string* (list 1 2 "my string"))
@end itemize
*MY-STRING*
@itemize
@item (sb-ext:search-roots (sb-ext:make-weak-pointer (third *my-string*)))
@end itemize
-> ((@code{simple-vector} 3)) #x10004E9EAF[2] -> (@code{symbol}) #x5044100F[1] -> (@code{cons}) #x100181FAE7[1] -> (@code{cons}) #x100181FAF7[1] -> (@code{cons}) #x100181FB07[0] -> #x100181F9AF
The single line of output on @code{*standard-output*} shows the path from a
root to @code{"my string"}: the path starts with SBCL's internal
package system data structures followed by the symbol
(@code{cl-user:*my-string*}) followed the three cons cells of the list.
The @code{:print :verbose} argument produces similar behavior but
describes the path elements in more detail:
@itemize
@item (sb-ext:search-roots (sb-ext:make-weak-pointer (third *my-string*))
:print :verbose)
@end itemize
Path to "my string":
6 10004E9EAF [ 2] a (simple-vector 3)
0 5044100F [ 1] COMMON-LISP-USER::*MY-STRING*
0 100181FAE7 [ 1] a cons
0 100181FAF7 [ 1] a cons
0 100181FB07 [ 0] a cons
The @code{:print nil} argument is a bit different:
@itemize
@item (sb-ext:search-roots (sb-ext:make-weak-pointer (third *my-string*))
:print nil)
@end itemize
(("my string" @code{:static} (#(*MY-STRING* 0 0) . 2) (*MY-STRING* . 1)
((1 2 "my string") . 1) ((2 "my string") . 1) (("my string") . 0)))
There is no output on @code{*standard-output*}, and the return value is a
single path for the target object @code{"my string"}. As before, the
path shows the symbol and the three cons cells.
@node generic function dispatch
@section Generic Function Dispatch
If a generic function with standard or short method combination is
called, and the set of applicable methods does not include any
primary methods, then the generic function @code{sb-pcl:no-primary-method}
will be invoked with the arguments being the invoked generic
function and its arguments, similar to the standard function
@code{no-applicable-method}. As with @code{no-applicable-method}, the default
method on @code{sb-pcl:no-primary-method} signals an error; programmers may
define methods on it.
@node extended slot access
@section Extended Slot Access
The slot access functions @code{slot-value}, @code{(setf slot-value)},
@code{slot-boundp} and @code{slot-makunbound} are defined to function as expected
on conditions (of metaclass @code{sb-pcl::condition-class}) and, with some
limitations, on structures (of metaclass @code{structure-class}).
For structures:
@cindex unbound slot
@cindex slot, unbound
@itemize
@item The name of a slot for the purposes of the slot access functions
is the symbol used as the slot-name in the slot-description in the
@code{defstruct} form;
@item @code{slot-value} and @code{slot-boundp} function as expected, including (for
@code{slot-value}) calling and respecting the return value of
@code{slot-unbound} if the slot is unbound;
@item @code{(setf slot-value)} functions as expected, including performing
type checks to verify that the new value is of an appropriate type
for the slot;
@item @code{slot-makunbound} makes the slot unbound only when the slot
corresponds to an @code{&aux} argument with no default in a
by-order-of-arguments (BOA) constructor. In all other cases
calling @code{slot-makunbound} on a structure signals an error.
@item If any of the slot access functions is called with a structure
instance which does not have a slot of the given name,
@code{slot-missing} is called and the return value of the effective
method, if any, is respected.
@end itemize
@node metaobject protocol
@section Metaobject Protocol
@menu
* AMOP Compatibility of Metaobject Protocol: amop compatibility of metaobject protocol.
* Metaobject Protocol Extensions: metaobject protocol extensions.
@end menu
@node amop compatibility of metaobject protocol
@subsection AMOP Compatibility of Metaobject Protocol
SBCL supports a metaobject protocol which is intended to be compatible
with AMOP; present exceptions to this (as distinct from current bugs)
are:
@itemize
@item @code{sb-mop:compute-effective-method} only returns one value, not two.
There is no record of what the second return value was meant to
indicate, and apparently no clients for it.
@item The direct superclasses of @code{sb-mop:funcallable-standard-object} are
(@code{function} @code{standard-object}) instead of the correct (@code{standard-object}
@code{function}).
This is to ensure that the @code{standard-object} class is the last of
the standardized classes before class @code{t} appearing in the
precedence list of @code{generic-function} and
@code{standard-generic-function}, as required by @code{clhs} @code{1.4.4.5}.
@item The arguments @code{:declare} and @code{:declarations} are both accepted by
@code{ensure-generic-function}, with the leftmost argument defining the
declarations to be stored and returned by
@code{sb-mop:generic-function-declarations}.
Where AMOP specifies @code{:declarations} as the keyword argument to
@code{ensure-generic-function}, the Common Lisp standard specifies
@code{:declare}. Portable code should use @code{:declare}.
@item Although SBCL obeys the requirement in AMOP that
@code{sb-mop:validate-superclass} should treat @code{standard-class} and
@code{sb-mop:funcallable-standard-class} as compatible metaclasses, we
impose an additional requirement at class finalization time: a
class of metaclass @code{sb-mop:funcallable-standard-class} must have
@code{function} in its superclasses, and a class of metaclass
@code{standard-class} must not.
After a class has been finalized, it is associated with a class
prototype which is accessible by a standard MOP function
@code{sb-mop:class-prototype}. The user can then ask whether this
object is a @code{function} or not in several different ways: whether
it is a function according to @code{typep}; whether its @code{class-of} is
@code{subtypep} @code{function}, or whether @code{function} appears in the
superclasses of the class. The additional consistency
requirement comes from the desire to make all of these answers
the same.
The following class definitions are bad, and will lead to errors
either immediately or if an instance is created:
@example
(defclass bad-object (funcallable-standard-object)
()
(:metaclass standard-class))
(defclass bad-funcallable-object (standard-object)
()
(:metaclass funcallable-standard-class))
@end example
The following definition is acceptable:
@example
(defclass mixin ()
((slot :initarg slot)))
(defclass funcallable-object (funcallable-standard-object mixin)
()
(:metaclass funcallable-standard-class))
@end example
and leads to a class whose instances are funcallable and have one slot.
Note that this requirement also applies to the class
@code{sb-mop:funcallable-standard-object}, which has metaclass
@code{sb-mop:funcallable-standard-class} rather than @code{standard-class} as
AMOP specifies.
@item The requirement that @emph{no portable class may inherit, by virtue of
being a direct or indirect subclass of a specified class, any slot
for which the name is a symbol accessible in the
@code{common-lisp-user} package or exported by any package defined in
the ANSI Common Lisp standard}. is interpreted to mean that the
standardized classes themselves should not have slots named by
external symbols of public packages.
The rationale behind the restriction is likely to be similar to
the ANSI Common Lisp restriction on defining functions,
variables and types named by symbols in the Common Lisp package:
preventing two independent pieces of software from colliding
with each other.
@item Specializations of the @code{new-value} argument to (@code{setf}
@code{sb-mop:slot-value-using-class}) are not allowed: all user-defined
methods must have a specializer of the class @code{t}.
This prohibition is motivated by a separation of layers: the
@code{sb-mop:slot-value-using-class} family of functions is intended
for use in implementing different and new slot allocation
strategies, rather than in performing application-level
dispatching. Additionally, with this requirement, there is a
one-to-one mapping between metaclass, class and
slot-definition-class tuples and effective methods of (@code{setf}
@code{sb-mop:slot-value-using-class}), which permits optimization
of (@code{setf} @code{sb-mop:slot-value-using-class})'s discriminating
function in the same manner as for @code{sb-mop:slot-value-using-class}
and @code{sb-mop:slot-boundp-using-class}.
Note that application code may specialize on the @code{new-value}
argument of slot accessors.
@item The class named by the @code{name} argument to @code{sb-mop:ensure-class}, if any, is
only redefined if it is the proper name of that class; otherwise,
a new class is created.
This is consistent with the description @code{sb-mop:ensure-class} in
AMOP as the functional version of @code{defclass}, which has this
behaviour; however, it is not consistent with the weaker
requirement in AMOP, which states that any class found by
@code{find-class}, no matter what its @code{class-name}, is
redefined.
@item An error is not signaled in the case of the @code{:name} initialization
argument for @code{sb-mop:slot-definition} objects being a constant, when
the slot definition is of type @code{sb-pcl::structure-slot-definition}
(i.e. it is associated with a class of type @code{structure-class}).
This allows code which uses constant names for structure slots
to continue working as specified in ANSI, while enforcing the
constraint for all other types of slot.
@item The class @code{t} is not an instance of the @code{built-in-class} metaclass.
AMOP specifies, in the _Inheritance Structure of Metaobject
Classes_ section, that the class @code{t} should be an instance of
@code{built-in-class}. However, it also specifies that
@code{sb-mop:validate-superclass} should return true (indicating that a
direct superclass relationship is permissible) if the second
argument is the class @code{t}. Also, ANSI specifies that classes with
metaclass @code{built-in-class} may not be subclassed using @code{defclass},
and also that the class @code{t} is the universal superclass,
inconsistent with it being a @code{built-in-class}.
@item Uses of @code{change-class} and redefinitions of classes with
@code{defclass} (or the functional interfaces @code{sb-mop:ensure-class} or
@code{sb-mop:ensure-class-using-class}) must ensure that for each slot
with allocation @code{:instance} or @code{:class}, the set of applicable methods
on the @code{sb-mop:slot-value-using-class} family of generic functions
is the same before and after the change.
This is required for correct operation of the protocol to update
instances for the new or redefined class, and can be seen as
part of the contract of the @code{:instance} or @code{:class} allocations.
@item Metaobject protocol users may wish to override
@code{sb-mop:compute-discriminating-function} for their own generic
function classes. Overriding implementations of
@code{sb-mop:compute-discriminating-function} must, in order to
participate in the @code{no-applicable-method} and
@code{sb-pcl:no-primary-method} protocols, perform appropriate checks on
the return value of @code{compute-applicable-methods} before processing
the effective method; the standard effective method contains
error-invoking forms, but those forms have no access to the
generic function invocation's arguments.
@end itemize
@node metaobject protocol extensions
@subsection Metaobject Protocol Extensions
In addition, SBCL supports extensions to the Metaobject protocol from
AMOP; at present, they are:
@cindex unbound slot
@cindex slot, unbound
@itemize
@item Compile-time support for generating specializer metaobjects from
specializer names in @code{defmethod} forms is provided by the
@code{sb-pcl:make-method-specializers-form} function, which returns a
form which, when evaluated in the lexical environment of the
@code{defmethod}, returns a list of specializer metaobjects. This
operator suffers from similar restrictions to those affecting
@code{sb-mop:make-method-lambda}, namely that the generic function must
be defined when the @code{defmethod} form is expanded, so that the
correct method of @code{sb-pcl:make-method-specializers-form} is invoked.
The system-provided method on @code{sb-pcl:make-method-specializers-form}
generates a call to @code{find-class} for each symbol specializer name,
and a call to @code{sb-mop:intern-eql-specializer} for each
@code{(EQL <x>)} specializer name.
@item Run-time support for converting between specializer names and
specializer metaobjects, mostly for the purposes of @code{find-method},
is provided by @code{sb-pcl:parse-specializer-using-class} and
@code{sb-pcl:unparse-specializer-using-class}, which dispatch on their
first argument, the generic function associated with a method with
the given specializer. The system-provided methods on those
methods convert between classes and proper names and between lists
of the form @code{(EQL <x>)} and interned eql specializer objects.
@item Distinguishing unbound instance allocated slots from
bound ones when using @code{sb-mop:standard-instance-access} and
@code{sb-mop:funcallable-standard-instance-access} is possible by
comparison to the symbol-macro @code{sb-pcl:+slot-unbound+}.
@end itemize
@node extensible sequences
@section Extensible Sequences
@menu
* Iterator Protocol: exseq iterator protocol.
* Simple Iterator Protocol: exseq simple iterator protocol.
@end menu
ANSI Common Lisp has a class @code{sequence} with subclasses @code{list} and
@code{vector}, on which the sequence functions like @code{find}, @code{subseq}, etc.
operate. As an extension to the ANSI specification, SBCL allows
additional subclasses of @code{sequence} to be defined.
@quotation
A motivation, rationale and additional examples for the design of
this extension can be found in the paper @emph{Rhodes,
Christophe (2007): User-extensible sequences in Common Lisp}
available for download at
@url{http://www.doc.gold.ac.uk/~mas01cr/papers/ilc2007/sequences-20070301.pdf}.
@end quotation
Users of this extension just make instances of @code{sequence} subclasses
and transparently operate on them using sequence functions:
@example
(coerce (subseq (make-instance 'my-sequence) 5 10) 'list)
@end example
From this perspective, no distinction between builtin and user-defined
@code{sequence} subclasses should be necessary.
Providers of the extension, that is of user-defined @code{sequence}
subclasses, have to adhere to a @emph{sequence protocol} which consists
of a set of generic functions in the @code{sequence} package.
A minimal @code{sequence} subclass has to specify @code{standard-object} and
@code{sequence} as its superclasses and has to be the specializer of the
@code{sequence} parameter of methods on at least the following generic
functions:
@anchor{Generic function sb-sequence length}
@ffindex @sortas{length sb-sequence} length [sb-sequence]
@deffn{Generic function} sb-sequence:length sequence
Returns the length of @code{sequence} or signals a
@code{sequence:protocol-unimplemented} error if the sequence protocol is
not implemented for the class of @code{sequence}.
@end deffn
@anchor{Generic function sb-sequence elt}
@ffindex @sortas{elt sb-sequence} elt [sb-sequence]
@deffn{Generic function} sb-sequence:elt sequence index
Returns the element at position @code{index} of @code{sequence} or signals a
@code{sequence:protocol-unimplemented} error if the sequence protocol is
not implemented for the class of @code{sequence}.
@end deffn
@anchor{Setf generic function sb-sequence elt}
@ffindex @sortas{elt sb-sequence} elt [sb-sequence]
@deffn{Setf generic function} sb-sequence:elt sequence index
Returns the element at position @code{index} of @code{sequence} or signals a
@code{sequence:protocol-unimplemented} error if the sequence protocol is
not implemented for the class of @code{sequence}.
@end deffn
@anchor{Generic function sb-sequence adjust-sequence}
@ffindex @sortas{adjust-sequence sb-sequence} adjust-sequence [sb-sequence]
@deffn{Generic function} sb-sequence:adjust-sequence sequence length &key initial-element initial-contents
Returns destructively modified @code{sequence} or a freshly allocated
sequence of the same class as @code{sequence} of length @code{length}. Elements
of the returned sequence are initialized to @code{initial-element}, if
supplied, initialized to @code{initial-contents} if supplied, or identical
to the elements of @code{sequence} if neither is supplied. Signals a
@code{sequence:protocol-unimplemented} error if the sequence protocol is
not implemented for the class of @code{sequence}.
@end deffn
@anchor{Generic function sb-sequence make-sequence-like}
@ffindex @sortas{make-sequence-like sb-sequence} make-sequence-like [sb-sequence]
@deffn{Generic function} sb-sequence:make-sequence-like sequence length &key initial-element initial-contents
Returns a freshly allocated sequence of length @code{length} and of the
same class as @code{sequence}. Elements of the new sequence are
initialized to @code{initial-element}, if supplied, initialized to
@code{initial-contents} if supplied, or undefined if neither is supplied.
Signals a @code{sequence:protocol-unimplemented} error if the sequence
protocol is not implemented for the class of @code{sequence}.
@end deffn
@code{make-sequence-like} is needed for functions returning
freshly-allocated sequences such as @code{subseq} or @code{copy-seq}.
@code{adjust-sequence} is needed for functions which destructively modify
their arguments such as @code{delete}. In fact, all other sequence
functions can be implemented in terms of the above functions and
actually are, if no additional methods are defined. However, relying
on these generic implementations, in particular not implementing the
@ref{exseq iterator protocol} can incur a high performance penalty.
When the sequence protocol is only partially implemented for a given
@code{sequence} subclass, an attempt to apply one of the missing operations
to instances of that class signals the following condition:
@anchor{Condition sb-sequence protocol-unimplemented}
@ttindex @sortas{protocol-unimplemented sb-sequence} protocol-unimplemented [sb-sequence]
@deffn{Condition} sb-sequence:protocol-unimplemented
This error is signaled if a sequence operation is applied to an
instance of a sequence class that does not support the
operation.
@end deffn
In addition to the mandatory functions above, methods on the sequence
functions listed below can be defined.
There are some noteworthy irregularities:
@itemize
@item The function @code{sb-sequence:emptyp} does not have a counterpart in the
@code{cl} package. It is intended to be used instead of
@code{sb-sequence:length} when working with lazy or infinite sequences.
@item @code{sb-sequence:dosequence} does not have a direct counterpart either.
It is like @code{dolist} in spirit but traverses generic sequences.
@item The functions @code{map}, @code{concatenate} and @code{merge} receive a type designator
specifying the type of the constructed sequence as their first
argument. However, the corresponding generic functions
@code{sb-sequence:map}, @code{sb-sequence:concatenate} and @code{sb-sequence:merge}
receive a prototype instance of the requested @code{sequence} subclass
instead.
@item @code{cl:map-into} has no generic sequence counterpart, as its lambda
list does not provide reasonable specialization opportunities, but
it supports extensible sequences directly.
@end itemize
@anchor{Generic function sb-sequence emptyp}
@ffindex @sortas{emptyp sb-sequence} emptyp [sb-sequence]
@deffn{Generic function} sb-sequence:emptyp sequence
Returns @code{t} if @code{sequence} is an empty sequence and @code{nil}
otherwise. Signals an error if @code{sequence} is not a sequence.
@end deffn
@anchor{Macro sb-sequence dosequence}
@ffindex @sortas{dosequence sb-sequence} dosequence [sb-sequence]
@deffn{Macro} sb-sequence:dosequence (element sequence &optional return) &body body
Executes @code{body} with @code{element} subsequently bound to each element of
@code{sequence}, then returns @code{return}.
@end deffn
The remaining list parallels the @emph{Sequence Dictionary}, see
17.3 in the ANSI spec.
@anchor{Generic function sb-sequence copy-seq}
@ffindex @sortas{copy-seq sb-sequence} copy-seq [sb-sequence]
@deffn{Generic function} sb-sequence:copy-seq sequence
@end deffn
@anchor{Generic function sb-sequence fill}
@ffindex @sortas{fill sb-sequence} fill [sb-sequence]
@deffn{Generic function} sb-sequence:fill sequence item &key start end
@end deffn
@anchor{Generic function sb-sequence subseq}
@ffindex @sortas{subseq sb-sequence} subseq [sb-sequence]
@deffn{Generic function} sb-sequence:subseq sequence start &optional end
@end deffn
@anchor{Function sb-sequence map}
@ffindex @sortas{map sb-sequence} map [sb-sequence]
@deffn{Function} sb-sequence:map result-prototype function sequence &rest sequences
Implements @code{cl:map} for extended sequences.
@code{result-prototype} corresponds to the @code{result-type} of @code{cl:map} but
receives a prototype instance of an extended sequence class
instead of a type specifier. By dispatching on @code{result-prototype},
methods on this generic function specify how extended sequence
classes act when they are specified as the result type in a @code{cl:map}
call. @code{result-prototype} may not be fully initialized and thus
should only be used for dispatch and to determine its class.
Another difference to @code{cl:map} is that @code{function} is a function, not a
function designator.
@end deffn
@anchor{Generic function sb-sequence reduce}
@ffindex @sortas{reduce sb-sequence} reduce [sb-sequence]
@deffn{Generic function} sb-sequence:reduce function sequence &key from-end start end initial-value key
@end deffn
@anchor{Generic function sb-sequence search}
@ffindex @sortas{search sb-sequence} search [sb-sequence]
@deffn{Generic function} sb-sequence:search sequence1 sequence2 &key from-end start1 end1 start2 end2 test test-not key
@end deffn
@anchor{Generic function sb-sequence mismatch}
@ffindex @sortas{mismatch sb-sequence} mismatch [sb-sequence]
@deffn{Generic function} sb-sequence:mismatch sequence1 sequence2 &key from-end start1 end1 start2 end2 test test-not key
@end deffn
@anchor{Generic function sb-sequence replace}
@ffindex @sortas{replace sb-sequence} replace [sb-sequence]
@deffn{Generic function} sb-sequence:replace sequence1 sequence2 &key start1 end1 start2 end2
@end deffn
@anchor{Function sb-sequence concatenate}
@ffindex @sortas{concatenate sb-sequence} concatenate [sb-sequence]
@deffn{Function} sb-sequence:concatenate result-prototype &rest sequences
Implements @code{cl:concatenate} for extended sequences.
@code{result-prototype} corresponds to the @code{result-type} of @code{cl:concatenate}
but receives a prototype instance of an extended sequence class
instead of a type specifier. By dispatching on @code{result-prototype},
methods on this generic function specify how extended sequence
classes act when they are specified as the result type in a
@code{cl:concatenate} call. @code{result-prototype} may not be fully initialized
and thus should only be used for dispatch and to determine its
class.
@end deffn
@anchor{Function sb-sequence merge}
@ffindex @sortas{merge sb-sequence} merge [sb-sequence]
@deffn{Function} sb-sequence:merge result-prototype sequence1 sequence2 predicate &key key
Implements @code{cl:merge} for extended sequences.
@code{result-prototype} corresponds to the @code{result-type} of @code{cl:merge} but
receives a prototype instance of an extended sequence class
instead of a type specifier. By dispatching on @code{result-prototype},
methods on this generic function specify how extended sequence
classes act when they are specified as the result type in a
@code{cl:merge} call. @code{result-prototype} may not be fully initialized and
thus should only be used for dispatch and to determine its class.
Another difference to @code{cl:merge} is that @code{predicate} is a function,
not a function designator.
@end deffn
Counting:
@anchor{Generic function sb-sequence count}
@ffindex @sortas{count sb-sequence} count [sb-sequence]
@deffn{Generic function} sb-sequence:count item sequence &key from-end start end test test-not key
@end deffn
@anchor{Generic function sb-sequence count-if}
@ffindex @sortas{count-if sb-sequence} count-if [sb-sequence]
@deffn{Generic function} sb-sequence:count-if pred sequence &key from-end start end key
@end deffn
@anchor{Generic function sb-sequence count-if-not}
@ffindex @sortas{count-if-not sb-sequence} count-if-not [sb-sequence]
@deffn{Generic function} sb-sequence:count-if-not pred sequence &key from-end start end key
@end deffn
Reversing:
@anchor{Generic function sb-sequence reverse}
@ffindex @sortas{reverse sb-sequence} reverse [sb-sequence]
@deffn{Generic function} sb-sequence:reverse sequence
@end deffn
@anchor{Generic function sb-sequence nreverse}
@ffindex @sortas{nreverse sb-sequence} nreverse [sb-sequence]
@deffn{Generic function} sb-sequence:nreverse sequence
@end deffn
Sorting:
@anchor{Generic function sb-sequence sort}
@ffindex @sortas{sort sb-sequence} sort [sb-sequence]
@deffn{Generic function} sb-sequence:sort sequence predicate &key key
@end deffn
@anchor{Generic function sb-sequence stable-sort}
@ffindex @sortas{stable-sort sb-sequence} stable-sort [sb-sequence]
@deffn{Generic function} sb-sequence:stable-sort sequence predicate &key key
@end deffn
Finding an element:
@anchor{Generic function sb-sequence find}
@ffindex @sortas{find sb-sequence} find [sb-sequence]
@deffn{Generic function} sb-sequence:find item sequence &key from-end start end test test-not key
@end deffn
@anchor{Generic function sb-sequence find-if}
@ffindex @sortas{find-if sb-sequence} find-if [sb-sequence]
@deffn{Generic function} sb-sequence:find-if pred sequence &key from-end start end key
@end deffn
@anchor{Generic function sb-sequence find-if-not}
@ffindex @sortas{find-if-not sb-sequence} find-if-not [sb-sequence]
@deffn{Generic function} sb-sequence:find-if-not pred sequence &key from-end start end key
@end deffn
Finding a position:
@anchor{Generic function sb-sequence position}
@ffindex @sortas{position sb-sequence} position [sb-sequence]
@deffn{Generic function} sb-sequence:position item sequence &key from-end start end test test-not key
@end deffn
@anchor{Generic function sb-sequence position-if}
@ffindex @sortas{position-if sb-sequence} position-if [sb-sequence]
@deffn{Generic function} sb-sequence:position-if pred sequence &key from-end start end key
@end deffn
@anchor{Generic function sb-sequence position-if-not}
@ffindex @sortas{position-if-not sb-sequence} position-if-not [sb-sequence]
@deffn{Generic function} sb-sequence:position-if-not pred sequence &key from-end start end key
@end deffn
Substituting elements:
@anchor{Generic function sb-sequence substitute}
@ffindex @sortas{substitute sb-sequence} substitute [sb-sequence]
@deffn{Generic function} sb-sequence:substitute new old sequence &key start end from-end test test-not count key
@end deffn
@anchor{Generic function sb-sequence substitute-if}
@ffindex @sortas{substitute-if sb-sequence} substitute-if [sb-sequence]
@deffn{Generic function} sb-sequence:substitute-if new predicate sequence &key start end from-end count key
@end deffn
@anchor{Generic function sb-sequence substitute-if-not}
@ffindex @sortas{substitute-if-not sb-sequence} substitute-if-not [sb-sequence]
@deffn{Generic function} sb-sequence:substitute-if-not new predicate sequence &key start end from-end count key
@end deffn
@anchor{Generic function sb-sequence nsubstitute}
@ffindex @sortas{nsubstitute sb-sequence} nsubstitute [sb-sequence]
@deffn{Generic function} sb-sequence:nsubstitute new old sequence &key start end from-end test test-not count key
@end deffn
@anchor{Generic function sb-sequence nsubstitute-if}
@ffindex @sortas{nsubstitute-if sb-sequence} nsubstitute-if [sb-sequence]
@deffn{Generic function} sb-sequence:nsubstitute-if new predicate sequence &key start end from-end count key
@end deffn
@anchor{Generic function sb-sequence nsubstitute-if-not}
@ffindex @sortas{nsubstitute-if-not sb-sequence} nsubstitute-if-not [sb-sequence]
@deffn{Generic function} sb-sequence:nsubstitute-if-not new predicate sequence &key start end from-end count key
@end deffn
Removing elements:
@anchor{Generic function sb-sequence remove}
@ffindex @sortas{remove sb-sequence} remove [sb-sequence]
@deffn{Generic function} sb-sequence:remove item sequence &key from-end test test-not start end count key
@end deffn
@anchor{Generic function sb-sequence remove-if}
@ffindex @sortas{remove-if sb-sequence} remove-if [sb-sequence]
@deffn{Generic function} sb-sequence:remove-if predicate sequence &key from-end start end count key
@end deffn
@anchor{Generic function sb-sequence remove-if-not}
@ffindex @sortas{remove-if-not sb-sequence} remove-if-not [sb-sequence]
@deffn{Generic function} sb-sequence:remove-if-not predicate sequence &key from-end start end count key
@end deffn
@anchor{Generic function sb-sequence delete}
@ffindex @sortas{delete sb-sequence} delete [sb-sequence]
@deffn{Generic function} sb-sequence:delete item sequence &key from-end test test-not start end count key
@end deffn
@anchor{Generic function sb-sequence delete-if}
@ffindex @sortas{delete-if sb-sequence} delete-if [sb-sequence]
@deffn{Generic function} sb-sequence:delete-if predicate sequence &key from-end start end count key
@end deffn
@anchor{Generic function sb-sequence delete-if-not}
@ffindex @sortas{delete-if-not sb-sequence} delete-if-not [sb-sequence]
@deffn{Generic function} sb-sequence:delete-if-not predicate sequence &key from-end start end count key
@end deffn
Removing duplicates:
@anchor{Generic function sb-sequence remove-duplicates}
@ffindex @sortas{remove-duplicates sb-sequence} remove-duplicates [sb-sequence]
@deffn{Generic function} sb-sequence:remove-duplicates sequence &key from-end test test-not start end key
@end deffn
@anchor{Generic function sb-sequence delete-duplicates}
@ffindex @sortas{delete-duplicates sb-sequence} delete-duplicates [sb-sequence]
@deffn{Generic function} sb-sequence:delete-duplicates sequence &key from-end test test-not start end key
@end deffn
@node exseq iterator protocol
@subsection Iterator Protocol
The general iterator protocol allows subsequently accessing some or
all elements of a sequence in forward or reverse direction. Users
first call @code{sb-sequence:make-sequence-iterator} to create an iteration
state and receive functions to query and mutate it. These functions
allow, among other things, moving to, retrieving or modifying
elements of the sequence. The iteration state consists of a state
object, a limit object, a from-end indicator and six functions to
query or mutate this state.
An iterator is created by calling:
@anchor{Function sb-sequence make-sequence-iterator}
@ffindex @sortas{make-sequence-iterator sb-sequence} make-sequence-iterator [sb-sequence]
@deffn{Function} sb-sequence:make-sequence-iterator sequence &key from-end start end
Returns a sequence iterator for @code{sequence} or, if @code{start} and/or @code{end}
are supplied, the subsequence bounded by @code{start} and @code{end} as nine
values:
1. iterator state
2. limit
3. from-end
4. step function
5. endp function
6. element function
7. setf element function
8. index function
9. copy state function
If @code{from-end} is @code{nil}, the constructed iterator visits the specified
elements in the order in which they appear in @code{sequence}. Otherwise,
the elements are visited in the opposite order.
The six functions (items 4-9 in the list) have the same contract as
the generic functions described in
@ref{exseq simple iterator protocol}. In fact, when there is
no specialized method for a particular @code{sequence} subclass,
@code{sb-sequence:make-sequence-iterator} calls
@code{sb-sequence:make-simple-sequence-iterator} and returns those six
generic functions.
@end deffn
The following convenience macros simplify traversing sequences using
iterators:
@anchor{Macro sb-sequence with-sequence-iterator}
@ffindex @sortas{with-sequence-iterator sb-sequence} with-sequence-iterator [sb-sequence]
@deffn{Macro} sb-sequence:with-sequence-iterator (&optional iterator limit from-end-p step endp element set-element index copy) (sequence &key from-end start end) &body body
Executes @code{body} with the elements of @code{vars} bound to the iteration
state returned by @code{sequence:make-sequence-iterator} for @code{sequence} and
@code{args}. Elements of @code{vars} may be @code{nil} in which case the corresponding
value returned by @code{sequence:make-sequence-iterator} is ignored.
@end deffn
@anchor{Macro sb-sequence with-sequence-iterator-functions}
@ffindex @sortas{with-sequence-iterator-functions sb-sequence} with-sequence-iterator-functions [sb-sequence]
@deffn{Macro} sb-sequence:with-sequence-iterator-functions (&optional step endp elt setf index copy) (sequence &rest args &key from-end start end) &body body
Executes @code{body} with the names @code{step}, @code{endp}, @code{elt}, @code{setf}, @code{index} and @code{copy}
bound to local functions which execute the iteration state query and
mutation functions returned by @code{sequence:make-sequence-iterator} for
@code{sequence} and @code{args}. When some names are not supplied or @code{nil} is supplied
for a given name, no local functions are established for those names.
The functions established for @code{step}, @code{endp}, @code{elt}, @code{setf}, @code{index} and @code{copy}
have dynamic extent.
@end deffn
@node exseq simple iterator protocol
@subsection Simple Iterator Protocol
For cases in which the full flexibility and performance of the general
sequence iterator protocol is not required, there is a simplified
sequence iterator protocol consisting of a few generic functions which
can be specialized for iterator classes:
@anchor{Generic function sb-sequence iterator-step}
@ffindex @sortas{iterator-step sb-sequence} iterator-step [sb-sequence]
@deffn{Generic function} sb-sequence:iterator-step sequence iterator from-end
Moves @code{iterator} one position forward or backward in @code{sequence}
depending on the iteration direction encoded in @code{from-end}.
@end deffn
@anchor{Generic function sb-sequence iterator-endp}
@ffindex @sortas{iterator-endp sb-sequence} iterator-endp [sb-sequence]
@deffn{Generic function} sb-sequence:iterator-endp sequence iterator limit from-end
Returns non-@code{nil} when @code{iterator} has reached @code{limit} (which may
correspond to the end of @code{sequence}) with respect to the iteration
direction encoded in @code{from-end}.
@end deffn
@anchor{Generic function sb-sequence iterator-element}
@ffindex @sortas{iterator-element sb-sequence} iterator-element [sb-sequence]
@deffn{Generic function} sb-sequence:iterator-element sequence iterator
Returns the element of @code{sequence} associated to the position of
@code{iterator}.
@end deffn
@anchor{Setf generic function sb-sequence iterator-element}
@ffindex @sortas{iterator-element sb-sequence} iterator-element [sb-sequence]
@deffn{Setf generic function} sb-sequence:iterator-element sequence iterator
Returns the element of @code{sequence} associated to the position of
@code{iterator}.
@end deffn
@anchor{Generic function sb-sequence iterator-index}
@ffindex @sortas{iterator-index sb-sequence} iterator-index [sb-sequence]
@deffn{Generic function} sb-sequence:iterator-index sequence iterator
Returns the position of @code{iterator} in @code{sequence}.
@end deffn
@anchor{Generic function sb-sequence iterator-copy}
@ffindex @sortas{iterator-copy sb-sequence} iterator-copy [sb-sequence]
@deffn{Generic function} sb-sequence:iterator-copy sequence iterator
Returns a copy of @code{iterator} which also traverses @code{sequence} but can
be mutated independently of @code{iterator}.
@end deffn
Iterator objects implementing the above simple iteration protocol are
created by calling the following generic function:
@anchor{Generic function sb-sequence make-simple-sequence-iterator}
@ffindex @sortas{make-simple-sequence-iterator sb-sequence} make-simple-sequence-iterator [sb-sequence]
@deffn{Generic function} sb-sequence:make-simple-sequence-iterator sequence &key from-end start end
Returns a sequence iterator for @code{sequence}, @code{start}, @code{end} and @code{from-end}
as three values:
1. iterator state
2. limit
3. from-end
The returned iterator can be used with the generic iterator
functions described in @ref{exseq simple iterator protocol}.
@end deffn
@node support for unix
@section Support For Unix
@menu
* Running external programs: running external programs.
@end menu
@anchor{Variable sb-ext *posix-argv*}
@vvindex @sortas{posix-argv* sb-ext} *posix-argv* [sb-ext]
@deffn{Variable} sb-ext:*posix-argv*
A list of strings related to the UNIX command line (@code{argv} in C).
@ref{runtime options} are processed and removed by the runtime.
The default toplevel (see @code{sb-ext:save-lisp-and-die}) also removes the
@ref{toplevel options} that it processes.
@end deffn
@anchor{Function sb-ext posix-getenv}
@ffindex @sortas{posix-getenv sb-ext} posix-getenv [sb-ext]
@deffn{Function} sb-ext:posix-getenv name
Return the @code{value} part of the environment string @code{name=value} which
corresponds to @code{name}, or @code{nil} if there is none. See @code{getenv(3)}.
@end deffn
@anchor{Function sb-ext posix-environ}
@ffindex @sortas{posix-environ sb-ext} posix-environ [sb-ext]
@deffn{Function} sb-ext:posix-environ
Return the Unix environment as a list of @code{simple-string}s. See @code{man environ}.
@end deffn
@node running external programs
@subsection Running external programs
External programs can be run with @code{sb-ext:run-program}.
@quotation
@emph{Note}: In SBCL versions prior to 1.0.13, @code{sb-ext:run-program}
searched for executables in a manner somewhat incompatible with
other languages. As of this version, SBCL uses the system library
routine @code{execvp(3)}, and no longer contains the function
@code{find-executable-in-search-path}, which implemented the old
search. Users who need this function may find it in
@code{run-program.lisp} versions 1.67 and earlier in SBCL's CVS
repository here
@url{http://sbcl.cvs.sourceforge.net/sbcl/sbcl/src/code/run-program.lisp?view=log}.
However, we caution such users that this search routine finds
executables that system library routines do not.
@end quotation
@anchor{Function sb-ext run-program}
@ffindex @sortas{run-program sb-ext} run-program [sb-ext]
@deffn{Function} sb-ext:run-program program args &key env environment wait search pty input if-input-does-not-exist output if-output-exists error if-error-exists status-hook external-format directory preserve-fds use-posix-spawn
@code{run-program} creates a new process specified by @code{program}.
@code{args} is a list of strings to be passed literally to the new program.
In POSIX environments, this list becomes the array supplied as the second
parameter to the execv() or execvp() system call, each list element becoming
one array element. The strings should not contain shell escaping, as there is
no shell involvement. Further note that while conventionally the process
receives its own pathname in argv[0], that is automatic, and the 0th string
should not be present in @code{args}.
The program arguments and the environment are encoded using the
default external format for streams.
@code{run-program} will return a @code{process} structure. See the CMU Common Lisp
Users Manual for details about the @code{process} structure.
Notes about Unix environments (as in the @code{:environment} and @code{:env} args):
@itemize
@item The SBCL implementation of @code{run-program}, like Perl and many other
programs, but unlike the original CMU CL implementation, copies the
Unix environment by default.
@item Running Unix programs from a setuid process, or in any other
situation where the Unix environment is under the control of someone
else, is a mother lode of security problems. If you are
contemplating doing this, read about it first. (The Perl community
has a lot of good documentation about this and other security issues
in script-like programs.)
@end itemize
The @code{&key} arguments have the following meanings:
@itemize
@item @code{:environment}
A list of @code{string}s describing the new Unix environment
(as in "man environ"). The default is to copy the environment of
the current process.
@item @code{:env}
An alternative lossy representation of the new Unix environment,
for compatibility with CMU CL.
@item @code{:search}
Look for @code{program} in each of the directories in the child's $PATH
environment variable. Otherwise an absolute pathname is required.
@item @code{:wait}
If non-@code{nil} (default), wait until the created process finishes. If
@code{nil}, continue running Lisp until the program finishes.
@item @code{:pty} (not supported on win32)
Either @code{t}, @code{nil}, or a stream. Unless @code{nil}, the subprocess is
established under a @code{pty}. If @code{:pty} is a stream, all output to this
pty is sent to this stream, otherwise the @code{process-pty} slot is
filled in with a stream connected to pty that can read output and
write input.
@item @code{:input}
Either @code{t}, @code{nil} (the default), a pathname, a stream, or @code{:stream}.
@itemize
@item @code{t}: the standard input for the current process is inherited.
@item @code{nil}: @code{/dev/null} (nul on win32) is used.
@item Pathname: the specified file is used.
@item Stream: all the input is read from that stream and sent to the
subprocess.
@item @code{:stream}: the @code{process-input} slot is filled in with a stream that
sends its output to the process.
@end itemize
@item @code{:if-input-does-not-exist} (when @code{:input} is the name of a file)
It is one of:
@itemize
@item @code{:error} to generate an error
@item @code{:create} to create an empty file
@item @code{nil} (the default) to return @code{nil} from @code{run-program}
@end itemize
@item @code{:output}
Either @code{t}, @code{nil} (the default), a pathname, a stream, or @code{:stream}.
@itemize
@item @code{t}: the standard output for the current process is inherited.
@item @code{nil}: @code{/dev/null} (nul on win32) is used.
@item Pathname: the specified file is used.
@item Stream: all the output from the process is written to this stream.
@item @code{:stream}: the @code{process-output} slot is filled in with a stream that
can be read to get the output.
@end itemize
@item @code{:error}
Same as @code{:output}, additionally accepts @code{:output}, making all error
output routed to the same place as normal output. Defaults to
@code{:output}.
@item @code{:if-output-exists} (when @code{:output} is the name of a file)
It is one of:
@itemize
@item @code{:error} (the default) to generate an error
@item @code{:supersede} to supersede the file with output from the program
@item @code{:append} to append output from the program to the file
@item @code{nil} to return @code{nil} from @code{run-program}, without doing anything
@end itemize
@item @code{:if-error-exists}
Same as @code{:if-output-exists}, controlling @code{:error} output to files.
Ignored when @code{:error} @code{:output}. Defaults to @code{:error}.
@item @code{:status-hook}
This is a function the system calls whenever the status of the
process changes. The function takes the process as an argument.
@item @code{:external-format}
The external-format to use for @code{:input}, @code{:output}, and @code{:error} @code{:stream}s.
@item @code{:directory}
Specifies the directory in which the program should be run.
@code{nil} (the default) means the directory is unchanged.
@item @code{:preserve-fds}
A sequence of file descriptors which should remain open in the child
process.
@end itemize
Windows specific options:
@itemize
@item @code{:escape-arguments} (default @code{t})
Controls escaping of the arguments passed to CreateProcess.
@item @code{:window} (default @code{nil})
When @code{nil}, the subprocess decides how it will display its window.
The following options control how the subprocess window should be
displayed: @code{:hide}, @code{:show-normal}, @code{:show-maximized},
@code{:show-minimized}, @code{:show-no-activate}, @code{:show-min-no-active},
@code{:show-na}.
@quotation
@emph{Note}: console application subprocesses may or may not display
a console window depending on whether the SBCL runtime is itself
a console or GUI application. Invoke @code{cmd /c start} to
consistently display a console window or use the @code{:window}
@code{:hide} option to consistently hide the console window.
@end quotation
@end itemize
@end deffn
When @code{sb-ext:run-program} is called with @code{:wait} @code{nil}, an process object
is returned. The following functions are available for use with
processes:
@anchor{Function sb-ext process-p}
@ffindex @sortas{process-p sb-ext} process-p [sb-ext]
@deffn{Function} sb-ext:process-p object
@code{t} if @code{object} is a @code{process}, @code{nil} otherwise.
@end deffn
@anchor{Function sb-ext process-input}
@ffindex @sortas{process-input sb-ext} process-input [sb-ext]
@deffn{Function} sb-ext:process-input instance
The input stream of the process or @code{nil}.
@end deffn
@anchor{Function sb-ext process-output}
@ffindex @sortas{process-output sb-ext} process-output [sb-ext]
@deffn{Function} sb-ext:process-output instance
The output stream of the process or @code{nil}.
@end deffn
@anchor{Function sb-ext process-error}
@ffindex @sortas{process-error sb-ext} process-error [sb-ext]
@deffn{Function} sb-ext:process-error instance
The error stream of the process or @code{nil}.
@end deffn
@anchor{Function sb-ext process-alive-p}
@ffindex @sortas{process-alive-p sb-ext} process-alive-p [sb-ext]
@deffn{Function} sb-ext:process-alive-p process
Return @code{t} if @code{process} is still alive, @code{nil} otherwise. Can return a false
positive on a closed process.
@end deffn
@anchor{Function sb-ext process-status}
@ffindex @sortas{process-status sb-ext} process-status [sb-ext]
@deffn{Function} sb-ext:process-status process
Return the current status of @code{process}. The result is one of @code{:running},
@code{:stopped}, @code{:exited}, @code{:signaled}.
@end deffn
@anchor{Function sb-ext process-wait}
@ffindex @sortas{process-wait sb-ext} process-wait [sb-ext]
@deffn{Function} sb-ext:process-wait process &optional check-for-stopped
Wait for @code{process} to quit running for some reason. When
@code{check-for-stopped} is @code{t}, also returns when @code{process} is stopped. Returns
@code{process}.
@end deffn
@anchor{Function sb-ext process-exit-code}
@ffindex @sortas{process-exit-code sb-ext} process-exit-code [sb-ext]
@deffn{Function} sb-ext:process-exit-code process
The exit code or the signal of a stopped process.
@end deffn
@anchor{Function sb-ext process-core-dumped}
@ffindex @sortas{process-core-dumped sb-ext} process-core-dumped [sb-ext]
@deffn{Function} sb-ext:process-core-dumped instance
@code{t} if a core image was dumped by the process.
@end deffn
@anchor{Function sb-ext process-close}
@ffindex @sortas{process-close sb-ext} process-close [sb-ext]
@deffn{Function} sb-ext:process-close process
Close all streams connected to @code{process}, stop maintaining the
status slot. After @code{process-close}, @code{process-alive-p} and
@code{process-exit-code} can return stale information about a process, so
should not be used.
@end deffn
@anchor{Function sb-ext process-kill}
@ffindex @sortas{process-kill sb-ext} process-kill [sb-ext]
@deffn{Function} sb-ext:process-kill process signal &optional whom
Hand @code{signal} to @code{process}. If @code{whom} is @code{:pid}, use the kill Unix system call. If
@code{whom} is @code{:process-group}, use the @code{killpg(1)} Unix system call.
Returns @code{t} if successful, otherwise returns @code{nil} and error
number (two values).
@end deffn
@node unicode support
@cindex Unicode
@section Unicode Support
@menu
* Unicode property access: unicode property access.
* String operations: string operations.
* Breaking strings: breaking strings.
@end menu
SBCL provides support for working with Unicode text and querying the
standard Unicode database for information about individual codepoints.
Unicode-related functions are located in the @code{sb-unicode} package.
SBCL also extends ANSI character literal syntax to support Unicode
codepoints. You can either specify a character by its Unicode name,
with spaces replaced by underscores if a unique name exists or by
giving its hexadecimal codepoint preceded by a @code{u}, an optional
@code{+}, and an arbitrary number of leading zeros. You may also input
the character directly into your source code if it can be encoded in
your file. If a character had an assigned name in Unicode 1.0 that
was distinct from its current name, you may also use that name (with
spaces replaced by underscores) to specify the character, unless the
name is already associated with a codepoint in the latest Unicode
standard (such as @code{bell}).
@quotation
@emph{Note}: Please note that the codepoint @code{u+1f5cf} (Page) introduced
in Unicode 7.0 is named @code{unicode_page}, since the name @emph{Page} is
required to be assigned to form-feed (@code{u+0c}) by the ANSI
standard.
@end quotation
For example, you can specify the codepoint @code{u+00e1} ( @emph{Latin Small
Letter A With Acute}) as
@itemize
@item @code{#\latin_small_letter_a_with_acute}
@item @code{#\latin_small_letter_a_acute}
@item @code{#\á} (assuming a Unicode source file)
@item @code{#\u00e1}
@item @code{#\ue1}
@item @code{#\u+00e1}
@end itemize
@node unicode property access
@subsection Unicode property access
The following functions can be used to find information about a
Unicode codepoint.
@anchor{Function sb-unicode general-category}
@ffindex @sortas{general-category sb-unicode} general-category [sb-unicode]
@deffn{Function} sb-unicode:general-category character
Returns the general category of @code{character} as it appears in UnicodeData.txt
@end deffn
@anchor{Function sb-unicode bidi-class}
@ffindex @sortas{bidi-class sb-unicode} bidi-class [sb-unicode]
@deffn{Function} sb-unicode:bidi-class character
Returns the bidirectional class of @code{character}
@end deffn
@anchor{Function sb-unicode combining-class}
@ffindex @sortas{combining-class sb-unicode} combining-class [sb-unicode]
@deffn{Function} sb-unicode:combining-class character
Returns the canonical combining class (CCC) of @code{character}
@end deffn
@anchor{Function sb-unicode decimal-value}
@ffindex @sortas{decimal-value sb-unicode} decimal-value [sb-unicode]
@deffn{Function} sb-unicode:decimal-value character
Returns the decimal digit value associated with @code{character} or @code{nil} if
there is no such value.
The only characters in Unicode with a decimal digit value are those
that are part of a range of characters that encode the digits 0-9.
Because of this, @code{(decimal-digit c) <=> (digit-char-p c 10)} in
@code{#+sb-unicode} builds
@end deffn
@anchor{Function sb-unicode digit-value}
@ffindex @sortas{digit-value sb-unicode} digit-value [sb-unicode]
@deffn{Function} sb-unicode:digit-value character
Returns the Unicode digit value of @code{character} or @code{nil} if it doesn't exist.
Digit values are guaranteed to be integers between 0 and 9 inclusive.
All characters with decimal digit values have the same digit value,
but there are characters (such as digits of number systems without a 0 value)
that have a digit value but no decimal digit value
@end deffn
@anchor{Function sb-unicode numeric-value}
@ffindex @sortas{numeric-value sb-unicode} numeric-value [sb-unicode]
@deffn{Function} sb-unicode:numeric-value character
Returns the numeric value of @code{character} or @code{nil} if there is no such value.
Numeric value is the most general of the Unicode numeric properties.
The only constraint on the numeric value is that it be a rational number.
@end deffn
@anchor{Function sb-unicode mirrored-p}
@ffindex @sortas{mirrored-p sb-unicode} mirrored-p [sb-unicode]
@deffn{Function} sb-unicode:mirrored-p character
Returns @code{t} if @code{character} needs to be mirrored in bidirectional text.
Otherwise, returns @code{nil}.
@end deffn
@anchor{Function sb-unicode bidi-mirroring-glyph}
@ffindex @sortas{bidi-mirroring-glyph sb-unicode} bidi-mirroring-glyph [sb-unicode]
@deffn{Function} sb-unicode:bidi-mirroring-glyph character
Returns the mirror image of @code{character} if it exists.
Otherwise, returns @code{nil}.
@end deffn
@anchor{Function sb-unicode age}
@ffindex @sortas{age sb-unicode} age [sb-unicode]
@deffn{Function} sb-unicode:age character
Returns the version of Unicode in which @code{character} was assigned as a pair
of values, both integers, representing the major and minor version respectively.
If @code{character} is not assigned in Unicode, returns @code{nil} for both values.
@end deffn
@anchor{Function sb-unicode hangul-syllable-type}
@ffindex @sortas{hangul-syllable-type sb-unicode} hangul-syllable-type [sb-unicode]
@deffn{Function} sb-unicode:hangul-syllable-type character
Returns the Hangul syllable type of @code{character}.
The syllable type can be one of @code{:l}, @code{:v}, @code{:t}, @code{:lv}, or @code{:lvt}.
If the character is not a Hangul syllable or Jamo, returns @code{nil}
@end deffn
@anchor{Function sb-unicode east-asian-width}
@ffindex @sortas{east-asian-width sb-unicode} east-asian-width [sb-unicode]
@deffn{Function} sb-unicode:east-asian-width character
Returns the East Asian Width property of @code{character} as
one of the keywords @code{:n} (Narrow), @code{:a} (Ambiguous), @code{:h} (Halfwidth),
@code{:w} (Wide), @code{:f} (Fullwidth), or @code{:na} (Not applicable)
@end deffn
@anchor{Function sb-unicode script}
@ffindex @sortas{script sb-unicode} script [sb-unicode]
@deffn{Function} sb-unicode:script character
Returns the Script property of @code{character} as a keyword.
If @code{character} does not have a known script, returns @code{:unknown}
@end deffn
@anchor{Function sb-unicode char-block}
@ffindex @sortas{char-block sb-unicode} char-block [sb-unicode]
@deffn{Function} sb-unicode:char-block character
Returns the Unicode block in which @code{character} resides as a keyword.
If @code{character} does not have a known block, returns @code{:no-block}
@end deffn
@anchor{Function sb-unicode unicode-1-name}
@ffindex @sortas{unicode-1-name sb-unicode} unicode-1-name [sb-unicode]
@deffn{Function} sb-unicode:unicode-1-name character
Returns the name assigned to @code{character} in Unicode 1.0 if it is distinct
from the name currently assigned to @code{character}. Otherwise, returns @code{nil}.
This property has been officially obsoleted by the Unicode standard, and
is only included for backwards compatibility.
@end deffn
@anchor{Function sb-unicode proplist-p}
@ffindex @sortas{proplist-p sb-unicode} proplist-p [sb-unicode]
@deffn{Function} sb-unicode:proplist-p character property
Returns @code{t} if @code{character} has the specified @code{property}.
@code{property} is a keyword representing one of the properties from PropList.txt,
with underscores replaced by dashes.
@end deffn
@anchor{Function sb-unicode uppercase-p}
@ffindex @sortas{uppercase-p sb-unicode} uppercase-p [sb-unicode]
@deffn{Function} sb-unicode:uppercase-p character
Returns @code{t} if @code{character} has the Unicode property Uppercase and @code{nil} otherwise
@end deffn
@anchor{Function sb-unicode lowercase-p}
@ffindex @sortas{lowercase-p sb-unicode} lowercase-p [sb-unicode]
@deffn{Function} sb-unicode:lowercase-p character
Returns @code{t} if @code{character} has the Unicode property Lowercase and @code{nil} otherwise
@end deffn
@anchor{Function sb-unicode cased-p}
@ffindex @sortas{cased-p sb-unicode} cased-p [sb-unicode]
@deffn{Function} sb-unicode:cased-p character
Returns @code{t} if @code{character} has a (Unicode) case, and @code{nil} otherwise
@end deffn
@anchor{Function sb-unicode case-ignorable-p}
@ffindex @sortas{case-ignorable-p sb-unicode} case-ignorable-p [sb-unicode]
@deffn{Function} sb-unicode:case-ignorable-p character
Returns @code{t} if @code{character} is Case Ignorable as defined in Unicode 6.3, Chapter
3
@end deffn
@anchor{Function sb-unicode alphabetic-p}
@ffindex @sortas{alphabetic-p sb-unicode} alphabetic-p [sb-unicode]
@deffn{Function} sb-unicode:alphabetic-p character
Returns @code{t} if @code{character} is Alphabetic according to the Unicode standard
and @code{nil} otherwise
@end deffn
@anchor{Function sb-unicode ideographic-p}
@ffindex @sortas{ideographic-p sb-unicode} ideographic-p [sb-unicode]
@deffn{Function} sb-unicode:ideographic-p character
Returns @code{t} if @code{character} has the Unicode property Ideographic,
which loosely corresponds to the set of "Chinese characters"
@end deffn
@anchor{Function sb-unicode math-p}
@ffindex @sortas{math-p sb-unicode} math-p [sb-unicode]
@deffn{Function} sb-unicode:math-p character
Returns @code{t} if @code{character} is a mathematical symbol according to Unicode and
@code{nil} otherwise
@end deffn
@anchor{Function sb-unicode whitespace-p}
@ffindex @sortas{whitespace-p sb-unicode} whitespace-p [sb-unicode]
@deffn{Function} sb-unicode:whitespace-p character
Returns @code{t} if @code{character} is whitespace according to Unicode
and @code{nil} otherwise
@end deffn
@anchor{Function sb-unicode soft-dotted-p}
@ffindex @sortas{soft-dotted-p sb-unicode} soft-dotted-p [sb-unicode]
@deffn{Function} sb-unicode:soft-dotted-p character
Returns @code{t} if @code{character} has a soft dot (such as the dots on i and j) which
disappears when accents are placed on top of it. and @code{nil} otherwise
@end deffn
@anchor{Function sb-unicode hex-digit-p}
@ffindex @sortas{hex-digit-p sb-unicode} hex-digit-p [sb-unicode]
@deffn{Function} sb-unicode:hex-digit-p character &key ascii
Returns @code{t} if @code{character} is a hexadecimal digit and @code{nil} otherwise.
If @code{:ascii} is non-@code{nil}, fullwidth equivalents of the Latin letters A through F
are excluded.
@end deffn
@anchor{Function sb-unicode default-ignorable-p}
@ffindex @sortas{default-ignorable-p sb-unicode} default-ignorable-p [sb-unicode]
@deffn{Function} sb-unicode:default-ignorable-p character
Returns @code{t} if @code{character} is a Default@emph{Ignorable}Code_Point
@end deffn
@anchor{Function sb-unicode grapheme-break-class}
@ffindex @sortas{grapheme-break-class sb-unicode} grapheme-break-class [sb-unicode]
@deffn{Function} sb-unicode:grapheme-break-class character
Returns the grapheme breaking class of @code{character}, as specified in UAX #29.
@end deffn
@anchor{Function sb-unicode word-break-class}
@ffindex @sortas{word-break-class sb-unicode} word-break-class [sb-unicode]
@deffn{Function} sb-unicode:word-break-class character
Returns the word breaking class of @code{character}, as specified in UAX #29.
@end deffn
@anchor{Function sb-unicode sentence-break-class}
@ffindex @sortas{sentence-break-class sb-unicode} sentence-break-class [sb-unicode]
@deffn{Function} sb-unicode:sentence-break-class character
Returns the sentence breaking class of @code{character}, as specified in UAX #29.
@end deffn
@anchor{Function sb-unicode line-break-class}
@ffindex @sortas{line-break-class sb-unicode} line-break-class [sb-unicode]
@deffn{Function} sb-unicode:line-break-class character &key resolve
Returns the line breaking class of @code{character}, as specified in UAX #14.
If @code{:resolve} is @code{nil}, returns the character class found in the property file.
If @code{:resolve} is non-@code{nil}, certain line-breaking classes will be mapped to other
classes as specified in the applicable standards. Additionally, if @code{:resolve}
is @code{:east-asian}, Ambigious (class @code{:ai}) characters will be mapped to the
Ideographic (@code{:id}) class instead of Alphabetic (@code{:al}).
@end deffn
@node string operations
@cindex normalization of strings
@subsection String operations
SBCL can normalize strings using:
@anchor{Function sb-unicode normalize-string}
@ffindex @sortas{normalize-string sb-unicode} normalize-string [sb-unicode]
@deffn{Function} sb-unicode:normalize-string string &optional form filter
Normalize @code{string} to the Unicode normalization form @code{form}.
Acceptable values for form are @code{:nfd}, @code{:nfc}, @code{:nfkd}, and @code{:nfkc}.
If @code{filter} is a function it is called on each decomposed character and
only characters for which it returns @code{t} are collected.
@end deffn
@anchor{Function sb-unicode normalized-p}
@ffindex @sortas{normalized-p sb-unicode} normalized-p [sb-unicode]
@deffn{Function} sb-unicode:normalized-p string &optional form
Tests if @code{string} is normalized to @code{form}
@end deffn
SBCL implements the full range of Unicode case operations with the
functions
@anchor{Function sb-unicode uppercase}
@ffindex @sortas{uppercase sb-unicode} uppercase [sb-unicode]
@deffn{Function} sb-unicode:uppercase string &key locale
Returns the full uppercase of @code{string} according to the Unicode standard.
The result is not guaranteed to have the same length as the input. If @code{:locale}
is @code{nil}, no language-specific case transformations are applied. If @code{:locale} is a
keyword representing a two-letter ISO country code, the case transforms of that
locale are used. If @code{:locale} is @code{t}, the user's current locale is used (Unix and
Win32 only).
@end deffn
@anchor{Function sb-unicode lowercase}
@ffindex @sortas{lowercase sb-unicode} lowercase [sb-unicode]
@deffn{Function} sb-unicode:lowercase string &key locale
Returns the full lowercase of @code{string} according to the Unicode standard.
The result is not guaranteed to have the same length as the input.
@code{:locale} has the same semantics as the @code{:locale} argument to @code{uppercase}.
@end deffn
@anchor{Function sb-unicode titlecase}
@ffindex @sortas{titlecase sb-unicode} titlecase [sb-unicode]
@deffn{Function} sb-unicode:titlecase string &key locale
Returns the titlecase of @code{string}. The resulting string can
be longer than the input.
@code{:locale} has the same semantics as the @code{:locale} argument to @code{uppercase}.
@end deffn
@anchor{Function sb-unicode casefold}
@ffindex @sortas{casefold sb-unicode} casefold [sb-unicode]
@deffn{Function} sb-unicode:casefold string
Returns the full casefolding of @code{string} according to the Unicode standard.
Casefolding removes case information in a way that allows the results to be used
for case-insensitive comparisons.
The result is not guaranteed to have the same length as the input.
@end deffn
It also extends standard Common Lisp case functions such as
@code{string-upcase} and @code{string-downcase} to support a subset of Unicode's
casing behavior. Specifically, a character is @code{both-case-p} if its
case mapping in Unicode is one-to-one and invertable.
The @code{sb-unicode} package also provides functions for
collating/sorting strings according to the Unicode Collation
Algorithm.
@anchor{Function sb-unicode unicode<}
@ffindex @sortas{unicode< sb-unicode} unicode< [sb-unicode]
@deffn{Function} sb-unicode:unicode< string1 string2 &key start1 end1 start2 end2
Determines whether @code{string1} sorts before @code{string2} using the Unicode Collation
Algorithm. The function uses an untailored Default Unicode Collation Element Table
to produce the sort keys. The function uses the Shifted method for dealing
with variable-weight characters, as described in UTS #10
@end deffn
@anchor{Function sb-unicode unicode=}
@ffindex @sortas{unicode= sb-unicode} unicode= [sb-unicode]
@deffn{Function} sb-unicode:unicode= string1 string2 &key start1 end1 start2 end2 strict
Determines whether @code{string1} and @code{string2} are canonically equivalent according
to Unicode. The @code{start} and @code{end} arguments behave like the arguments to @code{string=}.
If @code{:strict} is @code{nil}, @code{unicode=} tests compatibility equavalence instead.
@end deffn
@anchor{Function sb-unicode unicode-equal}
@ffindex @sortas{unicode-equal sb-unicode} unicode-equal [sb-unicode]
@deffn{Function} sb-unicode:unicode-equal string1 string2 &key start1 end1 start2 end2 strict
Determines whether @code{string1} and @code{string2} are canonically equivalent after
casefolding (that is, ignoring case differences) according to Unicode. The
@code{start} and @code{end} arguments behave like the arguments to @code{string=}. If @code{:strict} is
@code{nil}, @code{unicode=} tests compatibility equavalence instead.
@end deffn
@anchor{Function sb-unicode unicode<=}
@ffindex @sortas{unicode<= sb-unicode} unicode<= [sb-unicode]
@deffn{Function} sb-unicode:unicode<= string1 string2 &key start1 end1 start2 end2
Tests if @code{string1} and @code{string2} are either @code{unicode<} or @code{unicode=}
@end deffn
@anchor{Function sb-unicode unicode>}
@ffindex @sortas{unicode> sb-unicode} unicode> [sb-unicode]
@deffn{Function} sb-unicode:unicode> string1 string2 &key start1 end1 start2 end2
Tests if @code{string2} is @code{unicode<} @code{string1}.
@end deffn
@anchor{Function sb-unicode unicode>=}
@ffindex @sortas{unicode>= sb-unicode} unicode>= [sb-unicode]
@deffn{Function} sb-unicode:unicode>= string1 string2 &key start1 end1 start2 end2
Tests if @code{string1} and @code{string2} are either @code{unicode=} or @code{unicode>}
@end deffn
The following functions are provided for detecting visually
confusable strings:
@anchor{Function sb-unicode confusable-p}
@ffindex @sortas{confusable-p sb-unicode} confusable-p [sb-unicode]
@deffn{Function} sb-unicode:confusable-p string1 string2 &key start1 end1 start2 end2
Determines whether @code{string1} and @code{string2} could be visually confusable
according to the IDNA confusableSummary.txt table
@end deffn
@node breaking strings
@subsection Breaking strings
The @code{sb-unicode} package includes several functions for breaking a
Unicode string into useful parts.
@anchor{Function sb-unicode graphemes}
@ffindex @sortas{graphemes sb-unicode} graphemes [sb-unicode]
@deffn{Function} sb-unicode:graphemes string
Breaks @code{string} into graphemes according to the default
grapheme breaking rules specified in UAX #29, returning a list of strings.
@end deffn
@anchor{Function sb-unicode words}
@ffindex @sortas{words sb-unicode} words [sb-unicode]
@deffn{Function} sb-unicode:words string
Breaks @code{string} into words according to the default
word breaking rules specified in UAX #29. Returns a list of strings
@end deffn
@anchor{Function sb-unicode sentences}
@ffindex @sortas{sentences sb-unicode} sentences [sb-unicode]
@deffn{Function} sb-unicode:sentences string
Breaks @code{string} into sentences according to the default
sentence breaking rules specified in UAX #29
@end deffn
@anchor{Function sb-unicode lines}
@ffindex @sortas{lines sb-unicode} lines [sb-unicode]
@deffn{Function} sb-unicode:lines string &key margin
Breaks @code{string} into lines that are no wider than @code{:margin} according to the
line breaking rules outlined in UAX #14. Combining marks will always be kept
together with their base characters, and spaces (but not other types of
whitespace) will be removed from the end of lines. If @code{:margin} is unspecified,
it defaults to 80 characters
@end deffn
@node customization hooks for users
@section Customization Hooks for Users
The toplevel repl prompt may be customized, and the function
that reads user input may be replaced completely. See the @code{:toplevel}
argument of @code{sb-ext:save-lisp-and-die}.
The behaviour of @code{require} when called with only one argument is
implementation-defined. In SBCL, @code{require} behaves in the following
way:
@anchor{Function common-lisp require}
@ffindex @sortas{require common-lisp} require [common-lisp]
@deffn{Function} require module-name &optional pathnames
Loads a module, unless it already has been loaded. @code{pathnames}, if supplied,
is a designator for a list of pathnames to be loaded if the module
needs to be. If @code{pathnames} is not supplied, functions from the list
@code{*module-provider-functions*} are called in order with @code{module-name}
as an argument, until one of them returns non-@code{nil}. User code is
responsible for calling @code{provide} to indicate a successful load of the
module.
@end deffn
@anchor{Variable sb-ext *module-provider-functions*}
@vvindex @sortas{module-provider-functions* sb-ext} *module-provider-functions* [sb-ext]
@deffn{Variable} sb-ext:*module-provider-functions*
See @code{require}.
@end deffn
Although SBCL does not provide a resident editor, the @code{ed}
function can be customized to hook into user-provided editing
mechanisms as follows:
@anchor{Function common-lisp ed}
@ffindex @sortas{ed common-lisp} ed [common-lisp]
@deffn{Function} ed &optional x
Starts the editor (on a file or a function if named). Functions
from the list @code{*ed-functions*} are called in order with @code{x} as an argument
until one of them returns non-@code{nil}; these functions are responsible for
signalling a @code{file-error} to indicate failure to perform an operation on
the file system.
@end deffn
@anchor{Variable sb-ext *ed-functions*}
@vvindex @sortas{ed-functions* sb-ext} *ed-functions* [sb-ext]
@deffn{Variable} sb-ext:*ed-functions*
See @code{ed}.
@end deffn
Conditions of type @code{warning} and @code{style-warning} are sometimes signaled at
runtime, especially during execution of Common Lisp defining forms
such as @code{defun}, @code{defmethod}, etc. To muffle these warnings at runtime,
SBCL provides a variable @code{sb-ext:*muffled-warnings*}:
@anchor{Variable sb-ext *muffled-warnings*}
@vvindex @sortas{muffled-warnings* sb-ext} *muffled-warnings* [sb-ext]
@deffn{Variable} sb-ext:*muffled-warnings*
A type that ought to specify a subtype of @code{warning}. Whenever a
warning is signaled, if the warning is of this type and is not
handled by any other handler, it will be muffled.
@end deffn
@node tools to help developers
@section Tools To Help Developers
SBCL provides a profiler and other extensions to the @code{trace}
facility.
The debugger supports a number of options. Its documentation is
accessed by typing @code{help} at the debugger prompt. See @ref{debugger}.
Documentation for the command @code{inspect} is accessed by typing
@code{help} at the @code{inspect} prompt.
@node resolution of name conflicts
@section Resolution of Name Conflicts
@code{clhs} @code{11.1.1.2.5} requires that name conflicts in packages be
resolvable in favour of any of the conflicting symbols. In the
interactive debugger, this is achieved by prompting for the symbol
in whose favour the conflict should be resolved; for programmatic
use, the @code{sb-ext:resolve-conflict} restart should be invoked
with one argument, which should be a member of the list returned by
the condition accessor @code{sb-ext:name-conflict-symbols}.
@node hash table extensions
@section Hash Table Extensions
@cindex hash table
hash table extensions supported by SBCL are all controlled by keyword
arguments to @code{make-hash-table}.
@anchor{Function common-lisp make-hash-table}
@ffindex @sortas{make-hash-table common-lisp} make-hash-table [common-lisp]
@deffn{Function} make-hash-table &key test size rehash-size rehash-threshold hash-function weakness synchronized
Create and return a new hash table. The keywords are as follows:
@itemize
@item @code{:test}
Determines how keys are compared. Must a designator for one of
the standard hash table tests, or a hash table test defined
using @code{sb-ext:define-hash-table-test}. Additionally, when an
explicit @code{hash-function} is provided (see below), any two argument
equivalence predicate can be used as the @code{test}.
@item @code{:size}
A hint as to how many elements will be put in this hash table.
@item @code{:rehash-size}
Indicates how to expand the table when it fills up. If an
integer, add space for that many elements. If a floating point
number (which must be greater than 1.0), multiply the size by
that amount.
@item @code{:rehash-threshold}
Indicates how dense the table can become before forcing a
rehash. Can be any positive number <=1, with density approaching
zero as the threshold approaches 0. Density 1 means an average
of one entry per bucket.
@item @code{:hash-function}
If unsupplied, a hash function based on the @code{test} argument is
used, which then must be one of the standardized hash table test
functions, or one for which a default hash function has been
defined using @code{sb-ext:define-hash-table-test}. If @code{hash-function} is
specified, the @code{test} argument can be any two argument predicate
consistent with it. The @code{hash-function} is expected to return a
non-negative fixnum hash code. If @code{test} is neither standard nor
defined by @code{define-hash-table-test}, then the @code{hash-function} must
be specified.
@item @code{:weakness}
When @code{:weakness} is not @code{nil}, garbage collection may remove entries
from the hash table. The value of @code{:weakness} specifies how the
presence of a key or value in the hash table preserves their
entries from garbage collection.
Valid values are:
@itemize
@item @code{:key} means that the key of an entry must be live to guarantee
that the entry is preserved.
@item @code{:value} means that the value of an entry must be live to
guarantee that the entry is preserved.
@item @code{:key-and-value} means that both the key and the value must be
live to guarantee that the entry is preserved.
@item @code{:key-or-value} means that either the key or the value must be
live to guarantee that the entry is preserved.
@item @code{nil} (the default) means that entries are always preserved.
@end itemize
@item @code{:synchronized}
If @code{nil} (the default), the hash-table may have multiple
concurrent readers, but results are undefined if a thread writes
to the hash-table concurrently with another reader or writer. If
@code{t}, all concurrent accesses are safe, but note that CLHS
3.6 (Traversal Rules and Side Effects) remains in force. See
also: @code{sb-ext:with-locked-hash-table}.
@end itemize
@end deffn
@anchor{Macro sb-ext define-hash-table-test}
@ffindex @sortas{define-hash-table-test sb-ext} define-hash-table-test [sb-ext]
@deffn{Macro} sb-ext:define-hash-table-test name hash-function
Defines @code{name} as a new kind of hash table test for use with the @code{:test}
argument to @code{make-hash-table}, and associates a default @code{hash-function} with it.
@code{name} must be a symbol naming a global two argument equivalence predicate.
Afterwards both '@code{name} and #'@code{name} can be used with @code{:test} argument. In both
cases @code{hash-table-test} will return the symbol @code{name}.
@code{hash-function} must be a symbol naming a global hash function consistent with
the predicate, or be a @code{lambda} form implementing one in the current lexical
environment. The hash function must compute the same hash code for any two
objects for which @code{name} returns true, and subsequent calls with already hashed
objects must always return the same hash code.
@quotation
@emph{Note}: The @code{:hash-function} keyword argument to @code{make-hash-table} can
be used to override the specified default hash-function.
@end quotation
Attempting to define @code{name} in a locked package as hash-table test causes a
package lock violation.
Examples:
@example
;; We want to use objects of type FOO as keys (by their
;; names.) EQUALP would work, but would make the names
;; case-insensitive -- which we don't want.
(defstruct foo (name nil :type (or null string)))
;; Define an equivalence test function and a hash function.
(defun foo-name= (f1 f2) (equal (foo-name f1) (foo-name f2)))
(defun sxhash-foo-name (f) (sxhash (foo-name f)))
(define-hash-table-test foo-name= sxhash-foo-name)
;; #'foo-name would work too.
(defun make-foo-table () (make-hash-table :test 'foo-name=))
@end example
@example
(defun == (x y) (= x y))
(define-hash-table-test ==
(lambda (x)
;; Hash codes must be consistent with test, so
;; not (SXHASH X), since
;; (= 1 1.0) => T
;; (= (SXHASH 1) (SXHASH 1.0)) => NIL
;; Note: this doesn't deal with complex numbers or
;; bignums too large to represent as double floats.
(sxhash (coerce x 'double-float))))
;; #'== would work too
(defun make-number-table () (make-hash-table :test '==))
@end example
@end deffn
@anchor{Macro sb-ext with-locked-hash-table}
@ffindex @sortas{with-locked-hash-table sb-ext} with-locked-hash-table [sb-ext]
@deffn{Macro} sb-ext:with-locked-hash-table (hash-table) &body body
Limits concurrent accesses to @code{hash-table} for the duration of @code{body}.
If @code{hash-table} is synchronized, @code{body} will execute with exclusive
ownership of the table. If @code{hash-table} is not synchronized, @code{body} will
execute with other @code{with-locked-hash-table} bodies excluded -- exclusion
of hash-table accesses not surrounded by @code{with-locked-hash-table} is
unspecified.
@end deffn
@anchor{Function sb-ext hash-table-synchronized-p}
@ffindex @sortas{hash-table-synchronized-p sb-ext} hash-table-synchronized-p [sb-ext]
@deffn{Function} sb-ext:hash-table-synchronized-p ht
Returns @code{t} if @code{hash-table} is synchronized.
@end deffn
@anchor{Function sb-ext hash-table-weakness}
@ffindex @sortas{hash-table-weakness sb-ext} hash-table-weakness [sb-ext]
@deffn{Function} sb-ext:hash-table-weakness ht
Return the @code{weakness} of @code{hash-table} which is one of @code{nil}, @code{:key},
@code{:value}, @code{:key-and-value}, @code{:key-or-value}.
@end deffn
@node random number generation
@cindex random number generation
@section Random Number Generation
The initial value of @code{*random-state*} is the same each time SBCL
is started. This makes it possible for user code to obtain
repeatable pseudo random numbers using only standard-provided
functionality. See @code{sb-ext:seed-random-state} below for an SBCL
extension that allows to seed the random number generator from given
data for an additional possibility to achieve this. Non-repeatable
random numbers can always be obtained using (@code{make-random-state} @code{t}).
The sequence of numbers produced by repeated calls to @code{random}
starting with the same random state and using the same sequence of
@code{limit} arguments is guaranteed to be reproducible only in the same
version of SBCL on the same platform, using the same code under the
same evaluator mode and compiler optimization qualities. Just two
examples of differences that may occur otherwise: calls to @code{random}
can be compiled differently depending on how much is known about the
@code{limit} argument at compile time, yielding different results even if
called with the same argument at run time, and the results can
differ depending on the machine's word size, for example for limits
that are fixnums under 64-bit word size but bignums under 32-bit
word size.
@anchor{Function sb-ext seed-random-state}
@ffindex @sortas{seed-random-state sb-ext} seed-random-state [sb-ext]
@deffn{Function} sb-ext:seed-random-state &optional state
Make a random state object. The optional @code{state} argument specifies a seed
for deterministic pseudo-random number generation.
As per the Common Lisp standard for @code{make-random-state},
@itemize
@item If @code{state} is @code{nil} or not supplied, return a copy of the default
@code{*random-state*}.
@item If @code{state} is a random state, return a copy of it.
@item If @code{state} is @code{t}, return a randomly initialized state (using operating-system
provided randomness where available, otherwise a poor substitute based on
internal time and pid).
@end itemize
As a supported SBCL extension, we also support receiving as a seed an object
of the following types:
@itemize
@item (@code{simple-array} (@code{unsigned-byte} 8) (*))
@item @code{unsigned-byte}
@end itemize
While we support arguments of any size and will mix the provided bits into
the random state, it is probably overkill to provide more than 256 bits worth
of actual information.
This particular SBCL version also accepts an argument of the following type:
(@code{simple-array} (@code{unsigned-byte} 32) (*))
This particular SBCL version uses the popular MT19937 PRNG algorithm, and its
internal state only effectively contains about 19937 bits of information.
@url{http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html}
@end deffn
Some notes on random floats: The standard doesn't prescribe a specific
method of generating random floats. The following paragraph
describes SBCL's current implementation and should be taken as
purely informational, that is, user code should not depend on any of
its specific properties. The method used has been chosen because it
is common, conceptually simple and fast.
To generate random floats, SBCL evaluates code that has an equivalent
effect as
@example
(* limit
(float (/ (random (expt 2 23)) (expt 2 23)) 1.0f0))
@end example
(for @code{single-float}s) and correspondingly (with @code{52} and @code{1.0d0}
instead of @code{23} and @code{1.0f0}) for @code{double-float}s. Note especially that
this means that zero is a possible return value occurring with
probability @code{(expt 2 -23)} and @code{(expt 2 -52)}, respectively. Also
note that there exist twice as many equidistant floats between 0 and
1 as are generated. For example, the largest number that
@code{(random 1.0f0)} ever returns is @code{(float (/ (1- (expt 2 23)) (expt 2
23)) 1.0f0)} while @code{(float (/ (1- (expt 2 24)) (expt 2 24)) 1.0f0)}
is the largest @code{single-float} less than 1. This is a side effect of
the fact that the implementation uses the fastest possible
conversion from bits to floats.
SBCL currently uses the Mersenne Twister as its random number
generator, specifically the 32-bit version under both 32- and 64-bit
word size. The seeding algorithm has been improved several times by
the authors of the Mersenne Twister; SBCL uses the third version
(from 2002), which is still the most recent as of June 2012. The
implementation has been tested to provide output identical to the
recommended C implementation.
While the Mersenne Twister generates random numbers of much better
statistical quality than other widely used generators, it uses only
linear operations modulo 2 and thus fails some statistical
tests.
(See chapter 7 @emph{Testing widely used RNGs} in @emph{TestU01: A C Library
for Empirical Testing of Random Number Generators} by Pierre
L'Ecuyer and Richard Simard, ACM Transactions on Mathematical
Software, Vol. 33, article 22, 2007.)
For example, the distribution of ranks of (sufficiently large)
random binary matrices is much distorted compared to the
theoretically expected one when the matrices are generated by the
Mersenne Twister. Thus, applications that are sensitive to this
aspect should use a different type of generator.
@node timeouts and deadlines
@section Timeouts and Deadlines
@menu
* Timeout Parameters: timeout parameters.
* Synchronous Timeouts: synchronous timeouts.
* Asynchronous Timeouts: asynchronous timeouts.
* Operations Supporting Timeouts and Deadlines: operations supporting timeouts and deadlines.
@end menu
SBCL supports three different ways of restricting the execution time
available to individual operations or parts of computations:
@itemize
@item @emph{Timeout Parameters}: Some operations such as thread
synchronization primitives accept a @code{:timeout} parameter. See
@ref{timeout parameters}.
@item @emph{Synchronous Timeouts (Deadlines)}: Certain operations that may
suspend execution for extended periods of time such as @code{cl:sleep},
thread synchronization primitives, IO and waiting for external
processes respect deadlines established for a part of a
computation. See @ref{synchronous timeouts}.
@item @emph{Asynchronous Timeouts}: Asynchronous timeouts can interrupt most
computations at (almost) any point. Thus, this kind of timeouts is
the most versatile but it is also somewhat unsafe. See
@ref{asynchronous timeouts}.
@end itemize
@node timeout parameters
@cindex timeout parameters
@subsection Timeout Parameters
Certain operations accept @code{:timeout} keyword arguments. These only
affect the specific operation and must be specified at each call
site by passing a @code{:timeout} keyword argument and a corresponding
timeout value to the respective operation. Expiration of the timeout
before the operation completes results in either a normal return
with a return value indicating the timeout or in the signaling of a
specialized condition such as @code{sb-thread:join-thread-error}.
Example:
@example
(defun join-thread-within-5-seconds (thread)
(multiple-value-bind (value result)
(sb-thread:join-thread thread :default nil :timeout 5)
(when (eq result :timeout)
(error "Could not join ~A within 5 seconds" thread))
value))
@end example
The above code attempts to join the specified thread for up to five
seconds, returning its value in case of success. If the thread is
still running after the five seconds have elapsed,
@code{sb-thread:join-thread} indicates the timeout in its second return
value. If a @code{:default} value was not provided, @code{sb-thread:join-thread}
would signal a @code{sb-thread:join-thread-error} instead.
To wait for an arbitrary condition, optionally with a timeout, the
@code{sb-ext:wait-for} macro can be used:
@anchor{Macro sb-ext wait-for}
@ffindex @sortas{wait-for sb-ext} wait-for [sb-ext]
@deffn{Macro} sb-ext:wait-for test-form &key timeout
Wait until @code{test-form} evaluates to true, then return its primary value.
If @code{timeout} is provided, waits at most approximately @code{timeout} seconds before
returning @code{nil}.
If @code{with-deadline} has been used to provide a global deadline, signals a
@code{deadline-timeout} if @code{test-form} doesn't evaluate to true before the
deadline.
Experimental: subject to change without prior notice.
@end deffn
@node synchronous timeouts
@cindex synchronous timeout
@cindex timeout, synchronous
@cindex deadline
@subsection Synchronous Timeouts
Deadlines, in contrast to timeout parameters, are established for a
dynamic scope using the @code{sb-sys:with-deadline} macro and indirectly
affect operations within that scope. In case of nested uses, the
effective deadline is the one that expires first unless an inner use
explicitly overrides outer deadlines.
@anchor{Macro sb-sys with-deadline}
@ffindex @sortas{with-deadline sb-sys} with-deadline [sb-sys]
@deffn{Macro} sb-sys:with-deadline (&key seconds override) &body body
Arranges for a @code{timeout} condition to be signalled if an operation
respecting deadlines occurs either after the deadline has passed, or
would take longer than the time left to complete.
Currently only @code{sleep}, blocking IO operations, @code{sb-thread:get-mutex}, and
@code{sb-thread:condition-wait} respect deadlines, but this includes their
implicit uses inside SBCL itself.
Unless @code{override} is true, existing deadlines can only be restricted,
not extended. Deadlines are per thread: children are unaffected by
their parent's deadlines.
Experimental.
@end deffn
Expiration of deadlines set up this way only has an effect when it
happens before or during the execution of a deadline-aware operation
(@ref{operations supporting timeouts and deadlines}). In this case, a
@code{sb-sys:deadline-timeout} is signaled. A handler for this condition
type may use the @code{sb-sys:defer-deadline} or @code{sb-sys:cancel-deadline}
restarts to defer or cancel the deadline respectively and resume
execution of the interrupted operation.
@anchor{Condition sb-sys deadline-timeout}
@ttindex @sortas{deadline-timeout sb-sys} deadline-timeout [sb-sys]
@deffn{Condition} sb-sys:deadline-timeout
Signaled when an operation in the context of a deadline takes
longer than permitted by the deadline.
@end deffn
@anchor{Function sb-sys defer-deadline}
@ffindex @sortas{defer-deadline sb-sys} defer-deadline [sb-sys]
@deffn{Function} sb-sys:defer-deadline seconds &optional condition
Find the @code{defer-deadline} restart associated with @code{condition}, and
invoke it with @code{seconds} as argument (deferring the deadline by that many
seconds.) Otherwise return @code{nil} if the restart is not found.
@end deffn
@anchor{Function sb-sys cancel-deadline}
@ffindex @sortas{cancel-deadline sb-sys} cancel-deadline [sb-sys]
@deffn{Function} sb-sys:cancel-deadline &optional condition
Find and invoke the @code{cancel-deadline} restart associated with
@code{condition}, or return @code{nil} if the restart is not found.
@end deffn
When a thread is executing the debugger, signaling of
@code{sb-sys:deadline-timeout} conditions for that thread is deferred until
it exits the debugger.
Example:
@example
(defun read-input ()
(list (read-line) (read-line)))
(defun do-it ()
(sb-sys:with-deadline (:seconds 5))
(read-input)
(sleep 2)
(sb-ext:run-program "my-program"))
@end example
The above code establishes a deadline of five seconds within which
the body of the @code{do-it} function should execute. All calls of
deadline-aware functions in the dynamic scope, in this case two
@code{read-line} calls, a @code{sleep} call and a @code{sb-ext:run-program} call, are
affected by the deadline. If, for example, the first @code{read-line} call
completes in one second and the second @code{read-line} call completes in
three seconds, a @code{sb-sys:deadline-timeout} condition will be signaled
after the @code{sleep} call has been executing for one second.
@node asynchronous timeouts
@cindex asynchronous timeout
@cindex timeout, asynchronous
@subsection Asynchronous Timeouts
Asynchronous timeouts are established for a dynamic scope using the
@code{sb-ext:with-timeout} macro:
@anchor{Macro sb-ext with-timeout}
@ffindex @sortas{with-timeout sb-ext} with-timeout [sb-ext]
@deffn{Macro} sb-ext:with-timeout expires &body body
Execute the body, asynchronously interrupting it and signalling a @code{timeout}
condition after at least @code{expires} seconds have passed.
Note that it is never safe to unwind from an asynchronous condition. Consider:
@example
(defun call-with-foo (function)
(let (foo)
(unwind-protect
(progn
(setf foo (get-foo))
(funcall function foo))
(when foo
(release-foo foo)))))
@end example
If @code{timeout} occurs after @code{get-foo} has executed, but before the
assignment, then @code{release-foo} will be missed. While individual sites
like this can be made proof against asynchronous unwinds, this doesn't
solve the fundamental issue, as all the frames potentially unwound
through need to be proofed, which includes both system and application
code -- and in essence proofing everything will make the system
uninterruptible.
@end deffn
Expiration of the timeout will cause the operation being executed at
that moment to be interrupted by an asynchronously signaled
@code{sb-ext:timeout} condition, (almost) irregardless of the operation
and its context.
@anchor{Condition sb-ext timeout}
@ttindex @sortas{timeout sb-ext} timeout [sb-ext]
@deffn{Condition} sb-ext:timeout
Signaled when an operation does not complete within an allotted time budget.
@end deffn
@node operations supporting timeouts and deadlines
@subsection Operations Supporting Timeouts and Deadlines
@example
| Operation | Timeout parameter | Affected by deadlines |
|------------------------+-------------------+-----------------------|
| cl:sleep | - | since SBCL 1.4.3 |
| cl:read-line, etc. | no | yes |
| wait-for | yes | yes |
| process-wait | no | yes |
| grab-mutex | yes | yes |
| condition-wait | yes | yes |
| wait-on-semaphore | yes | yes |
| join-thread | yes | yes |
| receive-message | yes | yes? |
| wait-on-gate | yes | yes? |
| frlock-write | yes | yes? |
| grab-frlock-write-lock | yes | yes? |
@end example
@node miscellaneous extensions
@section Miscellaneous Extensions
@anchor{Function sb-ext array-storage-vector}
@ffindex @sortas{array-storage-vector sb-ext} array-storage-vector [sb-ext]
@deffn{Function} sb-ext:array-storage-vector array
Returns the underlying storage vector of @code{array}, which must be a non-displaced array.
In SBCL, if @code{array} is a of type (@code{simple-array} * (*)), it is its own storage
vector. Multidimensional arrays, arrays with fill pointers, and adjustable
arrays have an underlying storage vector with the same @code{array-element-type} as
@code{array}, which this function returns.
@quotation
@emph{Note}: the underlying vector is an implementation detail. Even
though this function exposes it, changes in the implementation may
cause this function to be removed without further warning.
@end quotation
@end deffn
@anchor{Function sb-ext delete-directory}
@ffindex @sortas{delete-directory sb-ext} delete-directory [sb-ext]
@deffn{Function} sb-ext:delete-directory pathspec &key recursive
Deletes the directory designated by @code{pathspec} (a pathname designator).
Returns the truename of the directory deleted.
If @code{recursive} is false (the default), signals an error unless the directory is
empty. If @code{recursive} is true, first deletes all files and subdirectories. If
@code{recursive} is true and the directory contains symbolic links, the links are
deleted, not the files and directories they point to.
Signals an error if @code{pathspec} designates a file or a symbolic link instead of a
directory, or if the directory could not be deleted for any reason.
Both
@example
(DELETE-DIRECTORY "/tmp/foo")
(DELETE-DIRECTORY "/tmp/foo/")
@end example
delete the @code{"foo"} subdirectory of @code{"/tmp"}, or signal an error if
it does not exist or if is a file or a symbolic link.
@end deffn
@anchor{Function sb-ext get-time-of-day}
@ffindex @sortas{get-time-of-day sb-ext} get-time-of-day [sb-ext]
@deffn{Function} sb-ext:get-time-of-day
Return the number of seconds and microseconds since the beginning of
the UNIX epoch (January 1st 1970.)
@end deffn
@anchor{Function sb-ext assert-version->=}
@ffindex @sortas{assert-version->= sb-ext} assert-version->= [sb-ext]
@deffn{Function} sb-ext:assert-version->= &rest subversions
Asserts that the current SBCL is of version equal to or greater than
the version specified in the arguments. A continuable error is signaled
otherwise.
The arguments specify a sequence of subversion numbers in big endian order.
They are compared lexicographically with the runtime version, and versions
are treated as though trailed by an unbounded number of 0s.
For example, (@code{assert-version->=} 1 1 4) asserts that the current SBCL
is version 1.1.4[.0.0...] or greater, and (@code{assert-version->=} 1) that
it is version 1[.0.0...] or greater.
@end deffn
@anchor{Function sb-ext unencapsulated-function}
@ffindex @sortas{unencapsulated-function sb-ext} unencapsulated-function [sb-ext]
@deffn{Function} sb-ext:unencapsulated-function function
Return the innermost function within any encapsulations of the
function designated by @code{function}. The identity of the returned
function is not affected by encapsulations.
Note that the unencapsulated function may be @code{eq} to the designated
function even in the presence of encapsulations. For generic
functions, this is currently always the case.
@end deffn
@anchor{Generic function common-lisp documentation}
@ffindex @sortas{documentation common-lisp} documentation [common-lisp]
@deffn{Generic function} documentation object doc-type
Return the documentation string of @code{doc-type} for @code{object},
or @code{nil} if none exists. In addition to the @code{doc-type}s and methods
required by ANSI, SBCL's @code{documentation} (and its @code{setf}) supports methods
with the following signatures:
@itemize
@item @code{(object symbol) (doc-type (eql declaration))}
@item @code{(object sb-mop:slot-definition) (doc-type (eql t))}
@end itemize
Since @code{condition}s are implemented as classes in SBCL, the following
also work:
@itemize
@item @code{(object condition) (doc-type (eql t))}
@item @code{(object condition) (doc-type (eql 'type))}
@end itemize
Function documentation is stored separately for function names and objects:
@code{defun}, @code{lambda}, &co create function objects with the specified documentation
strings.
@example
(setf (documentation name 'function) string)
@end example
sets the documentation string stored under the specified name, and
@example
(setf (documentation func t) string)
@end example
sets the documentation string stored in the function object.
@example
(documentation name 'function)
@end example
returns the documentation stored under the function name if any, and
falls back on the documentation in the function object if necessary.
@end deffn
@node stale extensions
@section Stale Extensions
SBCL has inherited from CMUCL various hooks to allow the user to
tweak and monitor the garbage collection process. These are somewhat
stale code, and their interface might need to be cleaned up. If you
have urgent need of them, look at the code in @code{src/code/gc.lisp} and
bring it up on the developers' mailing list.
SBCL has various hooks inherited from CMUCL, like
@code{sb-ext:float-denormalized-p}, to allow a program to take advantage of
IEEE floating point arithmetic properties which aren't conveniently
or efficiently expressible using the ANSI standard. These look good,
and their interface looks good, but IEEE support is slightly broken
due to a stupid decision to remove some support for infinities
(because it wasn't in the ANSI spec and it didn't occur to me that
it was in the IEEE spec). If you need this stuff, take a look at the
code and bring it up on the developers' mailing list.
@node efficiency hacks
@section Efficiency Hacks
@cindex garbage collector, generational
@cindex generational garbage collector
The @code{sb-ext:purify} function (available when @code{#+cheneygc}) causes
SBCL first to collect all garbage, then to mark all uncollected
objects as permanent, never again attempting to collect them as
garbage. This can cause a large increase in efficiency when using a
primitive garbage collector, or a more moderate increase in
efficiency when using a more sophisticated garbage collector which
is well suited to the program's memory usage pattern. It also allows
permanent code to be frozen at fixed addresses, a precondition for
using copy-on-write to share code between multiple Lisp processes.
This is less important with modern generational GC, but not all
SBCL platforms use such a garbage collector.
The @code{sb-ext:truly-the} special form declares the type of the result of
the operations, producing its argument; the declaration is not
checked. In short: don't use it.
The @code{sb-ext:freeze-type} declaration declares that a type will never
change, which can make type testing (e.g. with @code{typep}) more efficient
for structure types.