Next: Getting Support and Reporting Bugs, Up: (dir) [Contents][Index]
This manual is part of the SBCL software system. See the README file for more information.
This manual is largely derived from the manual for the CMUCL system, which was produced at Carnegie Mellon University and later released into the public domain. This manual is in the public domain and is provided with absolutely no warranty. See the COPYING and CREDITS files for more information.
| • Getting Support and Reporting Bugs: | ||
| • Introduction: | ||
| • Starting and Stopping: | ||
| • Compiler: | ||
| • Debugger: | ||
| • Efficiency: | ||
| • Beyond the ANSI Standard: | ||
| • External Formats: | ||
| • Foreign Function Interface: | ||
| • Pathnames: | ||
| • Streams: | ||
| • Package Locks: | ||
| • Threading: | ||
| • Timers: | ||
| • Networking: | ||
| • Profiling: | ||
| • Contributed Modules: | ||
| • Deprecation: | ||
| • Concept Index: | ||
| • Function Index: | ||
| • Variable Index: | ||
| • Type Index: | ||
| • Colophon: |
Next: Introduction, Previous: Top, Up: Top [Contents][Index]
| • Volunteer Support: | ||
| • Commercial Support: | ||
| • Reporting Bugs: |
Next: Commercial Support, Up: Getting Support and Reporting Bugs [Contents][Index]
Your primary source of SBCL support should probably be the mailing list sbcl-help: in addition to other users SBCL developers monitor this list and are available for advice. As an anti-spam measure subscription is required for posting:
https://lists.sourceforge.net/lists/listinfo/sbcl-help
Remember that the people answering your question are volunteers, so you stand a much better chance of getting a good answer if you ask a good question.
Before sending mail, check the list archives at either
http://sourceforge.net/mailarchive/forum.php?forum_name=sbcl-help
or
http://news.gmane.org/gmane.lisp.steel-bank.general
to see if your question has been answered already. Checking the bug database is also worth it See Reporting Bugs, to see if the issue is already known.
For general advice on asking good questions, see
http://www.catb.org/~esr/faqs/smart-questions.html.
Next: Reporting Bugs, Previous: Volunteer Support, Up: Getting Support and Reporting Bugs [Contents][Index]
There is no formal organization developing SBCL, but if you need a paid support arrangement or custom SBCL development, we maintain the list of companies and consultants below. Use it to identify service providers with appropriate skills and interests, and contact them directly.
The SBCL project cannot verify the accuracy of the information or the competence of the people listed, and they have provided their own blurbs below: you must make your own judgement of suitability from the available information - refer to the links they provide, the CREDITS file, mailing list archives, CVS commit messages, and so on. Please feel free to ask for advice on the sbcl-help list.
(At present, no companies or consultants wish to advertise paid support or custom SBCL development in this manual).
Previous: Commercial Support, Up: Getting Support and Reporting Bugs [Contents][Index]
SBCL uses Launchpad to track bugs. The bug database is available at
https://bugs.launchpad.net/sbcl
Reporting bugs there requires registering at Launchpad. However, bugs can also be reported on the mailing list sbcl-bugs, which is moderated but does not require subscribing.
Simply send email to sbcl-bugs@lists.sourceforge.net and the bug will be checked and added to Launchpad by SBCL maintainers.
Please include enough information in a bug report that someone reading it can reproduce the problem, i.e. don’t write
Subject: apparent bug in PRINT-OBJECT (or *PRINT-LENGTH*?) PRINT-OBJECT doesn't seem to work with *PRINT-LENGTH*. Is this a bug?
but instead
Subject: apparent bug in PRINT-OBJECT (or *PRINT-LENGTH*?)
In sbcl-1.2.3 running under OpenBSD 4.5 on my Alpha box, when
I compile and load the file
(DEFSTRUCT (FOO (:PRINT-OBJECT (LAMBDA (X Y)
(LET ((*PRINT-LENGTH* 4))
(PRINT X Y)))))
X Y)
then at the command line type
(MAKE-FOO)
the program loops endlessly instead of printing the object.
A more in-depth discussion on reporting bugs effectively can be found at
http://www.chiark.greenend.org.uk/~sgtatham/bugs.html.
If you run into a signal related bug, you are getting fatal errors
such as signal N is [un]blocked or just hangs, and you want to
send a useful bug report then:
:sb-ldb, see
base-target-features.lisp-expr) and change #define
QSHOW_SIGNAL 0 to #define QSHOW_SIGNAL 1 in
src/runtime/runtime.h.
kill -ABRT <pidof sbcl>.
ba.
gdb -p <pidof sbcl> and get backtraces for all threads:
thread apply all ba.
thread apply all call
backtrace_from_fp($ebp, 100). Substitute $ebp with $rbp
on x86-64. The backtraces will appear in the stdout of the SBCL
process.
Next: Starting and Stopping, Previous: Getting Support and Reporting Bugs, Up: Top [Contents][Index]
SBCL is a mostly-conforming implementation of the ANSI Common Lisp standard. This manual focuses on behavior which is specific to SBCL, not on behavior which is common to all implementations of ANSI Common Lisp.
| • ANSI Conformance: | ||
| • Extensions: | ||
| • Idiosyncrasies: | ||
| • Development Tools: | ||
| • More SBCL Information: | ||
| • More Common Lisp Information: | ||
| • History and Implementation of SBCL: |
Next: Extensions, Up: Introduction [Contents][Index]
Essentially every type of non-conformance is considered a bug. (The exceptions involve internal inconsistencies in the standard.) See Reporting Bugs.
Next: Idiosyncrasies, Previous: ANSI Conformance, Up: Introduction [Contents][Index]
SBCL comes with numerous extensions, some in core and some in modules
loadable with require. Unfortunately, not all of these
extensions have proper documentation yet.
asdf is a flexible and popular protocol-oriented system
definition tool by Daniel Barlow. See (asdf)the asdf manual, for
more information.
sb-alien package allows interfacing with C-code, loading shared
object files, etc. See Foreign Function Interface.
sb-grovel can be used to partially automate generation of
foreign function interface definitions. See sb-grovel.
SBCL provides a recursive event loop (serve-event) for doing
non-blocking IO on multiple streams without using threads.
SBCL allows restricting the execution time of individual operations or
parts of a computation using :timeout arguments to certain
blocking operations, synchronous timeouts and asynchronous timeouts. The
latter two affect operations without explicit timeout support (such as
standard functions and macros). See Timeouts and Deadlines.
sb-mop package provides a metaobject protocol for the Common
Lisp Object System as described in Art of Metaobject Protocol.
SBCL allows users to define subclasses of the sequence
class. See Extensible Sequences.
SBCL has native threads on x86/Linux, capable of taking advantage of SMP on multiprocessor machines. See Threading.
sb-bsd-sockets is a low-level networking interface, providing
both TCP and UDP sockets. See Networking.
sb-introspect module offers numerous introspective extensions,
including access to function lambda-lists and a cross referencing
facility.
sb-ext contains a number of functions for running external
processes, accessing environment variables, etc.
sb-posix module provides a lispy interface to standard POSIX
facilities.
sb-gray is an implementation of Gray Streams. See Gray Streams.
sb-simple-streams is an implementation of the simple
streams API proposed by Franz Inc. See Simple Streams.
sb-profile is a exact per-function profiler. See Deterministic Profiler.
sb-sprof is a statistical profiler, capable of call-graph
generation and instruction level profiling, which also supports
allocation profiling. See Statistical Profiler.
SBCL contains a number of extra-standard customization hooks that can be used to tweak the behaviour of the system. See Customization Hooks for Users.
sb-aclrepl provides an Allegro CL -style toplevel for SBCL,
as an alternative to the classic CMUCL-style one. See sb-aclrepl.
sb-cltl2 module provides compiler-let and environment
access functionality described in Common Lisp The Language, 2nd
Edition which were removed from the language during the ANSI
standardization process.
The :executable argument to Function sb-ext save-lisp-and-die can produce a ‘standalone’ executable
containing both an image of the current Lisp session and an SBCL
runtime.
sb-rotate-byte provides an efficient primitive for bitwise
rotation of integers, an operation required by e.g. numerous
cryptographic algorithms, but not available as a primitive in ANSI
Common Lisp. See sb-rotate-byte.
sb-rt module is a simple yet attractive regression and
unit-test framework.
sb-md5 is an implementation of the MD5 message digest algorithm
for Common Lisp, using the modular arithmetic optimizations provided
by SBCL. See sb-md5.
Next: Development Tools, Previous: Extensions, Up: Introduction [Contents][Index]
The information in this section describes some of the ways that SBCL deals with choices that the ANSI standard leaves to the implementation.
| • Declarations: | ||
| • FASL Format: | ||
| • Compiler-only Implementation: | ||
| • Defining Constants: | ||
| • Style Warnings: |
Next: FASL Format, Up: Idiosyncrasies [Contents][Index]
Declarations are generally treated as assertions. This general principle, and its implications, and the bugs which still keep the compiler from quite satisfying this principle, are discussed in Declarations as Assertions.
Next: Compiler-only Implementation, Previous: Declarations, Up: Idiosyncrasies [Contents][Index]
SBCL fasl-format is binary compatible only with the exact SBCL version it was generated with. While this is obviously suboptimal, it has proven more robust than trying to maintain fasl compatibility across versions: accidentally breaking things is far too easy, and can lead to hard to diagnose bugs.
The following snippet handles fasl recompilation automatically for ASDF-based systems, and makes a good candidate for inclusion in the user or system initialization file (see Initialization Files.)
(require :asdf)
;;; If a fasl was stale, try to recompile and load (once).
(defmethod asdf:perform :around ((o asdf:load-op)
(c asdf:cl-source-file))
(handler-case (call-next-method o c)
;; If a fasl was stale, try to recompile and load (once).
(sb-ext:invalid-fasl ()
(asdf:perform (make-instance 'asdf:compile-op) c)
(call-next-method))))
Next: Defining Constants, Previous: FASL Format, Up: Idiosyncrasies [Contents][Index]
SBCL is essentially a compiler-only implementation of Common Lisp.
That is, for all but a few special cases, eval creates a lambda
expression, calls compile on the lambda expression to create a
compiled function, and then calls funcall on the resulting
function object. A more traditional interpreter is also available on
default builds; it is usually only called internally. This is
explicitly allowed by the ANSI standard, but leads to some oddities;
e.g. at default settings, functionp and
compiled-function-p are equivalent, and they collapse into the
same function when SBCL is built without the interpreter.
Next: Style Warnings, Previous: Compiler-only Implementation, Up: Idiosyncrasies [Contents][Index]
SBCL is quite strict about ANSI’s definition of defconstant.
ANSI says that doing defconstant of the same symbol more than
once is undefined unless the new value is eql to the old value.
Conforming to this specification is a nuisance when the “constant”
value is only constant under some weaker test like string= or
equal.
It’s especially annoying because, in SBCL, defconstant takes
effect not only at load time but also at compile time, so that just
compiling and loading reasonable code like
(defconstant +foobyte+ '(1 4))
runs into this undefined behavior. Many implementations of Common Lisp try to help the programmer around this annoyance by silently accepting the undefined code and trying to do what the programmer probably meant.
SBCL instead treats the undefined behavior as an error. Often such
code can be rewritten in portable ANSI Common Lisp which has the
desired behavior. E.g., the code above can be given an exactly defined
meaning by replacing defconstant either with
defparameter or with a customized macro which does the right
thing, e.g.
(defmacro define-constant (name value &optional doc)
`(defconstant ,name (if (boundp ',name) (symbol-value ',name) ,value)
,@(when doc (list doc))))
or possibly along the lines of the defconstant-eqx macro used
internally in the implementation of SBCL itself. In circumstances
where this is not appropriate, the programmer can handle the condition
type sb-ext:defconstant-uneql, and choose either the
continue or abort restart as appropriate.
Previous: Defining Constants, Up: Idiosyncrasies [Contents][Index]
SBCL gives style warnings about various kinds of perfectly legal code, e.g.
defuns of the same symbol in different units;
*foo* style,
and lexical variables unconventionally named in the *foo* style
This causes friction with people who point out that other ways of
organizing code (especially avoiding the use of defgeneric) are
just as aesthetically stylish. However, these warnings should be read
not as “warning, bad aesthetics detected, you have no style” but
“warning, this style keeps the compiler from understanding the code
as well as you might like.” That is, unless the compiler warns about
such conditions, there’s no way for the compiler to warn about some
programming errors which would otherwise be easy to overlook. (Related
bug: The warning about multiple defuns is pointlessly annoying
when you compile and then load a function containing defun
wrapped in eval-when, and ideally should be suppressed in that
case, but still isn’t as of SBCL 0.7.6.)
Next: More SBCL Information, Previous: Idiosyncrasies, Up: Introduction [Contents][Index]
| • Editor Integration: | ||
| • Language Reference: | ||
| • Generating Executables: |
Next: Language Reference, Up: Development Tools [Contents][Index]
Though SBCL can be used running “bare”, the recommended mode of development is with an editor connected to SBCL, supporting not only basic lisp editing (paren-matching, etc), but providing among other features an integrated debugger, interactive compilation, and automated documentation lookup.
Currently SLIME1 (Superior Lisp Interaction Mode for Emacs) together with Emacs is recommended for use with SBCL, though other options exist as well.
SLIME can be downloaded from http://www.common-lisp.net/project/slime/.
Next: Generating Executables, Previous: Editor Integration, Up: Development Tools [Contents][Index]
CLHS (Common Lisp Hyperspec) is a hypertext version of the ANSI standard, made freely available by LispWorks – an invaluable reference.
See: http://www.lispworks.com/reference/HyperSpec/index.html
Previous: Language Reference, Up: Development Tools [Contents][Index]
SBCL can generate stand-alone executables. The generated executables
include the SBCL runtime itself, so no restrictions are placed on
program functionality. For example, a deployed program can call
compile and load, which requires the compiler to be present
in the executable. For further information, See Function sb-ext save-lisp-and-die.
Next: More Common Lisp Information, Previous: Development Tools, Up: Introduction [Contents][Index]
| • SBCL Homepage: | ||
| • Online Documentation: | ||
| • Additional Documentation Files: | ||
| • Internals Documentation: |
Next: Online Documentation, Up: More SBCL Information [Contents][Index]
The SBCL website at http://www.sbcl.org/ has some general information, plus links to mailing lists devoted to SBCL, and to archives of these mailing lists. Subscribing to the mailing lists sbcl-help and sbcl-announce is recommended: both are fairly low-volume, and help you keep abreast with SBCL development.
Next: Additional Documentation Files, Previous: SBCL Homepage, Up: More SBCL Information [Contents][Index]
Documentation for non-ANSI extensions for various commands is
available online from the SBCL executable itself. The extensions
for functions which have their own command prompts (e.g. the debugger,
and inspect) are documented in text available by typing
help at their command prompts. The extensions for functions
which don’t have their own command prompt (such as trace) are
described in their documentation strings, unless your SBCL was
compiled with an option not to include documentation strings, in which
case the documentation strings are only readable in the source code.
Next: Internals Documentation, Previous: Online Documentation, Up: More SBCL Information [Contents][Index]
Besides this user manual both SBCL source and binary distributions include some other SBCL-specific documentation files, which should be installed along with this manual on your system, e.g. in /usr/local/share/doc/sbcl/.
Licence and copyright summary.
Authorship information on various parts of SBCL.
Covers installing SBCL from both source and binary distributions on your system, and also has some installation related troubleshooting information.
Summarizes changes between various SBCL versions.
Previous: Additional Documentation Files, Up: More SBCL Information [Contents][Index]
If you’re interested in the development of the SBCL system itself, then subscribing to sbcl-devel is a good idea.
SBCL internals documentation – besides comments in the source – is currently maintained as a wiki-like website: http://sbcl-internals.cliki.net/.
Some low-level information describing the programming details of the conversion from CMUCL to SBCL is available in the doc/FOR-CMUCL-DEVELOPERS file in the SBCL distribution, though it is not installed by default.
Next: History and Implementation of SBCL, Previous: More SBCL Information, Up: Introduction [Contents][Index]
| • Internet Community: | ||
| • Third-party Libraries: | ||
| • Common Lisp Books: |
Next: Third-party Libraries, Up: More Common Lisp Information [Contents][Index]
The Common Lisp internet community is fairly diverse: news://comp.lang.lisp is fairly high volume newsgroup, but has a rather poor signal/noise ratio. Various special interest mailing lists and IRC tend to provide more content and less flames. http://www.lisp.org and http://www.cliki.net contain numerous pointers places in the net where lispers talks shop.
Next: Common Lisp Books, Previous: Internet Community, Up: More Common Lisp Information [Contents][Index]
For a wealth of information about free Common Lisp libraries and tools we recommend checking out CLiki: http://www.cliki.net/.
Previous: Third-party Libraries, Up: More Common Lisp Information [Contents][Index]
If you’re not a programmer and you’re trying to learn, many introductory Lisp books are available. However, we don’t have any standout favorites. If you can’t decide, try checking the Usenet news://comp.lang.lisp FAQ for recent recommendations.
If you are an experienced programmer in other languages but need to learn about Common Lisp, some books stand out:
An excellent introduction to the language, covering both the basics and “advanced topics” like macros, CLOS, and packages. Available both in print format and on the web: http://www.gigamonkeys.com/book/.
Good information on general Common Lisp programming, and many nontrivial examples. Whether or not your work is AI, it’s a very good book to look at.
An in-depth treatment of macros, but not recommended as a first Common Lisp book, since it is slightly pre-ANSI so you need to be on your guard against non-standard usages, and since it doesn’t really even try to cover the language as a whole, focusing solely on macros. Downloadable from http://www.paulgraham.com/onlisp.html.
With the exception of Practical Common Lisp most introductory books don’t emphasize CLOS. This one does. Even if you’re very knowledgeable about object oriented programming in the abstract, it’s worth looking at this book if you want to do any OO in Common Lisp. Some abstractions in CLOS (especially multiple dispatch) go beyond anything you’ll see in most OO systems, and there are a number of lesser differences as well. This book tends to help with the culture shock.
Currently the prime source of information on the Common Lisp Metaobject Protocol, which is supported by SBCL. Section 2 (Chapters 5 and 6) are freely available at http://www.lisp.org/mop/.
Previous: More Common Lisp Information, Up: Introduction [Contents][Index]
You can work productively with SBCL without knowing or understanding anything about where it came from, how it is implemented, or how it extends the ANSI Common Lisp standard. However, a little knowledge can be helpful in order to understand error messages, to troubleshoot problems, to understand why some parts of the system are better debugged than others, and to anticipate which known bugs, known performance problems, and missing extensions are likely to be fixed, tuned, or added.
SBCL is descended from CMUCL, which is itself descended from Spice Lisp, including early implementations for the Mach operating system on the IBM RT, back in the 1980s. Some design decisions from that time are still reflected in the current implementation:
SBCL also inherited some newer architectural features from CMUCL. The most important is that on some architectures it has a generational garbage collector (“GC”), which has various implications (mostly good) for performance. These are discussed in another chapter, Efficiency.
SBCL has diverged from CMUCL in that SBCL is now essentially a
“compiler-only implementation” of Common Lisp. This is a change in
implementation strategy, taking advantage of the freedom “any of these
facilities might share the same execution strategy” guaranteed in the
ANSI specification section 3.1 (“Evaluation”). It does not mean SBCL
can’t be used interactively, and in fact the change is largely invisible
to the casual user, since SBCL still can and does execute code
interactively by compiling it on the fly. (It is visible if you know how
to look, like using compiled-function-p; and it is visible in the
way that SBCL doesn’t have many bugs which behave differently in
interpreted code than in compiled code.) What it means is that in SBCL,
the eval function only truly “interprets” a few easy kinds of
forms, such as symbols which are boundp. More complicated forms
are evaluated by calling compile and then calling funcall
on the returned result.
The direct ancestor of SBCL is the x86 port of CMUCL. This port was in some ways the most cobbled-together of all the CMUCL ports, since a number of strange changes had to be made to support the register-poor x86 architecture. Some things (like tracing and debugging) do not work particularly well there. SBCL should be able to improve in these areas (and has already improved in some other areas), but it takes a while.
On the x86 SBCL – like the x86 port of CMUCL – uses a conservative GC. This means that it doesn’t maintain a strict separation between tagged and untagged data, instead treating some untagged data (e.g. raw floating point numbers) as possibly-tagged data and so not collecting any Lisp objects that they point to. This has some negative consequences for average time efficiency (though possibly no worse than the negative consequences of trying to implement an exact GC on a processor architecture as register-poor as the X86) and also has potentially unlimited consequences for worst-case memory efficiency. In practice, conservative garbage collectors work reasonably well, not getting anywhere near the worst case. But they can occasionally cause odd patterns of memory usage.
The fork from CMUCL was based on a major rewrite of the system bootstrap process. CMUCL has for many years tolerated a very unusual “build” procedure which doesn’t actually build the complete system from scratch, but instead progressively overwrites parts of a running system with new versions. This quasi-build procedure can cause various bizarre bootstrapping hangups, especially when a major change is made to the system. It also makes the connection between the current source code and the current executable more tenuous than in other software systems – it’s easy to accidentally “build” a CMUCL system containing characteristics not reflected in the current version of the source code.
Other major changes since the fork from CMUCL include
Next: Compiler, Previous: Introduction, Up: Top [Contents][Index]
| • Starting SBCL: | ||
| • Stopping SBCL: | ||
| • Command Line Options: | ||
| • Initialization Files: | ||
| • Initialization and Exit Hooks: |
Next: Stopping SBCL, Up: Starting and Stopping [Contents][Index]
| • Running from Shell: | ||
| • Running from Emacs: | ||
| • Shebang Scripts: |
Next: Running from Emacs, Up: Starting SBCL [Contents][Index]
To run SBCL type sbcl at the command line.
You should end up in the toplevel REPL (read, eval, print -loop), where you can interact with SBCL by typing expressions.
$ sbcl This is SBCL 0.8.13.60, an implementation of ANSI Common Lisp. More information about SBCL is available at <http://www.sbcl.org/>. SBCL is free software, provided as is, with absolutely no warranty. It is mostly in the public domain; some portions are provided under BSD-style licenses. See the CREDITS and COPYING files in the distribution for more information. * (+ 2 2) 4 * (exit) $
See also Command Line Options and Stopping SBCL.
Next: Shebang Scripts, Previous: Running from Shell, Up: Starting SBCL [Contents][Index]
To run SBCL as an inferior-lisp from Emacs in your .emacs do something like:
;;; The SBCL binary and command-line arguments (setq inferior-lisp-program "/usr/local/bin/sbcl --noinform")
For more information on using SBCL with Emacs, see Editor Integration.
Previous: Running from Emacs, Up: Starting SBCL [Contents][Index]
Standard Unix tools that are interpreters follow a common command line
protocol that is necessary to work with “shebang scripts”. SBCL supports
this via the --script command line option.
Example file (hello.lisp):
#!/usr/local/bin/sbcl --script (write-line "Hello, World!")
Usage examples:
$ ./hello.lisp Hello, World!
$ sbcl --script hello.lisp Hello, World!
Next: Command Line Options, Previous: Starting SBCL, Up: Starting and Stopping [Contents][Index]
| • Exit: | ||
| • End of File: | ||
| • Saving a Core Image: | ||
| • Exit on Errors: |
Next: End of File, Up: Stopping SBCL [Contents][Index]
SBCL can be stopped at any time by calling sb-ext:exit,
optionally returning a specified numeric value to the calling process.
See Threading for information about terminating individual threads.
Terminates the process, causing sbcl to exit with code. code
defaults to 0 when abort is false, and 1 when it is true.
When abort is false (the default), current thread is first unwound,
*exit-hooks* are run, other threads are terminated, and standard
output streams are flushed before sbcl calls exit(3) -- at which point
atexit(3) functions will run. If multiple threads call exit with abort
being false, the first one to call it will complete the protocol.
When abort is true, sbcl exits immediately by calling _exit(2) without
unwinding stack, or calling exit hooks. Note that _exit(2) does not
call atexit(3) functions unlike exit(3).
Recursive calls to exit cause exit to behave as if abort was true.
timeout controls waiting for other threads to terminate when abort is
nil. Once current thread has been unwound and *exit-hooks* have been
run, spawning new threads is prevented and all other threads are
terminated by calling terminate-thread on them. The system then waits
for them to finish using join-thread, waiting at most a total timeout
seconds for all threads to join. Those threads that do not finish
in time are simply ignored while the exit protocol continues. timeout
defaults to *exit-timeout*, which in turn defaults to 60. timeout nil
means to wait indefinitely.
Note that timeout applies only to join-thread, not *exit-hooks*. Since
terminate-thread is asynchronous, getting multithreaded application
termination with complex cleanups right using it can be tricky. To
perform an orderly synchronous shutdown use an exit hook instead of
relying on implicit thread termination.
Consequences are unspecified if serious conditions occur during exit
excepting errors from *exit-hooks*, which cause warnings and stop
execution of the hook that signaled, but otherwise allow the exit
process to continue normally.
Next: Saving a Core Image, Previous: Exit, Up: Stopping SBCL [Contents][Index]
By default SBCL also exits on end of input, caused either by user pressing Control-D on an attached terminal, or end of input when using SBCL as part of a shell pipeline.
Next: Exit on Errors, Previous: End of File, Up: Stopping SBCL [Contents][Index]
SBCL has the ability to save its state as a file for later execution. This functionality is important for its bootstrapping process, and is also provided as an extension to the user.
Save a "core image", i.e. enough information to restart a Lisp process later in the same state, in the file of the specified name. Only global state is preserved: the stack is unwound in the process.
The following &key arguments are defined:
:toplevelThe function to run when the created core file is resumed. The
default function handles command line toplevel option processing
and runs the top level read-eval-print loop. This function returning
is equivalent to (sb-ext:exit :code 0) being called.
toplevel functions should always provide an abort restart: otherwise
code they call will run without one.
:executableIf true, arrange to combine the sbcl runtime and the core image
to create a standalone executable. If false (the default), the
core image will not be executable on its own. Executable images
always behave as if they were passed the –noinform runtime option.
:save-runtime-optionsIf true, values of runtime options –dynamic-space-size and
–control-stack-size that were used to start sbcl are stored in
the standalone executable, and restored when the executable is
run. This also inhibits normal runtime option processing, causing
all command line arguments to be passed to the toplevel.
Meaningless if :executable is nil.
:purifyIf true (the default on cheneygc), do a purifying gc which moves all
dynamically allocated objects into static space. This takes
somewhat longer than the normal gc which is otherwise done, but
it’s only done once, and subsequent GC’s will be done less often
and will take less time in the resulting core file. See the purify
function. This parameter has no effect on platforms using the
generational garbage collector.
:root-structuresThis should be a list of the main entry points in any newly loaded
systems. This need not be supplied, but locality and/or gc performance
may be better if they are. This has two different but related meanings:
If :purify is true - and only for cheneygc - the root structures
are those which anchor the set of objects moved into static space.
On gencgc - and only on platforms supporting immobile code - these are
the functions and/or function-names which commence a depth-first scan
of code when reordering based on the statically observable call chain.
The complete set of reachable objects is not affected per se.
This argument is meaningless if neither enabling precondition holds.
:environment-nameThis has no purpose; it is accepted only for legacy compatibility.
:compressionThis is only meaningful if the runtime was built with the :sb-core-compression
feature enabled. If nil (the default), saves to uncompressed core files. If
:sb-core-compression was enabled at build-time, the argument may also be
an integer from -1 to 9, corresponding to zlib compression levels, or t
(which is equivalent to the default compression level, -1).
:application-typePresent only on Windows and is meaningful only with :executable t.
Specifies the subsystem of the executable, :console or :gui.
The notable difference is that :gui doesn’t automatically create a console
window. The default is :console.
The save/load process changes the values of some global variables:
*standard-output*, *debug-io*, etc.Everything related to open streams is necessarily changed, since
the os won’t let us preserve a stream across save and load.
*default-pathname-defaults*This is reinitialized to reflect the working directory where the saved core is loaded.
save-lisp-and-die interacts with sb-alien:load-shared-object: see its
documentation for details.
On threaded platforms only a single thread may remain running after
sb-ext:*save-hooks* have run. Applications using multiple threads can
be save-lisp-and-die friendly by registering a save-hook that quits
any additional threads, and an init-hook that restarts them.
This implementation is not as polished and painless as you might like:
This isn’t because we like it this way, but just because there don’t seem to be good quick fixes for either limitation and no one has been sufficiently motivated to do lengthy fixes.
A list of function designators which are called in an unspecified order before creating a saved core image.
Unused by sbcl itself: reserved for user and applications.
In cases where the standard initialization files have already been loaded into the saved core, and alternative ones should be used (or none at all), SBCL allows customizing the initfile pathname computation.
Designator for a function of zero arguments called to obtain a
pathname designator for the default sysinit file, or nil. If the
function returns nil, no sysinit file is used unless one has been
specified on the command-line.
Designator for a function of zero arguments called to obtain a
pathname designator or a stream for the default userinit file, or nil.
If the function returns nil, no userinit file is used unless one has
been specified on the command-line.
To facilitate distribution of SBCL applications using external resources, the filesystem location of the SBCL core file being used is available from Lisp.
The absolute pathname of the running sbcl core.
Previous: Saving a Core Image, Up: Stopping SBCL [Contents][Index]
SBCL can also be configured to exit if an unhandled error occurs, which is mainly useful for acting as part of a shell pipeline; doing so under most other circumstances would mean giving up large parts of the flexibility and robustness of Common Lisp. See Debugger Entry.
Next: Initialization Files, Previous: Stopping SBCL, Up: Starting and Stopping [Contents][Index]
Command line options can be considered an advanced topic; for ordinary interactive use, no command line arguments should be necessary.
In order to understand the command line argument syntax for SBCL, it is helpful to understand that the SBCL system is implemented as two components, a low-level runtime environment written in C and a higher-level system written in Common Lisp itself. Some command line arguments are processed during the initialization of the low-level runtime environment, some command line arguments are processed during the initialization of the Common Lisp system, and any remaining command line arguments are passed on to user code.
The full, unambiguous syntax for invoking SBCL at the command line is:
sbcl runtime-option* --end-runtime-options toplevel-option* --end-toplevel-options user-options*
For convenience, the --end-runtime-options and
--end-toplevel-options elements can be omitted. Omitting these
elements can be convenient when you are running the program
interactively, and you can see that no ambiguities are possible with
the option values you are using. Omitting these elements is probably a
bad idea for any batch file where any of the options are under user
control, since it makes it impossible for SBCL to detect erroneous
command line input, so that erroneous command line arguments will be
passed on to the user program even if they was intended for the
runtime system or the Lisp system.
| • Runtime Options: | ||
| • Toplevel Options: |
Next: Toplevel Options, Up: Command Line Options [Contents][Index]
--core corefilenameRun the specified Lisp core file instead of the default. Note that if the Lisp core file is a user-created core file, it may run a nonstandard toplevel which does not recognize the standard toplevel options.
--dynamic-space-size megabytesSize of the dynamic space reserved on startup in megabytes. Default value is platform dependent.
--control-stack-size megabytesSize of control stack reserved for each thread in megabytes. Default value is 2.
--noinformSuppress the printing of any banner or other informational message at
startup. This makes it easier to write Lisp programs which work
cleanly in Unix pipelines. See also the --noprint and
--disable-debugger options.
--disable-ldbDisable the low-level debugger. Only effective if SBCL is compiled with LDB.
--lose-on-corruptionThere are some dangerous low level errors (for instance, control stack exhausted, memory fault) that (or whose handlers) can corrupt the image. By default SBCL prints a warning, then tries to continue and handle the error in Lisp, but this will not always work and SBCL may malfunction or even hang. With this option, upon encountering such an error SBCL will invoke ldb (if present and enabled) or else exit.
--script filenameAs a runtime option this is equivalent to --noinform
--disable-ldb --lose-on-corruption
--end-runtime-options --script filename. See the
description of --script as a toplevel option below. If there
are no other command line arguments following --script, the
filename argument can be omitted.
--merge-core-pagesWhen platform support is present, provide hints to the operating system that identical pages may be shared between processes until they are written to. This can be useful to reduce the memory usage on systems with multiple SBCL processes started from similar but differently-named core files, or from compressed cores. Without platform support, do nothing. By default only compressed cores trigger hinting.
--no-merge-core-pagesEnsures that no sharing hint is provided to the operating system.
--helpPrint some basic information about SBCL, then exit.
--versionPrint SBCL’s version information, then exit.
In the future, runtime options may be added to control behaviour such as lazy allocation of memory.
Runtime options, including any –end-runtime-options option, are stripped out of the command line before the Lisp toplevel logic gets a chance to see it.
Previous: Runtime Options, Up: Command Line Options [Contents][Index]
--sysinit filenameLoad filename instead of the default system initialization file (see Initialization Files.)
--no-sysinitDon’t load a system-wide initialization file. If this option is given,
the --sysinit option is ignored.
--userinit filenameLoad filename instead of the default user initialization file (see Initialization Files.)
--no-userinitDon’t load a user initialization file. If this option is given,
the --userinit option is ignored.
--eval commandAfter executing any initialization file, but before starting the
read-eval-print loop on standard input, read and evaluate the command
given. More than one --eval option can be used, and all will be
read and executed, in the order they appear on the command line.
--load filenameThis is equivalent to --eval '(load "filename")'. The
special syntax is intended to reduce quoting headaches when invoking
SBCL from shell scripts.
--noprintWhen ordinarily the toplevel "read-eval-print loop" would be executed,
execute a "read-eval loop" instead, i.e. don’t print a prompt and
don’t echo results. Combined with the --noinform runtime
option, this makes it easier to write Lisp "scripts" which work
cleanly in Unix pipelines.
--disable-debuggerBy default when SBCL encounters an error, it enters the builtin
debugger, allowing interactive diagnosis and possible intercession.
This option disables the debugger, causing errors to print a backtrace
and exit with status 1 instead. When given, this option takes effect
before loading of initialization files or processing --eval and
--load options. See sb-ext:disable-debugger for details.
See Debugger Entry.
--script filenameImplies --no-userinit --no-sysinit
--disable-debugger --end-toplevel-options.
Causes the system to load the specified file instead of entering the read-eval-print-loop, and exit afterwards. If the file begins with a shebang line, it is ignored.
If there are no other command line arguments following, the filename can be omitted: this causes the script to be loaded from standard input instead. Shebang lines in standard input script are currently not ignored.
In either case, if there is an unhandled error (e.g. end of file, or a
broken pipe) on either standard input, standard output, or standard
error, the script silently exits with code 0. This allows e.g. safely
piping output from SBCL to head -n1 or similar.
Next: Initialization and Exit Hooks, Previous: Command Line Options, Up: Starting and Stopping [Contents][Index]
SBCL processes initialization files with read and eval,
not load; hence initialization files can be used to set startup
*package* and *readtable*, and for proclaiming a global
optimization policy.
Defaults to $SBCL_HOME/sbclrc, or if that doesn’t exist to
/etc/sbclrc. Can be overridden with the command line option
--sysinit or --no-sysinit (see Toplevel Options).
The system initialization file is intended for system administrators and software packagers to configure locations of installed third party modules, etc.
Defaults to $HOME/.sbclrc. Can be overridden with the
command line option --userinit or --no-userinit
(see Toplevel Options).
The user initialization file is intended for personal customizations, such as loading certain modules at startup, defining convenience functions to use in the REPL, handling automatic recompilation of FASLs (see FASL Format), etc.
Neither initialization file is required.
Previous: Initialization Files, Up: Starting and Stopping [Contents][Index]
SBCL provides hooks into the system initialization and exit.
A list of function designators which are called in an unspecified order when a saved core image starts up, after the system itself has been initialized.
Unused by sbcl itself: reserved for user and applications.
A list of function designators which are called in an unspecified
order when sbcl process exits.
Unused by sbcl itself: reserved for user and applications.
Using (sb-ext:exit :abort t), or calling exit(3) directly circumvents
these hooks.
Next: Debugger, Previous: Starting and Stopping, Up: Top [Contents][Index]
This chapter will discuss most compiler issues other than efficiency, including compiler error messages, the SBCL compiler’s unusual approach to type safety in the presence of type declarations, the effects of various compiler optimization policies, and the way that inlining and open coding may cause optimized code to differ from a naive translation. Efficiency issues are sufficiently varied and separate that they have their own chapter, Efficiency.
| • Diagnostic Messages: | ||
| • Handling of Types: | ||
| • Compiler Policy: | ||
| • Compiler Errors: | ||
| • Open Coding and Inline Expansion: | ||
| • Interpreter: |
Next: Handling of Types, Up: Compiler [Contents][Index]
| • Controlling Verbosity: | ||
| • Diagnostic Severity: | ||
| • Understanding Compiler Diagnostics: |
Next: Diagnostic Severity, Up: Diagnostic Messages [Contents][Index]
The compiler can be quite verbose in its diagnostic reporting, rather more then some users would prefer – the amount of noise emitted can be controlled, however.
To control emission of compiler diagnostics (of any severity other
than error: see Diagnostic Severity) use the
sb-ext:muffle-conditions and sb-ext:unmuffle-conditions
declarations, specifying the type of condition that is to be muffled
(the muffling is done using an associated muffle-warning restart).
Global control:
;;; Muffle compiler-notes globally (declaim (sb-ext:muffle-conditions sb-ext:compiler-note))
Local control:
;;; Muffle compiler-notes based on lexical scope
(defun foo (x)
(declare (optimize speed) (fixnum x)
(sb-ext:muffle-conditions sb-ext:compiler-note))
(values (* x 5) ; no compiler note from this
(locally
(declare (sb-ext:unmuffle-conditions sb-ext:compiler-note))
;; this one gives a compiler note
(* x -5))))
Syntax: type*
Muffles the diagnostic messages that would be caused by compile-time signals of given types.
Syntax: type*
Cancels the effect of a previous sb-ext:muffle-conditions
declaration.
Various details of how the compiler messages are printed can be
controlled via the alist
sb-ext:*compiler-print-variable-alist*.
an association list describing new bindings for special variables to be used by the compiler for error-reporting, etc. Eg.
((*PRINT-LENGTH* . 10) (*PRINT-LEVEL* . 6) (*PRINT-PRETTY* . NIL))
The variables in the car positions are bound to the values in the cdr
during the execution of some debug commands. When evaluating arbitrary
expressions in the debugger, the normal values of the printer control
variables are in effect.
Initially empty, *compiler-print-variable-alist* is Typically used to
specify bindings for printer control variables.
For information about muffling warnings signaled outside of the compiler, see Customization Hooks for Users.
Next: Understanding Compiler Diagnostics, Previous: Controlling Verbosity, Up: Diagnostic Messages [Contents][Index]
There are four levels of compiler diagnostic severity:
The first three levels correspond to condition classes which are
defined in the ANSI standard for Common Lisp and which have special
significance to the compile and compile-file functions.
These levels of compiler error severity occur when the compiler
handles conditions of these classes.
The fourth level of compiler error severity, note, corresponds
to the sb-ext:compiler-note, and is used for problems which are
too mild for the standard condition classes, typically hints about how
efficiency might be improved. The sb-ext:code-deletion-note, a
subtype of compiler-note, is signalled when the compiler
deletes user-supplied code after proving that the code in question is
unreachable.
Future work for SBCL includes expanding this hierarchy of types to allow more fine-grained control over emission of diagnostic messages.
Class precedence list: compiler-note, condition, t
Root of the hierarchy of conditions representing information discovered
by the compiler that the user might wish to know, but which does not merit
a style-warning (or any more serious condition).
Class precedence list: code-deletion-note, compiler-note, condition, t
A condition type signalled when the compiler deletes code that the user has written, having proved that it is unreachable.
Previous: Diagnostic Severity, Up: Diagnostic Messages [Contents][Index]
The messages emitted by the compiler contain a lot of detail in a terse format, so they may be confusing at first. The messages will be illustrated using this example program:
(defmacro zoq (x) `(roq (ploq (+ ,x 3)))) (defun foo (y) (declare (symbol y)) (zoq y))
The main problem with this program is that it is trying to add
3 to a symbol. Note also that the functions roq and
ploq aren’t defined anywhere.
| • The Parts of a Compiler Diagnostic: | ||
| • The Original and Actual Source: | ||
| • The Processing Path: |
When processing this program, the compiler will produce this warning:
; file: /tmp/foo.lisp ; in: DEFUN FOO ; (ZOQ Y) ; --> ROQ PLOQ ; ==> ; (+ Y 3) ; ; caught WARNING: ; Asserted type NUMBER conflicts with derived type (VALUES SYMBOL &OPTIONAL).
In this example we see each of the six possible parts of a compiler diagnostic:
with-compilation-unit is used to delay undefined warnings.
defun for
foo.
compile or in the top level form read from the source file. In
this example, the expansion of the zoq macro was responsible
for the message.
roq and ploq. These calls resulted from the
expansion of the zoq macro.
y.
+ requires that its arguments are all of type number,
the compiler has derived that y will evaluate to a
symbol. Note that ‘(VALUES SYMBOL &OPTIONAL)’ expresses
that y evaluates to precisely one value.
Note that each part of the message is distinctively marked:
Each part of the message is more specific than the preceding one. If consecutive messages are for nearby locations, then the front part of the messages would be the same. In this case, the compiler omits as much of the second message as in common with the first. For example:
; file: /tmp/foo.lisp ; in: DEFUN FOO ; (ZOQ Y) ; --> ROQ ; ==> ; (PLOQ (+ Y 3)) ; ; caught STYLE-WARNING: ; undefined function: PLOQ ; ==> ; (ROQ (PLOQ (+ Y 3))) ; ; caught STYLE-WARNING: ; undefined function: ROQ
In this example, the file, definition and original source are identical for the two messages, so the compiler omits them in the second message. If consecutive messages are entirely identical, then the compiler prints only the first message, followed by: ‘[Last message occurs repeats times]’ where repeats is the number of times the message was given.
If the source was not from a file, then no file line is printed. If the actual source is the same as the original source, then the processing path and actual source will be omitted. If no forms intervene between the original source and the actual source, then the processing path will also be omitted.
Next: The Processing Path, Previous: The Parts of a Compiler Diagnostic, Up: Understanding Compiler Diagnostics [Contents][Index]
The original source displayed will almost always be a list. If the actual source for an message is a symbol, the original source will be the immediately enclosing evaluated list form. So even if the offending symbol does appear in the original source, the compiler will print the enclosing list and then print the symbol as the actual source (as though the symbol were introduced by a macro.)
When the actual source is displayed (and is not a symbol), it will always be code that resulted from the expansion of a macro or a source-to-source compiler optimization. This is code that did not appear in the original source program; it was introduced by the compiler.
Keep in mind that when the compiler displays a source form in an diagnostic message, it always displays the most specific (innermost) responsible form. For example, compiling this function
(defun bar (x)
(let (a)
(declare (fixnum a))
(setq a (foo x))
a))
gives this error message
; file: /tmp/foo.lisp ; in: DEFUN BAR ; (LET (A) ; (DECLARE (FIXNUM A)) ; (SETQ A (FOO X)) ; A) ; ; caught WARNING: ; Asserted type FIXNUM conflicts with derived type (VALUES NULL &OPTIONAL).
This message is not saying “there is a problem somewhere in this
let” – it is saying that there is a problem with the
let itself. In this example, the problem is that a’s
nil initial value is not a fixnum.
Previous: The Original and Actual Source, Up: Understanding Compiler Diagnostics [Contents][Index]
The processing path is mainly useful for debugging macros, so if you don’t write macros, you can probably ignore it. Consider this example:
(defun foo (n) (dotimes (i n *undefined*)))
Compiling results in this error message:
; in: DEFUN FOO ; (DOTIMES (I N *UNDEFINED*)) ; --> DO BLOCK LET TAGBODY RETURN-FROM ; ==> ; (PROGN *UNDEFINED*) ; ; caught WARNING: ; undefined variable: *UNDEFINED*
Note that do appears in the processing path. This is because
dotimes expands into:
(do ((i 0 (1+ i)) (#:g1 n))
((>= i #:g1) *undefined*)
(declare (type unsigned-byte i)))
The rest of the processing path results from the expansion of
do:
(block nil
(let ((i 0) (#:g1 n))
(declare (type unsigned-byte i))
(tagbody (go #:g3)
#:g2 (psetq i (1+ i))
#:g3 (unless (>= i #:g1) (go #:g2))
(return-from nil (progn *undefined*)))))
In this example, the compiler descended into the block,
let, tagbody and return-from to reach the
progn printed as the actual source. This is a place where the
“actual source appears in explanation” rule was applied. The
innermost actual source form was the symbol *undefined* itself,
but that also appeared in the explanation, so the compiler backed out
one level.
Next: Compiler Policy, Previous: Diagnostic Messages, Up: Compiler [Contents][Index]
One of the most important features of the SBCL compiler (similar to the original CMUCL compiler, also known as Python) is its fairly sophisticated understanding of the Common Lisp type system and its conservative approach to the implementation of type declarations.
These two features reward the use of type declarations throughout development, even when high performance is not a concern. Also, as discussed in the chapter on performance (see Efficiency), the use of appropriate type declarations can be very important for performance as well.
The SBCL compiler also has a greater knowledge of the Common Lisp
type system than other compilers. Support is incomplete only for types
involving the satisfies type specifier.
| • Declarations as Assertions: | ||
| • Precise Type Checking: | ||
| • Getting Existing Programs to Run: | ||
| • Implementation Limitations: |
Next: Precise Type Checking, Up: Handling of Types [Contents][Index]
The SBCL compiler treats type declarations differently from most other Lisp compilers. Under default compilation policy the compiler doesn’t blindly believe type declarations, but considers them assertions about the program that should be checked: all type declarations that have not been proven to always hold are asserted at runtime.
Remaining bugs in the compiler’s handling of types unfortunately provide some exceptions to this rule, see Implementation Limitations.
CLOS slot types form a notable exception. Types declared using the
:type slot option in defclass are asserted if and only
if the class was defined in safe code and the slot access
location is in safe code as well. This laxness does not pose
any internal consistency issues, as the CLOS slot types are not
available for the type inferencer, nor do CLOS slot types provide any
efficiency benefits.
There are three type checking policies available in SBCL, selectable
via optimize declarations.
All declarations are considered assertions to be checked at runtime, and all type checks are precise. The default compilation policy provides full type checks.
Used when (or (>= safety 2) (>= safety speed 1)).
Declared types may be simplified into faster to check supertypes: for
example, (or (integer -17 -7) (integer 7 17)) is simplified
into (integer -17 17).
Note: it is relatively easy to corrupt the heap when weak type checks are used if the program contains type-errors.
Used when (and (< safety 2) (< safety speed))
All declarations are believed without assertions. Also disables argument count and array bounds checking.
Note: any type errors in code where type checks are not performed are liable to corrupt the heap.
Used when (= safety 0).
Next: Getting Existing Programs to Run, Previous: Declarations as Assertions, Up: Handling of Types [Contents][Index]
Precise checking means that the check is done as though typep
had been called with the exact type specifier that appeared in the
declaration.
If a variable is declared to be (integer 3 17) then its value
must always be an integer between 3 and 17. If multiple
type declarations apply to a single variable, then all the
declarations must be correct; it is as though all the types were
intersected producing a single and type specifier.
To gain maximum benefit from the compiler’s type checking, you should
always declare the types of function arguments and structure slots as
precisely as possible. This often involves the use of or,
member, and other list-style type specifiers.
Next: Implementation Limitations, Previous: Precise Type Checking, Up: Handling of Types [Contents][Index]
Since SBCL’s compiler does much more comprehensive type checking than most Lisp compilers, SBCL may detect type errors in programs that have been debugged using other compilers. These errors are mostly incorrect declarations, although compile-time type errors can find actual bugs if parts of the program have never been tested.
Some incorrect declarations can only be detected by run-time type
checking. It is very important to initially compile a program with
full type checks (high safety optimization) and then test this
safe version. After the checking version has been tested, then you can
consider weakening or eliminating type checks. This applies
even to previously debugged programs, because the SBCL compiler does
much more type inference than other Common Lisp compilers, so an
incorrect declaration can do more damage.
The most common problem is with variables whose constant initial value doesn’t match the type declaration. Incorrect constant initial values will always be flagged by a compile-time type error, and they are simple to fix once located. Consider this code fragment:
(prog (foo) (declare (fixnum foo)) (setq foo ...) ...)
Here foo is given an initial value of nil, but is
declared to be a fixnum. Even if it is never read, the initial
value of a variable must match the declared type. There are two ways
to fix this problem. Change the declaration
(prog (foo) (declare (type (or fixnum null) foo)) (setq foo ...) ...)
or change the initial value
(prog ((foo 0)) (declare (fixnum foo)) (setq foo ...) ...)
It is generally preferable to change to a legal initial value rather than to weaken the declaration, but sometimes it is simpler to weaken the declaration than to try to make an initial value of the appropriate type.
Another declaration problem occasionally encountered is incorrect
declarations on defmacro arguments. This can happen when a
function is converted into a macro. Consider this macro:
(defmacro my-1+ (x) (declare (fixnum x)) `(the fixnum (1+ ,x)))
Although legal and well-defined Common Lisp code, this meaning of this definition is almost certainly not what the writer intended. For example, this call is illegal:
(my-1+ (+ 4 5))
This call is illegal because the argument to the macro is (+ 4
5), which is a list, not a fixnum. Because of macro
semantics, it is hardly ever useful to declare the types of macro
arguments. If you really want to assert something about the type of
the result of evaluating a macro argument, then put a the in
the expansion:
(defmacro my-1+ (x) `(the fixnum (1+ (the fixnum ,x))))
In this case, it would be stylistically preferable to change this macro back to a function and declare it inline.
Some more subtle problems are caused by incorrect declarations that can’t be detected at compile time. Consider this code:
(do ((pos 0 (position #\a string :start (1+ pos)))) ((null pos)) (declare (fixnum pos)) ...)
Although pos is almost always a fixnum, it is nil
at the end of the loop. If this example is compiled with full type
checks (the default), then running it will signal a type error at the
end of the loop. If compiled without type checks, the program will go
into an infinite loop (or perhaps position will complain
because (1+ nil) isn’t a sensible start.) Why? Because if you
compile without type checks, the compiler just quietly believes the
type declaration. Since the compiler believes that pos is
always a fixnum, it believes that pos is never
nil, so (null pos) is never true, and the loop exit test
is optimized away. Such errors are sometimes flagged by unreachable
code notes, but it is still important to initially compile and test
any system with full type checks, even if the system works fine when
compiled using other compilers.
In this case, the fix is to weaken the type declaration to (or
fixnum null) 2.
Note that there is usually little performance penalty for weakening a
declaration in this way. Any numeric operations in the body can still
assume that the variable is a fixnum, since nil is not a
legal numeric argument. Another possible fix would be to say:
(do ((pos 0 (position #\a string :start (1+ pos))))
((null pos))
(let ((pos pos))
(declare (fixnum pos))
...))
This would be preferable in some circumstances, since it would allow a
non-standard representation to be used for the local pos
variable in the loop body.
Previous: Getting Existing Programs to Run, Up: Handling of Types [Contents][Index]
Ideally, the compiler would consider all type declarations to be assertions, so that adding type declarations to a program, no matter how incorrect they might be, would never cause undefined behavior. However, the compiler is known to fall short of this goal in two areas:
For example,
(defun foo (x) (the integer (bar x)))
causes the following compiler diagnostic to be emitted:
; note: type assertion too complex to check: ; (VALUES INTEGER &REST T).
A partial workaround is instead write:
(defun foo (x) (the (values integer &optional) (bar x)))
These are important issues, but are not necessarily easy to fix, so they may, alas, remain in the system for a while.
Next: Compiler Errors, Previous: Handling of Types, Up: Compiler [Contents][Index]
Compiler policy is controlled by the optimize declaration,
supporting all ANSI optimization qualities (debug,
safety, space, and speed).3
For effects of various optimization qualities on type-safety and debuggability see Declarations as Assertions and Debugger Policy Control.
Ordinarily, when the speed quality is high, the compiler emits
notes to notify the programmer about its inability to apply various
optimizations. For selective muffling of these notes See Controlling Verbosity.
The value of space mostly influences the compiler’s decision
whether to inline operations, which tend to increase the size of
programs. Use the value 0 with caution, since it can cause the
compiler to inline operations so indiscriminately that the net effect
is to slow the program by causing cache misses or even swapping.
Print all global optimization settings, augmented by spec.
Assign a minimum value to an optimization quality. quality is the name of
the optimization quality to restrict, min (defaulting to zero) is the
minimum allowed value, and max (defaults to 3) is the maximum.
Returns the alist describing the current policy restrictions.
If quality is nil or not given, nothing is done.
Otherwise, if min is zero or max is 3 or neither are given, any
existing restrictions of quality are removed.
See also :policy option in with-compilation-unit.
Affects compilations that take place within its dynamic extent. It is intended to be eg. wrapped around the compilation of all files in the same system.
Following options are defined:
:override Boolean-FormOne of the effects of this form is to delay undefined warnings until the
end of the form, instead of giving them at the end of each compilation.
If override is nil (the default), then the outermost
with-compilation-unit form grabs the undefined warnings. Specifying
override true causes that form to grab any enclosed warnings, even if it
is enclosed by another with-compilation-unit.
:policy Optimize-Declaration-FormProvides dynamic scoping for global compiler optimization qualities and
restrictions, limiting effects of subsequent optimize proclamations and
calls to sb-ext:restrict-compiler-policy to the dynamic scope of body.
If override is false, specified policy is merged with current global
policy. If override is true, current global policy, including any
restrictions, is discarded in favor of the specified policy.
Supplying policy nil is equivalent to the option not being supplied at
all, ie. dynamic scoping of policy does not take place.
This option is an SBCL-specific experimental extension: Interface subject to change.
:source-namestring Namestring-FormAttaches the value returned by the Namestring-Form to the internal
debug-source information as the namestring of the source file. Normally
the namestring of the input-file for compile-file is used: this option
can be used to provide source-file information for functions compiled
using compile, or to override the input-file of compile-file.
If both an outer and an inner with-compilation-unit provide a
source-namestring, the inner one takes precedence. Unaffected
by :override.
This is an SBCL-specific extension.
:source-plist Plist-FormAttaches the value returned by the Plist-Form to internal debug-source
information of functions compiled in within the dynamic extent of body.
Primarily for use by development environments, in order to eg. associate
function definitions with editor-buffers. Can be accessed using
sb-introspect:definition-source-plist.
If an outer with-compilation-unit form also provide a source-plist, it
is appended to the end of the provided source-plist. Unaffected
by :override.
This is an SBCL-specific extension.
Examples:
;; Prevent proclamations from the file leaking, and restrict
;; SAFETY to 3 -- otherwise uses the current global policy.
(with-compilation-unit (:policy '(optimize))
(restrict-compiler-policy 'safety 3)
(load "foo.lisp"))
;; Using default policy instead of the current global one,
;; except for DEBUG 3.
(with-compilation-unit (:policy '(optimize debug)
:override t)
(load "foo.lisp"))
;; Same as if :POLICY had not been specified at all: SAFETY 3
;; proclamation leaks out from WITH-COMPILATION-UNIT.
(with-compilation-unit (:policy nil)
(declaim (optimize safety))
(load "foo.lisp"))
Next: Open Coding and Inline Expansion, Previous: Compiler Policy, Up: Compiler [Contents][Index]
| • Type Errors at Compile Time: | ||
| • Errors During Macroexpansion: | ||
| • Read Errors: |
Next: Errors During Macroexpansion, Up: Compiler Errors [Contents][Index]
If the compiler can prove at compile time that some portion of the program cannot be executed without a type error, then it will give a warning at compile time.
It is possible that the offending code would never actually be executed at run-time due to some higher level consistency constraint unknown to the compiler, so a type warning doesn’t always indicate an incorrect program.
For example, consider this code fragment:
(defun raz (foo)
(let ((x (case foo
(:this 13)
(:that 9)
(:the-other 42))))
(declare (fixnum x))
(foo x)))
Compilation produces this warning:
; in: DEFUN RAZ ; (CASE FOO (:THIS 13) (:THAT 9) (:THE-OTHER 42)) ; --> LET COND IF COND IF COND IF ; ==> ; (COND) ; ; caught WARNING: ; This is not a FIXNUM: ; NIL
In this case, the warning means that if foo isn’t any of
:this, :that or :the-other, then x will be
initialized to nil, which the fixnum declaration makes
illegal. The warning will go away if ecase is used instead of
case, or if :the-other is changed to t.
This sort of spurious type warning happens moderately often in the expansion of complex macros and in inline functions. In such cases, there may be dead code that is impossible to correctly execute. The compiler can’t always prove this code is dead (could never be executed), so it compiles the erroneous code (which will always signal an error if it is executed) and gives a warning.
Next: Read Errors, Previous: Type Errors at Compile Time, Up: Compiler Errors [Contents][Index]
The compiler handles errors that happen during macroexpansion, turning
them into compiler errors. If you want to debug the error (to debug a
macro), you can set *break-on-signals* to error. For
example, this definition:
(defun foo (e l)
(do ((current l (cdr current))
((atom current) nil))
(when (eq (car current) e) (return current))))
gives this error:
; in: DEFUN FOO ; (DO ((CURRENT L (CDR CURRENT)) ; ((ATOM CURRENT) NIL)) ; (WHEN (EQ (CAR CURRENT) E) (RETURN CURRENT))) ; ; caught ERROR: ; (in macroexpansion of (DO # #)) ; (hint: For more precise location, try *BREAK-ON-SIGNALS*.) ; DO step variable is not a symbol: (ATOM CURRENT)
Previous: Errors During Macroexpansion, Up: Compiler Errors [Contents][Index]
SBCL’s compiler does not attempt to recover from read errors when reading a source file, but instead just reports the offending character position and gives up on the entire source file.
Next: Interpreter, Previous: Compiler Errors, Up: Compiler [Contents][Index]
Since Common Lisp forbids the redefinition of standard functions, the compiler can have special knowledge of these standard functions embedded in it. This special knowledge is used in various ways (open coding, inline expansion, source transformation), but the implications to the user are basically the same:
trace macro. Special-casing of standard functions can be
inhibited using the notinline declaration, but even then some
phases of analysis such as type inferencing are applied by the
compiler.
When a function call is open coded, inline code whose effect is
equivalent to the function call is substituted for that function
call. When a function call is closed coded, it is usually left
as is, although it might be turned into a call to a different function
with different arguments. As an example, if nthcdr were to be
open coded, then
(nthcdr 4 foobar)
might turn into
(cdr (cdr (cdr (cdr foobar))))
or even
(do ((i 0 (1+ i)) (list foobar (cdr foobar))) ((= i 4) list))
If nth is closed coded, then
(nth x l)
might stay the same, or turn into something like
(car (nthcdr x l))
In general, open coding sacrifices space for speed, but some functions
(such as car) are so simple that they are always
open-coded. Even when not open-coded, a call to a standard function
may be transformed into a different function call (as in the last
example) or compiled as static call. Static function call uses
a more efficient calling convention that forbids redefinition.
Previous: Open Coding and Inline Expansion, Up: Compiler [Contents][Index]
By default SBCL implements eval by calling the native code
compiler.
SBCL also includes an interpreter for use in special cases where using the compiler is undesirable, for example due to compilation overhead. Unlike in some other Lisp implementations, in SBCL interpreted code is not safer or more debuggable than compiled code.
Toggle between different evaluator implementations. If set to :compile,
an implementation of eval that calls the compiler will be used. If set
to :interpret, an interpreter will be used.
Next: Efficiency, Previous: Compiler, Up: Top [Contents][Index]
This chapter documents the debugging facilities of SBCL, including
the debugger, single-stepper and trace, and the effect of
(optimize debug) declarations.
Next: Debugger Command Loop, Up: Debugger [Contents][Index]
| • Debugger Banner: | ||
| • Debugger Invocation: |
Next: Debugger Invocation, Up: Debugger Entry [Contents][Index]
When you enter the debugger, it looks something like this:
debugger invoked on a TYPE-ERROR in thread 11184: The value 3 is not of type LIST. You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT ] Reduce debugger level (leaving debugger, returning to toplevel). 1: [TOPLEVEL] Restart at toplevel READ/EVAL/PRINT loop. (CAR 1 3) 0]
The first group of lines describe what the error was that put us in
the debugger. In this case car was called on 3, causing
a type-error.
This is followed by the “beginner help line”, which appears only if
sb-debug:*debug-beginner-help-p* is true (default).
Next comes a listing of the active restart names, along with their descriptions – the ways we can restart execution after this error. In this case, both options return to top-level. Restarts can be selected by entering the corresponding number or name.
The current frame appears right underneath the restarts, immediately followed by the debugger prompt.
Previous: Debugger Banner, Up: Debugger Entry [Contents][Index]
The debugger is invoked when:
error is called, and the condition it signals is not handled.
break is called, or signal is called with a condition
that matches the current *break-on-signals*.
invoke-debugger
function.
When the debugger is invoked by a condition, ANSI mandates that the
value of *debugger-hook*, if any, be called with two arguments:
the condition that caused the debugger to be invoked and the previous
value of *debugger-hook*. When this happens,
*debugger-hook* is bound to NIL to prevent recursive errors.
However, ANSI also mandates that *debugger-hook* not be invoked
when the debugger is to be entered by the break function. For
users who wish to provide an alternate debugger interface (and thus
catch break entries into the debugger), SBCL provides
sb-ext:*invoke-debugger-hook*, which is invoked during any
entry into the debugger.
This is either nil or a designator for a function of two arguments,
to be run when the debugger is about to be entered. The function is
run with *invoke-debugger-hook* bound to nil to minimize recursive
errors, and receives as arguments the condition that triggered
debugger entry and the previous value of *invoke-debugger-hook*
This mechanism is an sbcl extension similar to the standard *debugger-hook*.
In contrast to *debugger-hook*, it is observed by invoke-debugger even when
called by break.
Next: Stack Frames, Previous: Debugger Entry, Up: Debugger [Contents][Index]
The debugger is an interactive read-eval-print loop much like the
normal top level, but some symbols are interpreted as debugger
commands instead of being evaluated. A debugger command starts with
the symbol name of the command, possibly followed by some arguments on
the same line. Some commands prompt for additional input. Debugger
commands can be abbreviated by any unambiguous prefix: help
can be typed as ‘h’, ‘he’, etc.
The package is not significant in debugger commands; any symbol with
the name of a debugger command will work. If you want to show the
value of a variable that happens also to be the name of a debugger
command you can wrap the variable in a progn to hide it from
the command loop.
The debugger prompt is “frame]”, where frame is
the number of the current frame. Frames are numbered starting from
zero at the top (most recent call), increasing down to the bottom.
The current frame is the frame that commands refer to.
It is possible to override the normal printing behaviour in the
debugger by using the sb-ext:*debug-print-variable-alist*.
an association list describing new bindings for special variables to be used within the debugger. Eg.
((*PRINT-LENGTH* . 10) (*PRINT-LEVEL* . 6) (*PRINT-PRETTY* . NIL))
The variables in the car positions are bound to the values in the cdr
during the execution of some debug commands. When evaluating arbitrary
expressions in the debugger, the normal values of the printer control
variables are in effect.
Initially empty, *debug-print-variable-alist* is typically used to
provide bindings for printer control variables.
Next: Variable Access, Previous: Debugger Command Loop, Up: Debugger [Contents][Index]
A stack frame is the run-time representation of a call to a function; the frame stores the state that a function needs to remember what it is doing. Frames have:
| • Stack Motion: | ||
| • How Arguments are Printed: | ||
| • Function Names: | ||
| • Debug Tail Recursion: | ||
| • Unknown Locations and Interrupts: |
Next: How Arguments are Printed, Up: Stack Frames [Contents][Index]
These commands move to a new stack frame and print the name of the function and the values of its arguments in the style of a Lisp function call:
Move up to the next higher frame. More recent function calls are considered to be higher on the stack.
Move down to the next lower frame.
Move to the highest frame, that is, the frame where the debugger was entered.
Move to the lowest frame.
Move to the frame with the specified number. Prompts for the number if not supplied. The frame with number 0 is the frame where the debugger was entered.
Next: Function Names, Previous: Stack Motion, Up: Stack Frames [Contents][Index]
A frame is printed to look like a function call, but with the actual argument values in the argument positions. So the frame for this call in the source:
(myfun (+ 3 4) 'a)
would look like this:
(MYFUN 7 A)
All keyword and optional arguments are displayed with their actual values; if the corresponding argument was not supplied, the value will be the default. So this call:
(subseq "foo" 1)
would look like this:
(SUBSEQ "foo" 1 3)
And this call:
(string-upcase "test case")
would look like this:
(STRING-UPCASE "test case" :START 0 :END NIL)
The arguments to a function call are displayed by accessing the argument variables. Although those variables are initialized to the actual argument values, they can be set inside the function; in this case the new value will be displayed.
&rest arguments are handled somewhat differently. The value of
the rest argument variable is displayed as the spread-out arguments to
the call, so:
(format t "~A is a ~A." "This" 'test)
would look like this:
(FORMAT T "~A is a ~A." "This" 'TEST)
Rest arguments cause an exception to the normal display of keyword
arguments in functions that have both &rest and &key
arguments. In this case, the keyword argument variables are not
displayed at all; the rest arg is displayed instead. So for these
functions, only the keywords actually supplied will be shown, and the
values displayed will be the argument values, not values of the
(possibly modified) variables.
If the variable for an argument is never referenced by the function, it will be deleted. The variable value is then unavailable, so the debugger prints ‘#<unused-arg>’ instead of the value. Similarly, if for any of a number of reasons the value of the variable is unavailable or not known to be available (see Variable Access), then ‘#<unavailable-arg>’ will be printed instead of the argument value.
Note that inline expansion and open-coding affect what frames are present in the debugger, see Debugger Policy Control.
Next: Debug Tail Recursion, Previous: How Arguments are Printed, Up: Stack Frames [Contents][Index]
If a function is defined by defun it will appear in backtrace
by that name. Functions defined by labels and flet will
appear as (FLET name) and (LABELS name) respectively.
Anonymous lambdas will appear as (LAMDBA lambda-list).
| • Entry Point Details: |
Up: Function Names [Contents][Index]
Sometimes the compiler introduces new functions that are used to implement a user function, but are not directly specified in the source. This is mostly done for argument type and count checking.
With recursive functions, an additional external frame may
appear before the frame representing the first call to the recursive
function. This is a consequence of the way the compiler works: there
is nothing odd with your program. You may also see cleanup
frames during the execution of unwind-protect cleanup code, and
optional for variable argument entry points.
Next: Unknown Locations and Interrupts, Previous: Function Names, Up: Stack Frames [Contents][Index]
The compiler is “properly tail recursive.” If a function call is in a tail-recursive position, the stack frame will be deallocated at the time of the call, rather than after the call returns. Consider this backtrace:
(BAR ...) (FOO ...)
Because of tail recursion, it is not necessarily the case that
FOO directly called BAR. It may be that FOO
called some other function FOO2 which then called BAR
tail-recursively, as in this example:
(defun foo () ... (foo2 ...) ...) (defun foo2 (...) ... (bar ...)) (defun bar (...) ...)
Usually the elimination of tail-recursive frames makes debugging more pleasant, since these frames are mostly uninformative. If there is any doubt about how one function called another, it can usually be eliminated by finding the source location in the calling frame. See Source Location Printing.
The elimination of tail-recursive frames can be prevented by disabling
tail-recursion optimization, which happens when the debug
optimization quality is greater than 2.
See Debugger Policy Control.
Previous: Debug Tail Recursion, Up: Stack Frames [Contents][Index]
The debugger operates using special debugging information attached to the compiled code. This debug information tells the debugger what it needs to know about the locations in the code where the debugger can be invoked. If the debugger somehow encounters a location not described in the debug information, then it is said to be unknown. If the code location for a frame is unknown, then some variables may be inaccessible, and the source location cannot be precisely displayed.
There are three reasons why a code location could be unknown:
debug
optimization quality. See Debugger Policy Control.
safety optimization
quality.
In the last two cases, the values of argument variables are accessible, but may be incorrect. For more details on when variable values are accessible, Variable Value Availability.
It is possible for an interrupt to happen when a function call or return is in progress. The debugger may then flame out with some obscure error or insist that the bottom of the stack has been reached, when the real problem is that the current stack frame can’t be located. If this happens, return from the interrupt and try again.
Next: Source Location Printing, Previous: Stack Frames, Up: Debugger [Contents][Index]
There are two ways to access the current frame’s local variables in
the debugger: list-locals and sb-debug:var.
The debugger doesn’t really understand lexical scoping; it has just one namespace for all the variables in the current stack frame. If a symbol is the name of multiple variables in the same function, then the reference appears ambiguous, even though lexical scoping specifies which value is visible at any given source location. If the scopes of the two variables are not nested, then the debugger can resolve the ambiguity by observing that only one variable is accessible.
When there are ambiguous variables, the evaluator assigns each one a
small integer identifier. The sb-debug:var function uses this
identifier to distinguish between ambiguous variables. The
list-locals command prints the identifier. In the
following example, there are two variables named X. The first
one has identifier 0 (which is not printed), the second one has
identifier 1.
X = 1 X#1 = 2
This command prints the name and value of all variables in the current
frame whose name has the specified prefix. prefix may be
a string or a symbol. If no prefix is given, then all available
variables are printed. If a variable has a potentially ambiguous
name, then the name is printed with a “#identifier”
suffix, where identifier is the small integer used to make the
name unique.
This function returns the value of the variable in the current frame with the specified name. If supplied, identifier determines which value to return when there are ambiguous variables.
When name is a symbol, it is interpreted as the symbol name of
the variable, i.e. the package is significant. If name is an
uninterned symbol (gensym), then return the value of the uninterned
variable with the same name. If name is a string,
sb-debug:var interprets it as the prefix of a variable name
that must unambiguously complete to the name of a valid variable.
identifier is used to disambiguate the variable name; use
list-locals to find out the identifiers.
| • Variable Value Availability: | ||
| • Note On Lexical Variable Access: |
Next: Note On Lexical Variable Access, Up: Variable Access [Contents][Index]
The value of a variable may be unavailable to the debugger in portions of the program where Lisp says that the variable is defined. If a variable value is not available, the debugger will not let you read or write that variable. With one exception, the debugger will never display an incorrect value for a variable. Rather than displaying incorrect values, the debugger tells you the value is unavailable.
The one exception is this: if you interrupt (e.g., with C-c) or if there is an unexpected hardware error such as “‘bus error’” (which should only happen in unsafe code), then the values displayed for arguments to the interrupted frame might be incorrect.4 This exception applies only to the interrupted frame: any frame farther down the stack will be fine.
The value of a variable may be unavailable for these reasons:
debug optimization quality may have omitted debug
information needed to determine whether the variable is available.
Unless a variable is an argument, its value will only be available when
debug is at least 2.
debug optimization quality is 3.
debug optimization quality is 3.
compilation-speed optimization quality, but most
source-level optimizations are done under all compilation policies.
(LET ((var1 var2)) ...)
In this case, var1 is substituted with var2.
Since it is especially useful to be able to get the arguments to a
function, argument variables are treated specially when the
speed optimization quality is less than 3 and the
debug quality is at least 1. With this compilation
policy, the values of argument variables are almost always available
everywhere in the function, even at unknown locations. For
non-argument variables, debug must be at least 2 for
values to be available, and even then, values are only available at
known locations.
Previous: Variable Value Availability, Up: Variable Access [Contents][Index]
When the debugger command loop establishes variable bindings for available variables, these variable bindings have lexical scope and dynamic extent.5 You can close over them, but such closures can’t be used as upward function arguments.
You can also set local variables using setq, but if the
variable was closed over in the original source and never set, then
setting the variable in the debugger may not change the value in all
the functions the variable is defined in. Another risk of setting
variables is that you may assign a value of a type that the compiler
proved the variable could never take on. This may result in bad
things happening.
Next: Debugger Policy Control, Previous: Variable Access, Up: Debugger [Contents][Index]
One of the debugger’s capabilities is source level debugging of compiled code. These commands display the source location for the current frame:
This command displays the file that the current frame’s function was defined from (if it was defined from a file), and then the source form responsible for generating the code that the current frame was executing. If context is specified, then it is an integer specifying the number of enclosing levels of list structure to print.
The source form for a location in the code is the innermost list present
in the original source that encloses the form responsible for generating
that code. If the actual source form is not a list, then some enclosing
list will be printed. For example, if the source form was a reference
to the variable *some-random-special*, then the innermost
enclosing evaluated form will be printed. Here are some possible
enclosing forms:
(let ((a *some-random-special*)) ...) (+ *some-random-special* ...)
If the code at a location was generated from the expansion of a macro or a source-level compiler optimization, then the form in the original source that expanded into that code will be printed. Suppose the file /usr/me/mystuff.lisp looked like this:
(defmacro mymac () '(myfun)) (defun foo () (mymac) ...)
If foo has called myfun, and is waiting for it to
return, then the source command would print:
; File: /usr/me/mystuff.lisp (MYMAC)
Note that the macro use was printed, not the actual function call form,
(myfun).
If enclosing source is printed by giving an argument to
source or vsource, then the actual source form is
marked by wrapping it in a list whose first element is
‘#:***HERE***’. In the previous example, source 1 would
print:
; File: /usr/me/mystuff.lisp (DEFUN FOO () (#:***HERE*** (MYMAC)) ...)
| • How the Source is Found: | ||
| • Source Location Availability: |
Next: Source Location Availability, Up: Source Location Printing [Contents][Index]
If the code was defined from Lisp by compile or
eval, then the source can always be reliably located. If the
code was defined from a fasl file created by
compile-file, then the debugger gets the source forms it
prints by reading them from the original source file. This is a
potential problem, since the source file might have moved or changed
since the time it was compiled.
The source file is opened using the truename of the source file
pathname originally given to the compiler. This is an absolute pathname
with all logical names and symbolic links expanded. If the file can’t
be located using this name, then the debugger gives up and signals an
error.
If the source file can be found, but has been modified since the time it was compiled, the debugger prints this warning:
; File has been modified since compilation: ; filename ; Using form offset instead of character position.
where filename is the name of the source file. It then proceeds using a robust but not foolproof heuristic for locating the source. This heuristic works if:
If the heuristic doesn’t work, the displayed source will be wrong, but will probably be near the actual source. If the “shape” of the top-level form in the source file is too different from the original form, then an error will be signaled. When the heuristic is used, the source location commands are noticeably slowed.
Source location printing can also be confused if (after the source was
compiled) a read-macro you used in the code was redefined to expand
into something different, or if a read-macro ever returns the same
eq list twice. If you don’t define read macros and don’t use
## in perverted ways, you don’t need to worry about this.
Previous: How the Source is Found, Up: Source Location Printing [Contents][Index]
Source location information is only available when the debug
optimization quality is at least 2. If source location
information is unavailable, the source commands will give an error
message.
If source location information is available, but the source location is unknown because of an interrupt or unexpected hardware error (see Unknown Locations and Interrupts), then the command will print:
Unknown location: using block start.
and then proceed to print the source location for the start of the basic block enclosing the code location. It’s a bit complicated to explain exactly what a basic block is, but here are some properties of the block start location:
if,
cond, or) will intervene between the block start and the
true location (but note that some conditionals present in the original
source could be optimized away.) Function calls do not end
basic blocks.
block special form are totally unrelated to the compiler’s
basic block.
In other words, the true location lies between the printed location and the next conditional (but watch out because the compiler may have changed the program on you.)
Next: Exiting Commands, Previous: Source Location Printing, Up: Debugger [Contents][Index]
The compilation policy specified by optimize declarations
affects the behavior seen in the debugger. The debug quality
directly affects the debugger by controlling the amount of debugger
information dumped. Other optimization qualities have indirect but
observable effects due to changes in the way compilation is done.
Unlike the other optimization qualities (which are compared in relative value
to evaluate tradeoffs), the debug optimization quality is directly
translated to a level of debug information. This absolute interpretation
allows the user to count on a particular amount of debug information being
available even when the values of the other qualities are changed during
compilation. These are the levels of debug information that correspond to the
values of the debug quality:
0Only the function name and enough information to allow the stack to be parsed.
> 0Any level greater than 0 gives level 0 plus all argument
variables. Values will only be accessible if the argument variable is
never set and speed is not 3. SBCL allows any real
value for optimization qualities. It may be useful to specify
0.5 to get backtrace argument display without argument
documentation.
1Level 1 provides argument documentation (printed argument lists) and
derived argument/result type information. This makes describe
more informative, and allows the compiler to do compile-time argument
count and type checking for any calls compiled at run-time. This is
the default.
2Level 1 plus all interned local variables, source location
information, and lifetime information that tells the debugger when
arguments are available (even when speed is 3 or the
argument is set).
> 2Any level greater than 2 gives level 2 and in addition
disables tail-call optimization, so that the backtrace will contain
frames for all invoked functions, even those in tail positions.
3Level 2 plus all uninterned variables. In addition, lifetime
analysis is disabled (even when speed is 3), ensuring
that all variable values are available at any known location within
the scope of the binding. This has a speed penalty in addition to the
obvious space penalty.
> (max speed space)If debug is greater than both speed and space,
the command return can be used to continue execution by
returning a value from the current stack frame.
> (max speed space compilation-speed)If debug is greater than all of speed, space and
compilation-speed the code will be steppable (see Single Stepping).
As you can see, if the speed quality is 3, debugger performance is
degraded. This effect comes from the elimination of argument variable
special-casing (see Variable Value Availability). Some degree of
speed/debuggability tradeoff is unavoidable, but the effect is not too drastic
when debug is at least 2.
In addition to inline and notinline declarations, the
relative values of the speed and space qualities also
change whether functions are inline expanded.
If a function is inline expanded, then
there will be no frame to represent the call, and the arguments will
be treated like any other local variable. Functions may also be
“semi-inline”, in which case there is a frame to represent the call,
but the call is to an optimized local version of the function, not to
the original function.
Next: Information Commands, Previous: Debugger Policy Control, Up: Debugger [Contents][Index]
These commands get you out of the debugger.
Throw to top level.
Invokes the nth restart case as displayed by the error
command. If n is not specified, the available restart cases are
reported.
Calls continue on the condition given to debug. If there is no
restart case named continue, then an error is signaled.
Calls abort on the condition given to debug. This is
useful for popping debug command loop levels or aborting to top level,
as the case may be.
Returns value from the current stack frame. This command is
available when the debug optimization quality is greater than
both speed and space. Care must be taken that the value
is of the same type as SBCL expects the stack frame to return.
Restarts execution of the current stack frame. This command is
available when the debug optimization quality is greater than
both speed and space and when the frame is for is a global
function. If the function is redefined in the debugger before the frame
is restarted, the new function will be used.
Next: Function Tracing, Previous: Exiting Commands, Up: Debugger [Contents][Index]
Most of these commands print information about the current frame or function, but a few show general information.
Displays a synopsis of debugger commands.
Calls describe on the current function and displays the number of
local variables.
Displays the current function call as it would be displayed by moving to this frame.
Prints the condition given to invoke-debugger and the active
proceed cases.
Displays all the frames from the current to the bottom. Only shows
n frames if specified. The printing is controlled by
*debug-print-variable-alist*.
Next: Single Stepping, Previous: Information Commands, Up: Debugger [Contents][Index]
The tracer causes selected functions to print their arguments and their results whenever they are called. Options allow conditional printing of the trace information and conditional breakpoints on function entry or exit.
trace {Option Global-Value}* {Name {Option Value}*}*
trace is a debugging tool that provides information when specified
functions are called. In its simplest form:
(TRACE NAME-1 NAME-2 ...)
The NAMEs are not evaluated. Each may be a symbol, denoting an individual function, or a string, denoting all functions fbound to symbols whose home package is the package with the given name.
Options allow modification of the default behavior. Each option is a
pair of an option keyword and a value form. Global options are
specified before the first name, and affect all functions traced by a
given use of trace. Options may also be interspersed with function
names, in which case they act as local options, only affecting tracing
of the immediately preceding function name. Local options override
global options.
By default, trace causes a printout on *trace-output* each time that
one of the named functions is entered or returns. (This is the basic,
ansi Common Lisp behavior of trace.)
The following options are defined:
:report Report-TypeIf Report-Type is trace (the default) then information is
reported by printing immediately. If Report-Type is nil, then
the only effect of the trace is to execute other
options (e.g. print or break).
:condition Form:condition-after Form:condition-all FormIf :condition is specified, then trace does nothing unless Form
evaluates to true at the time of the call. :condition-after is
similar, but suppresses the initial printout, and is tested when the
function returns. :condition-all tries both before and after.
:break Form:break-after Form:break-all FormIf specified, and Form evaluates to true, then the debugger is invoked at the start of the function, at the end of the function, or both, according to the respective option.
:print Form:print-after Form:print-all FormIn addition to the usual printout, the result of evaluating Form is printed at the start of the function, at the end of the function, or both, according to the respective option. Multiple print options cause multiple values to be printed.
:wherein NamesIf specified, Names is a function name or list of names. trace does
nothing unless a call to one of those functions encloses the call to
this function (i.e. it would appear in a backtrace.) Anonymous
functions have string names like "DEFUN FOO".
:encapsulate {:DEFAULT | t | NIL}If t, the default, tracing is done via encapsulation (redefining the
function name) rather than by modifying the function. :default is
not the default, but means to use encapsulation for interpreted
functions and funcallable instances, breakpoints otherwise. When
encapsulation is used, forms are *not* evaluated in the function’s
lexical environment, but sb-debug:arg can still be used.
:methods {T | NIL}If t, any function argument naming a generic function will have its
methods traced in addition to the generic function itself.
:function Function-FormThis is a not really an option, but rather another way of specifying what function to trace. The Function-Form is evaluated immediately, and the resulting function is traced.
:condition, :break and :print forms are evaluated in a context which
mocks up the lexical environment of the called function, so that
sb-debug:var and sb-debug:arg can be used.
The -after and -all forms can use sb-debug:arg.
Remove tracing from the specified functions. Untraces all functions when called with no arguments.
the increase in trace indentation at each call level
If the trace indentation exceeds this value, then indentation restarts at 0.
the default value for the :encapsulate option to trace
Next: Enabling and Disabling the Debugger, Previous: Function Tracing, Up: Debugger [Contents][Index]
SBCL includes an instrumentation based single-stepper for compiled
code, that can be invoked via the step macro, or from within
the debugger. See Debugger Policy Control, for details on enabling
stepping for compiled code.
The following debugger commands are used for controlling single stepping.
Selects the continue restart if one exists and starts single stepping.
None of the other single stepping commands can be used before stepping has
been started either by using start or by using the standard
step macro.
Steps into the current form. Stepping will be resumed when the next form that has been compiled with stepper instrumentation is evaluated.
Steps over the current form. Stepping will be disabled until evaluation of the form is complete.
Steps out of the current frame. Stepping will be disabled until the topmost stack frame that had been stepped into returns.
Stops the single stepper and resumes normal execution.
The form is evaluated with single stepping enabled. Function calls
outside the lexical scope of the form can be stepped into only if the
functions in question have been compiled with sufficient debug policy
to be at least partially steppable.
Previous: Single Stepping, Up: Debugger [Contents][Index]
In certain contexts (e.g., non-interactive applications), it may be desirable to turn off the SBCL debugger (and possibly re-enable it). The functions here control the debugger.
When invoked, this function will turn off both the sbcl debugger
and ldb (the low-level debugger). See also enable-debugger.
Restore the debugger if it has been turned off by disable-debugger.
Next: Beyond the ANSI Standard, Previous: Debugger, Up: Top [Contents][Index]
| • Slot access: | ||
| • Dynamic-extent allocation: | ||
| • Modular arithmetic: | ||
| • Global and Always-Bound variables: | ||
| • Miscellaneous Efficiency Issues: |
Next: Dynamic-extent allocation, Up: Efficiency [Contents][Index]
Structure slot accessors are efficient only if the compiler is able to
open code them: compiling a call to a structure slot accessor before
the structure is defined, declaring one notinline, or passing
it as a functional argument to another function causes severe
performance degradation.
The most efficient way to access a slot of a standard-object is
by using slot-value with a constant slot name argument inside a
defmethod body, where the variable holding the instance is a
specializer parameter of the method and is never assigned to. The cost
is roughly 1.6 times that of an open coded structure slot accessor.
Second most efficient way is to use a CLOS slot accessor, or
slot-value with a constant slot name argument, but in
circumstances other than specified above. This may be up to 3 times as
slow as the method described above.
Example:
(defclass foo () ((bar)))
;; Fast: specializer and never assigned to
(defmethod quux ((foo foo) new)
(let ((old (slot-value foo 'bar)))
(setf (slot-value foo 'bar) new)
old))
;; Slow: not a specializer
(defmethod quux ((foo foo) new)
(let* ((temp foo)
(old (slot-value temp 'bar)))
(setf (slot-value temp 'bar) new)
old))
;; Slow: assignment to FOO
(defmethod quux ((foo foo) new)
(let ((old (slot-value foo 'bar)))
(setf (slot-value foo 'bar) new)
(setf foo new)
old))
Note that when profiling code such as this, the first few calls to the generic function are not representative, as the dispatch mechanism is lazily set up during those calls.
Next: Modular arithmetic, Previous: Slot access, Up: Efficiency [Contents][Index]
SBCL has fairly extensive support for performing allocation on the
stack when a variable is declared dynamic-extent. The
dynamic-extent declarations are not verified, but are simply
trusted as long as sb-ext:*stack-allocate-dynamic-extent* is
true.
If true (the default), the compiler respects dynamic-extent declarations
and stack allocates otherwise inaccessible parts of the object whenever
possible. Potentially long (over one page in size) vectors are, however, not
stack allocated except in zero safety code, as such a vector could overflow
the stack without triggering overflow protection.
If dynamic extent constraints specified in the Common Lisp standard are violated, the best that can happen is for the program to have garbage in variables and return values; more commonly, the system will crash.
In particular, it is important to realize that dynamic extend is contagious:
(let* ((a (list 1 2 3))
(b (cons a a)))
(declare (dynamic-extent b))
;; Unless A is accessed elsewhere as well, SBCL will consider
;; it to be otherwise inaccessible -- it can only be accessed
;; through B, after all -- and stack allocate it as well.
;;
;; Hence returning (CAR B) here is unsafe.
...)
This allows stack allocation of complex structures. As a notable
exception to this, SBCL does not as of 1.0.48.21 propagate
dynamic-extentness through &rest arguments – but another
conforming implementation might, so portable code should not rely on
this.
(declaim (inline foo)) (defun foo (fun &rest arguments) (declare (dynamic-extent arguments)) (apply fun arguments)) (defun bar (a) ;; SBCL will heap allocate the result of (LIST A), and stack allocate ;; only the spine of the &rest list -- so this is safe, but unportable. ;; ;; Another implementation, including earlier versions of SBCL might consider ;; (LIST A) to be otherwise inaccessible and stack-allocate it as well! (foo #'car (list a)))
There are many cases when dynamic-extent declarations could be
useful. At present, SBCL implements stack allocation for
&rest lists, when these are declared dynamic-extent.
cons, list, list*, and vector when the
result is bound to a variable declared dynamic-extent.
make-array, whose result is bound to a variable
declared dynamic-extent: stack allocation is possible only if
the resulting array is known to be both simple and one-dimensional,
and has a constant :element-type.
Note: stack space is limited, so allocation of a large vector
may cause stack overflow. For this reason potentially large vectors,
which might circumvent stack overflow detection, are stack allocated
only in zero safety policies.
flet or labels, with a bound
dynamic-extent declaration. Blocks and tags are also allocated
on the heap, unless all non-local control transfers to them are
compiled with zero safety.
defstruct has been declared inline and the result of the
call to the constructor is bound to a variable declared
dynamic-extent.
Note: structures with “raw” slots can currently be stack-allocated only on x86 and x86-64.
Examples:
;;; Declaiming a structure constructor inline before definition makes
;;; stack allocation possible.
(declaim (inline make-thing))
(defstruct thing obj next)
;;; Stack allocation of various objects bound to DYNAMIC-EXTENT
;;; variables.
(let* ((list (list 1 2 3))
(nested (cons (list 1 2) (list* 3 4 (list 5))))
(vector (make-array 3 :element-type 'single-float))
(thing (make-thing :obj list
:next (make-thing :obj (make-array 3)))))
(declare (dynamic-extent list nested vector thing))
...)
;;; Stack allocation of arguments to a local function is equivalent
;;; to stack allocation of local variable values.
(flet ((f (x)
(declare (dynamic-extent x))
...))
...
(f (list 1 2 3))
(f (cons (cons 1 2) (cons 3 4)))
...)
;;; Stack allocation of &REST lists
(defun foo (&rest args)
(declare (dynamic-extent args))
...)
Future plans include
dynamic-extent.
Next: Global and Always-Bound variables, Previous: Dynamic-extent allocation, Up: Efficiency [Contents][Index]
Some numeric functions have a property: N lower bits of the
result depend only on N lower bits of (all or some)
arguments. If the compiler sees an expression of form (logand
exp mask), where exp is a tree of such “good”
functions and mask is known to be of type (unsigned-byte
w), where w is a “good” width, all intermediate results
will be cut to w bits (but it is not done for variables and
constants!). This often results in an ability to use simple machine
instructions for the functions.
Consider an example.
(defun i (x y) (declare (type (unsigned-byte 32) x y)) (ldb (byte 32 0) (logxor x (lognot y))))
The result of (lognot y) will be negative and of type
(signed-byte 33), so a naive implementation on a 32-bit
platform is unable to use 32-bit arithmetic here. But modular
arithmetic optimizer is able to do it: because the result is cut down
to 32 bits, the compiler will replace logxor and lognot
with versions cutting results to 32 bits, and because terminals
(here—expressions x and y) are also of type
(unsigned-byte 32), 32-bit machine arithmetic can be used.
As of SBCL 0.8.5 “good” functions are +, -;
logand, logior, logxor, lognot and their
combinations; and ash with the positive second
argument. “Good” widths are 32 on HPPA, MIPS, PPC, Sparc and x86 and
64 on Alpha. While it is possible to support smaller widths as well,
currently this is not implemented.
Next: Miscellaneous Efficiency Issues, Previous: Modular arithmetic, Up: Efficiency [Contents][Index]
Defines name as a global variable that is always bound. value is evaluated
and assigned to name both at compile- and load-time, but only if name is not
already bound.
Global variables share their values between all threads, and cannot be locally bound, declared special, defined as constants, and neither bound nor defined as symbol macros.
See also the declarations sb-ext:global and sb-ext:always-bound.
Syntax: (sb-ext:global symbol*)
Only valid as a global proclamation.
Specifies that the named symbols cannot be proclaimed or locally
declared special. Proclaiming an already special or constant
variable name as global signal an error. Allows more efficient
value lookup in threaded environments in addition to expressing
programmer intention.
Syntax: (sb-ext:always-bound symbol*)
Only valid as a global proclamation.
Specifies that the named symbols are always bound. Inhibits
makunbound of the named symbols. Proclaiming an unbound symbol
as always-bound signals an error. Allows the compiler to elide
boundness checks from value lookups.
Previous: Global and Always-Bound variables, Up: Efficiency [Contents][Index]
FIXME: The material in the CMUCL manual about getting good performance from the compiler should be reviewed, reformatted in Texinfo, lightly edited for SBCL, and substituted into this manual. In the meantime, the original CMUCL manual is still 95+% correct for the SBCL version of the Python compiler. See the sections
Besides this information from the CMUCL manual, there are a few other points to keep in mind.
let, let*, inline function call, and so
forth. However, it’s much more passive and dumb about inferring the
types of values assigned with setq, setf, and
friends. It would be nice to fix this, but in the meantime don’t
expect that just because it’s very smart about types in most respects
it will be smart about types involved in assignments. (This doesn’t
affect its ability to benefit from explicit type declarations
involving the assigned variables, only its ability to get by without
explicit type declarations.)
Finally, note that Common Lisp defines many constructs which, in the infamous phrase, “could be compiled efficiently by a sufficiently smart compiler”. The phrase is infamous because making a compiler which actually is sufficiently smart to find all these optimizations systematically is well beyond the state of the art of current compiler technology. Instead, they’re optimized on a case-by-case basis by hand-written code, or not optimized at all if the appropriate case hasn’t been hand-coded. Some cases where no such hand-coding has been done as of SBCL version 0.6.3 include
(reduce #'f x) where the type of x is known at compile
time
(position 0
some-bit-vector)
(remove item list :count 1)
(locally (declare (safety 1)) (assoc item
list)) (which currently performs safe endp checking internal
to assoc).
If your system’s performance is suffering because of some construct
which could in principle be compiled efficiently, but which the SBCL
compiler can’t in practice compile efficiently, consider writing a
patch to the compiler and submitting it for inclusion in the main
sources. Such code is often reasonably straightforward to write;
search the sources for the string “deftransform” to find many
examples (some straightforward, some less so).
Next: External Formats, Previous: Efficiency, Up: Top [Contents][Index]
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 Contributed Modules.
Next: Package-Local Nicknames, Up: Beyond the ANSI Standard [Contents][Index]
SBCL supports extended package prefix syntax, which allows specifying
an alternate package instead of *package* for the reader to use
as the default package for interning symbols:
package-name::form-with-interning-into-package
Example:
'foo::(bar quux zot) == '(foo::bar foo::quux foo::zot)
Doesn’t alter *package*: if foo::bar would cause a
read-time package lock violation, so does foo::(bar).
SBCL also extends the reader to normalize all symbols to Normalization Form KC in builds with Unicode enabled. Whether symbols are normalized is controlled by
Returns t if readtable normalizes strings to nfkc, and nil otherwise.
The readtable-normalization of the standard readtable is t.
Symbols created by
intern and similar functions are not affected by this setting. If
sb-ext:readtable-normalization is t, symbols that are not
normalized are escaped during printing.
Next: Package Variance, Previous: Reader Extensions, Up: Beyond the ANSI Standard [Contents][Index]
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.
Symbol :package-local-nicknames in *features* denotes the
support for this feature.
Options are extended to include
:local-nicknames (local-nickname actual-package-name)*
The package has the specified local nicknames for the corresponding actual packages.
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
Returns an alist of (local-nickname . actual-package) describing the nicknames local to the designated package.
When in the designated package, calls to find-package with the any of the
local-nicknames will return the corresponding actual-package instead. This
also affects all implied calls to 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.
See also: add-package-local-nickname, package-locally-nicknamed-by-list,
remove-package-local-nickname, and the defpackage option :local-nicknames.
Experimental: interface subject to change.
Returns a list of packages which have a local nickname for the designated package.
See also: add-package-local-nickname, package-local-nicknames,
remove-package-local-nickname, and the defpackage option :local-nicknames.
Experimental: interface subject to change.
Adds local-nickname for actual-package in the designated package, defaulting
to current package. local-nickname must be a string designator, and
actual-package must be a package designator.
Returns the designated package.
Signals a continuable error if local-nickname is already a package local
nickname for a different package, or if local-nickname is one of "CL",
"COMMON-LISP", or, "KEYWORD", or if 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 find-package with the local-nickname
will return the package the designated actual-package instead. This also
affects all implied calls to 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.
See also: package-local-nicknames, package-locally-nicknamed-by-list,
remove-package-local-nickname, and the defpackage option :local-nicknames.
Experimental: interface subject to change.
If the designated package had old-nickname as a local nickname for
another package, it is removed. Returns true if the nickname existed and was
removed, and nil otherwise.
See also: add-package-local-nickname, package-local-nicknames,
package-locally-nicknamed-by-list, and the defpackage option :local-nicknames.
Experimental: interface subject to change.
Next: Garbage Collection, Previous: Package-Local Nicknames, Up: Beyond the ANSI Standard [Contents][Index]
Common Lisp standard specifies that “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 using sb-ext:*on-package-variance*:
Specifies behavior when redefining a package using defpackage and the
definition is in variance with the current state of the package.
The value should be of the form:
(:WARN [T | packages-names] :ERROR [T | package-names])
specifying which packages get which behaviour -- with t signifying the default unless
otherwise specified. If default is not specified, :warn is used.
:warn keeps as much state as possible and causes sbcl to signal a full warning.
:error causes sbcl to signal an error when the variant defpackage form is executed,
with restarts provided for user to specify what action should be taken.
Example:
(setf *on-package-variance* '(:warn (:swank :swank-backend) :error t))
specifies to signal a warning if swank package is in variance, and an error otherwise.
Next: Metaobject Protocol, Previous: Package Variance, Up: Beyond the ANSI Standard [Contents][Index]
SBCL provides additional garbage collection functionality not specified by ANSI.
Called after each garbage collection, except for garbage collections triggered during thread exits. In a multithreaded environment these hooks may run in any thread.
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.
On CheneyGC platforms arguments full and gen take no effect: a full
collection is always performed.
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.
Arrange for the designated function to be called when there
are no more references to object, including references in
function itself.
If dont-save is true, the finalizer will be cancelled when
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 function may be called in any
thread. In both single and multithreaded environments function
may be called in any dynamic scope: consequences are unspecified
if function is not fully re-entrant.
Errors from function are handled and cause a warning to be
signalled in whichever thread the function was called in.
Examples:
;;; GOOD, assuming RELEASE-HANDLE is re-entrant.
(let* ((handle (get-handle))
(object (make-object handle)))
(finalize object (lambda () (release-handle handle)))
object)
;;; 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)))))
;;; 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
(progn
(finalize "oops" #'oops)
(oops)) ; GC causes re-entry to #'oops due to the finalizer
; -> ERROR, caught, WARNING signalled
Cancel all finalizations for object.
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 Hash Table Extensions.
Allocate and return a weak pointer which points to object.
If weak-pointer is valid, return the value of weak-pointer and t.
If the referent of weak-pointer has been garbage collected,
returns the values nil and nil.
Total cpu time spent doing garbage collection (as reported by
get-internal-run-time.) Initialized to zero on startup. It is safe to bind
this to zero in order to measure gc time inside a certain section of code, but
doing so may interfere with results reported by eg. time.
The amount of memory that will be allocated before the next garbage
collection is initiated. This can be set with setf.
On gencgc platforms this is the nursery size, and defaults to 5% of dynamic
space size.
Note: currently changes to this value are lost when saving core.
Size of the dynamic space in bytes.
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
sb-profile package does), or to design a more microefficient interface
and submit it as a patch.
Return the pathname used to log garbage collections. Can be setf.
Default is 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.
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.
Number of bytes allocated to generation currently. Available on gencgc
platforms only.
Experimental: interface subject to change.
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 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 setf. Available on gencgc platforms only.
Experimental: interface subject to change.
Minimum average age of objects allocated to generation before that
generation is may be garbage collected. Default is 0.75. See also
generation-average-age. Can be assigned to using setf. Available on gencgc
platforms only.
Experimental: interface subject to change.
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 setf. Available on gencgc platforms only.
Experimental: interface subject to change.
Number of times garbage collection has been done on generation without
promotion. Available on gencgc platforms only.
Experimental: interface subject to change.
Next: Extensible Sequences, Previous: Garbage Collection, Up: Beyond the ANSI Standard [Contents][Index]
SBCL supports a metaobject protocol which is intended to be compatible with AMOP; present exceptions to this (as distinct from current bugs) are:
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.
funcallable-standard-object are
(function standard-object), not (standard-object function).
This is to ensure that the standard-object class is the last of
the standardized classes before t appearing in the class
precedence list of generic-function and
standard-generic-function, as required by section 1.4.4.5 of the
ANSI specification.
:declare and :declarations to
ensure-generic-function are both accepted, with the leftmost
argument defining the declarations to be stored and returned by
generic-function-declarations.
Where AMOP specifies :declarations as the keyword argument to
ensure-generic-function, the Common Lisp standard specifies
:declare. Portable code should use :declare.
validate-superclass should treat standard-class and
funcallable-standard-class as compatible metaclasses, we
impose an additional requirement at class finalization time: a class
of metaclass funcallable-standard-class must have
function in its superclasses, and a class of metaclass
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
class-prototype. The user can then ask whether this object is a
function or not in several different ways: whether it is a
function according to typep; whether its class-of is
subtypep function, or whether 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:
(defclass bad-object (funcallable-standard-object) () (:metaclass standard-class))
(defclass bad-funcallable-object (standard-object) () (:metaclass funcallable-standard-class))
The following definition is acceptable:
(defclass mixin () ((slot :initarg slot))) (defclass funcallable-object (funcallable-standard-object mixin) () (:metaclass funcallable-standard-class))
and leads to a class whose instances are funcallable and have one slot.
Note that this requirement also applies to the class
funcallable-standard-object, which has metaclass
funcallable-standard-class rather than
standard-class as AMOP specifies.
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.
new-value argument to (setf
slot-value-using-class) are not allowed: all user-defined methods must
have a specializer of the class t.
This prohibition is motivated by a separation of layers: the
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 (setf
slot-value-using-class), which permits optimization of (setf
slot-value-using-class)’s discriminating function in the same manner as
for slot-value-using-class and slot-boundp-using-class.
Note that application code may specialize on the new-value
argument of slot accessors.
name argument to 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 of ensure-class in AMOP
as the functional version of defclass, which has this behaviour;
however, it is not consistent with the weaker requirement in AMOP, which
states that any class found by find-class, no matter what its
class-name, is redefined.
:name initialization
argument for slot-definition objects being a constant, when the
slot definition is of type structure-slot-definition (i.e. it is
associated with a class of type 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.
t is not an instance of the built-in-class
metaclass.
AMOP specifies, in the “Inheritance Structure of Metaobject Classes”
section, that the class named t should be an instance of
built-in-class. However, it also specifies that
validate-superclass should return true (indicating that a direct
superclass relationship is permissible) if the second argument is the
class named t. Also, ANSI specifies that classes with metaclass
built-in-class may not be subclassed using defclass, and
also that the class named t is the universal superclass,
inconsistent with it being a built-in-class.
In addition, SBCL supports extensions to the Metaobject protocol from AMOP; at present, they are:
defmethod forms is provided by the
make-method-specializers-form function, which returns a form
which, when evaluated in the lexical environment of the
defmethod, returns a list of specializer metaobjects. This
operator suffers from similar restrictions to those affecting
make-method-lambda, namely that the generic function must be
defined when the defmethod form is expanded, so that the
correct method of make-method-specializers-form is invoked.
The system-provided method on make-method-specializers-form
generates a call to find-class for each symbol specializer
name, and a call to intern-eql-specializer for each (eql
x) specializer name.
find-method, is provided by
parse-specializer-using-class and
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
(eql x) and interned eql specializer objects.
standard-instance-access and
funcallable-standard-instance-access is possible by comparison
to the symbol-macro +slot-unbound+.
Next: Support For Unix, Previous: Metaobject Protocol, Up: Beyond the ANSI Standard [Contents][Index]
| • Iterator Protocol: | ||
| • Simple Iterator Protocol: |
ANSI Common Lisp has a class sequence with subclasses list and
vector on which the “sequence functions” like find,
subseq, etc. operate. As an extension to the ANSI specification,
SBCL allows additional subclasses of sequence to be defined
6.
Users of this extension just make instances of sequence subclasses
and transparently operate on them using sequence functions:
(coerce (subseq (make-instance 'my-sequence) 5 10) 'list)
From this perspective, no distinction between builtin and user-defined
sequence subclasses should be necessary.
Providers of the extension, that is of user-defined sequence
subclasses, have to adhere to a “sequence protocol” which consists of
a set of generic functions in the sequence package.
A minimal sequence subclass has to specify standard-object and
sequence as its superclasses and has to be the specializer of the
sequence parameter of methods on at least the following generic
functions:
Returns the length of sequence or signals a protocol-unimplemented
error if the sequence protocol is not implemented for the class of
sequence.
Returns the element at position index of sequence or signals a
protocol-unimplemented error if the sequence protocol is not
implemented for the class of sequence.
Replaces the element at position index of sequence with new-value
and returns new-value or signals a protocol-unimplemented error if
the sequence protocol is not implemented for the class of
sequence.
Return destructively modified sequence or a freshly allocated
sequence of the same class as sequence of length length. Elements
of the returned sequence are initialized to initial-element, if
supplied, initialized to initial-contents if supplied, or identical
to the elements of sequence if neither is supplied. Signals a
protocol-unimplemented error if the sequence protocol is not
implemented for the class of sequence.
Returns a freshly allocated sequence of length length and of the
same class as sequence. Elements of the new sequence are
initialized to initial-element, if supplied, initialized to
initial-contents if supplied, or identical to the elements of
sequence if neither is supplied. Signals a protocol-unimplemented
error if the sequence protocol is not implemented for the class of
sequence.
make-sequence-like is needed for functions returning
freshly-allocated sequences such as subseq or
copy-seq. adjust-sequence is needed for functions which
destructively modify their arguments such as 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 iterator protocol can incur a high
performance penalty See Iterator Protocol.
When the sequence protocol is only partially implemented for a given
sequence subclass, an attempt to apply one of the missing
operations to instances of that class signals the following condition:
Class precedence list: protocol-unimplemented, type-error, error, serious-condition, condition, t
This error is signaled if a sequence operation is applied to an instance of a sequence class that does not support the operation.
In addition to the mandatory functions above, methods on the sequence functions listed below can be defined.
There are two noteworthy irregularities:
sb-sequence:emptyp does not have a counterpart in
the cl package. It is intended to be used instead of
length when working with lazy or infinite sequences.
map, concatenate and merge receive a
type designator specifying the type of the constructed sequence as their
first argument. However, the corresponding generic functions
sb-sequence:map, sb-sequence:concatenate and
sb-sequence:merge receive a prototype instance of the requested
sequence subclass instead.
Returns t if sequence is an empty sequence and nil
otherwise. Signals an error if sequence is not a sequence.
sb-sequence:count, sb-sequence:count-if, sb-sequence:count-if-not
sb-sequence:find, sb-sequence:find-if, sb-sequence:find-if-not
sb-sequence:position, sb-sequence:position-if, sb-sequence:position-if-not
sb-sequence:subseq
sb-sequence:copy-seq
sb-sequence:fill
Implements cl:map for extended sequences.
result-prototype corresponds to the result-type of cl:map but
receives a prototype instance of an extended sequence class
instead of a type specifier. By dispatching on result-prototype,
methods on this generic function specify how extended sequence
classes act when they are specified as the result type in a cl:map
call. result-prototype may not be fully initialized and thus
should only be used for dispatch and to determine its class.
Another difference to cl:map is that function is a function, not a
function designator.
sb-sequence:nsubstitute, sb-sequence:nsubstitute-if,
sb-sequence:nsubstitute-if-not, sb-sequence:substitute,
sb-sequence:substitute-if, sb-sequence:substitute-if-not
sb-sequence:replace
sb-sequence:nreverse, sb-sequence:reverse
Implements cl:concatenate for extended sequences.
result-prototype corresponds to the result-type of cl:concatenate
but receives a prototype instance of an extended sequence class
instead of a type specifier. By dispatching on result-prototype,
methods on this generic function specify how extended sequence
classes act when they are specified as the result type in a
cl:concatenate call. result-prototype may not be fully initialized
and thus should only be used for dispatch and to determine its
class.
sb-sequence:reduce
sb-sequence:mismatch
sb-sequence:search
sb-sequence:delete, sb-sequence:delete-if, sb-sequence:delete-if-not,
sb-sequence:remove, sb-sequence:remove-if, sb-sequence:remove-if-not,
sb-sequence:delete-duplicates, sb-sequence:remove-duplicates
sb-sequence:sort, sb-sequence:stable-sort
Implements cl:merge for extended sequences.
result-prototype corresponds to the result-type of cl:merge but
receives a prototype instance of an extended sequence class
instead of a type specifier. By dispatching on result-prototype,
methods on this generic function specify how extended sequence
classes act when they are specified as the result type in a
cl:merge call. result-prototype may not be fully initialized and
thus should only be used for dispatch and to determine its class.
Another difference to cl:merge is that predicate is a function,
not a function designator.
In the spirit of dolist, generic sequences can be traversed using
the macro
Executes body with element subsequently bound to each element of
sequence, then returns return.
Next: Simple Iterator Protocol, Up: Extensible Sequences [Contents][Index]
The iterator protocol allows subsequently accessing some or all elements
of a sequence in forward or reverse direction. Users first call
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. An iteration state consists of a state object, a limit object,
a from-end indicator and the following six functions to query or mutate
this state:
step function sequence iterator from-endMoves the iterator one position forward or backward in the associated sequence depending on the iteration direction.
endp function sequence iterator limit from-endReturns non-nil when the iterator has reached the end of the
associated sequence with respect to the iteration direction.
element function sequence iteratorReturns the sequence element associated to the current position of the iteration.
setf element function new-value sequence iteratorDestructively modifies the associates sequence by replacing the sequence element associated to the current iteration position with a new value.
index function sequence iteratorReturns the position of the iteration in the associated sequence.
copy function sequence iteratorReturns a copy of the iteration state which can be mutated independently of the copied iteration state.
An iterator is created by calling:
Returns a sequence iterator for sequence or, if start and/or end
are supplied, the subsequence bounded by start and 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 from-end is nil, the constructed iterator visits the specified
elements in the order in which they appear in sequence. Otherwise,
the elements are visited in the opposite order.
Note that make-sequence-iterator calls
make-simple-sequence-iterator when there is no specialized
method for a particular sequence subclass. See Simple Iterator Protocol.
The following convenience macros simplify traversing sequences using iterators:
Executes body with the elements of vars bound to the iteration
state returned by make-sequence-iterator for sequence and
args. Elements of vars may be nil in which case the corresponding
value returned by make-sequence-iterator is ignored.
Executes body with the names step, endp, elt, setf, index and copy
bound to local functions which execute the iteration state query and
mutation functions returned by make-sequence-iterator for sequence
and args. step, endp, elt, setf, index and copy have dynamic
extent.
Previous: Iterator Protocol, Up: Extensible Sequences [Contents][Index]
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:
Moves iterator one position forward or backward in sequence
depending on the iteration direction encoded in from-end.
Returns non-NIL when iterator has reached limit (which may
correspond to the end of sequence) with respect to the iteration
direction encoded in from-end.
Returns the element of sequence associated to the position of
iterator.
Destructively modifies sequence by replacing the sequence element
associated to position of iterator with new-value.
Returns the position of iterator in sequence.
Returns a copy of iterator which also traverses sequence but can
be mutated independently of iterator.
Iterator objects implementing the above simple iteration protocol are created by calling the following generic function:
Returns a sequence iterator for sequence, start, end and from-end
as three values:
1. iterator state 2. limit 3. from-end
The returned iterator can be used with the generic iterator
functions iterator-step, iterator-endp, iterator-element, (setf
iterator-element), iterator-index and iterator-copy.
Next: Unicode Support, Previous: Extensible Sequences, Up: Beyond the ANSI Standard [Contents][Index]
| • Command-line arguments: | ||
| • Querying the process environment: | ||
| • Running external programs: |
Next: Querying the process environment, Up: Support For Unix [Contents][Index]
The UNIX command line can be read from the variable
sb-ext:*posix-argv*.
Next: Running external programs, Previous: Command-line arguments, Up: Support For Unix [Contents][Index]
The UNIX environment can be queried with the
sb-ext:posix-getenv function.
Return the "value" part of the environment string "name=value" which
corresponds to name, or nil if there is none.
Previous: Querying the process environment, Up: Support For Unix [Contents][Index]
External programs can be run with sb-ext:run-program.
7
run-program creates a new process specified by program.
args are passed as the arguments to the program.
The program arguments and the environment are encoded using the default external format for streams.
run-program will return a process structure. See the cmu Common Lisp
Users Manual for details about the process structure.
Notes about Unix environments (as in the :environment and :env args):
sbcl implementation of run-program, like Perl and many other
programs, but unlike the original cmu cl implementation, copies
the Unix environment by default.
&key arguments have the following meanings::environmenta list of STRINGs describing the new Unix environment (as in "man environ"). The default is to copy the environment of the current process.
:envan alternative lossy representation of the new Unix environment,
for compatibility with cmu cl
:searchLook for program in each of the directories in the child’s $PATH
environment variable. Otherwise an absolute pathname is required.
:waitIf non-NIL (default), wait until the created process finishes. If
nil, continue running Lisp until the program finishes.
:pty (not supported on win32)Either t, nil, or a stream. Unless nil, the subprocess is established
under a pty. If :pty is a stream, all output to this pty is sent to
this stream, otherwise the process-pty slot is filled in with a stream
connected to pty that can read output and write input.
:inputEither t, nil, a pathname, a stream, or :stream.
t: the standard input for the current process is inherited.
nil: /dev/null (nul on win32) is used.
pathname: the specified file is used.
stream: all the input is read from that stream and sent to the
subprocess.
:stream: the process-input slot is filled in with a stream that sends
its output to the process.
Defaults to nil.
:if-input-does-not-exist (when :input is the name of a file)can be one of:
:error to generate an error
:create to create an empty file
nil (the default) to return nil from run-program
:outputEither t, nil, a pathname, a stream, or :stream.
t: the standard output for the current process is inherited.
nil: /dev/null (nul on win32) is used.
pathname: the specified file is used.
stream: all the output from the process is written to this stream.
:stream: the process-output slot is filled in with a stream that can be
read to get the output.
Defaults to nil.
:errorSame as :output, additionally accepts :output, making all error
output routed to the same place as normal output.
Defaults to :output.
:if-output-exists (when :output is the name of a file)can be one of:
:error (the default) to generate an error
:supersede to supersede the file with output from the program
:append to append output from the program to the file
nil to return nil from run-program, without doing anything
:if-error-existsSame as :if-output-exists, controlling :error output to files.
Ignored when :error :output.
Defaults to :error.
:status-hookThis is a function the system calls whenever the status of the process changes. The function takes the process as an argument.
:external-formatThe external-format to use for :input, :output, and :error :STREAMs.
:directorySpecifies the directory in which the program should be run.
nil (the default) means the directory is unchanged.
:escape-arguments (default t)Controls escaping of the arguments passed to CreateProcess.
When sb-ext:run-program is called with wait equal to
NIL, an instance of class sb-ext:process is returned. The
following functions are available for use with processes:
t if object is a process, nil otherwise.
The input stream of the process or nil.
The output stream of the process or nil.
The error stream of the process or nil.
Return t if process is still alive, nil otherwise.
Return the current status of process. The result is one of :running,
:stopped, :exited, or :signaled.
Wait for process to quit running for some reason. When
check-for-stopped is t, also returns when process is stopped. Returns
process.
The exit code or the signal of a stopped process.
t if a core image was dumped by the process.
Close all streams connected to process and stop maintaining the
status slot.
Hand signal to process. If whom is :pid, use the kill Unix system call. If
whom is :process-group, use the killpg Unix system call. If whom is
:pty-process-group deliver the signal to whichever process group is
currently in the foreground.
Next: Customization Hooks for Users, Previous: Support For Unix, Up: Beyond the ANSI Standard [Contents][Index]
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 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 8 or by giving its hexadecimal codepoint preceded by a “U”, an optional “+”, 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 “BELL”).
For example, you can specify the codepoint U+00E1 (“Latin Small Letter A With Acute”) as
#\LATIN_SMALL_LETTER_A_WITH_ACUTE
#\LATIN_SMALL_LETTER_A_ACUTE
#\á assuming a Unicode source file
#\U00E1
#\UE1
#\U+00E1
The following functions can be used to find information about a Unicode codepoint.
Returns the general category of character as it appears in UnicodeData.txt
Returns the bidirectional class of character
Returns the canonical combining class (ccc) of character
Returns the decimal digit value associated with character or 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, ‘(decimal-digit c) <=> (digit-char-p c 10)‘ in #+sb-unicode builds
Returns the Unicode digit value of character or 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
Returns the numeric value of character or 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.
Returns t if character needs to be mirrored in bidirectional text.
Otherwise, returns nil.
Returns the mirror image of character if it exists.
Otherwise, returns nil.
Returns the version of Unicode in which character was assigned as a pair
of values, both integers, representing the major and minor version respectively.
If character is not assigned in Unicode, returns nil for both values.
Returns the Hangul syllable type of character.
The syllable type can be one of :l, :v, :t, :lv, or :lvt.
If the character is not a Hangul syllable or Jamo, returns nil
Returns the East Asian Width property of character as
one of the keywords :n (Narrow), :a (Ambiguous), :h (Halfwidth),
:w (Wide), :f (Fullwidth), or :na (Not applicable)
Returns the Script property of character as a keyword.
If character does not have a known script, returns :unknown
Returns the Unicode block in which character resides as a keyword.
If character does not have a known block, returns :no-block
Returns the name assigned to character in Unicode 1.0 if it is distinct
from the name currently assigned to character. Otherwise, returns nil.
This property has been officially obsoleted by the Unicode standard, and
is only included for backwards compatibility.
Returns t if character has the specified property.
property is a keyword representing one of the properties from PropList.txt,
with underscores replaced by dashes.
Returns t if character has the Unicode property Uppercase and nil otherwise
Returns t if character has the Unicode property Lowercase and nil otherwise
Returns t if character has a (Unicode) case, and nil otherwise
Returns t if character is Case Ignorable as defined in Unicode 6.3, Chapter
3
Returns t if character is Alphabetic according to the Unicode standard
and nil otherwise
Returns t if character has the Unicode property Ideographic,
which loosely corresponds to the set of "Chinese characters"
Returns t if character is a mathematical symbol according to Unicode and
nil otherwise
Returns t if character is whitespace according to Unicode
and nil otherwise
Returns t if character has a soft dot (such as the dots on i and j) which
disappears when accents are placed on top of it. and nil otherwise
Returns t if character is a hexadecimal digit and nil otherwise.
If :ascii is non-NIL, fullwidth equivalents of the Latin letters A through f
are excluded.
Returns t if character is a Default_Ignorable_Code_Point
Returns the grapheme breaking class of character, as specified in uax #29.
Returns the word breaking class of character, as specified in uax #29.
Returns the sentence breaking class of character, as specified in uax #29.
Returns the line breaking class of character, as specified in uax #14.
If :resolve is nil, returns the character class found in the property file.
If :resolve is non-NIL, centain line-breaking classes will be mapped to othec
classes as specified in the applicable standards. Addinionally, if :resolve
is :east-asian, Ambigious (class :ai) characters will be mapped to the
Ideographic (:id) class instead of Alphabetic (:al).
SBCL can normalize strings using:
Normalize string to the Unicode normalization form form.
Acceptable values for form are :nfd, :nfc, :nfkd, and :nfkc.
If filter is a function it is called on each decomposed character and
only characters for which it returns t are collected.
Tests if string is normalized to form
SBCL implements the full range of Unicode case operations with the functions
Returns the full uppercase of string according to the Unicode standard.
The result is not guaranteed to have the same length as the input. If :locale
is nil, no language-specific case transformations are applied. If :locale is a
keyword representing a two-letter iso country code, the case transforms of that
locale are used. If :locale is t, the user’s current locale is used (Unix and
Win32 only).
Returns the full lowercase of string according to the Unicode standard.
The result is not guaranteed to have the same length as the input.
:locale has the same semantics as the :locale argument to uppercase.
Returns the titlecase of string. The resulting string can
be longer than the input.
:locale has the same semantics as the :locale argument to uppercase.
Returns the full casefolding of 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.
It also extends standard Common Lisp case functions such as
string-upcase and
string-downcase to support a subset of Unicode’s casing behavior.
Specifically, a character is
both-case-p if its case mapping in Unicode is one-to-one and
invertable.
The sb-unicode package also provides functions for
collating/sorting strings according to the Unicode Collation Algorithm.
Determines whether STRING1 sorts before 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
Determines whether STRING1 and STRING2 are canonically equivalent according
to Unicode. The start and end arguments behave like the arguments to STRING=.
If :strict is nil, UNICODE= tests compatibility equavalence instead.
Determines whether STRING1 and STRING2 are canonically equivalent after
casefoldin8 (that is, ignoring case differences) according to Unicode. The
start and end arguments behave like the arguments to STRING=. If :strict is
nil, UNICODE= tests compatibility equavalence instead.
Tests if STRING1 and STRING2 are either UNICODE< or UNICODE=
Tests if STRING2 is UNICODE< STRING1.
Tests if STRING1 and STRING2 are either UNICODE= or UNICODE>
The following functions are provided for detecting visually confusable strings:
Determines whether STRING1 and STRING2 could be visually confusable
according to the idna confusableSummary.txt table
The sb-unicode package includes several functions for breaking a
Unicode string into useful parts.
Breaks string into graphemes according to the default
grapheme breaking rules specified in uax #29, returning a list of strings.
Breaks string into words according to the default
word breaking rules specified in uax #29. Returns a list of strings
Breaks string into sentences according to the default
sentence breaking rules specified in uax #29
Breaks string into lines that are no wider than :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 :margin is unspecified,
it defaults to 80 characters
Next: Tools To Help Developers, Previous: Unicode Support, Up: Beyond the ANSI Standard [Contents][Index]
The toplevel repl prompt may be customized, and the function that reads user input may be replaced completely.
The behaviour of require when called with only one argument is
implementation-defined. In SBCL, require behaves in the
following way:
Loads a module, unless it already has been loaded. pathnames, if supplied,
is a designator for a list of pathnames to be loaded if the module
needs to be. If pathnames is not supplied, functions from the list
*module-provider-functions* are called in order with module-name
as an argument, until one of them returns non-NIL. User code is
responsible for calling provide to indicate a successful load of the
module.
See function documentation for require.
Although SBCL does not provide a resident editor, the ed
function can be customized to hook into user-provided editing
mechanisms as follows:
Starts the editor (on a file or a function if named). Functions
from the list *ed-functions* are called in order with x as an argument
until one of them returns non-NIL; these functions are responsible for
signalling a file-error to indicate failure to perform an operation on
the file system.
See function documentation for ed.
Conditions of type warning and style-warning are
sometimes signaled at runtime, especially during execution of Common
Lisp defining forms such as defun, defmethod, etc. To
muffle these warnings at runtime, SBCL provides a variable
sb-ext:*muffled-warnings*:
A type that ought to specify a subtype of 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.
Next: Resolution of Name Conflicts, Previous: Customization Hooks for Users, Up: Beyond the ANSI Standard [Contents][Index]
SBCL provides a profiler and other extensions to the ANSI trace
facility. For more information, see Macro common-lisp trace.
The debugger supports a number of options. Its documentation is accessed by typing help at the debugger prompt. See Debugger.
Documentation for inspect is accessed by typing help at
the inspect prompt.
Next: Hash Table Extensions, Previous: Tools To Help Developers, Up: Beyond the ANSI Standard [Contents][Index]
The ANSI standard (section 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 sb-ext:resolve-conflict restart should be invoked with one
argument, which should be a member of the list returned by the condition
accessor sb-ext:name-conflict-symbols.
Next: Random Number Generation, Previous: Resolution of Name Conflicts, Up: Beyond the ANSI Standard [Contents][Index]
Hash table extensions supported by SBCL are all controlled by keyword
arguments to make-hash-table.
Create and return a new hash table. The keywords are as follows:
:testDetermines how keys are compared. Must a designator for one of the
standard hash table tests, or a hash table test defined using
sb-ext:define-hash-table-test. Additionally, when an explicit
hash-function is provided (see below), any two argument equivalence
predicate can be used as the test.
:sizeA hint as to how many elements will be put in this hash table.
:rehash-sizeIndicates 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.
:rehash-thresholdIndicates 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.
:hash-functionIf nil (the default), a hash function based on the 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
sb-ext:define-hash-table-test. If hash-function is specified, the test
argument can be any two argument predicate consistent with it. The
hash-function is expected to return a non-negative fixnum hash code.
:weaknessWhen :weakness is not nil, garbage collection may remove entries from the
hash table. The value of :weakness specifies how the presence of a key or
value in the hash table preserves their entries from garbage collection.
Valid values are:
:key means that the key of an entry must be live to guarantee that the
entry is preserved.
:value means that the value of an entry must be live to guarantee that
the entry is preserved.
:key-and-value means that both the key and the value must be live to
guarantee that the entry is preserved.
:key-or-value means that either the key or the value must be live to
guarantee that the entry is preserved.
nil (the default) means that entries are always preserved.
:synchronizedIf 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 t, all concurrent accesses
are safe, but note that clhs 3.6 (Traversal Rules and Side Effects)
remains in force. See also: sb-ext:with-locked-hash-table. This keyword
argument is experimental, and may change incompatibly or be removed in the
future.
Defines name as a new kind of hash table test for use with the :test
argument to make-hash-table, and associates a default hash-function with it.
name must be a symbol naming a global two argument equivalence predicate.
Afterwards both 'name and #'name can be used with :test argument. In both
cases hash-table-test will return the symbol name.
hash-function must be a symbol naming a global hash function consistent with
the predicate, or be a lambda form implementing one in the current lexical
environment. The hash function must compute the same hash code for any two
objects for which name returns true, and subsequent calls with already hashed
objects must always return the same hash code.
Note: The :hash-function keyword argument to make-hash-table can be used to
override the specified default hash-function.
Attempting to define name in a locked package as hash-table test causes a
package lock violation.
Examples:
;;; 1.
;; 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=))
;;; 2.
(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 '==))
Limits concurrent accesses to hash-table for the duration of body.
If hash-table is synchronized, body will execute with exclusive
ownership of the table. If hash-table is not synchronized, body will
execute with other with-locked-hash-table bodies excluded -- exclusion
of hash-table accesses not surrounded by with-locked-hash-table is
unspecified.
Returns t if hash-table is synchronized.
Return the weakness of hash-table which is one of nil, :key,
:value, :key-and-value, :key-or-value.
Next: Timeouts and Deadlines, Previous: Hash Table Extensions, Up: Beyond the ANSI Standard [Contents][Index]
The initial value of *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
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 (make-random-state t).
The sequence of numbers produced by repeated calls to random
starting with the same random state and using the same sequence of
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
random can be compiled differently depending on how much is
known about the 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.
Make a random state object. The optional state argument specifies a seed
for deterministic pseudo-random number generation.
As per the Common Lisp standard for make-random-state,
state is nil or not supplied, return a copy of the default
*random-state*.
state is a random state, return a copy of it.
state is t, return a randomly initialized state (using operating-system
provided randomness where available, otherwise a poor substitute based on
internal time and pid).
As a supported sbcl extension, we also support receiving as a seed an object
of the following types:
simple-array (unsigned-byte 8) (*))
unsigned-byte
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:
(simple-array (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.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
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 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
(* limit (float (/ (random (expt 2 23)) (expt 2 23)) 1.0f0))
(for single-floats) and correspondingly (with 52 and
1.0d0 instead of 23 and 1.0f0) for double-floats.
Note especially that this means that zero is a possible return value
occurring with probability (expt 2 -23) respectively
(expt 2 -52). Also note that there exist twice as many
equidistant floats between 0 and 1 as are generated. For example, the
largest number that (random 1.0f0) ever returns is
(float (/ (1- (expt 2 23)) (expt 2 23)) 1.0f0) while
(float (/ (1- (expt 2 24)) (expt 2 24)) 1.0f0) is the
largest 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 tests9. 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.
Next: Miscellaneous Extensions, Previous: Random Number Generation, Up: Beyond the ANSI Standard [Contents][Index]
SBCL supports three different ways of restricting the execution time available to individual operations or parts of computations:
Some operations such as thread synchronization primitives accept a
:timeout parameter. See Timeout Parameters.
Certain operations that may suspend execution for extended periods of
time such as cl:sleep, thread synchronization primitives, IO and
waiting for external processes respect deadlines established for a part
of a computation. See Synchronous Timeouts (Deadlines).
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 Asynchronous Timeouts.
| • Timeout Parameters: | ||
| • Synchronous Timeouts (Deadlines): | ||
| • Asynchronous Timeouts: | ||
| • Operations Supporting Timeouts and Deadlines: |
Next: Synchronous Timeouts (Deadlines), Up: Timeouts and Deadlines [Contents][Index]
Certain operations accept :timeout keyword arguments. These only
affect the specific operation and must be specified at each call site by
passing a :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
sb-thread:join-thread-error.
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))
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,
sb-thread:join-thread indicates the timeout in its second return
value. If a :default value was not provided,
sb-thread:join-thread would signal a
sb-thread:join-thread-error instead.
To wait for an arbitrary condition, optionally with a timeout, the
sb-ext:wait-for macro can be used:
Wait until test-form evaluates to true, then return its primary value.
If timeout is provided, waits at most approximately timeout seconds before
returning nil.
If with-deadline has been used to provide a global deadline, signals a
deadline-timeout if test-form doesn’t evaluate to true before the
deadline.
Experimental: subject to change without prior notice.
Next: Asynchronous Timeouts, Previous: Timeout Parameters, Up: Timeouts and Deadlines [Contents][Index]
Deadlines, in contrast to timeout parameters, are established for a
dynamic scope using the 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.
Arranges for a 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 sleep, blocking io operations, get-mutex, and
condition-wait respect deadlines, but this includes their implicit
uses inside sbcl itself.
Unless override is true, existing deadlines can only be restricted,
not extended. Deadlines are per thread: children are unaffected by
their parent’s deadlines.
Experimental.
Expiration of deadlines set up this way only has an effect when it
happens before or during the execution of a deadline-aware operation
(see Operations Supporting Timeouts and Deadlines). In this case, a
sb-sys:deadline-timeout is signaled. A handler for this condition
type may use the sb-sys:defer-deadline or
sb-sys:cancel-deadline restarts to defer or cancel the deadline
respectively and resume execution of the interrupted operation.
Class precedence list: deadline-timeout, timeout, serious-condition, condition, t
Signaled when an operation in the context of a deadline takes longer than permitted by the deadline.
When a thread is executing the debugger, signaling of
sb-sys:deadline-timeout conditions for that thread is deferred
until it exits the debugger.
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"))
The above code establishes a deadline of five seconds within which the
body of the do-it function should execute. All calls of
deadline-aware functions in the dynamic scope, in this case two
read-line calls, a sleep call and a
sb-ext:run-program call, are affected by the deadline. If, for
example, the first read-line call completes in one second and the
second read-line call completes in three seconds, a
sb-sys:deadline-timeout condition will be signaled after the
sleep call has been executing for one second.
Next: Operations Supporting Timeouts and Deadlines, Previous: Synchronous Timeouts (Deadlines), Up: Timeouts and Deadlines [Contents][Index]
Asynchronous timeouts are established for a dynamic scope using the
sb-sys:with-timeout macro:
Execute the body, asynchronously interrupting it and signalling a timeout
condition after at least expires seconds have passed.
Note that it is never safe to unwind from an asynchronous condition. Consider:
(defun call-with-foo (function)
(let (foo)
(unwind-protect
(progn
(setf foo (get-foo))
(funcall function foo))
(when foo
(release-foo foo)))))
If timeout occurs after get-foo has executed, but before the assignment, then
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.
Expiration of the timeout will cause the operation being executed at
that moment to be interrupted by an asynchronously signaled
sb-ext:timeout condition, (almost) irregardless of the operation
and its context.
Class precedence list: timeout, serious-condition, condition, t
Signaled when an operation does not complete within an allotted time budget.
Previous: Asynchronous Timeouts, Up: Timeouts and Deadlines [Contents][Index]
| 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? |
Next: Stale Extensions, Previous: Timeouts and Deadlines, Up: Beyond the ANSI Standard [Contents][Index]
Returns the underlying storage vector of array, which must be a non-displaced array.
In sbcl, if array is a of type (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 array-element-type as
array, which this function returns.
Important 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.
Deletes the directory designated by pathspec (a pathname designator).
Returns the truename of the directory deleted.
If recursive is false (the default), signals an error unless the directory is
empty. If recursive is true, first deletes all files and subdirectories. If
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 pathspec designates a file or a symbolic link instead of a
directory, or if the directory could not be deleted for any reason.
Both
(DELETE-DIRECTORY "/tmp/foo") (DELETE-DIRECTORY "/tmp/foo/")
delete the "foo" subdirectory of "/tmp", or signal an error if it does not exist or if is a file or a symbolic link.
Return the number of seconds and microseconds since the beginning of
the unix epoch (January 1st 1970.)
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, (assert-version->= 1 1 4) asserts that the current sbcl is
version 1.1.4[.0.0...] or greater, and (assert-version->= 1) that it is
version 1[.0.0...] or greater.
Next: Efficiency Hacks, Previous: Miscellaneous Extensions, Up: Beyond the ANSI Standard [Contents][Index]
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 src/code/gc.lisp and bring it up on the developers’ mailing list.
SBCL has various hooks inherited from CMUCL, like
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.
Previous: Stale Extensions, Up: Beyond the ANSI Standard [Contents][Index]
The sb-ext:purify function 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 garbage
collectors, but not all SBCL platforms use such a garbage collector.
The 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.
Specifies that the values returned by form conform to the
value-type, and causes the compiler to trust this information
unconditionally.
Consequences are undefined if any result is not of the declared type
-- typical symptoms including memory corruptions. Use with great
care.
The sb-ext:freeze-type declaration declares that a
type will never change, which can make type testing
(typep, etc.) more efficient for structure types.
Next: Foreign Function Interface, Previous: Beyond the ANSI Standard, Up: Top [Contents][Index]
External formats determine the coding of characters from/to sequences of octets when exchanging data with the outside world. Examples of such exchanges are:
Technically, external formats in SBCL are named objects describing coding of characters as well as policies in case de- or encoding is not possible. Each external format has a canonical name and zero or more aliases. User code mostly interacts with external formats by supplying external format designators to functions that use external formats internally.
| • The Default External Format: | ||
| • External Format Designators: | ||
| • Character Coding Conditions: | ||
| • Converting between Strings and Octet Vectors: | ||
| • Supported External Formats: |
Next: External Format Designators, Up: External Formats [Contents][Index]
Most functions interacting with external formats use a default external format if none is explicitly specified. In some cases, the default external format is used unconditionally.
SBCL determines the default external format according to the following rules:
:latin-1.
nl_langinfo(3) on UNIX and GetACP on Windows.
note: On UNIX, the values of the
LANGandLC_*variables in the environment of the SBCL process determine the external format (vianl_langinfo(3)).
:latin-1 external format is used
as a fallback.
Example:
$ LANG=C.UTF-8 sbcl --noinform --no-userinit --eval "(print (map 'string #'code-char (list 97 98 246)))" --quit "abö" $ LANG=C sbcl --noinform --no-userinit --eval "(print (map 'string #'code-char (list 97 98 246)))" --quit "ab?"
Next: Character Coding Conditions, Previous: The Default External Format, Up: External Formats [Contents][Index]
In situations where an external format designator is required, such as
the :external-format argument in calls to open or
with-open-file, users may supply the name of an encoding to
denote the external format which is applying that encoding to Lisp
characters.
In addition to the basic encoding for an external format, options controlling various special cases may be passed, by using a list (whose first element must be an encoding name and whose rest is a plist) as an external file format designator.
More specifically, external format designators can take the following forms:
:defaultDesignates the current default external format (See The Default External Format).
keywordDesignates the supported external format that has keyword as one of its names. (See Supported External Formats).
(keyword :replacement replacement)Designates an external format that is like the one designated by keyword but does not signal an error in case a character or octet sequence cannot be en- or decoded. Instead, it inserts replacement at the position in question. replacement has to be a string designator, that is a character or string.
For example:
(with-open-file (stream pathname :external-format '(:utf-8 :replacement #\?)) (read-line stream))
will read the first line of pathname, replacing any octet sequence that is not valid in the UTF-8 external format with a question mark character.
Next: Converting between Strings and Octet Vectors, Previous: External Format Designators, Up: External Formats [Contents][Index]
De- or encoding characters using a given external format is not always possible:
#\ö.
Unless the external format governing the coding uses the
:replacement keyword, SBCL will signal (continuable) errors under
the above circumstances. The types of the condition signaled are not
currently exported or documented but will be in future SBCL versions.
Next: Supported External Formats, Previous: Character Coding Conditions, Up: External Formats [Contents][Index]
To encode Lisp strings as octet vectors and decode octet vectors as Lisp strings, the following SBCL-specific functions can be used:
Return an octet vector that is string encoded according to external-format.
If external-format is given, it must designate an external format.
If given, start and end must be bounding index designators and
designate a subsequence of string that should be encoded.
If null-terminate is true, the returned octet vector ends with an
additional 0 element that does not correspond to any part of string.
If some of the characters of string (or the subsequence bounded by
start and end) cannot be encoded by external-format an error of a
subtype of sb-int:character-encoding-error is signaled.
Note that for some values of external-format and null-terminate the
length of the returned vector may be different from the length of
string (or the subsequence bounded by start and end).
Return a string obtained by decoding vector according to external-format.
If external-format is given, it must designate an external format.
If given, start and end must be bounding index designators and
designate a subsequence of vector that should be decoded.
If some of the octets of vector (or the subsequence bounded by start
and end) cannot be decoded by external-format an error of a subtype of
sb-int:character-decoding-error is signaled.
Note that for some values of external-format the length of the
returned string may be different from the length of vector (or the
subsequence bounded by start and end).
Previous: Converting between Strings and Octet Vectors, Up: External Formats [Contents][Index]
The following table lists the external formats supported by SBCL in the form of the respective canonical name followed by the list of aliases:
:ASCII:US-ASCII, :ANSI_X3.4-1968, :ISO-646, :ISO-646-US, :|646|
:CP1250:|cp1250|, :WINDOWS-1250, :|windows-1250|
:CP1251:|cp1251|, :WINDOWS-1251, :|windows-1251|
:CP1252:|cp1252|, :WINDOWS-1252, :|windows-1252|
:CP1253:|cp1253|, :WINDOWS-1253, :|windows-1253|
:CP1254:|cp1254|
:CP1255:|cp1255|, :WINDOWS-1255, :|windows-1255|
:CP1256:|cp1256|, :WINDOWS-1256, :|windows-1256|
:CP1257:|cp1257|, :WINDOWS-1257, :|windows-1257|
:CP1258:|cp1258|, :WINDOWS-1258, :|windows-1258|
:CP437:|cp437|
:CP850:|cp850|
:CP852:|cp852|
:CP855:|cp855|
:CP857:|cp857|
:CP860:|cp860|
:CP861:|cp861|
:CP862:|cp862|
:CP863:|cp863|
:CP864:|cp864|
:CP865:|cp865|
:CP866:|cp866|
:CP869:|cp869|
:CP874:|cp874|
:EBCDIC-US:CP037, :|cp037|, :IBM-037, :IBM037
:EUC-JP:EUCJP, :|eucJP|
:GBK:CP936
:ISO-8859-10:|iso-8859-10|, :LATIN-6, :|latin-6|
:ISO-8859-11:|iso-8859-11|
:ISO-8859-13:|iso-8859-13|, :LATIN-7, :|latin-7|
:ISO-8859-14:|iso-8859-14|, :LATIN-8, :|latin-8|
:ISO-8859-2:|iso-8859-2|, :LATIN-2, :|latin-2|
:ISO-8859-3:|iso-8859-3|, :LATIN-3, :|latin-3|
:ISO-8859-4:|iso-8859-4|, :LATIN-4, :|latin-4|
:ISO-8859-5:|iso-8859-5|
:ISO-8859-6:|iso-8859-6|
:ISO-8859-7:|iso-8859-7|
:ISO-8859-8:|iso-8859-8|
:ISO-8859-9:|iso-8859-9|, :LATIN-5, :|latin-5|
:KOI8-R:|koi8-r|
:KOI8-U:|koi8-u|
:LATIN-1:LATIN1, :ISO-8859-1, :ISO8859-1
:LATIN-9:LATIN9, :ISO-8859-15, :ISO8859-15
:MAC-ROMAN:|mac-roman|, :|MacRoman|, :MAC, :|mac|, :MACINTOSH, :|macintosh|
:SHIFT_JIS:SJIS, :|Shift_JIS|, :CP932
:UCS-2BE:UCS2BE
:UCS-2LE:UCS2LE
:UCS-4BE:UCS4BE
:UCS-4LE:UCS4LE
:UTF-16BE:UTF16BE
:UTF-16LE:UTF16LE
:UTF-32BE:UTF32BE
:UTF-32LE:UTF32LE
:UTF-8:UTF8
:X-MAC-CYRILLIC:|x-mac-cyrillic|
Next: Pathnames, Previous: External Formats, Up: Top [Contents][Index]
This chapter describes SBCL’s interface to C programs and libraries (and, since C interfaces are a sort of lingua franca of the Unix world, to other programs and libraries in general.)
Note: In the modern Lisp world, the usual term for this functionality is Foreign Function Interface, or FFI, where despite the mention of “function” in this term, FFI also refers to direct manipulation of C data structures as well as functions. The traditional CMUCL terminology is Alien Interface, and while that older terminology is no longer used much in the system documentation, it still reflected in names in the implementation, notably in the name of the
SB-ALIENpackage.
Next: Foreign Types, Up: Foreign Function Interface [Contents][Index]
Because of Lisp’s emphasis on dynamic memory allocation and garbage collection, Lisp implementations use non-C-like memory representations for objects. This representation mismatch creates friction when a Lisp program must share objects with programs which expect C data. There are three common approaches to establishing communication:
SBCL, like CMUCL before it, relies primarily on the automatic
conversion and direct manipulation approaches. The SB-ALIEN
package provides a facility wherein foreign values of simple scalar
types are automatically converted and complex types are directly
manipulated in their foreign representation. Additionally the
lower-level System Area Pointers (or SAPs) can be used where
necessary to provide untyped access to foreign memory.
Any foreign objects that can’t automatically be converted into Lisp
values are represented by objects of type alien-value. Since
Lisp is a dynamically typed language, even foreign objects must have a
run-time type; this type information is provided by encapsulating the
raw pointer to the foreign data within an alien-value object.
The type language and operations on foreign types are intentionally similar to those of the C language.
Next: Operations On Foreign Values, Previous: Introduction to the Foreign Function Interface, Up: Foreign Function Interface [Contents][Index]
Alien types have a description language based on nested list structure. For example the C type
struct foo {
int a;
struct foo *b[100];
};
has the corresponding SBCL FFI type
(struct foo (a int) (b (array (* (struct foo)) 100)))
| • Defining Foreign Types: | ||
| • Foreign Types and Lisp Types: | ||
| • Foreign Type Specifiers: |
Next: Foreign Types and Lisp Types, Up: Foreign Types [Contents][Index]
Types may be either named or anonymous. With structure and union types, the name is part of the type specifier, allowing recursively defined types such as:
(struct foo (a (* (struct foo))))
An anonymous structure or union type is specified by using the name
nil. The with-alien macro defines a local scope which
“captures” any named type definitions. Other types are not
inherently named, but can be given named abbreviations using the
define-alien-type macro.
Next: Foreign Type Specifiers, Previous: Defining Foreign Types, Up: Foreign Types [Contents][Index]
The foreign types form a subsystem of the SBCL type system. An
alien type specifier provides a way to use any foreign type as a
Lisp type specifier. For example,
(typep foo '(alien (* int)))
can be used to determine whether foo is a pointer to a foreign
int. alien type specifiers can be used in the same ways
as ordinary Lisp type specifiers (like string.) Alien type
declarations are subject to the same precise type checking as any
other declaration. See Precise Type Checking.
Note that the type identifiers used in the foreign type system overlap
with native Lisp type specifiers in some cases. For example, the type
specifier (alien single-float) is identical to
single-float, since foreign floats are automatically converted
to Lisp floats. When type-of is called on an alien value that
is not automatically converted to a Lisp value, then it will return an
alien type specifier.
Previous: Foreign Types and Lisp Types, Up: Foreign Types [Contents][Index]
Note: All foreign type names are exported from the sb-alien
package. Some foreign type names are also symbols in
the common-lisp package, in which case they are
reexported from the sb-alien package, so that
e.g. it is legal to refer to sb-alien:single-float.
These are the basic foreign type specifiers:
(* foo) describes a pointer to
an object of type foo. A pointed-to type foo of t
indicates a pointer to anything, similar to void * in
ANSI C. A null alien pointer can be detected with the
sb-alien:null-alien function.
(array foo &rest
dimensions) describes array of the specified dimensions,
holding elements of type foo. Note that (unlike in C) (*
foo) and (array foo) are considered to be
different types when type checking is done. If equivalence of pointer
and array types is desired, it may be explicitly coerced using
sb-alien:cast.
Arrays are accessed using sb-alien:deref, passing the indices
as additional arguments. Elements are stored in column-major order
(as in C), so the first dimension determines only the size of the
memory block, and not the layout of the higher dimensions. An array
whose first dimension is variable may be specified by using nil
as the first dimension. Fixed-size arrays can be allocated as array
elements, structure slots or sb-alien:with-alien
variables. Dynamic arrays can only be allocated using
sb-alien:make-alien.
(sb-alien:struct name &rest
fields) describes a structure type with the specified
name and fields. Fields are allocated at the same offsets
used by the implementation’s C compiler, as guessed by the SBCL
internals. An optional :alignment keyword argument can be
specified for each field to explicitly control the alignment of a
field. If name is nil then the structure is anonymous.
If a named foreign struct specifier is passed to
define-alien-type or with-alien, then this defines,
respectively, a new global or local foreign structure type. If no
fields are specified, then the fields are taken
from the current (local or global) alien structure type definition of
name.
(sb-alien:union name &rest
fields) is similar to sb-alien:struct, but describes a
union type. All fields are allocated at the same offset, and the size
of the union is the size of the largest field. The programmer must
determine which field is active from context.
(sb-alien:enum name &rest
specs) describes an enumeration type that maps between integer
values and symbols. If name is nil, then the type is
anonymous. Each element of the specs list is either a Lisp
symbol, or a list (symbol value). value is
an integer. If value is not supplied, then it defaults to one
greater than the value for the preceding spec (or to zero if it is the
first spec).
(sb-alien:signed &optional
bits) specifies a signed integer with the specified number of
bits precision. The upper limit on integer
precision is determined by the machine’s word size. If
bits is not specified, the maximum size will be
used.
(integer &optional bits)
is equivalent to the corresponding type specifier using
sb-alien:signed instead of integer.
(sb-alien:unsigned &optional
bits) is like corresponding type specifier using
sb-alien:signed except that the variable is treated as an
unsigned integer.
(boolean &optional bits) is
similar to an enumeration type, but maps from Lisp nil and
t to C 0 and 1 respectively. bits
determines the amount of storage allocated to hold the truth value.
single-float describes a
floating-point number in IEEE single-precision format.
double-float describes a
floating-point number in IEEE double-precision format.
(function result-type &rest
arg-types) describes a foreign function that takes arguments of
the specified arg-types and returns a result of type
result-type. Note that the only context where a foreign
function type is directly specified is in the argument to
sb-alien:alien-funcall. In all other contexts, foreign
functions are represented by foreign function pointer types: (*
(function …)).
sb-alien:system-area-pointer
describes a pointer which is represented in Lisp as a
system-area-pointer object. SBCL exports this type from
sb-alien because CMUCL did, but tentatively (as of the first
draft of this section of the manual, SBCL 0.7.6) it is deprecated,
since it doesn’t seem to be required by user code.
sb-alien:void is used in function
types to declare that no useful value is returned. Using
alien-funcall to call a void foreign function will
return zero values.
(sb-alien:c-string &key
external-format element-type not-null) is similar to
(* char), but is interpreted as a null-terminated string, and
is automatically converted into a Lisp string when accessed; or if the
pointer is C NULL or 0, then accessing it gives Lisp
nil unless not-null is true, in which case a type-error
is signalled.
External format conversion is automatically done when Lisp strings are
passed to foreign code, or when foreign strings are passed to Lisp code.
If the type specifier has an explicit external-format, that
external format will be used. Otherwise a default external format that
has been determined at SBCL startup time based on the current locale
settings will be used. For example, when the following alien routine is
called, the Lisp string given as argument is converted to an
ebcdic octet representation.
(define-alien-routine test int (str (c-string :external-format :ebcdic-us)))
Lisp strings of type base-string are stored with a trailing NUL
termination, so no copying (either by the user or the implementation) is
necessary when passing them to foreign code, assuming that the
external-format and element-type of the c-string
type are compatible with the internal representation of the string. For
an SBCL built with Unicode support that means an external-format
of :ascii and an element-type of base-char. Without
Unicode support the external-format can also be
:iso-8859-1, and the element-type can also be
character. If the external-format or element-type
is not compatible, or the string is a (simple-array character
(*)), this data is copied by the implementation as required.
Assigning a Lisp string to a c-string structure field or
variable stores the contents of the string to the memory already
pointed to by that variable. When a foreign object of type (*
char) is assigned to a c-string, then the
c-string pointer is assigned to. This allows
c-string pointers to be initialized. For example:
(cl:in-package "CL-USER") ; which USEs package "SB-ALIEN"
(define-alien-type nil (struct foo (str c-string)))
(defun make-foo (str)
(let ((my-foo (make-alien (struct foo))))
(setf (slot my-foo 'str) (make-alien char (length str))
(slot my-foo 'str) str)
my-foo))
Storing Lisp NIL in a c-string writes C NULL to
the variable.
sb-alien also exports translations of these C type
specifiers as foreign type specifiers:
char,
short,
int,
long,
unsigned-char,
unsigned-short,
unsigned-int,
unsigned-long,
float, double,
size-t, and off-t.
Next: Foreign Variables, Previous: Foreign Types, Up: Foreign Function Interface [Contents][Index]
This section describes how to read foreign values as Lisp values, how to coerce foreign values to different kinds of foreign values, and how to dynamically allocate and free foreign variables.
| • Accessing Foreign Values: | ||
| • Coercing Foreign Values: | ||
| • Foreign Dynamic Allocation: |
Next: Coercing Foreign Values, Up: Operations On Foreign Values [Contents][Index]
The sb-alien:deref function returns the value pointed to by a
foreign pointer, or the value of a foreign array element. When
dereferencing a pointer, an optional single index can be specified to
give the equivalent of C pointer arithmetic; this index is scaled by
the size of the type pointed to. When dereferencing an array, the
number of indices must be the same as the number of dimensions in the
array type. deref can be set with setf to assign a new
value.
The sb-alien:slot function extracts the value of the slot named
slot-name from a foreign struct or union. If
struct-or-union is a pointer to a structure or union, then it is
automatically dereferenced. sb-alien:slot can be set with
setf to assign a new value. Note that slot-name is
evaluated, and need not be a compile-time constant (but only constant
slot accesses are efficiently compiled).
As noted at the beginning of the chapter, the System Area Pointer
facilities allow untyped access to foreign memory. SAPs can
be converted to and from the usual typed foreign values using
sap-alien and alien-sap (described elsewhere), and also
to and from integers - raw machine addresses. They should thus be
used with caution; corrupting the Lisp heap or other memory with
SAPs is trivial.
Creates a SAP pointing at the virtual address machine-address.
Access the value of the memory location at offset bytes from
sap. This form may also be used with setf to alter the
memory at that location.
Compare sap1 and sap2 for equality.
Similarly named functions exist for accessing other sizes of word,
other comparisons, and other conversions. The reader is invited to
use apropos and describe for more details
(apropos "sap" :sb-sys)
Next: Foreign Dynamic Allocation, Previous: Accessing Foreign Values, Up: Operations On Foreign Values [Contents][Index]
The sb-alien:addr macro returns a pointer to the location
specified by alien-expr, which must be either a foreign
variable, a use of sb-alien:deref, a use of
sb-alien:slot, or a use of sb-alien:extern-alien.
The sb-alien:cast macro converts foreign-value to a new
foreign value with the specified new-type. Both types, old and
new, must be foreign pointer, array or function types. Note that the
resulting Lisp foreign variable object is not eq to the
argument, but it does refer to the same foreign data bits.
The sb-alien:sap-alien macro converts sap (a system
area pointer) to a foreign value with the specified
type. type is not evaluated.
The type must be some foreign pointer, array, or record type.
The sb-alien:alien-sap function returns the SAP which
points to alien-value’s data.
The foreign-value must be of some foreign pointer, array, or record type.
Previous: Coercing Foreign Values, Up: Operations On Foreign Values [Contents][Index]
Lisp code can call the C standard library functions malloc and
free to dynamically allocate and deallocate foreign variables.
The Lisp code shares the same allocator with foreign C code, so it’s
OK for foreign code to call free on the result of Lisp
sb-alien:make-alien, or for Lisp code to call
sb-alien:free-alien on foreign objects allocated by C code.
Allocate an alien of type type in foreign heap, and return an alien
pointer to it. The allocated memory is not initialized, and may
contain garbage. The memory is allocated using malloc(3), so it can be
passed to foreign functions which use free(3), or released using
free-alien.
For alien stack allocation, see macro with-alien.
The type argument is not evaluated. If size is supplied, how it is
interpreted depends on type:
type is a foreign array type, an array of that type is
allocated, and a pointer to it is returned. Note that you
must use deref to first access the array through the pointer.
If supplied, size is used as the first dimension for the array.
type is any other foreign type, then an object for that
type is allocated, and a pointer to it is returned. So
(make-alien int) returns a (* int).
If size is specified, then a block of that many objects is
allocated, with the result pointing to the first one.
Examples:
(defvar *foo* (make-alien (array char 10))) (type-of *foo*) ; => (alien (* (array (signed 8) 10))) (setf (deref (deref foo) 0) 10) ; => 10 (make-alien char 12) ; => (alien (* (signed 8)))
Copy part of string delimited by start and end into freshly
allocated foreign memory, freeable using free(3) or free-alien.
Returns the allocated string as a (* char) alien, and the number of
bytes allocated as secondary value.
The string is encoded using external-format. If null-terminate is
true (the default), the alien string is terminated by an additional
null byte.
Dispose of the storage pointed to by alien. The alien must have been
allocated by make-alien, make-alien-string or malloc(3).
Next: Foreign Data Structure Examples, Previous: Operations On Foreign Values, Up: Foreign Function Interface [Contents][Index]
Both local (stack allocated) and external (C global) foreign variables are supported.
| • Local Foreign Variables: | ||
| • External Foreign Variables: |
Next: External Foreign Variables, Up: Foreign Variables [Contents][Index]
The with-alien macro establishes local foreign variables with
the specified alien types and names. This form is analogous to
defining a local variable in C: additional storage is allocated, and
the initial value is copied. This form is less analogous to
LET-allocated Lisp variables, since the variables can’t be
captured in closures: they live only for the dynamic extent of the
body, and referring to them outside is a gruesome error.
The var-definitions argument is a list of variable definitions, each of the form
(name type &optional initial-value)
The names of the variables are established as symbol-macros; the
bindings have lexical scope, and may be assigned with setq or
setf.
The with-alien macro also establishes a new scope for named
structures and unions. Any type specified for a variable may
contain named structure or union types with the slots specified.
Within the lexical scope of the binding specifiers and body, a locally
defined foreign structure type foo can be referenced by its name
using (struct foo).
Previous: Local Foreign Variables, Up: Foreign Variables [Contents][Index]
External foreign names are strings, and Lisp names are symbols. When
an external foreign value is represented using a Lisp variable, there
must be a way to convert from one name syntax into the other. The
macros extern-alien, define-alien-variable and
define-alien-routine use this conversion heuristic:
(alien-string lisp-symbol)
The define-alien-variable macro defines name as an
external foreign variable of the specified foreign type.
name and type are not evaluated. The Lisp name of the
variable (see above) becomes a global alien variable. Global alien
variables are effectively “global symbol macros”; a reference to the
variable fetches the contents of the external variable. Similarly,
setting the variable stores new contents – the new contents must be
of the declared type. Someday, they may well be implemented
using the ANSI define-symbol-macro mechanism, but as
of SBCL 0.7.5, they are still implemented using an older more-or-less
parallel mechanism inherited from CMUCL.
For example, to access a C-level counter foo, one could write
(define-alien-variable "foo" int) ;; Now it is possible to get the value of the C variable foo simply by ;; referencing that Lisp variable: (print foo) (setf foo 14) (incf foo)
Since in modern C libraries, the errno “variable” is typically
no longer a variable, but some bizarre artificial construct
which behaves superficially like a variable within a given thread,
it can no longer reliably be accessed through the ordinary
define-alien-variable mechanism. Instead, SBCL provides
the operator sb-alien:get-errno to allow Lisp code to read it.
The extern-alien macro returns an alien with the specified
type which points to an externally defined value. name is
not evaluated, and may be either a string or a symbol. type is
an unevaluated alien type specifier.
Next: Loading Shared Object Files, Previous: Foreign Variables, Up: Foreign Function Interface [Contents][Index]
Now that we have alien types, operations and variables, we can manipulate foreign data structures. This C declaration
struct foo {
int a;
struct foo *b[100];
};
can be translated into the following alien type:
(define-alien-type nil
(struct foo
(a int)
(b (array (* (struct foo)) 100))))
Once the foo alien type has been defined as above, the C
expression
struct foo f; f.b[7].a;
can be translated in this way:
(with-alien ((f (struct foo))) (slot (deref (slot f 'b) 7) 'a) ;; ;; Do something with f... )
Or consider this example of an external C variable and some accesses:
struct c_struct {
short x, y;
char a, b;
int z;
c_struct *n;
};
extern struct c_struct *my_struct;
my_struct->x++;
my_struct->a = 5;
my_struct = my_struct->n;
which can be manipulated in Lisp like this:
(define-alien-type nil
(struct c-struct
(x short)
(y short)
(a char)
(b char)
(z int)
(n (* c-struct))))
(define-alien-variable "my_struct" (* c-struct))
(incf (slot my-struct 'x))
(setf (slot my-struct 'a) 5)
(setq my-struct (slot my-struct 'n))