mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
2774 lines
120 KiB
Plaintext
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.
|
|
|