16432 lines
1,002 KiB
HTML
16432 lines
1,002 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<!-- 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. -->
|
|
<!-- Created by GNU Texinfo 6.7, http://www.gnu.org/software/texinfo/ -->
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<title>SBCL 2.2.8 User Manual</title>
|
|
|
|
<meta name="description" content="SBCL 2.2.8 User Manual">
|
|
<meta name="keywords" content="SBCL 2.2.8 User Manual">
|
|
<meta name="resource-type" content="document">
|
|
<meta name="distribution" content="global">
|
|
<meta name="Generator" content="makeinfo">
|
|
<link href="index.html#Top" rel="start" title="Top">
|
|
<link href="index.html#Concept-Index" rel="index" title="Concept Index">
|
|
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
|
|
<style type="text/css">
|
|
<!--
|
|
/*
|
|
* Based on version 1.0.1 of the texinfo-css stylesheet published by
|
|
* sirgazil (https://bitbucket.org/sirgazil/texinfo-css).
|
|
*
|
|
* Public domain 2016 sirgazil. All rights waived.
|
|
*/
|
|
|
|
/* NATIVE ELEMENTS */
|
|
|
|
a.summary-letter {text-decoration: none}
|
|
blockquote.indentedblock {margin-right: 0em}
|
|
div.display {margin-left: 3.2em}
|
|
div.example {margin-left: 3.2em}
|
|
div.lisp {margin-left: 3.2em}
|
|
kbd {font-style: oblique}
|
|
pre.display {font-family: inherit}
|
|
pre.format {font-family: inherit}
|
|
pre.menu-comment {font-family: serif}
|
|
pre.menu-preformatted {font-family: serif}
|
|
span.nolinebreak {white-space: nowrap}
|
|
span.roman {font-family: initial; font-weight: normal}
|
|
span.sansserif {font-family: sans-serif; font-weight: normal}
|
|
ul.no-bullet {list-style: none}
|
|
a:link,
|
|
a:visited {
|
|
color: #1E90FF;
|
|
text-decoration: none;
|
|
}
|
|
|
|
a:active,
|
|
a:focus,
|
|
a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
abbr,
|
|
acronym {
|
|
cursor: help;
|
|
}
|
|
|
|
blockquote {
|
|
color: #555753;
|
|
font-style: oblique;
|
|
margin: 30px 0px;
|
|
padding-left: 3em;
|
|
}
|
|
|
|
body {
|
|
background-color: white;
|
|
box-shadow: 0 0 2px gray;
|
|
box-sizing: border-box;
|
|
color: #333;
|
|
font-family: sans-serif;
|
|
font-size: 16px;
|
|
margin: 50px auto;
|
|
max-width: 70em; /*960px;*/
|
|
padding: 50px;
|
|
}
|
|
|
|
code,
|
|
samp,
|
|
tt,
|
|
var {
|
|
color: purple;
|
|
font-size: 0.8em;
|
|
}
|
|
|
|
div.example,
|
|
div.lisp {
|
|
margin: 0px;
|
|
}
|
|
|
|
dl {
|
|
margin: 3em 0em;
|
|
}
|
|
|
|
dl dl {
|
|
margin: 0em;
|
|
}
|
|
|
|
dt {
|
|
background-color: #F5F5F5;
|
|
padding: 0.5em;
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h2.contents-heading,
|
|
h3,
|
|
h4 {
|
|
padding: 20px 0px 0px 0px;
|
|
font-weight: normal;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 2.4em;
|
|
}
|
|
|
|
h2 {
|
|
font-size: 2.2em;
|
|
font-weight: bold;
|
|
}
|
|
|
|
h3 {
|
|
font-size: 1.8em;
|
|
}
|
|
|
|
h4 {
|
|
font-size: 1.4em;
|
|
}
|
|
|
|
hr {
|
|
background-color: silver;
|
|
border-style: none;
|
|
height: 1px;
|
|
margin: 0px;
|
|
}
|
|
|
|
html {
|
|
background-color: #F5F5F5;
|
|
}
|
|
|
|
img {
|
|
max-width: 100%;
|
|
}
|
|
|
|
li {
|
|
padding: 5px;
|
|
}
|
|
|
|
div.display,
|
|
div.example,
|
|
div.format,
|
|
div.lisp,
|
|
div.verbatim {
|
|
overflow: auto;
|
|
}
|
|
|
|
div.example,
|
|
div.lisp,
|
|
div.verbatim {
|
|
background-color: #F5F5F5; /* #2D3743;*/
|
|
border-color: #000;
|
|
border-style: solid;
|
|
border-width: thin;
|
|
/*color: #E1E1E1;*/
|
|
font-size: smaller;
|
|
padding: 1em;
|
|
}
|
|
|
|
pre {
|
|
padding: 0;
|
|
margin: 0 0 1em 0;
|
|
}
|
|
pre:last-of-type {
|
|
margin: 0 0 0 0;
|
|
}
|
|
|
|
table {
|
|
border-collapse: collapse;
|
|
margin: 40px 0px;
|
|
}
|
|
|
|
table.index-cp *,
|
|
table.index-fn *,
|
|
table.index-ky *,
|
|
table.index-pg *,
|
|
table.index-tp *,
|
|
table.index-vr * {
|
|
background-color: inherit;
|
|
border-style: none;
|
|
}
|
|
|
|
td,
|
|
th {
|
|
border-color: silver;
|
|
border-style: solid;
|
|
border-width: thin;
|
|
padding: 10px;
|
|
}
|
|
|
|
th {
|
|
background-color: #F5F5F5;
|
|
}
|
|
/* END NATIVE ELEMENTS */
|
|
|
|
|
|
|
|
/* CLASSES */
|
|
.contents {
|
|
margin-bottom: 4em;
|
|
}
|
|
|
|
.float {
|
|
margin: 3em 0em;
|
|
}
|
|
|
|
.float-caption {
|
|
font-size: smaller;
|
|
text-align: center;
|
|
}
|
|
|
|
.float > img {
|
|
display: block;
|
|
margin: auto;
|
|
}
|
|
|
|
.footnote {
|
|
font-size: smaller;
|
|
margin: 5em 0em;
|
|
}
|
|
|
|
.footnote h3 {
|
|
display: inline;
|
|
font-size: small;
|
|
}
|
|
|
|
.key {
|
|
color: purple;
|
|
font-size: 0.8em;
|
|
}
|
|
|
|
/* END CLASSES */
|
|
.header {
|
|
display: none;
|
|
}
|
|
|
|
.menu {
|
|
display: none;
|
|
}
|
|
|
|
-->
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
<body lang="en">
|
|
<h1 class="settitle" align="center">SBCL 2.2.8 User Manual</h1>
|
|
|
|
|
|
|
|
|
|
<span id="SEC_Contents"></span>
|
|
<h2 class="contents-heading">Table of Contents</h2>
|
|
|
|
<div class="contents">
|
|
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Getting-Support-and-Reporting-Bugs-1" href="index.html#Getting-Support-and-Reporting-Bugs">1 Getting Support and Reporting Bugs</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Volunteer-Support-1" href="index.html#Volunteer-Support">1.1 Volunteer Support</a></li>
|
|
<li><a id="toc-Commercial-Support-1" href="index.html#Commercial-Support">1.2 Commercial Support</a></li>
|
|
<li><a id="toc-Reporting-Bugs-1" href="index.html#Reporting-Bugs">1.3 Reporting Bugs</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-How-to-Report-Bugs-Effectively" href="index.html#How-to-Report-Bugs-Effectively">1.3.1 How to Report Bugs Effectively</a></li>
|
|
<li><a id="toc-Signal-Related-Bugs" href="index.html#Signal-Related-Bugs">1.3.2 Signal Related Bugs</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-Introduction-1" href="index.html#Introduction">2 Introduction</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-ANSI-Conformance-1" href="index.html#ANSI-Conformance">2.1 ANSI Conformance</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Exceptions" href="index.html#Exceptions-to-ANSI-Conformance">2.1.1 Exceptions</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Extensions-1" href="index.html#Extensions">2.2 Extensions</a></li>
|
|
<li><a id="toc-Idiosyncrasies-1" href="index.html#Idiosyncrasies">2.3 Idiosyncrasies</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Declarations-1" href="index.html#Declarations">2.3.1 Declarations</a></li>
|
|
<li><a id="toc-FASL-Format-1" href="index.html#FASL-Format">2.3.2 FASL Format</a></li>
|
|
<li><a id="toc-Compiler_002donly-Implementation-1" href="index.html#Compiler_002donly-Implementation">2.3.3 Compiler-only Implementation</a></li>
|
|
<li><a id="toc-Defining-Constants-1" href="index.html#Defining-Constants">2.3.4 Defining Constants</a></li>
|
|
<li><a id="toc-Style-Warnings-1" href="index.html#Style-Warnings">2.3.5 Style Warnings</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Development-Tools-1" href="index.html#Development-Tools">2.4 Development Tools</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Editor-Integration-1" href="index.html#Editor-Integration">2.4.1 Editor Integration</a></li>
|
|
<li><a id="toc-Language-Reference-1" href="index.html#Language-Reference">2.4.2 Language Reference</a></li>
|
|
<li><a id="toc-Generating-Executables-1" href="index.html#Generating-Executables">2.4.3 Generating Executables</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-More-SBCL-Information-1" href="index.html#More-SBCL-Information">2.5 More SBCL Information</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-SBCL-Homepage-1" href="index.html#SBCL-Homepage">2.5.1 SBCL Homepage</a></li>
|
|
<li><a id="toc-Online-Documentation-1" href="index.html#Online-Documentation">2.5.2 Online Documentation</a></li>
|
|
<li><a id="toc-Additional-Documentation-Files-1" href="index.html#Additional-Documentation-Files">2.5.3 Additional Documentation Files</a></li>
|
|
<li><a id="toc-Internals-Documentation-1" href="index.html#Internals-Documentation">2.5.4 Internals Documentation</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-More-Common-Lisp-Information-1" href="index.html#More-Common-Lisp-Information">2.6 More Common Lisp Information</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Internet-Community-1" href="index.html#Internet-Community">2.6.1 Internet Community</a></li>
|
|
<li><a id="toc-Third_002dparty-Libraries-1" href="index.html#Third_002dparty-Libraries">2.6.2 Third-party Libraries</a></li>
|
|
<li><a id="toc-Common-Lisp-Books-1" href="index.html#Common-Lisp-Books">2.6.3 Common Lisp Books</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-History-and-Implementation-of-SBCL-1" href="index.html#History-and-Implementation-of-SBCL">2.7 History and Implementation of SBCL</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Starting-and-Stopping-1" href="index.html#Starting-and-Stopping">3 Starting and Stopping</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Starting-SBCL-1" href="index.html#Starting-SBCL">3.1 Starting SBCL</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-From-Shell-to-Lisp" href="index.html#Running-from-Shell">3.1.1 From Shell to Lisp</a></li>
|
|
<li><a id="toc-Running-from-Emacs-1" href="index.html#Running-from-Emacs">3.1.2 Running from Emacs</a></li>
|
|
<li><a id="toc-Shebang-Scripts-1" href="index.html#Shebang-Scripts">3.1.3 Shebang Scripts</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Stopping-SBCL-1" href="index.html#Stopping-SBCL">3.2 Stopping SBCL</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Exit-1" href="index.html#Exit">3.2.1 Exit</a></li>
|
|
<li><a id="toc-End-of-File-1" href="index.html#End-of-File">3.2.2 End of File</a></li>
|
|
<li><a id="toc-Saving-a-Core-Image-1" href="index.html#Saving-a-Core-Image">3.2.3 Saving a Core Image</a></li>
|
|
<li><a id="toc-Exit-on-Errors-1" href="index.html#Exit-on-Errors">3.2.4 Exit on Errors</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Command-Line-Options-1" href="index.html#Command-Line-Options">3.3 Command Line Options</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Runtime-Options-1" href="index.html#Runtime-Options">3.3.1 Runtime Options</a></li>
|
|
<li><a id="toc-Toplevel-Options-1" href="index.html#Toplevel-Options">3.3.2 Toplevel Options</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Initialization-Files-1" href="index.html#Initialization-Files">3.4 Initialization Files</a></li>
|
|
<li><a id="toc-Initialization-and-Exit-Hooks-1" href="index.html#Initialization-and-Exit-Hooks">3.5 Initialization and Exit Hooks</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Compiler-1" href="index.html#Compiler">4 Compiler</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Diagnostic-Messages-1" href="index.html#Diagnostic-Messages">4.1 Diagnostic Messages</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Controlling-Verbosity-1" href="index.html#Controlling-Verbosity">4.1.1 Controlling Verbosity</a></li>
|
|
<li><a id="toc-Diagnostic-Severity-1" href="index.html#Diagnostic-Severity">4.1.2 Diagnostic Severity</a></li>
|
|
<li><a id="toc-Understanding-Compile-Diagnostics" href="index.html#Understanding-Compiler-Diagnostics">4.1.3 Understanding Compile Diagnostics</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-The-Parts-of-a-Compiler-Diagnostic-1" href="index.html#The-Parts-of-a-Compiler-Diagnostic">4.1.3.1 The Parts of a Compiler Diagnostic</a></li>
|
|
<li><a id="toc-The-Original-and-Actual-Source-1" href="index.html#The-Original-and-Actual-Source">4.1.3.2 The Original and Actual Source</a></li>
|
|
<li><a id="toc-The-Processing-Path-1" href="index.html#The-Processing-Path">4.1.3.3 The Processing Path</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-Handling-of-Types-1" href="index.html#Handling-of-Types">4.2 Handling of Types</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Declarations-as-Assertions-1" href="index.html#Declarations-as-Assertions">4.2.1 Declarations as Assertions</a></li>
|
|
<li><a id="toc-Precise-Type-Checking-1" href="index.html#Precise-Type-Checking">4.2.2 Precise Type Checking</a></li>
|
|
<li><a id="toc-Getting-Existing-Programs-to-Run-1" href="index.html#Getting-Existing-Programs-to-Run">4.2.3 Getting Existing Programs to Run</a></li>
|
|
<li><a id="toc-Implementation-Limitations-1" href="index.html#Implementation-Limitations">4.2.4 Implementation Limitations</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Compiler-Policy-1" href="index.html#Compiler-Policy">4.3 Compiler Policy</a></li>
|
|
<li><a id="toc-Compiler-Errors-1" href="index.html#Compiler-Errors">4.4 Compiler Errors</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Type-Errors-at-Compile-Time-1" href="index.html#Type-Errors-at-Compile-Time">4.4.1 Type Errors at Compile Time</a></li>
|
|
<li><a id="toc-Errors-During-Macroexpansion-1" href="index.html#Errors-During-Macroexpansion">4.4.2 Errors During Macroexpansion</a></li>
|
|
<li><a id="toc-Read-Errors-1" href="index.html#Read-Errors">4.4.3 Read Errors</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Open-Coding-and-Inline-Expansion-1" href="index.html#Open-Coding-and-Inline-Expansion">4.5 Open Coding and Inline Expansion</a></li>
|
|
<li><a id="toc-Interpreter-1" href="index.html#Interpreter">4.6 Interpreter</a></li>
|
|
<li><a id="toc-Advanced-Compiler-Use-and-Efficiency-Hints-1" href="index.html#Advanced-Compiler-Use-and-Efficiency-Hints">4.7 Advanced Compiler Use and Efficiency Hints</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Debugger-1" href="index.html#Debugger">5 Debugger</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Debugger-Entry-1" href="index.html#Debugger-Entry">5.1 Debugger Entry</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Debugger-Banner-1" href="index.html#Debugger-Banner">5.1.1 Debugger Banner</a></li>
|
|
<li><a id="toc-Debugger-Invocation-1" href="index.html#Debugger-Invocation">5.1.2 Debugger Invocation</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Debugger-Command-Loop-1" href="index.html#Debugger-Command-Loop">5.2 Debugger Command Loop</a></li>
|
|
<li><a id="toc-Stack-Frames-1" href="index.html#Stack-Frames">5.3 Stack Frames</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Stack-Motion-1" href="index.html#Stack-Motion">5.3.1 Stack Motion</a></li>
|
|
<li><a id="toc-How-Arguments-are-Printed-1" href="index.html#How-Arguments-are-Printed">5.3.2 How Arguments are Printed</a></li>
|
|
<li><a id="toc-Function-Names-1" href="index.html#Function-Names">5.3.3 Function Names</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Entry-Point-Details-1" href="index.html#Entry-Point-Details">5.3.3.1 Entry Point Details</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Debug-Tail-Recursion-1" href="index.html#Debug-Tail-Recursion">5.3.4 Debug Tail Recursion</a></li>
|
|
<li><a id="toc-Unknown-Locations-and-Interrupts-1" href="index.html#Unknown-Locations-and-Interrupts">5.3.5 Unknown Locations and Interrupts</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Variable-Access-1" href="index.html#Variable-Access">5.4 Variable Access</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Variable-Value-Availability-1" href="index.html#Variable-Value-Availability">5.4.1 Variable Value Availability</a></li>
|
|
<li><a id="toc-Note-On-Lexical-Variable-Access-1" href="index.html#Note-On-Lexical-Variable-Access">5.4.2 Note On Lexical Variable Access</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Source-Location-Printing-1" href="index.html#Source-Location-Printing">5.5 Source Location Printing</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-How-the-Source-is-Found-1" href="index.html#How-the-Source-is-Found">5.5.1 How the Source is Found</a></li>
|
|
<li><a id="toc-Source-Location-Availability-1" href="index.html#Source-Location-Availability">5.5.2 Source Location Availability</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Debugger-Policy-Control-1" href="index.html#Debugger-Policy-Control">5.6 Debugger Policy Control</a></li>
|
|
<li><a id="toc-Exiting-Commands-1" href="index.html#Exiting-Commands">5.7 Exiting Commands</a></li>
|
|
<li><a id="toc-Information-Commands-1" href="index.html#Information-Commands">5.8 Information Commands</a></li>
|
|
<li><a id="toc-Function-Tracing-1" href="index.html#Function-Tracing">5.9 Function Tracing</a></li>
|
|
<li><a id="toc-Single-Stepping-1" href="index.html#Single-Stepping">5.10 Single Stepping</a></li>
|
|
<li><a id="toc-Enabling-and-Disabling-the-Debugger-1" href="index.html#Enabling-and-Disabling-the-Debugger">5.11 Enabling and Disabling the Debugger</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Efficiency-1" href="index.html#Efficiency">6 Efficiency</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Slot-access-1" href="index.html#Slot-access">6.1 Slot access</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Structure-object-slot-access" href="index.html#Structure-object-slot-access">6.1.1 Structure object slot access</a></li>
|
|
<li><a id="toc-Standard-object-slot-access" href="index.html#Standard-object-slot-access">6.1.2 Standard object slot access</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Dynamic_002dextent-allocation-1" href="index.html#Dynamic_002dextent-allocation">6.2 Dynamic-extent allocation</a></li>
|
|
<li><a id="toc-Modular-arithmetic-1" href="index.html#Modular-arithmetic">6.3 Modular arithmetic</a></li>
|
|
<li><a id="toc-Global-and-Always_002dBound-variables-1" href="index.html#Global-and-Always_002dBound-variables">6.4 Global and Always-Bound variables</a></li>
|
|
<li><a id="toc-Miscellaneous-Efficiency-Issues-1" href="index.html#Miscellaneous-Efficiency-Issues">6.5 Miscellaneous Efficiency Issues</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Beyond-the-ANSI-Standard-1" href="index.html#Beyond-the-ANSI-Standard">7 Beyond the ANSI Standard</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Reader-Extensions-1" href="index.html#Reader-Extensions">7.1 Reader Extensions</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Extended-Package-Prefix-Syntax" href="index.html#Extended-Package-Prefix-Syntax">7.1.1 Extended Package Prefix Syntax</a></li>
|
|
<li><a id="toc-Symbol-Name-Normalization" href="index.html#Symbol-Name-Normalization">7.1.2 Symbol Name Normalization</a></li>
|
|
<li><a id="toc-Decimal-Syntax-for-Rationals" href="index.html#Decimal-Syntax-for-Rationals">7.1.3 Decimal Syntax for Rationals</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Package_002dLocal-Nicknames-1" href="index.html#Package_002dLocal-Nicknames">7.2 Package-Local Nicknames</a></li>
|
|
<li><a id="toc-Package-Variance-1" href="index.html#Package-Variance">7.3 Package Variance</a></li>
|
|
<li><a id="toc-Garbage-Collection-1" href="index.html#Garbage-Collection">7.4 Garbage Collection</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Finalization" href="index.html#Finalization">7.4.1 Finalization</a></li>
|
|
<li><a id="toc-Weak-Pointers" href="index.html#Weak-Pointers">7.4.2 Weak Pointers</a></li>
|
|
<li><a id="toc-Introspection-and-Tuning" href="index.html#Introspection-and-Tuning">7.4.3 Introspection and Tuning</a></li>
|
|
<li><a id="toc-Tracing-Live-Objects-Back-to-Roots" href="index.html#Tracing-Live-Objects-Back-to-Roots">7.4.4 Tracing Live Objects Back to Roots</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Metaobject-Protocol-1" href="index.html#Metaobject-Protocol">7.5 Metaobject Protocol</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-AMOP-Compatibility-of-Metaobject-Protocol" href="index.html#AMOP-Compatibility-of-Metaobject-Protocol">7.5.1 AMOP Compatibility of Metaobject Protocol</a></li>
|
|
<li><a id="toc-Metaobject-Protocol-Extensions" href="index.html#Metaobject-Protocol-Extensions">7.5.2 Metaobject Protocol Extensions</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Extensible-Sequences-1" href="index.html#Extensible-Sequences">7.6 Extensible Sequences</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Iterator-Protocol-1" href="index.html#Iterator-Protocol">7.6.1 Iterator Protocol</a></li>
|
|
<li><a id="toc-Simple-Iterator-Protocol-1" href="index.html#Simple-Iterator-Protocol">7.6.2 Simple Iterator Protocol</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Support-For-Unix-1" href="index.html#Support-For-Unix">7.7 Support For Unix</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Command_002dline-arguments-1" href="index.html#Command_002dline-arguments">7.7.1 Command-line arguments</a></li>
|
|
<li><a id="toc-Querying-the-process-environment-1" href="index.html#Querying-the-process-environment">7.7.2 Querying the process environment</a></li>
|
|
<li><a id="toc-Running-external-programs-1" href="index.html#Running-external-programs">7.7.3 Running external programs</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Unicode-Support-1" href="index.html#Unicode-Support">7.8 Unicode Support</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Unicode-property-access" href="index.html#Unicode-property-access">7.8.1 Unicode property access</a></li>
|
|
<li><a id="toc-String-operations" href="index.html#String-operations">7.8.2 String operations</a></li>
|
|
<li><a id="toc-Breaking-strings" href="index.html#Breaking-strings">7.8.3 Breaking strings</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Customization-Hooks-for-Users-1" href="index.html#Customization-Hooks-for-Users">7.9 Customization Hooks for Users</a></li>
|
|
<li><a id="toc-Tools-To-Help-Developers-1" href="index.html#Tools-To-Help-Developers">7.10 Tools To Help Developers</a></li>
|
|
<li><a id="toc-Resolution-of-Name-Conflicts-1" href="index.html#Resolution-of-Name-Conflicts">7.11 Resolution of Name Conflicts</a></li>
|
|
<li><a id="toc-Hash-Table-Extensions-1" href="index.html#Hash-Table-Extensions">7.12 Hash Table Extensions</a></li>
|
|
<li><a id="toc-Random-Number-Generation-1" href="index.html#Random-Number-Generation">7.13 Random Number Generation</a></li>
|
|
<li><a id="toc-Timeouts-and-Deadlines-1" href="index.html#Timeouts-and-Deadlines">7.14 Timeouts and Deadlines</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Timeout-Parameters-1" href="index.html#Timeout-Parameters">7.14.1 Timeout Parameters</a></li>
|
|
<li><a id="toc-Synchronous-Timeouts-_0028Deadlines_0029-1" href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">7.14.2 Synchronous Timeouts (Deadlines)</a></li>
|
|
<li><a id="toc-Asynchronous-Timeouts-1" href="index.html#Asynchronous-Timeouts">7.14.3 Asynchronous Timeouts</a></li>
|
|
<li><a id="toc-Operations-Supporting-Timeouts-and-Deadlines-1" href="index.html#Operations-Supporting-Timeouts-and-Deadlines">7.14.4 Operations Supporting Timeouts and Deadlines</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Miscellaneous-Extensions-1" href="index.html#Miscellaneous-Extensions">7.15 Miscellaneous Extensions</a></li>
|
|
<li><a id="toc-Stale-Extensions-1" href="index.html#Stale-Extensions">7.16 Stale Extensions</a></li>
|
|
<li><a id="toc-Efficiency-Hacks-1" href="index.html#Efficiency-Hacks">7.17 Efficiency Hacks</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-External-Formats-1" href="index.html#External-Formats">8 External Formats</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-The-Default-External-Format-1" href="index.html#The-Default-External-Format">8.1 The Default External Format</a></li>
|
|
<li><a id="toc-External-Format-Designators-1" href="index.html#External-Format-Designators">8.2 External Format Designators</a></li>
|
|
<li><a id="toc-Character-Coding-Conditions-1" href="index.html#Character-Coding-Conditions">8.3 Character Coding Conditions</a></li>
|
|
<li><a id="toc-Converting-between-Strings-and-Octet-Vectors-1" href="index.html#Converting-between-Strings-and-Octet-Vectors">8.4 Converting between Strings and Octet Vectors</a></li>
|
|
<li><a id="toc-Supported-External-Formats-1" href="index.html#Supported-External-Formats">8.5 Supported External Formats</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Foreign-Function-Interface-1" href="index.html#Foreign-Function-Interface">9 Foreign Function Interface</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Introduction-to-the-Foreign-Function-Interface-1" href="index.html#Introduction-to-the-Foreign-Function-Interface">9.1 Introduction to the Foreign Function Interface</a></li>
|
|
<li><a id="toc-Foreign-Types-1" href="index.html#Foreign-Types">9.2 Foreign Types</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Defining-Foreign-Types-1" href="index.html#Defining-Foreign-Types">9.2.1 Defining Foreign Types</a></li>
|
|
<li><a id="toc-Foreign-Types-and-Lisp-Types-1" href="index.html#Foreign-Types-and-Lisp-Types">9.2.2 Foreign Types and Lisp Types</a></li>
|
|
<li><a id="toc-Foreign-Type-Specifiers-1" href="index.html#Foreign-Type-Specifiers">9.2.3 Foreign Type Specifiers</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Operations-On-Foreign-Values-1" href="index.html#Operations-On-Foreign-Values">9.3 Operations On Foreign Values</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Accessing-Foreign-Values-1" href="index.html#Accessing-Foreign-Values">9.3.1 Accessing Foreign Values</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Untyped-memory" href="index.html#Untyped-memory">9.3.1.1 Untyped memory</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Coercing-Foreign-Values-1" href="index.html#Coercing-Foreign-Values">9.3.2 Coercing Foreign Values</a></li>
|
|
<li><a id="toc-Foreign-Dynamic-Allocation-1" href="index.html#Foreign-Dynamic-Allocation">9.3.3 Foreign Dynamic Allocation</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Foreign-Variables-1" href="index.html#Foreign-Variables">9.4 Foreign Variables</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Local-Foreign-Variables-1" href="index.html#Local-Foreign-Variables">9.4.1 Local Foreign Variables</a></li>
|
|
<li><a id="toc-External-Foreign-Variables-1" href="index.html#External-Foreign-Variables">9.4.2 External Foreign Variables</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Foreign-Data-Structure-Examples-1" href="index.html#Foreign-Data-Structure-Examples">9.5 Foreign Data Structure Examples</a></li>
|
|
<li><a id="toc-Loading-Shared-Object-Files-1" href="index.html#Loading-Shared-Object-Files">9.6 Loading Shared Object Files</a></li>
|
|
<li><a id="toc-Foreign-Function-Calls-1" href="index.html#Foreign-Function-Calls">9.7 Foreign Function Calls</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-The-alien_002dfuncall-Primitive-1" href="index.html#The-alien_002dfuncall-Primitive">9.7.1 The <code>alien-funcall</code> Primitive</a></li>
|
|
<li><a id="toc-The-define_002dalien_002droutine-Macro-1" href="index.html#The-define_002dalien_002droutine-Macro">9.7.2 The <code>define-alien-routine</code> Macro</a></li>
|
|
<li><a id="toc-define_002dalien_002droutine-Example-1" href="index.html#define_002dalien_002droutine-Example">9.7.3 <code>define-alien-routine</code> Example</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Calling-Lisp-From-C-1" href="index.html#Calling-Lisp-From-C">9.8 Calling Lisp From C</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Lisp-as-a-Shared-Library-1" href="index.html#Lisp-as-a-Shared-Library">9.8.1 Lisp as a Shared Library</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Step_002dBy_002dStep-Example-of-the-Foreign-Function-Interface-1" href="index.html#Step_002dBy_002dStep-Example-of-the-Foreign-Function-Interface">9.9 Step-By-Step Example of the Foreign Function Interface</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Pathnames-1" href="index.html#Pathnames">10 Pathnames</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Lisp-Pathnames-1" href="index.html#Lisp-Pathnames">10.1 Lisp Pathnames</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Home-Directory-Specifiers" href="index.html#Home-Directory-Specifiers">10.1.1 Home Directory Specifiers</a></li>
|
|
<li><a id="toc-The-SYS-Logical-Pathname-Host" href="index.html#The-SYS-Logical-Pathname-Host">10.1.2 The SYS Logical Pathname Host</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Native-Filenames-1" href="index.html#Native-Filenames">10.2 Native Filenames</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Streams-1" href="index.html#Streams">11 Streams</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Stream-External-Formats-1" href="index.html#Stream-External-Formats">11.1 Stream External Formats</a></li>
|
|
<li><a id="toc-Bivalent-Streams-1" href="index.html#Bivalent-Streams">11.2 Bivalent Streams</a></li>
|
|
<li><a id="toc-Gray-Streams-1" href="index.html#Gray-Streams">11.3 Gray Streams</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Gray-Streams-classes-1" href="index.html#Gray-Streams-classes">11.3.1 Gray Streams classes</a></li>
|
|
<li><a id="toc-Methods-common-to-all-streams-1" href="index.html#Methods-common-to-all-streams">11.3.2 Methods common to all streams</a></li>
|
|
<li><a id="toc-Input-stream-methods-1" href="index.html#Input-stream-methods">11.3.3 Input stream methods</a></li>
|
|
<li><a id="toc-Character-input-stream-methods-1" href="index.html#Character-input-stream-methods">11.3.4 Character input stream methods</a></li>
|
|
<li><a id="toc-Output-stream-methods-1" href="index.html#Output-stream-methods">11.3.5 Output stream methods</a></li>
|
|
<li><a id="toc-Character-output-stream-methods-1" href="index.html#Character-output-stream-methods">11.3.6 Character output stream methods</a></li>
|
|
<li><a id="toc-Binary-stream-methods-1" href="index.html#Binary-stream-methods">11.3.7 Binary stream methods</a></li>
|
|
<li><a id="toc-Gray-Streams-examples-1" href="index.html#Gray-Streams-examples">11.3.8 Gray Streams examples</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Character-counting-input-stream-1" href="index.html#Character-counting-input-stream">11.3.8.1 Character counting input stream</a></li>
|
|
<li><a id="toc-Output-prefixing-character-stream-1" href="index.html#Output-prefixing-character-stream">11.3.8.2 Output prefixing character stream</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-Simple-Streams-1" href="index.html#Simple-Streams">11.4 Simple Streams</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Package-Locks-1" href="index.html#Package-Locks">12 Package Locks</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Package-Lock-Concepts-1" href="index.html#Package-Lock-Concepts">12.1 Package Lock Concepts</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Package-Locking-Overview" href="index.html#Package-Lock-Overview">12.1.1 Package Locking Overview</a></li>
|
|
<li><a id="toc-Implementation-Packages-1" href="index.html#Implementation-Packages">12.1.2 Implementation Packages</a></li>
|
|
<li><a id="toc-Package-Lock-Violations-1" href="index.html#Package-Lock-Violations">12.1.3 Package Lock Violations</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Lexical-Bindings-and-Declarations" href="index.html#Lexical-Bindings-and-Declarations">12.1.3.1 Lexical Bindings and Declarations</a></li>
|
|
<li><a id="toc-Other-Operations" href="index.html#Other-Operations">12.1.3.2 Other Operations</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Package-Locks-in-Compiled-Code-1" href="index.html#Package-Locks-in-Compiled-Code">12.1.4 Package Locks in Compiled Code</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Interned-Symbols" href="index.html#Interned-Symbols">12.1.4.1 Interned Symbols</a></li>
|
|
<li><a id="toc-Other-Limitations-on-Compiled-Code" href="index.html#Other-Limitations-on-Compiled-Code">12.1.4.2 Other Limitations on Compiled Code</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Operations-Violating-Package-Locks-1" href="index.html#Operations-Violating-Package-Locks">12.1.5 Operations Violating Package Locks</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Operations-on-Packages" href="index.html#Operations-on-Packages">12.1.5.1 Operations on Packages</a></li>
|
|
<li><a id="toc-Operations-on-Symbols" href="index.html#Operations-on-Symbols">12.1.5.2 Operations on Symbols</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-Package-Lock-Dictionary-1" href="index.html#Package-Lock-Dictionary">12.2 Package Lock Dictionary</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Threading-1" href="index.html#Threading">13 Threading</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Threading-basics-1" href="index.html#Threading-basics">13.1 Threading basics</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Thread-Objects" href="index.html#Thread-Objects">13.1.1 Thread Objects</a></li>
|
|
<li><a id="toc-Making_002c-Returning-From_002c-Joining_002c-and-Yielding-Threads" href="index.html#Making_002c-Returning-From_002c-Joining_002c-and-Yielding-Threads">13.1.2 Making, Returning From, Joining, and Yielding Threads</a></li>
|
|
<li><a id="toc-Asynchronous-Operations" href="index.html#Asynchronous-Operations">13.1.3 Asynchronous Operations</a></li>
|
|
<li><a id="toc-Miscellaneous-Operations" href="index.html#Miscellaneous-Operations">13.1.4 Miscellaneous Operations</a></li>
|
|
<li><a id="toc-Error-Conditions" href="index.html#Error-Conditions">13.1.5 Error Conditions</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Special-Variables-1" href="index.html#Special-Variables">13.2 Special Variables</a></li>
|
|
<li><a id="toc-Atomic-Operations-1" href="index.html#Atomic-Operations">13.3 Atomic Operations</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-CAS-Protocol" href="index.html#CAS-Protocol">CAS Protocol</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Mutex-Support-1" href="index.html#Mutex-Support">13.4 Mutex Support</a></li>
|
|
<li><a id="toc-Semaphores-1" href="index.html#Semaphores">13.5 Semaphores</a></li>
|
|
<li><a id="toc-Waitqueue_002fcondition-variables-1" href="index.html#Waitqueue_002fcondition-variables">13.6 Waitqueue/condition variables</a></li>
|
|
<li><a id="toc-Barriers-1" href="index.html#Barriers">13.7 Barriers</a></li>
|
|
<li><a id="toc-Sessions_002fDebugging-1" href="index.html#Sessions_002fDebugging">13.8 Sessions/Debugging</a></li>
|
|
<li><a id="toc-Foreign-threads-1" href="index.html#Foreign-threads">13.9 Foreign threads</a></li>
|
|
<li><a id="toc-Implementation-_0028Linux-x86_002fx86_002d64_0029-1" href="index.html#Implementation-_0028Linux-x86_002fx86_002d64_0029">13.10 Implementation (Linux x86/x86-64)</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Timers-1" href="index.html#Timers">14 Timers</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Timer-Dictionary" href="index.html#Timer-Dictionary">14.1 Timer Dictionary</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Networking-1" href="index.html#Networking">15 Networking</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Sockets-Overview-1" href="index.html#Sockets-Overview">15.1 Sockets Overview</a></li>
|
|
<li><a id="toc-General-Sockets-1" href="index.html#General-Sockets">15.2 General Sockets</a></li>
|
|
<li><a id="toc-Socket-Options-1" href="index.html#Socket-Options">15.3 Socket Options</a></li>
|
|
<li><a id="toc-INET-Domain-Sockets-1" href="index.html#INET-Domain-Sockets">15.4 INET Domain Sockets</a></li>
|
|
<li><a id="toc-Local-_0028Unix_0029-Domain-Sockets-1" href="index.html#Local-_0028Unix_0029-Domain-Sockets">15.5 Local (Unix) Domain Sockets</a></li>
|
|
<li><a id="toc-Name-Service-1" href="index.html#Name-Service">15.6 Name Service</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Profiling-1" href="index.html#Profiling">16 Profiling</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Deterministic-Profiler-1" href="index.html#Deterministic-Profiler">16.1 Deterministic Profiler</a></li>
|
|
<li><a id="toc-Statistical-Profiler-1" href="index.html#Statistical-Profiler">16.2 Statistical Profiler</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Example-Usage" href="index.html#Example-Usage">16.2.1 Example Usage</a></li>
|
|
<li><a id="toc-Output" href="index.html#Output">16.2.2 Output</a></li>
|
|
<li><a id="toc-Platform-support" href="index.html#Platform-support">16.2.3 Platform support</a></li>
|
|
<li><a id="toc-Macros" href="index.html#Macros">16.2.4 Macros</a></li>
|
|
<li><a id="toc-Functions" href="index.html#Functions">16.2.5 Functions</a></li>
|
|
<li><a id="toc-Variables" href="index.html#Variables">16.2.6 Variables</a></li>
|
|
<li><a id="toc-Credits" href="index.html#Credits">16.2.7 Credits</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-Contributed-Modules-1" href="index.html#Contributed-Modules">17 Contributed Modules</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-sb_002daclrepl-1" href="index.html#sb_002daclrepl">17.1 sb-aclrepl</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Usage" href="index.html#Usage">17.1.1 Usage</a></li>
|
|
<li><a id="toc-Customization" href="index.html#Customization">17.1.2 Customization</a></li>
|
|
<li><a id="toc-Example-Initialization" href="index.html#Example-Initialization">17.1.3 Example Initialization</a></li>
|
|
<li><a id="toc-Credits-1" href="index.html#Credits-1">17.1.4 Credits</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-sb_002dconcurrency-1" href="index.html#sb_002dconcurrency">17.2 sb-concurrency</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Queue" href="index.html#Queue">17.2.1 Queue</a></li>
|
|
<li><a id="toc-Mailbox-_0028lock_002dfree_0029" href="index.html#Mailbox-_0028lock_002dfree_0029">17.2.2 Mailbox (lock-free)</a></li>
|
|
<li><a id="toc-Gates" href="index.html#Gates">17.2.3 Gates</a></li>
|
|
<li><a id="toc-Frlocks_002c-aka-Fast-Read-Locks" href="index.html#Frlocks_002c-aka-Fast-Read-Locks">17.2.4 Frlocks, aka Fast Read Locks</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-sb_002dcover-1" href="index.html#sb_002dcover">17.3 sb-cover</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Example-Usage-1" href="index.html#Example-Usage-1">17.3.1 Example Usage</a></li>
|
|
<li><a id="toc-Functions-1" href="index.html#Functions-1">17.3.2 Functions</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-sb_002dgrovel-1" href="index.html#sb_002dgrovel">17.4 sb-grovel</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Using-sb_002dgrovel-in-your-own-ASDF-system" href="index.html#Using-sb_002dgrovel-in-your-own-ASDF-system">17.4.1 Using sb-grovel in your own ASDF system</a></li>
|
|
<li><a id="toc-Contents-of-a-grovel_002dconstants_002dfile" href="index.html#Contents-of-a-grovel_002dconstants_002dfile">17.4.2 Contents of a grovel-constants-file</a></li>
|
|
<li><a id="toc-Programming-with-sb_002dgrovel_0027s-structure-types" href="index.html#Programming-with-sb_002dgrovel_0027s-structure-types">17.4.3 Programming with sb-grovel’s structure types</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Traps-and-Pitfalls" href="index.html#Traps-and-Pitfalls">17.4.3.1 Traps and Pitfalls</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-sb_002dmd5-1" href="index.html#sb_002dmd5">17.5 sb-md5</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Credits-2" href="index.html#Credits-2">17.5.1 Credits</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-sb_002dposix-1" href="index.html#sb_002dposix">17.6 sb-posix</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Lisp-names-for-C-names-1" href="index.html#Lisp-names-for-C-names">17.6.1 Lisp names for C names</a></li>
|
|
<li><a id="toc-Types-1" href="index.html#Types">17.6.2 Types</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-File_002ddescriptors-1" href="index.html#File_002ddescriptors">17.6.2.1 File-descriptors</a></li>
|
|
<li><a id="toc-Filenames-1" href="index.html#Filenames">17.6.2.2 Filenames</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Function-Parameters-1" href="index.html#Function-Parameters">17.6.3 Function Parameters</a></li>
|
|
<li><a id="toc-Function-Return-Values-1" href="index.html#Function-Return-Values">17.6.4 Function Return Values</a></li>
|
|
<li><a id="toc-Lisp-objects-and-C-structures-1" href="index.html#Lisp-objects-and-C-structures">17.6.5 Lisp objects and C structures</a></li>
|
|
<li><a id="toc-Functions-with-idiosyncratic-bindings-1" href="index.html#Functions-with-idiosyncratic-bindings">17.6.6 Functions with idiosyncratic bindings</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-sb_002dqueue-1" href="index.html#sb_002dqueue">17.7 sb-queue</a></li>
|
|
<li><a id="toc-sb_002drotate_002dbyte-1" href="index.html#sb_002drotate_002dbyte">17.8 sb-rotate-byte</a></li>
|
|
<li><a id="toc-sb_002dsimd-1" href="index.html#sb_002dsimd">17.9 sb-simd</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Data-Types" href="index.html#Data-Types">17.9.1 Data Types</a></li>
|
|
<li><a id="toc-Casts" href="index.html#Casts">17.9.2 Casts</a></li>
|
|
<li><a id="toc-Constructors" href="index.html#Constructors">17.9.3 Constructors</a></li>
|
|
<li><a id="toc-Unpackers" href="index.html#Unpackers">17.9.4 Unpackers</a></li>
|
|
<li><a id="toc-Reinterpret-Casts" href="index.html#Reinterpret-Casts">17.9.5 Reinterpret Casts</a></li>
|
|
<li><a id="toc-Associatives" href="index.html#Associatives">17.9.6 Associatives</a></li>
|
|
<li><a id="toc-Reducers" href="index.html#Reducers">17.9.7 Reducers</a></li>
|
|
<li><a id="toc-Rounding" href="index.html#Rounding">17.9.8 Rounding</a></li>
|
|
<li><a id="toc-Comparisons" href="index.html#Comparisons">17.9.9 Comparisons</a></li>
|
|
<li><a id="toc-Conditionals" href="index.html#Conditionals">17.9.10 Conditionals</a></li>
|
|
<li><a id="toc-Loads-and-Stores" href="index.html#Loads-and-Stores">17.9.11 Loads and Stores</a></li>
|
|
<li><a id="toc-Specialized-Scalar-Operations" href="index.html#Specialized-Scalar-Operations">17.9.12 Specialized Scalar Operations</a></li>
|
|
<li><a id="toc-Instruction-Set-Dispatch" href="index.html#Instruction-Set-Dispatch">17.9.13 Instruction Set Dispatch</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-Deprecation-1" href="index.html#Deprecation">18 Deprecation</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Why-Deprecate_003f-1" href="index.html#Why-Deprecate_003f">18.1 Why Deprecate?</a></li>
|
|
<li><a id="toc-The-Deprecation-Pipeline-1" href="index.html#The-Deprecation-Pipeline">18.2 The Deprecation Pipeline</a></li>
|
|
<li><a id="toc-Deprecation-Conditions-1" href="index.html#Deprecation-Conditions">18.3 Deprecation Conditions</a></li>
|
|
<li><a id="toc-Introspecting-Deprecation-Information-1" href="index.html#Introspecting-Deprecation-Information">18.4 Introspecting Deprecation Information</a></li>
|
|
<li><a id="toc-Deprecation-Declaration-1" href="index.html#Deprecation-Declaration">18.5 Deprecation Declaration</a></li>
|
|
<li><a id="toc-Deprecation-Examples-1" href="index.html#Deprecation-Examples">18.6 Deprecation Examples</a></li>
|
|
<li><a id="toc-Deprecated-Interfaces-in-SBCL-1" href="index.html#Deprecated-Interfaces-in-SBCL">18.7 Deprecated Interfaces in SBCL</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-List-of-Deprecated-Interfaces" href="index.html#List-of-Deprecated-Interfaces">18.7.1 List of Deprecated Interfaces</a>
|
|
<ul class="no-bullet">
|
|
<li><a id="toc-Early-Deprecation" href="index.html#Early-Deprecation">18.7.1.1 Early Deprecation</a></li>
|
|
<li><a id="toc-Late-Deprecation" href="index.html#Late-Deprecation">18.7.1.2 Late Deprecation</a></li>
|
|
<li><a id="toc-Final-Deprecation" href="index.html#Final-Deprecation">18.7.1.3 Final Deprecation</a></li>
|
|
</ul></li>
|
|
<li><a id="toc-Historical-Interfaces" href="index.html#Historical-Interfaces">18.7.2 Historical Interfaces</a></li>
|
|
</ul></li>
|
|
</ul></li>
|
|
<li><a id="toc-Concept-Index-1" href="index.html#Concept-Index" rel="index">Appendix A Concept Index</a></li>
|
|
<li><a id="toc-Function-Index-1" href="index.html#Function-Index" rel="index">Appendix B Function Index</a></li>
|
|
<li><a id="toc-Variable-Index-1" href="index.html#Variable-Index" rel="index">Appendix C Variable Index</a></li>
|
|
<li><a id="toc-Type-Index-1" href="index.html#Type-Index" rel="index">Appendix D Type Index</a></li>
|
|
<li><a id="toc-Colophon-1" href="index.html#Colophon">Colophon</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<span id="Top"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Getting-Support-and-Reporting-Bugs" accesskey="n" rel="next">Getting Support and Reporting Bugs</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sbcl"></span><h1 class="top">sbcl</h1>
|
|
|
|
<blockquote>
|
|
<p>This manual is part of the SBCL software system. See
|
|
the <samp>README</samp> file for more information.
|
|
</p>
|
|
<p>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 <samp>COPYING</samp> and
|
|
<samp>CREDITS</samp> files for more information.
|
|
</p></blockquote>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Getting-Support-and-Reporting-Bugs" accesskey="1">Getting Support and Reporting Bugs</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Introduction" accesskey="2">Introduction</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Starting-and-Stopping" accesskey="3">Starting and Stopping</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Compiler" accesskey="4">Compiler</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Debugger" accesskey="5">Debugger</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Efficiency" accesskey="6">Efficiency</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Beyond-the-ANSI-Standard" accesskey="7">Beyond the ANSI Standard</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#External-Formats" accesskey="8">External Formats</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Function-Interface" accesskey="9">Foreign Function Interface</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Pathnames">Pathnames</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Streams">Streams</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package-Locks">Package Locks</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Threading">Threading</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Timers">Timers</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Networking">Networking</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Profiling">Profiling</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Contributed-Modules">Contributed Modules</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Deprecation">Deprecation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Concept-Index" rel="index">Concept Index</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Function-Index" rel="index">Function Index</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Variable-Index" rel="index">Variable Index</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Type-Index" rel="index">Type Index</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Colophon">Colophon</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
|
|
<hr>
|
|
<span id="Getting-Support-and-Reporting-Bugs"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Introduction" accesskey="n" rel="next">Introduction</a>, Previous: <a href="index.html#Top" accesskey="p" rel="prev">Top</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Getting-Support-and-Reporting-Bugs-1"></span><h2 class="chapter">1 Getting Support and Reporting Bugs</h2>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Volunteer-Support" accesskey="1">Volunteer Support</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Commercial-Support" accesskey="2">Commercial Support</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Reporting-Bugs" accesskey="3">Reporting Bugs</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Volunteer-Support"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Commercial-Support" accesskey="n" rel="next">Commercial Support</a>, Up: <a href="index.html#Getting-Support-and-Reporting-Bugs" accesskey="u" rel="up">Getting Support and Reporting Bugs</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Volunteer-Support-1"></span><h3 class="section">1.1 Volunteer Support</h3>
|
|
|
|
<p>Your primary source of SBCL support should probably be the mailing
|
|
list <strong>sbcl-help</strong>: 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:
|
|
</p>
|
|
<p> <!-- /@w --> <!-- /@w --> <a href="https://lists.sourceforge.net/lists/listinfo/sbcl-help">https://lists.sourceforge.net/lists/listinfo/sbcl-help</a>
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>Before sending mail, check the list archives at either
|
|
</p>
|
|
<p> <!-- /@w --> <!-- /@w --> <a href="http://sourceforge.net/mailarchive/forum.php?forum_name=sbcl-help">http://sourceforge.net/mailarchive/forum.php?forum_name=sbcl-help</a>
|
|
</p>
|
|
<p>or
|
|
</p>
|
|
<p> <!-- /@w --> <!-- /@w --> <a href="http://news.gmane.org/gmane.lisp.steel-bank.general">http://news.gmane.org/gmane.lisp.steel-bank.general</a>
|
|
</p>
|
|
<p>to see if your question has been answered already. Checking the bug
|
|
database is also worth it See <a href="index.html#Reporting-Bugs">Reporting Bugs</a>, to see if the issue
|
|
is already known.
|
|
</p>
|
|
<p>For general advice on asking good questions, see
|
|
</p>
|
|
<p> <!-- /@w --> <!-- /@w --> <a href="http://www.catb.org/~esr/faqs/smart-questions.html">http://www.catb.org/~esr/faqs/smart-questions.html</a>.
|
|
</p>
|
|
<hr>
|
|
<span id="Commercial-Support"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Reporting-Bugs" accesskey="n" rel="next">Reporting Bugs</a>, Previous: <a href="index.html#Volunteer-Support" accesskey="p" rel="prev">Volunteer Support</a>, Up: <a href="index.html#Getting-Support-and-Reporting-Bugs" accesskey="u" rel="up">Getting Support and Reporting Bugs</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Commercial-Support-1"></span><h3 class="section">1.2 Commercial Support</h3>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>(At present, no companies or consultants wish to advertise paid support
|
|
or custom SBCL development in this manual).
|
|
</p>
|
|
<hr>
|
|
<span id="Reporting-Bugs"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Commercial-Support" accesskey="p" rel="prev">Commercial Support</a>, Up: <a href="index.html#Getting-Support-and-Reporting-Bugs" accesskey="u" rel="up">Getting Support and Reporting Bugs</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Reporting-Bugs-1"></span><h3 class="section">1.3 Reporting Bugs</h3>
|
|
|
|
<p>SBCL uses Launchpad to track bugs. The bug database is available at
|
|
</p>
|
|
<p> <!-- /@w --> <!-- /@w --> <a href="https://bugs.launchpad.net/sbcl">https://bugs.launchpad.net/sbcl</a>
|
|
</p>
|
|
<p>Reporting bugs there requires registering at Launchpad. However, bugs
|
|
can also be reported on the mailing list <strong>sbcl-bugs</strong>, which is
|
|
moderated but does <em>not</em> require subscribing.
|
|
</p>
|
|
<p>Simply send email to <a href="mailto:sbcl-bugs@lists.sourceforge.net">sbcl-bugs@lists.sourceforge.net</a> and the
|
|
bug will be checked and added to Launchpad by SBCL maintainers.
|
|
</p>
|
|
<span id="How-to-Report-Bugs-Effectively"></span><h4 class="subsection">1.3.1 How to Report Bugs Effectively</h4>
|
|
|
|
<p>Please include enough information in a bug report that someone reading
|
|
it can reproduce the problem, i.e. don’t write
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">Subject: apparent bug in PRINT-OBJECT (or *PRINT-LENGTH*?)
|
|
PRINT-OBJECT doesn't seem to work with *PRINT-LENGTH*. Is this a bug?
|
|
</pre></div>
|
|
|
|
<p>but instead
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">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.
|
|
</pre></div>
|
|
|
|
<p>A more in-depth discussion on reporting bugs effectively can be found
|
|
at
|
|
</p>
|
|
<p> <!-- /@w --> <!-- /@w --> <a href="http://www.chiark.greenend.org.uk/~sgtatham/bugs.html">http://www.chiark.greenend.org.uk/~sgtatham/bugs.html</a>.
|
|
</p>
|
|
<span id="Signal-Related-Bugs"></span><h4 class="subsection">1.3.2 Signal Related Bugs</h4>
|
|
|
|
<p>If you run into a signal related bug, you are getting fatal errors
|
|
such as <code>signal N is [un]blocked</code> or just hangs, and you want to
|
|
send a useful bug report then:
|
|
</p>
|
|
<ol>
|
|
<li> <span id="index-ldb"></span>
|
|
Compile SBCL with ldb enabled (feature <code>:sb-ldb</code>, see
|
|
<samp>base-target-features.lisp-expr</samp>).
|
|
|
|
</li><li> Isolate a smallish test case, run it.
|
|
|
|
</li><li> If it just hangs kill it with sigabrt: <code>kill -ABRT <pidof sbcl></code>.
|
|
|
|
</li><li> Print the backtrace from ldb by typing <code>ba</code>.
|
|
|
|
</li><li> Attach gdb: <code>gdb -p <pidof sbcl></code> and get backtraces for all threads:
|
|
<code>thread apply all ba</code>.
|
|
|
|
</li><li> If multiple threads are in play then still in gdb, try to get Lisp
|
|
backtrace for all threads: <code>thread apply all call
|
|
backtrace_from_fp($ebp, 100)</code>. Substitute <code>$ebp</code> with <code>$rbp</code>
|
|
on x86-64. The backtraces will appear in the stdout of the SBCL
|
|
process.
|
|
|
|
</li><li> Send a report with the backtraces and the output (both stdout and
|
|
stderr) produced by SBCL.
|
|
|
|
</li><li> Don’t forget to include OS and SBCL version.
|
|
|
|
</li><li> If available, include information on outcome of the same test with
|
|
other versions of SBCL, OS, ...
|
|
</li></ol>
|
|
<hr>
|
|
<span id="Introduction"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Starting-and-Stopping" accesskey="n" rel="next">Starting and Stopping</a>, Previous: <a href="index.html#Getting-Support-and-Reporting-Bugs" accesskey="p" rel="prev">Getting Support and Reporting Bugs</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Introduction-1"></span><h2 class="chapter">2 Introduction</h2>
|
|
|
|
<p>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.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#ANSI-Conformance" accesskey="1">ANSI Conformance</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Extensions" accesskey="2">Extensions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Idiosyncrasies" accesskey="3">Idiosyncrasies</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Development-Tools" accesskey="4">Development Tools</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#More-SBCL-Information" accesskey="5">More SBCL Information</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#More-Common-Lisp-Information" accesskey="6">More Common Lisp Information</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#History-and-Implementation-of-SBCL" accesskey="7">History and Implementation of SBCL</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="ANSI-Conformance"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Extensions" accesskey="n" rel="next">Extensions</a>, Up: <a href="index.html#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="ANSI-Conformance-1"></span><h3 class="section">2.1 ANSI Conformance</h3>
|
|
|
|
<p>Essentially every type of non-conformance is considered a bug. (The
|
|
exceptions involve internal inconsistencies in the standard.)
|
|
See <a href="index.html#Reporting-Bugs">Reporting Bugs</a>.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Exceptions-to-ANSI-Conformance" accesskey="1">Exceptions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Exceptions-to-ANSI-Conformance"></span><div class="header">
|
|
<p>
|
|
Up: <a href="index.html#ANSI-Conformance" accesskey="u" rel="up">ANSI Conformance</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Exceptions"></span><h4 class="subsection">2.1.1 Exceptions</h4>
|
|
|
|
<ul>
|
|
<li> <span id="index-prog2-_005bcl_005d"></span>
|
|
<code>prog2</code> returns the primary value of its second form, as
|
|
specified in the <strong>Arguments and Values</strong> section of the
|
|
specification for that operator, not that of its first form, as
|
|
specified in the <strong>Description</strong>.
|
|
|
|
</li><li> <span id="index-string-_005bcl_005d"></span>
|
|
<span id="index-character-_005bcl_005d"></span>
|
|
<span id="index-nil-_005bcl_005d"></span>
|
|
The <code>string</code> type is considered to be the union of all types
|
|
<code>(array <em>c</em> (<em>size</em>))</code> for all non-<code>nil</code> subtypes <code><em>c</em></code> of
|
|
<code>character</code>, excluding arrays specialized to the empty type.
|
|
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="Extensions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Idiosyncrasies" accesskey="n" rel="next">Idiosyncrasies</a>, Previous: <a href="index.html#ANSI-Conformance" accesskey="p" rel="prev">ANSI Conformance</a>, Up: <a href="index.html#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Extensions-1"></span><h3 class="section">2.2 Extensions</h3>
|
|
|
|
<p>SBCL comes with numerous extensions, some in core and some in modules
|
|
loadable with <code>require</code>. Unfortunately, not all of these
|
|
extensions have proper documentation yet.
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><strong>System Definition Tool</strong></dt>
|
|
<dd><p><code>asdf</code> is a flexible and popular protocol-oriented system
|
|
definition tool by Daniel Barlow. See <a href="https://sbcl.org/manual/asdf.html#Top">(asdf)the asdf manual</a>, for
|
|
more information.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Foreign Function Interface</strong></dt>
|
|
<dd><p><code>sb-alien</code> package allows interfacing with C-code, loading shared
|
|
object files, etc. See <a href="index.html#Foreign-Function-Interface">Foreign Function Interface</a>.
|
|
</p>
|
|
<p><code>sb-grovel</code> can be used to partially automate generation of
|
|
foreign function interface definitions. See <a href="index.html#sb_002dgrovel">sb-grovel</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Recursive Event Loop</strong></dt>
|
|
<dd><p>SBCL provides a recursive event loop (<code>serve-event</code>) for doing
|
|
non-blocking IO on multiple streams without using threads.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Timeouts and Deadlines</strong></dt>
|
|
<dd><p>SBCL allows restricting the execution time of individual operations or
|
|
parts of a computation using <code>:timeout</code> 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 <a href="index.html#Timeouts-and-Deadlines">Timeouts and Deadlines</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Metaobject Protocol</strong></dt>
|
|
<dd><p><code>sb-mop</code> package provides a metaobject protocol for the Common
|
|
Lisp Object System as described in <cite>Art of Metaobject Protocol</cite>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Extensible Sequences</strong></dt>
|
|
<dd><p>SBCL allows users to define subclasses of the <code>sequence</code>
|
|
class. See <a href="index.html#Extensible-Sequences">Extensible Sequences</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Native Threads</strong></dt>
|
|
<dd><p>SBCL has native threads on x86/Linux, capable of taking advantage
|
|
of SMP on multiprocessor machines. See <a href="index.html#Threading">Threading</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Network Interface</strong></dt>
|
|
<dd><p><code>sb-bsd-sockets</code> is a low-level networking interface, providing
|
|
both TCP and UDP sockets. See <a href="index.html#Networking">Networking</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Introspective Facilities</strong></dt>
|
|
<dd><p><code>sb-introspect</code> module offers numerous introspective extensions,
|
|
including access to function lambda-lists and a cross referencing
|
|
facility.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Operating System Interface</strong></dt>
|
|
<dd><p><code>sb-ext</code> contains a number of functions for running external
|
|
processes, accessing environment variables, etc.
|
|
</p>
|
|
<p><code>sb-posix</code> module provides a lispy interface to standard POSIX
|
|
facilities.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Extensible Streams</strong></dt>
|
|
<dd><p><code>sb-gray</code> is an implementation of <em>Gray Streams</em>. See <a href="index.html#Gray-Streams">Gray Streams</a>.
|
|
</p>
|
|
<p><code>sb-simple-streams</code> is an implementation of the <em>simple
|
|
streams</em> API proposed by Franz Inc. See <a href="index.html#Simple-Streams">Simple Streams</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Profiling</strong></dt>
|
|
<dd><p><code>sb-profile</code> is a exact per-function profiler. See <a href="index.html#Deterministic-Profiler">Deterministic Profiler</a>.
|
|
</p>
|
|
<p><code>sb-sprof</code> is a statistical profiler, capable of call-graph
|
|
generation and instruction level profiling, which also supports
|
|
allocation profiling. See <a href="index.html#Statistical-Profiler">Statistical Profiler</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Customization Hooks</strong></dt>
|
|
<dd><p>SBCL contains a number of extra-standard customization hooks that
|
|
can be used to tweak the behaviour of the system. See <a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a>.
|
|
</p>
|
|
<p><code>sb-aclrepl</code> provides an Allegro CL -style toplevel for SBCL,
|
|
as an alternative to the classic CMUCL-style one. See <a href="index.html#sb_002daclrepl">sb-aclrepl</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>CLTL2 Compatibility Layer</strong></dt>
|
|
<dd><p><code>sb-cltl2</code> module provides <code>compiler-let</code> and environment
|
|
access functionality described in <cite>Common Lisp The Language, 2nd
|
|
Edition</cite> which were removed from the language during the ANSI
|
|
standardization process.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Executable Delivery</strong></dt>
|
|
<dd><p>The <code>:executable</code> argument to <a href="index.html#Function-sb_002dext-save_002dlisp_002dand_002ddie">Function sb-ext save-lisp-and-die</a> can produce a ‘standalone’ executable
|
|
containing both an image of the current Lisp session and an SBCL
|
|
runtime.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Bitwise Rotation</strong></dt>
|
|
<dd><p><code>sb-rotate-byte</code> 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 <a href="index.html#sb_002drotate_002dbyte">sb-rotate-byte</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Test Harness</strong></dt>
|
|
<dd><p><code>sb-rt</code> module is a simple yet attractive regression and
|
|
unit-test framework.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>MD5 Sums</strong></dt>
|
|
<dd><p><code>sb-md5</code> is an implementation of the MD5 message digest algorithm
|
|
for Common Lisp, using the modular arithmetic optimizations provided
|
|
by SBCL. See <a href="index.html#sb_002dmd5">sb-md5</a>.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="Idiosyncrasies"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Development-Tools" accesskey="n" rel="next">Development Tools</a>, Previous: <a href="index.html#Extensions" accesskey="p" rel="prev">Extensions</a>, Up: <a href="index.html#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Idiosyncrasies-1"></span><h3 class="section">2.3 Idiosyncrasies</h3>
|
|
|
|
<p>The information in this section describes some of the ways that SBCL
|
|
deals with choices that the ANSI standard leaves to the
|
|
implementation.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Declarations" accesskey="1">Declarations</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#FASL-Format" accesskey="2">FASL Format</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Compiler_002donly-Implementation" accesskey="3">Compiler-only Implementation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Defining-Constants" accesskey="4">Defining Constants</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Style-Warnings" accesskey="5">Style Warnings</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Declarations"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#FASL-Format" accesskey="n" rel="next">FASL Format</a>, Up: <a href="index.html#Idiosyncrasies" accesskey="u" rel="up">Idiosyncrasies</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Declarations-1"></span><h4 class="subsection">2.3.1 Declarations</h4>
|
|
|
|
<p>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
|
|
<a href="index.html#Declarations-as-Assertions">Declarations as Assertions</a>.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="FASL-Format"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Compiler_002donly-Implementation" accesskey="n" rel="next">Compiler-only Implementation</a>, Previous: <a href="index.html#Declarations" accesskey="p" rel="prev">Declarations</a>, Up: <a href="index.html#Idiosyncrasies" accesskey="u" rel="up">Idiosyncrasies</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="FASL-Format-1"></span><h4 class="subsection">2.3.2 FASL Format</h4>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>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 <a href="index.html#Initialization-Files">Initialization Files</a>.)
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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))))
|
|
</pre></div>
|
|
|
|
|
|
<hr>
|
|
<span id="Compiler_002donly-Implementation"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Defining-Constants" accesskey="n" rel="next">Defining Constants</a>, Previous: <a href="index.html#FASL-Format" accesskey="p" rel="prev">FASL Format</a>, Up: <a href="index.html#Idiosyncrasies" accesskey="u" rel="up">Idiosyncrasies</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Compiler_002donly-Implementation-1"></span><h4 class="subsection">2.3.3 Compiler-only Implementation</h4>
|
|
|
|
<p>SBCL is essentially a compiler-only implementation of Common Lisp.
|
|
That is, for all but a few special cases, <code>eval</code> creates a lambda
|
|
expression, calls <code>compile</code> on the lambda expression to create a
|
|
compiled function, and then calls <code>funcall</code> 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, <code>functionp</code> and
|
|
<code>compiled-function-p</code> are equivalent, and they collapse into the
|
|
same function when SBCL is built without the interpreter.
|
|
</p>
|
|
<hr>
|
|
<span id="Defining-Constants"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Style-Warnings" accesskey="n" rel="next">Style Warnings</a>, Previous: <a href="index.html#Compiler_002donly-Implementation" accesskey="p" rel="prev">Compiler-only Implementation</a>, Up: <a href="index.html#Idiosyncrasies" accesskey="u" rel="up">Idiosyncrasies</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Defining-Constants-1"></span><h4 class="subsection">2.3.4 Defining Constants</h4>
|
|
<span id="index-defconstant-_005bcl_005d"></span>
|
|
|
|
<p>SBCL is quite strict about ANSI’s definition of <code>defconstant</code>.
|
|
ANSI says that doing <code>defconstant</code> of the same symbol more than
|
|
once is undefined unless the new value is <code>eql</code> to the old value.
|
|
Conforming to this specification is a nuisance when the “constant”
|
|
value is only constant under some weaker test like <code>string=</code> or
|
|
<code>equal</code>.
|
|
</p>
|
|
<p>It’s especially annoying because, in SBCL, <code>defconstant</code> takes
|
|
effect not only at load time but also at compile time, so that just
|
|
compiling and loading reasonable code like
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(defconstant +foobyte+ '(1 4))
|
|
</pre></div>
|
|
<p>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.
|
|
</p>
|
|
<p>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 <code>defconstant</code> either with
|
|
<code>defparameter</code> or with a customized macro which does the right
|
|
thing, e.g.
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(defmacro define-constant (name value &optional doc)
|
|
`(defconstant ,name (if (boundp ',name) (symbol-value ',name) ,value)
|
|
,@(when doc (list doc))))
|
|
</pre></div>
|
|
<p>or possibly along the lines of the <code>defconstant-eqx</code> macro used
|
|
internally in the implementation of SBCL itself. In circumstances
|
|
where this is not appropriate, the programmer can handle the condition
|
|
type <code>sb-ext:defconstant-uneql</code>, and choose either the
|
|
<code>continue</code> or <code>abort</code> restart as appropriate.
|
|
</p>
|
|
<hr>
|
|
<span id="Style-Warnings"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Defining-Constants" accesskey="p" rel="prev">Defining Constants</a>, Up: <a href="index.html#Idiosyncrasies" accesskey="u" rel="up">Idiosyncrasies</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Style-Warnings-1"></span><h4 class="subsection">2.3.5 Style Warnings</h4>
|
|
|
|
<p>SBCL gives style warnings about various kinds of perfectly legal code,
|
|
e.g.
|
|
</p>
|
|
<ul>
|
|
<li> multiple <code>defun</code>s of the same symbol in different units;
|
|
|
|
</li><li> special variables not named in the conventional <code>*foo*</code> style,
|
|
and lexical variables unconventionally named in the <code>*foo*</code> style
|
|
|
|
</li></ul>
|
|
|
|
<p>This causes friction with people who point out that other ways of
|
|
organizing code (especially avoiding the use of <code>defgeneric</code>) 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 <code>defun</code>s is pointlessly annoying
|
|
when you compile and then load a function containing <code>defun</code>
|
|
wrapped in <code>eval-when</code>, and ideally should be suppressed in that
|
|
case, but still isn’t as of SBCL 0.7.6.)
|
|
</p>
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="Development-Tools"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#More-SBCL-Information" accesskey="n" rel="next">More SBCL Information</a>, Previous: <a href="index.html#Idiosyncrasies" accesskey="p" rel="prev">Idiosyncrasies</a>, Up: <a href="index.html#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Development-Tools-1"></span><h3 class="section">2.4 Development Tools</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Editor-Integration" accesskey="1">Editor Integration</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Language-Reference" accesskey="2">Language Reference</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Generating-Executables" accesskey="3">Generating Executables</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Editor-Integration"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Language-Reference" accesskey="n" rel="next">Language Reference</a>, Up: <a href="index.html#Development-Tools" accesskey="u" rel="up">Development Tools</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Editor-Integration-1"></span><h4 class="subsection">2.4.1 Editor Integration</h4>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>Currently <em>SLIME</em><a id="DOCF1" href="index.html#FOOT1"><sup>1</sup></a> (Superior Lisp Interaction
|
|
Mode for Emacs) together with Emacs is recommended for use with
|
|
SBCL, though other options exist as well.
|
|
</p>
|
|
<p>SLIME can be downloaded from
|
|
<a href="http://www.common-lisp.net/project/slime/">http://www.common-lisp.net/project/slime/</a>.
|
|
</p>
|
|
<hr>
|
|
<span id="Language-Reference"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Generating-Executables" accesskey="n" rel="next">Generating Executables</a>, Previous: <a href="index.html#Editor-Integration" accesskey="p" rel="prev">Editor Integration</a>, Up: <a href="index.html#Development-Tools" accesskey="u" rel="up">Development Tools</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Language-Reference-1"></span><h4 class="subsection">2.4.2 Language Reference</h4>
|
|
|
|
<p><em>CLHS</em> (Common Lisp Hyperspec) is a hypertext version of the ANSI
|
|
standard, made freely available by <em>LispWorks</em> – an invaluable
|
|
reference.
|
|
</p>
|
|
<p>See: <a href="http://www.lispworks.com/reference/HyperSpec/index.html">http://www.lispworks.com/reference/HyperSpec/index.html</a>
|
|
</p>
|
|
<hr>
|
|
<span id="Generating-Executables"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Language-Reference" accesskey="p" rel="prev">Language Reference</a>, Up: <a href="index.html#Development-Tools" accesskey="u" rel="up">Development Tools</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Generating-Executables-1"></span><h4 class="subsection">2.4.3 Generating Executables</h4>
|
|
|
|
<p>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
|
|
<code>compile</code> and <code>load</code>, which requires the compiler to be present
|
|
in the executable. For further information, See <a href="index.html#Function-sb_002dext-save_002dlisp_002dand_002ddie">Function sb-ext save-lisp-and-die</a>.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="More-SBCL-Information"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#More-Common-Lisp-Information" accesskey="n" rel="next">More Common Lisp Information</a>, Previous: <a href="index.html#Development-Tools" accesskey="p" rel="prev">Development Tools</a>, Up: <a href="index.html#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="More-SBCL-Information-1"></span><h3 class="section">2.5 More SBCL Information</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#SBCL-Homepage" accesskey="1">SBCL Homepage</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Online-Documentation" accesskey="2">Online Documentation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Additional-Documentation-Files" accesskey="3">Additional Documentation Files</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Internals-Documentation" accesskey="4">Internals Documentation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="SBCL-Homepage"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Online-Documentation" accesskey="n" rel="next">Online Documentation</a>, Up: <a href="index.html#More-SBCL-Information" accesskey="u" rel="up">More SBCL Information</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="SBCL-Homepage-1"></span><h4 class="subsection">2.5.1 SBCL Homepage</h4>
|
|
|
|
<p>The SBCL website at <a href="http://www.sbcl.org/">http://www.sbcl.org/</a> has some general
|
|
information, plus links to mailing lists devoted to SBCL, and to
|
|
archives of these mailing lists. Subscribing to the mailing lists
|
|
<cite>sbcl-help</cite> and <cite>sbcl-announce</cite> is recommended: both are
|
|
fairly low-volume, and help you keep abreast with SBCL development.
|
|
</p>
|
|
<hr>
|
|
<span id="Online-Documentation"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Additional-Documentation-Files" accesskey="n" rel="next">Additional Documentation Files</a>, Previous: <a href="index.html#SBCL-Homepage" accesskey="p" rel="prev">SBCL Homepage</a>, Up: <a href="index.html#More-SBCL-Information" accesskey="u" rel="up">More SBCL Information</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Online-Documentation-1"></span><h4 class="subsection">2.5.2 Online Documentation</h4>
|
|
|
|
<p>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 <code>inspect</code>) are documented in text available by typing
|
|
<code>help</code> at their command prompts. The extensions for functions
|
|
which don’t have their own command prompt (such as <code>trace</code>) 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.
|
|
</p>
|
|
<hr>
|
|
<span id="Additional-Documentation-Files"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Internals-Documentation" accesskey="n" rel="next">Internals Documentation</a>, Previous: <a href="index.html#Online-Documentation" accesskey="p" rel="prev">Online Documentation</a>, Up: <a href="index.html#More-SBCL-Information" accesskey="u" rel="up">More SBCL Information</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Additional-Documentation-Files-1"></span><h4 class="subsection">2.5.3 Additional Documentation Files</h4>
|
|
|
|
<p>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
|
|
<samp>/usr/local/share/doc/sbcl/</samp>.
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><samp>COPYING</samp></dt>
|
|
<dd><p>Licence and copyright summary.
|
|
</p>
|
|
</dd>
|
|
<dt><samp>CREDITS</samp></dt>
|
|
<dd><p>Authorship information on various parts of SBCL.
|
|
</p>
|
|
</dd>
|
|
<dt><samp>INSTALL</samp></dt>
|
|
<dd><p>Covers installing SBCL from both source and binary distributions on
|
|
your system, and also has some installation related troubleshooting
|
|
information.
|
|
</p>
|
|
</dd>
|
|
<dt><samp>NEWS</samp></dt>
|
|
<dd><p>Summarizes changes between various SBCL versions.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<hr>
|
|
<span id="Internals-Documentation"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Additional-Documentation-Files" accesskey="p" rel="prev">Additional Documentation Files</a>, Up: <a href="index.html#More-SBCL-Information" accesskey="u" rel="up">More SBCL Information</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Internals-Documentation-1"></span><h4 class="subsection">2.5.4 Internals Documentation</h4>
|
|
|
|
<p>If you’re interested in the development of the SBCL system itself,
|
|
then subscribing to <cite>sbcl-devel</cite> is a good idea.
|
|
</p>
|
|
<p>SBCL internals documentation – besides comments in the source – is
|
|
currently maintained as a <em>wiki-like</em> website:
|
|
<a href="http://sbcl-internals.cliki.net/">http://sbcl-internals.cliki.net/</a>.
|
|
</p>
|
|
<p>Some low-level information describing the programming details of the
|
|
conversion from CMUCL to SBCL is available in the
|
|
<samp>doc/FOR-CMUCL-DEVELOPERS</samp> file in the SBCL distribution, though
|
|
it is not installed by default.
|
|
</p>
|
|
<hr>
|
|
<span id="More-Common-Lisp-Information"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#History-and-Implementation-of-SBCL" accesskey="n" rel="next">History and Implementation of SBCL</a>, Previous: <a href="index.html#More-SBCL-Information" accesskey="p" rel="prev">More SBCL Information</a>, Up: <a href="index.html#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="More-Common-Lisp-Information-1"></span><h3 class="section">2.6 More Common Lisp Information</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Internet-Community" accesskey="1">Internet Community</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Third_002dparty-Libraries" accesskey="2">Third-party Libraries</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Common-Lisp-Books" accesskey="3">Common Lisp Books</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Internet-Community"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Third_002dparty-Libraries" accesskey="n" rel="next">Third-party Libraries</a>, Up: <a href="index.html#More-Common-Lisp-Information" accesskey="u" rel="up">More Common Lisp Information</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Internet-Community-1"></span><h4 class="subsection">2.6.1 Internet Community</h4>
|
|
|
|
|
|
<p>The Common Lisp internet community is fairly diverse:
|
|
<a href="news://comp.lang.lisp">news://comp.lang.lisp</a> 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.
|
|
<a href="http://www.lisp.org">http://www.lisp.org</a> and <a href="http://www.cliki.net">http://www.cliki.net</a> contain
|
|
numerous pointers places in the net where lispers talks shop.
|
|
</p>
|
|
<hr>
|
|
<span id="Third_002dparty-Libraries"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Common-Lisp-Books" accesskey="n" rel="next">Common Lisp Books</a>, Previous: <a href="index.html#Internet-Community" accesskey="p" rel="prev">Internet Community</a>, Up: <a href="index.html#More-Common-Lisp-Information" accesskey="u" rel="up">More Common Lisp Information</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Third_002dparty-Libraries-1"></span><h4 class="subsection">2.6.2 Third-party Libraries</h4>
|
|
|
|
<p>For a wealth of information about free Common Lisp libraries and tools
|
|
we recommend checking out <em>CLiki</em>: <a href="http://www.cliki.net/">http://www.cliki.net/</a>.
|
|
</p>
|
|
<hr>
|
|
<span id="Common-Lisp-Books"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Third_002dparty-Libraries" accesskey="p" rel="prev">Third-party Libraries</a>, Up: <a href="index.html#More-Common-Lisp-Information" accesskey="u" rel="up">More Common Lisp Information</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Common-Lisp-Books-1"></span><h4 class="subsection">2.6.3 Common Lisp Books</h4>
|
|
|
|
<p>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
|
|
<a href="news://comp.lang.lisp">news://comp.lang.lisp</a> FAQ for recent recommendations.
|
|
</p>
|
|
|
|
<p>If you are an experienced programmer in other languages but need to
|
|
learn about Common Lisp, some books stand out:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><cite>Practical Common Lisp, by Peter Seibel</cite></dt>
|
|
<dd><p>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: <a href="http://www.gigamonkeys.com/book/">http://www.gigamonkeys.com/book/</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><cite>Paradigms Of Artificial Intelligence Programming, by Peter Norvig</cite></dt>
|
|
<dd><p>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.
|
|
</p>
|
|
</dd>
|
|
<dt><cite>On Lisp, by Paul Graham</cite></dt>
|
|
<dd><p>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 <a href="http://www.paulgraham.com/onlisp.html">http://www.paulgraham.com/onlisp.html</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><cite>Object-Oriented Programming In Common Lisp, by Sonya Keene</cite></dt>
|
|
<dd><p>With the exception of <cite>Practical Common Lisp</cite> 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.
|
|
</p>
|
|
</dd>
|
|
<dt><cite>Art Of Metaobject Programming, by Gregor Kiczales et al.</cite></dt>
|
|
<dd><p>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 <a href="http://mop.lisp.se/www.alu.org/mop/">http://mop.lisp.se/www.alu.org/mop/</a>.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="History-and-Implementation-of-SBCL"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#More-Common-Lisp-Information" accesskey="p" rel="prev">More Common Lisp Information</a>, Up: <a href="index.html#Introduction" accesskey="u" rel="up">Introduction</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="History-and-Implementation-of-SBCL-1"></span><h3 class="section">2.7 History and Implementation of SBCL</h3>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>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:
|
|
</p>
|
|
<ul>
|
|
<li> The system expects to be loaded into a fixed-at-compile-time location
|
|
in virtual memory, and also expects the location of all of its heap
|
|
storage to be specified at compile time.
|
|
|
|
</li><li> The system overcommits memory, allocating large amounts of address
|
|
space from the system (often more than the amount of virtual memory
|
|
available) and then failing if ends up using too much of the allocated
|
|
storage.
|
|
|
|
</li><li> The system is implemented as a C program which is responsible for
|
|
supplying low-level services and loading a Lisp <samp>.core</samp>
|
|
file.
|
|
|
|
</li></ul>
|
|
|
|
<span id="index-Garbage-Collection_002c-generational"></span>
|
|
<p>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,
|
|
<a href="index.html#Efficiency">Efficiency</a>.
|
|
</p>
|
|
<p>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 <code>compiled-function-p</code>; 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 <code>eval</code> function only truly “interprets” a few easy kinds of
|
|
forms, such as symbols which are <code>boundp</code>. More complicated forms
|
|
are evaluated by calling <code>compile</code> and then calling <code>funcall</code>
|
|
on the returned result.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<span id="index-Garbage-Collection_002c-conservative"></span>
|
|
<p>On the x86 SBCL – like the x86 port of CMUCL – uses a
|
|
<em>conservative</em> 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.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>Other major changes since the fork from CMUCL include
|
|
</p>
|
|
<ul>
|
|
<li> SBCL has removed many CMUCL extensions, (e.g. IP networking,
|
|
remote procedure call, Unix system interface, and X11 interface) from
|
|
the core system. Most of these are available as contributed modules
|
|
(distributed with SBCL) or third-party modules instead.
|
|
|
|
</li><li> SBCL has deleted or deprecated some nonstandard features and code
|
|
complexity which helped efficiency at the price of
|
|
maintainability. For example, the SBCL compiler no longer implements
|
|
memory pooling internally (and so is simpler and more maintainable,
|
|
but generates more garbage and runs more slowly), and various
|
|
block-compilation efficiency-increasing extensions to the language
|
|
have been deleted or are no longer used in the implementation of SBCL
|
|
itself.
|
|
|
|
</li></ul>
|
|
<hr>
|
|
<span id="Starting-and-Stopping"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Compiler" accesskey="n" rel="next">Compiler</a>, Previous: <a href="index.html#Introduction" accesskey="p" rel="prev">Introduction</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Starting-and-Stopping-1"></span><h2 class="chapter">3 Starting and Stopping</h2>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Starting-SBCL" accesskey="1">Starting SBCL</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Stopping-SBCL" accesskey="2">Stopping SBCL</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Command-Line-Options" accesskey="3">Command Line Options</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Initialization-Files" accesskey="4">Initialization Files</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Initialization-and-Exit-Hooks" accesskey="5">Initialization and Exit Hooks</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Starting-SBCL"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Stopping-SBCL" accesskey="n" rel="next">Stopping SBCL</a>, Up: <a href="index.html#Starting-and-Stopping" accesskey="u" rel="up">Starting and Stopping</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Starting-SBCL-1"></span><h3 class="section">3.1 Starting SBCL</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Running-from-Shell" accesskey="1">Running from Shell</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Running-from-Emacs" accesskey="2">Running from Emacs</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Shebang-Scripts" accesskey="3">Shebang Scripts</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Running-from-Shell"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Running-from-Emacs" accesskey="n" rel="next">Running from Emacs</a>, Up: <a href="index.html#Starting-SBCL" accesskey="u" rel="up">Starting SBCL</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="From-Shell-to-Lisp"></span><h4 class="subsection">3.1.1 From Shell to Lisp</h4>
|
|
|
|
<p>To run SBCL type <code>sbcl</code> at the command line.
|
|
</p>
|
|
<p>You should end up in the toplevel <em>REPL</em> (read, eval, print
|
|
-loop), where you can interact with SBCL by typing expressions.
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">$ 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)
|
|
$
|
|
</pre></div>
|
|
|
|
<p>See also <a href="index.html#Command-Line-Options">Command Line Options</a> and <a href="index.html#Stopping-SBCL">Stopping SBCL</a>.
|
|
</p>
|
|
<hr>
|
|
<span id="Running-from-Emacs"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Shebang-Scripts" accesskey="n" rel="next">Shebang Scripts</a>, Previous: <a href="index.html#Running-from-Shell" accesskey="p" rel="prev">Running from Shell</a>, Up: <a href="index.html#Starting-SBCL" accesskey="u" rel="up">Starting SBCL</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Running-from-Emacs-1"></span><h4 class="subsection">3.1.2 Running from Emacs</h4>
|
|
|
|
<p>To run SBCL as an inferior-lisp from Emacs in your <samp>.emacs</samp> do
|
|
something like:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">;;; The SBCL binary and command-line arguments
|
|
(setq inferior-lisp-program "/usr/local/bin/sbcl --noinform")
|
|
</pre></div>
|
|
|
|
<p>For more information on using SBCL with Emacs, see <a href="index.html#Editor-Integration">Editor Integration</a>.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Shebang-Scripts"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Running-from-Emacs" accesskey="p" rel="prev">Running from Emacs</a>, Up: <a href="index.html#Starting-SBCL" accesskey="u" rel="up">Starting SBCL</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Shebang-Scripts-1"></span><h4 class="subsection">3.1.3 Shebang Scripts</h4>
|
|
<span id="index-_002aposix_002dargv_002a-_005bsb_002dext_005d"></span>
|
|
|
|
<p>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 <code>--script</code> command line option.
|
|
</p>
|
|
<p>Example file (<samp>hello.lisp</samp>):
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">#!/usr/local/bin/sbcl --script
|
|
(write-line "Hello, World!")
|
|
</pre></div>
|
|
|
|
<p>Usage examples:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">$ ./hello.lisp
|
|
Hello, World!
|
|
</pre></div>
|
|
|
|
<div class="example">
|
|
<pre class="example">$ sbcl --script hello.lisp
|
|
Hello, World!
|
|
</pre></div>
|
|
|
|
<hr>
|
|
<span id="Stopping-SBCL"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Command-Line-Options" accesskey="n" rel="next">Command Line Options</a>, Previous: <a href="index.html#Starting-SBCL" accesskey="p" rel="prev">Starting SBCL</a>, Up: <a href="index.html#Starting-and-Stopping" accesskey="u" rel="up">Starting and Stopping</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Stopping-SBCL-1"></span><h3 class="section">3.2 Stopping SBCL</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Exit" accesskey="1">Exit</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#End-of-File" accesskey="2">End of File</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Saving-a-Core-Image" accesskey="3">Saving a Core Image</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Exit-on-Errors" accesskey="4">Exit on Errors</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Exit"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#End-of-File" accesskey="n" rel="next">End of File</a>, Up: <a href="index.html#Stopping-SBCL" accesskey="u" rel="up">Stopping SBCL</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Exit-1"></span><h4 class="subsection">3.2.1 Exit</h4>
|
|
|
|
<p>SBCL can be stopped at any time by calling <code>sb-ext:exit</code>,
|
|
optionally returning a specified numeric value to the calling process.
|
|
See <a href="index.html#Threading">Threading</a> for information about terminating individual threads.
|
|
</p>
|
|
<span id="Function-sb_002dext-exit"></span><dl>
|
|
<dt id="index-exit">Function: <strong>exit</strong> <em>[sb-ext] &key code abort timeout</em></dt>
|
|
<dd><p>Terminates the process, causing <code>sbcl</code> to exit with <code>code</code>. <code>code</code>
|
|
defaults to 0 when <code>abort</code> is false, and 1 when it is true.
|
|
</p>
|
|
<p>When <code>abort</code> is false (the default), current thread is first unwound,
|
|
<code>*exit-hooks*</code> are run, other threads are terminated, and standard
|
|
output streams are flushed before <code>sbcl</code> calls exit(3) <code>--</code> at which point
|
|
atexit(3) functions will run. If multiple threads call <code>exit</code> with <code>abort</code>
|
|
being false, the first one to call it will complete the protocol.
|
|
</p>
|
|
<p>When <code>abort</code> is true, <code>sbcl</code> 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).
|
|
</p>
|
|
<p>Recursive calls to <code>exit</code> cause <code>exit</code> to behave as if <code>abort</code> was true.
|
|
</p>
|
|
<p><code>timeout</code> controls waiting for other threads to terminate when <code>abort</code> is
|
|
<code>nil</code>. Once current thread has been unwound and <code>*exit-hooks*</code> have been
|
|
run, spawning new threads is prevented and all other threads are
|
|
terminated by calling <code>terminate-thread</code> on them. The system then waits
|
|
for them to finish using <code>join-thread</code>, waiting at most a total <code>timeout</code>
|
|
seconds for all threads to join. Those threads that do not finish
|
|
in time are simply ignored while the exit protocol continues. <code>timeout</code>
|
|
defaults to <code>*exit-timeout*</code>, which in turn defaults to 60. <code>timeout</code> <code>nil</code>
|
|
means to wait indefinitely.
|
|
</p>
|
|
<p>Note that <code>timeout</code> applies only to <code>join-thread</code>, not <code>*exit-hooks*</code>. Since
|
|
<code>terminate-thread</code> 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.
|
|
</p>
|
|
<p>Consequences are unspecified if serious conditions occur during <code>exit</code>
|
|
excepting errors from <code>*exit-hooks*</code>, which cause warnings and stop
|
|
execution of the hook that signaled, but otherwise allow the exit
|
|
process to continue normally.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="End-of-File"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Saving-a-Core-Image" accesskey="n" rel="next">Saving a Core Image</a>, Previous: <a href="index.html#Exit" accesskey="p" rel="prev">Exit</a>, Up: <a href="index.html#Stopping-SBCL" accesskey="u" rel="up">Stopping SBCL</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="End-of-File-1"></span><h4 class="subsection">3.2.2 End of File</h4>
|
|
|
|
<p>By default SBCL also exits on end of input, caused either by user
|
|
pressing <kbd>Control-D</kbd> on an attached terminal, or end of input when
|
|
using SBCL as part of a shell pipeline.
|
|
</p>
|
|
<hr>
|
|
<span id="Saving-a-Core-Image"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Exit-on-Errors" accesskey="n" rel="next">Exit on Errors</a>, Previous: <a href="index.html#End-of-File" accesskey="p" rel="prev">End of File</a>, Up: <a href="index.html#Stopping-SBCL" accesskey="u" rel="up">Stopping SBCL</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Saving-a-Core-Image-1"></span><h4 class="subsection">3.2.3 Saving a Core Image</h4>
|
|
|
|
<p>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.
|
|
</p>
|
|
<span id="Function-sb_002dext-save_002dlisp_002dand_002ddie"></span><dl>
|
|
<dt id="index-save_002dlisp_002dand_002ddie">Function: <strong>save-lisp-and-die</strong> <em>[sb-ext] core-file-name &key toplevel executable save-runtime-options callable-exports purify root-structures environment-name compression</em></dt>
|
|
<dd><p>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.
|
|
</p>
|
|
<p>The following <code>&key</code> arguments are defined:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:toplevel</code></em></dt>
|
|
<dd><p>The 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 (<code>sb-ext:exit</code> <code>:code</code> 0) being called.
|
|
</p>
|
|
<p><code>toplevel</code> functions should always provide an <code>abort</code> restart: otherwise
|
|
code they call will run without one.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:executable</code></em></dt>
|
|
<dd><p>If true, arrange to combine the <code>sbcl</code> 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.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:save-runtime-options</code></em></dt>
|
|
<dd><p>If true, values of runtime options –dynamic-space-size and
|
|
–control-stack-size that were used to start <code>sbcl</code> 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 <code>:executable</code> is <code>nil</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:callable-exports</code></em></dt>
|
|
<dd><p>This should be a list of symbols to be initialized to the
|
|
appropriate alien callables on startup. All exported symbols should
|
|
be present as global symbols in the symbol table of the runtime
|
|
before the saved core is loaded. When this list is non-empty, the
|
|
<code>:toplevel</code> argument cannot be supplied.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:purify</code></em></dt>
|
|
<dd><p>If true (the default), then some objects in the restarted core will
|
|
be memory-mapped as read-only. Among those objects are numeric vectors
|
|
that were determined to be compile-time constants, and any immutable
|
|
values according to the language specification such as symbol names.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:root-structures</code></em></dt>
|
|
<dd><p>This should be a list of the main entry points in any newly loaded
|
|
systems. This need not be supplied, but locality and/or <code>gc</code> performance
|
|
may be better if they are. This has two different but related meanings:
|
|
If <code>:purify</code> is true <code>-</code> and only for cheneygc <code>-</code> the root structures
|
|
are those which anchor the set of objects moved into static space.
|
|
On gencgc <code>-</code> and only on platforms supporting immobile code <code>-</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.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:environment-name</code></em></dt>
|
|
<dd><p>This has no purpose; it is accepted only for legacy compatibility.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:compression</code></em></dt>
|
|
<dd><p>This is only meaningful if the runtime was built with the <code>:sb-core-compression</code>
|
|
feature enabled. If <code>nil</code> (the default), saves to uncompressed core files. If
|
|
<code>:sb-core-compression</code> was enabled at build-time, the argument may also be
|
|
an integer from -7 to 22, corresponding to zstd compression levels, or <code>t</code>
|
|
(which is equivalent to the default compression level, 9).
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:application-type</code></em></dt>
|
|
<dd><p>Present only on Windows and is meaningful only with <code>:executable</code> <code>t</code>.
|
|
Specifies the subsystem of the executable, <code>:console</code> or <code>:gui</code>.
|
|
The notable difference is that <code>:gui</code> doesn’t automatically create a console
|
|
window. The default is <code>:console</code>.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>The save/load process changes the values of some global variables:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>*standard-output*</code>, <code>*debug-io*</code>, etc.</em></dt>
|
|
<dd><p>Everything related to open streams is necessarily changed, since
|
|
the <code>os</code> won’t let us preserve a stream across save and load.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>*default-pathname-defaults*</code></em></dt>
|
|
<dd><p>This is reinitialized to reflect the working directory where the
|
|
saved core is loaded.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p><code>save-lisp-and-die</code> interacts with <code>sb-alien:load-shared-object:</code> see its
|
|
documentation for details.
|
|
</p>
|
|
<p>On threaded platforms only a single thread may remain running after
|
|
<code>sb-ext:*save-hooks*</code> have run. Applications using multiple threads can
|
|
be <code>save-lisp-and-die</code> friendly by registering a save-hook that quits
|
|
any additional threads, and an init-hook that restarts them.
|
|
</p>
|
|
<p>This implementation is not as polished and painless as you might like:
|
|
</p><ul>
|
|
<li> It corrupts the current Lisp image enough that the current process
|
|
needs to be killed afterwards. This can be worked around by forking
|
|
another process that saves the core.
|
|
</li><li> There is absolutely no binary compatibility of core images between
|
|
different runtime support programs. Even runtimes built from the same
|
|
sources at different times are treated as incompatible for this
|
|
purpose.
|
|
</li></ul>
|
|
<p>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.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002dext-_002asave_002dhooks_002a"></span><dl>
|
|
<dt id="index-_002asave_002dhooks_002a">Variable: <strong>*save-hooks*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>A list of function designators which are called in an unspecified
|
|
order before creating a saved core image.
|
|
</p>
|
|
<p>Unused by <code>sbcl</code> itself: reserved for user and applications.
|
|
</p></dd></dl>
|
|
|
|
<p>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.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002asysinit_002dpathname_002dfunction_002a"></span><dl>
|
|
<dt id="index-_002asysinit_002dpathname_002dfunction_002a">Variable: <strong>*sysinit-pathname-function*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Designator for a function of zero arguments called to obtain a
|
|
pathname designator for the default sysinit file, or <code>nil</code>. If the
|
|
function returns <code>nil</code>, no sysinit file is used unless one has been
|
|
specified on the command-line.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002dext-_002auserinit_002dpathname_002dfunction_002a"></span><dl>
|
|
<dt id="index-_002auserinit_002dpathname_002dfunction_002a">Variable: <strong>*userinit-pathname-function*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Designator for a function of zero arguments called to obtain a
|
|
pathname designator or a stream for the default userinit file, or <code>nil</code>.
|
|
If the function returns <code>nil</code>, no userinit file is used unless one has
|
|
been specified on the command-line.
|
|
</p></dd></dl>
|
|
|
|
<p>To facilitate distribution of SBCL applications using external
|
|
resources, the filesystem location of the SBCL core file being used is
|
|
available from Lisp.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002acore_002dpathname_002a"></span><dl>
|
|
<dt id="index-_002acore_002dpathname_002a">Variable: <strong>*core-pathname*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>The absolute pathname of the running <code>sbcl</code> core.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Exit-on-Errors"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Saving-a-Core-Image" accesskey="p" rel="prev">Saving a Core Image</a>, Up: <a href="index.html#Stopping-SBCL" accesskey="u" rel="up">Stopping SBCL</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Exit-on-Errors-1"></span><h4 class="subsection">3.2.4 Exit on Errors</h4>
|
|
|
|
<p>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 <a href="index.html#Debugger-Entry">Debugger Entry</a>.
|
|
</p>
|
|
<hr>
|
|
<span id="Command-Line-Options"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Initialization-Files" accesskey="n" rel="next">Initialization Files</a>, Previous: <a href="index.html#Stopping-SBCL" accesskey="p" rel="prev">Stopping SBCL</a>, Up: <a href="index.html#Starting-and-Stopping" accesskey="u" rel="up">Starting and Stopping</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Command-Line-Options-1"></span><h3 class="section">3.3 Command Line Options</h3>
|
|
|
|
|
|
<p>Command line options can be considered an advanced topic; for ordinary
|
|
interactive use, no command line arguments should be necessary.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>The full, unambiguous syntax for invoking SBCL at the command line is:
|
|
</p>
|
|
<p><code>sbcl</code> <var>runtime-option</var>* <code>--end-runtime-options</code> <var>toplevel-option</var>* <code>--end-toplevel-options</code> <var>user-options</var>*
|
|
</p>
|
|
<p>For convenience, the <code>--end-runtime-options</code> and
|
|
<code>--end-toplevel-options</code> 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.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Runtime-Options" accesskey="1">Runtime Options</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Toplevel-Options" accesskey="2">Toplevel Options</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Runtime-Options"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Toplevel-Options" accesskey="n" rel="next">Toplevel Options</a>, Up: <a href="index.html#Command-Line-Options" accesskey="u" rel="up">Command Line Options</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Runtime-Options-1"></span><h4 class="subsection">3.3.1 Runtime Options</h4>
|
|
|
|
<dl compact="compact">
|
|
<dt><code>--core <var>corefilename</var></code></dt>
|
|
<dd><p>Run 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.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--dynamic-space-size <var>megabytes</var></code></dt>
|
|
<dd><p>Size of the dynamic space reserved on startup in megabytes. Default
|
|
value is platform dependent.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--control-stack-size <var>megabytes</var></code></dt>
|
|
<dd><p>Size of control stack reserved for each thread in megabytes. Default
|
|
value is 2.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--noinform</code></dt>
|
|
<dd><p>Suppress 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 <code>--noprint</code> and
|
|
<code>--disable-debugger</code> options.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--disable-ldb</code></dt>
|
|
<dd><span id="index-ldb-1"></span>
|
|
<span id="index-ldb_002c-disabling"></span>
|
|
<span id="index-disabling-ldb"></span>
|
|
<p>Disable the low-level debugger. Only effective if SBCL is compiled
|
|
with LDB.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--lose-on-corruption</code></dt>
|
|
<dd><span id="index-ldb-2"></span>
|
|
<p>There 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.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><code>--script <var>filename</var></code></dt>
|
|
<dd><p>As a runtime option this is equivalent to <code>--noinform</code>
|
|
<code>--disable-ldb</code> <code>--lose-on-corruption</code>
|
|
<code>--end-runtime-options</code> <code>--script</code> <var>filename</var>. See the
|
|
description of <code>--script</code> as a toplevel option below. If there
|
|
are no other command line arguments following <code>--script</code>, the
|
|
filename argument can be omitted.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><code>--merge-core-pages</code></dt>
|
|
<dd><p>When 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.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--no-merge-core-pages</code></dt>
|
|
<dd><p>Ensures that no sharing hint is provided to the operating system.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--help</code></dt>
|
|
<dd><p>Print some basic information about SBCL, then exit.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--version</code></dt>
|
|
<dd><p>Print SBCL’s version information, then exit.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>In the future, runtime options may be added to control behaviour such
|
|
as lazy allocation of memory.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<hr>
|
|
<span id="Toplevel-Options"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Runtime-Options" accesskey="p" rel="prev">Runtime Options</a>, Up: <a href="index.html#Command-Line-Options" accesskey="u" rel="up">Command Line Options</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Toplevel-Options-1"></span><h4 class="subsection">3.3.2 Toplevel Options</h4>
|
|
|
|
<dl compact="compact">
|
|
<dt><code>--sysinit <var>filename</var></code></dt>
|
|
<dd><p>Load filename instead of the default system initialization file
|
|
(see <a href="index.html#Initialization-Files">Initialization Files</a>.)
|
|
</p>
|
|
</dd>
|
|
<dt><code>--no-sysinit</code></dt>
|
|
<dd><p>Don’t load a system-wide initialization file. If this option is given,
|
|
the <code>--sysinit</code> option is ignored.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--userinit <var>filename</var></code></dt>
|
|
<dd><p>Load filename instead of the default user initialization file
|
|
(see <a href="index.html#Initialization-Files">Initialization Files</a>.)
|
|
</p>
|
|
</dd>
|
|
<dt><code>--no-userinit</code></dt>
|
|
<dd><p>Don’t load a user initialization file. If this option is given,
|
|
the <code>--userinit</code> option is ignored.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--eval <var>command</var></code></dt>
|
|
<dd><p>After executing any initialization file, but before starting the
|
|
read-eval-print loop on standard input, read and evaluate the command
|
|
given. More than one <code>--eval</code> option can be used, and all will be
|
|
read and executed, in the order they appear on the command line.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--load <var>filename</var></code></dt>
|
|
<dd><p>This is equivalent to <code>--eval '(load "<var>filename</var>")'</code>. The
|
|
special syntax is intended to reduce quoting headaches when invoking
|
|
SBCL from shell scripts.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--noprint</code></dt>
|
|
<dd><p>When 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 <code>--noinform</code> runtime
|
|
option, this makes it easier to write Lisp "scripts" which work
|
|
cleanly in Unix pipelines.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--disable-debugger</code></dt>
|
|
<dd><p>By 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 <code>--eval</code> and
|
|
<code>--load</code> options. See <code>sb-ext:disable-debugger</code> for details.
|
|
See <a href="index.html#Debugger-Entry">Debugger Entry</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><code>--script <var>filename</var></code></dt>
|
|
<dd><p>Implies <code>--no-userinit</code> <code>--no-sysinit</code>
|
|
<code>--disable-debugger</code> <code>--end-toplevel-options</code>.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>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
|
|
<em>not</em> ignored.
|
|
</p>
|
|
<p>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 <code>head -n1</code> or similar.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<hr>
|
|
<span id="Initialization-Files"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Initialization-and-Exit-Hooks" accesskey="n" rel="next">Initialization and Exit Hooks</a>, Previous: <a href="index.html#Command-Line-Options" accesskey="p" rel="prev">Command Line Options</a>, Up: <a href="index.html#Starting-and-Stopping" accesskey="u" rel="up">Starting and Stopping</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Initialization-Files-1"></span><h3 class="section">3.4 Initialization Files</h3>
|
|
|
|
<p>SBCL processes initialization files with <code>read</code> and <code>eval</code>,
|
|
not <code>load</code>; hence initialization files can be used to set startup
|
|
<code>*package*</code> and <code>*readtable*</code>, and for proclaiming a global
|
|
optimization policy.
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><strong>System Initialization File</strong></dt>
|
|
<dd><p>Defaults to <samp><code>$SBCL_HOME</code>/sbclrc</samp>, or if that doesn’t exist to
|
|
<samp>/etc/sbclrc</samp>. Can be overridden with the command line option
|
|
<code>--sysinit</code> or <code>--no-sysinit</code> (see <a href="index.html#Toplevel-Options">Toplevel Options</a>).
|
|
</p>
|
|
<p>The system initialization file is intended for system administrators
|
|
and software packagers to configure locations of installed third party
|
|
modules, etc.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>User Initialization File</strong></dt>
|
|
<dd><p>Defaults to <samp><code>$HOME</code>/.sbclrc</samp>. Can be overridden with the
|
|
command line option <code>--userinit</code> or <code>--no-userinit</code>
|
|
(see <a href="index.html#Toplevel-Options">Toplevel Options</a>).
|
|
</p>
|
|
<p>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 <a href="index.html#FASL-Format">FASL Format</a>), etc.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>Neither initialization file is required.
|
|
</p>
|
|
<hr>
|
|
<span id="Initialization-and-Exit-Hooks"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Initialization-Files" accesskey="p" rel="prev">Initialization Files</a>, Up: <a href="index.html#Starting-and-Stopping" accesskey="u" rel="up">Starting and Stopping</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Initialization-and-Exit-Hooks-1"></span><h3 class="section">3.5 Initialization and Exit Hooks</h3>
|
|
|
|
<p>SBCL provides hooks into the system initialization and exit.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002ainit_002dhooks_002a"></span><dl>
|
|
<dt id="index-_002ainit_002dhooks_002a">Variable: <strong>*init-hooks*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>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, but before non-user threads such as the finalizer
|
|
thread have been started.
|
|
</p>
|
|
<p>Unused by <code>sbcl</code> itself: reserved for user and applications.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002dext-_002aexit_002dhooks_002a"></span><dl>
|
|
<dt id="index-_002aexit_002dhooks_002a">Variable: <strong>*exit-hooks*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>A list of function designators which are called in an unspecified
|
|
order when <code>sbcl</code> process exits.
|
|
</p>
|
|
<p>Unused by <code>sbcl</code> itself: reserved for user and applications.
|
|
</p>
|
|
<p>Using (<code>sb-ext:exit</code> <code>:abort</code> <code>t</code>), or calling exit(3) directly circumvents
|
|
these hooks.
|
|
</p></dd></dl>
|
|
<hr>
|
|
<span id="Compiler"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Debugger" accesskey="n" rel="next">Debugger</a>, Previous: <a href="index.html#Starting-and-Stopping" accesskey="p" rel="prev">Starting and Stopping</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Compiler-1"></span><h2 class="chapter">4 Compiler</h2>
|
|
|
|
<p>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, <a href="index.html#Efficiency">Efficiency</a>.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Diagnostic-Messages" accesskey="1">Diagnostic Messages</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Handling-of-Types" accesskey="2">Handling of Types</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Compiler-Policy" accesskey="3">Compiler Policy</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Compiler-Errors" accesskey="4">Compiler Errors</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Open-Coding-and-Inline-Expansion" accesskey="5">Open Coding and Inline Expansion</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Interpreter" accesskey="6">Interpreter</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Advanced-Compiler-Use-and-Efficiency-Hints" accesskey="7">Advanced Compiler Use and Efficiency Hints</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Diagnostic-Messages"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Handling-of-Types" accesskey="n" rel="next">Handling of Types</a>, Up: <a href="index.html#Compiler" accesskey="u" rel="up">Compiler</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Diagnostic-Messages-1"></span><h3 class="section">4.1 Diagnostic Messages</h3>
|
|
<span id="index-Messages_002c-Compiler"></span>
|
|
<span id="index-Compiler-messages"></span>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Controlling-Verbosity" accesskey="1">Controlling Verbosity</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Diagnostic-Severity" accesskey="2">Diagnostic Severity</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Understanding-Compiler-Diagnostics" accesskey="3">Understanding Compiler Diagnostics</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Controlling-Verbosity"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Diagnostic-Severity" accesskey="n" rel="next">Diagnostic Severity</a>, Up: <a href="index.html#Diagnostic-Messages" accesskey="u" rel="up">Diagnostic Messages</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Controlling-Verbosity-1"></span><h4 class="subsection">4.1.1 Controlling Verbosity</h4>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>To control emission of compiler diagnostics (of any severity other
|
|
than <code>error</code>: see <a href="index.html#Diagnostic-Severity">Diagnostic Severity</a>) use the
|
|
<code>sb-ext:muffle-conditions</code> and <code>sb-ext:unmuffle-conditions</code>
|
|
declarations, specifying the type of condition that is to be muffled
|
|
(the muffling is done using an associated <code>muffle-warning</code> restart).
|
|
</p>
|
|
<p>Global control:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">;;; Muffle compiler-notes globally
|
|
(declaim (sb-ext:muffle-conditions sb-ext:compiler-note))
|
|
</pre></div>
|
|
|
|
<p>Local control:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">;;; 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))))
|
|
</pre></div>
|
|
|
|
<dl>
|
|
<dt id="index-muffle_002dconditions">Declaration: <strong>muffle-conditions</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Syntax: type*
|
|
</p>
|
|
<p>Muffles the diagnostic messages that would be caused by compile-time
|
|
signals of given types.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-unmuffle_002dconditions">Declaration: <strong>unmuffle-conditions</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Syntax: type*
|
|
</p>
|
|
<p>Cancels the effect of a previous <code>sb-ext:muffle-conditions</code>
|
|
declaration.
|
|
</p></dd></dl>
|
|
|
|
<p>Various details of <em>how</em> the compiler messages are printed can be
|
|
controlled via the alist
|
|
<code>sb-ext:*compiler-print-variable-alist*</code>.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002acompiler_002dprint_002dvariable_002dalist_002a"></span><dl>
|
|
<dt id="index-_002acompiler_002dprint_002dvariable_002dalist_002a">Variable: <strong>*compiler-print-variable-alist*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>an association list describing new bindings for special variables
|
|
to be used by the compiler for error-reporting, etc. Eg.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> ((*PRINT-LENGTH* . 10) (*PRINT-LEVEL* . 6) (*PRINT-PRETTY* . NIL))
|
|
</pre></div>
|
|
|
|
<p>The variables in the <code>car</code> positions are bound to the values in the <code>cdr</code>
|
|
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.
|
|
</p>
|
|
<p>Initially empty, <code>*compiler-print-variable-alist*</code> is Typically used to
|
|
specify bindings for printer control variables.
|
|
</p></dd></dl>
|
|
|
|
<p>For information about muffling warnings signaled outside of the
|
|
compiler, see <a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a>.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Diagnostic-Severity"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Understanding-Compiler-Diagnostics" accesskey="n" rel="next">Understanding Compiler Diagnostics</a>, Previous: <a href="index.html#Controlling-Verbosity" accesskey="p" rel="prev">Controlling Verbosity</a>, Up: <a href="index.html#Diagnostic-Messages" accesskey="u" rel="up">Diagnostic Messages</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Diagnostic-Severity-1"></span><h4 class="subsection">4.1.2 Diagnostic Severity</h4>
|
|
<span id="index-Severity-of-compiler-messages"></span>
|
|
<span id="index-Compiler-Diagnostic-Severity"></span>
|
|
<span id="index-error-_005bcl_005d"></span>
|
|
<span id="index-warning-_005bcl_005d"></span>
|
|
<span id="index-style_002dwarning-_005bcl_005d"></span>
|
|
<span id="index-compiler_002dnote-_005bsb_002dext_005d"></span>
|
|
<span id="index-code_002ddeletion_002dnote-_005bsb_002dext_005d"></span>
|
|
|
|
<p>There are four levels of compiler diagnostic severity:
|
|
</p>
|
|
<ol>
|
|
<li> error
|
|
</li><li> warning
|
|
</li><li> style warning
|
|
</li><li> note
|
|
</li></ol>
|
|
|
|
<p>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 <code>compile</code> and <code>compile-file</code> functions.
|
|
These levels of compiler error severity occur when the compiler
|
|
handles conditions of these classes.
|
|
</p>
|
|
<p>The fourth level of compiler error severity, <em>note</em>, corresponds
|
|
to the <code>sb-ext:compiler-note</code>, and is used for problems which are
|
|
too mild for the standard condition classes, typically hints about how
|
|
efficiency might be improved. The <code>sb-ext:code-deletion-note</code>, a
|
|
subtype of <code>compiler-note</code>, is signalled when the compiler
|
|
deletes user-supplied code after proving that the code in question is
|
|
unreachable.
|
|
</p>
|
|
<p>Future work for SBCL includes expanding this hierarchy of types to
|
|
allow more fine-grained control over emission of diagnostic messages.
|
|
</p>
|
|
<span id="Condition-sb_002dext-compiler_002dnote"></span><dl>
|
|
<dt id="index-compiler_002dnote">Condition: <strong>compiler-note</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">compiler-note</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>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 <code>style-warning</code> (or any more serious condition).
|
|
</p></dd></dl>
|
|
<span id="Condition-sb_002dext-code_002ddeletion_002dnote"></span><dl>
|
|
<dt id="index-code_002ddeletion_002dnote">Condition: <strong>code-deletion-note</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">code-deletion-note</span><!-- /@w --></code>, <code><span class="nolinebreak">compiler-note</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>A condition type signalled when the compiler deletes code that the user
|
|
has written, having proved that it is unreachable.
|
|
</p></dd></dl>
|
|
|
|
|
|
<hr>
|
|
<span id="Understanding-Compiler-Diagnostics"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Diagnostic-Severity" accesskey="p" rel="prev">Diagnostic Severity</a>, Up: <a href="index.html#Diagnostic-Messages" accesskey="u" rel="up">Diagnostic Messages</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Understanding-Compile-Diagnostics"></span><h4 class="subsection">4.1.3 Understanding Compile Diagnostics</h4>
|
|
|
|
<p>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:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defmacro zoq (x)
|
|
`(roq (ploq (+ ,x 3))))
|
|
|
|
(defun foo (y)
|
|
(declare (symbol y))
|
|
(zoq y))
|
|
</pre></div>
|
|
|
|
<p>The main problem with this program is that it is trying to add
|
|
<code>3</code> to a symbol. Note also that the functions <code>roq</code> and
|
|
<code>ploq</code> aren’t defined anywhere.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#The-Parts-of-a-Compiler-Diagnostic" accesskey="1">The Parts of a Compiler Diagnostic</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#The-Original-and-Actual-Source" accesskey="2">The Original and Actual Source</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#The-Processing-Path" accesskey="3">The Processing Path</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="The-Parts-of-a-Compiler-Diagnostic"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#The-Original-and-Actual-Source" accesskey="n" rel="next">The Original and Actual Source</a>, Up: <a href="index.html#Understanding-Compiler-Diagnostics" accesskey="u" rel="up">Understanding Compiler Diagnostics</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="The-Parts-of-a-Compiler-Diagnostic-1"></span><h4 class="subsubsection">4.1.3.1 The Parts of a Compiler Diagnostic</h4>
|
|
|
|
<p>When processing this program, the compiler will produce this warning:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; 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).
|
|
</pre></div>
|
|
|
|
<p>In this example we see each of the six possible parts of a compiler
|
|
diagnostic:
|
|
</p>
|
|
<ol>
|
|
<li> <span id="index-with_002dcompilation_002dunit-_005bcl_005d"></span>
|
|
‘<samp>file: /tmp/foo.lisp</samp>’ This is the name of the file that the
|
|
compiler read the relevant code from. The file name is displayed
|
|
because it may not be immediately obvious when there is an error
|
|
during compilation of a large system, especially when
|
|
<code>with-compilation-unit</code> is used to delay undefined warnings.
|
|
|
|
</li><li> ‘<samp>in: DEFUN FOO</samp>’ This is the definition top level form responsible
|
|
for the diagnostic. It is obtained by taking the first two elements of
|
|
the enclosing form whose first element is a symbol beginning with
|
|
“‘<samp>def</samp>’”. If there is no such enclosing “‘<samp>def</samp>’” form,
|
|
then the outermost form is used. If there are multiple ‘<samp>def</samp>’
|
|
forms, then they are all printed from the outside in, separated by
|
|
‘<samp>=></samp>’’s. In this example, the problem was in the <code>defun</code> for
|
|
<code>foo</code>.
|
|
|
|
</li><li> <span id="index-Original-Source"></span>
|
|
‘<samp>(ZOQ Y)</samp>’ This is the <em>original source</em> form responsible for
|
|
the diagnostic. Original source means that the form directly appeared
|
|
in the original input to the compiler, i.e. in the lambda passed to
|
|
<code>compile</code> or in the top level form read from the source file. In
|
|
this example, the expansion of the <code>zoq</code> macro was responsible
|
|
for the message.
|
|
|
|
</li><li> <span id="index-Processing-Path"></span>
|
|
‘<samp>--> ROQ PLOQ</samp>’ This is the <em>processing path</em> that the
|
|
compiler used to produce the code that caused the message to be
|
|
emitted. The processing path is a representation of the evaluated
|
|
forms enclosing the actual source that the compiler encountered when
|
|
processing the original source. The path is the first element of each
|
|
form, or the form itself if the form is not a list. These forms result
|
|
from the expansion of macros or source-to-source transformation done
|
|
by the compiler. In this example, the enclosing evaluated forms are
|
|
the calls to <code>roq</code> and <code>ploq</code>. These calls resulted from the
|
|
expansion of the <code>zoq</code> macro.
|
|
|
|
</li><li> <span id="index-Actual-Source"></span>
|
|
‘<samp>==> (+ Y 3)</samp>’ This is the <em>actual source</em> responsible for the
|
|
diagnostic. If the actual source appears in the explanation, then we
|
|
print the next enclosing evaluated form, instead of printing the
|
|
actual source twice. (This is the form that would otherwise have been
|
|
the last form of the processing path.) In this example, the problem is
|
|
with the evaluation of the reference to the variable <code>y</code>.
|
|
|
|
</li><li> ‘<samp>caught WARNING: Asserted type NUMBER conflicts with derived type
|
|
(VALUES SYMBOL &OPTIONAL).</samp>’ This is the <em>explanation</em> of the
|
|
problem. In this example, the problem is that, while the call to
|
|
<code>+</code> requires that its arguments are all of type <code>number</code>,
|
|
the compiler has derived that <code>y</code> will evaluate to a
|
|
<code>symbol</code>. Note that ‘<samp>(VALUES SYMBOL &OPTIONAL)</samp>’ expresses
|
|
that <code>y</code> evaluates to precisely one value.
|
|
|
|
</li></ol>
|
|
|
|
<p>Note that each part of the message is distinctively marked:
|
|
</p>
|
|
<ul>
|
|
<li> ‘<samp>file:</samp>’ and ‘<samp>in:</samp>’ mark the file and definition,
|
|
respectively.
|
|
|
|
</li><li> The original source is an indented form with no prefix.
|
|
|
|
</li><li> Each line of the processing path is prefixed with ‘<samp>--></samp>’
|
|
|
|
</li><li> The actual source form is indented like the original source, but is
|
|
marked by a preceding ‘<samp>==></samp>’ line.
|
|
|
|
</li><li> The explanation is prefixed with the diagnostic severity, which can be
|
|
‘<samp>caught ERROR:</samp>’, ‘<samp>caught WARNING:</samp>’, ‘<samp>caught
|
|
STYLE-WARNING:</samp>’, or ‘<samp>note:</samp>’.
|
|
|
|
</li></ul>
|
|
|
|
<p>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:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="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
|
|
</pre></div>
|
|
|
|
<p>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: ‘<samp>[Last
|
|
message occurs <var>repeats</var> times]</samp>’ where <var>repeats</var> is the number
|
|
of times the message was given.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="The-Original-and-Actual-Source"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#The-Processing-Path" accesskey="n" rel="next">The Processing Path</a>, Previous: <a href="index.html#The-Parts-of-a-Compiler-Diagnostic" accesskey="p" rel="prev">The Parts of a Compiler Diagnostic</a>, Up: <a href="index.html#Understanding-Compiler-Diagnostics" accesskey="u" rel="up">Understanding Compiler Diagnostics</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="The-Original-and-Actual-Source-1"></span><h4 class="subsubsection">4.1.3.2 The Original and Actual Source</h4>
|
|
<span id="index-Original-Source-1"></span>
|
|
<span id="index-Actual-Source-1"></span>
|
|
|
|
<p>The <em>original source</em> 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.)
|
|
</p>
|
|
<p>When the <em>actual source</em> 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.
|
|
</p>
|
|
<p>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
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun bar (x)
|
|
(let (a)
|
|
(declare (fixnum a))
|
|
(setq a (foo x))
|
|
a))
|
|
</pre></div>
|
|
|
|
<p>gives this error message
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; 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).
|
|
</pre></div>
|
|
|
|
<p>This message is not saying “there is a problem somewhere in this
|
|
<code>let</code>” – it is saying that there is a problem with the
|
|
<code>let</code> itself. In this example, the problem is that <code>a</code>’s
|
|
<code>nil</code> initial value is not a <code>fixnum</code>.
|
|
</p>
|
|
<hr>
|
|
<span id="The-Processing-Path"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#The-Original-and-Actual-Source" accesskey="p" rel="prev">The Original and Actual Source</a>, Up: <a href="index.html#Understanding-Compiler-Diagnostics" accesskey="u" rel="up">Understanding Compiler Diagnostics</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="The-Processing-Path-1"></span><h4 class="subsubsection">4.1.3.3 The Processing Path</h4>
|
|
<span id="index-Processing-Path-1"></span>
|
|
<span id="index-Macroexpansion"></span>
|
|
<span id="index-Source_002dto_002dsource-transformation"></span>
|
|
|
|
<p>The processing path is mainly useful for debugging macros, so if you
|
|
don’t write macros, you can probably ignore it. Consider this example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun foo (n)
|
|
(dotimes (i n *undefined*)))
|
|
</pre></div>
|
|
|
|
<p>Compiling results in this error message:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; in: DEFUN FOO
|
|
; (DOTIMES (I N *UNDEFINED*))
|
|
; --> DO BLOCK LET TAGBODY RETURN-FROM
|
|
; ==>
|
|
; (PROGN *UNDEFINED*)
|
|
;
|
|
; caught WARNING:
|
|
; undefined variable: *UNDEFINED*
|
|
</pre></div>
|
|
|
|
<p>Note that <code>do</code> appears in the processing path. This is because
|
|
<code>dotimes</code> expands into:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(do ((i 0 (1+ i)) (#:g1 n))
|
|
((>= i #:g1) *undefined*)
|
|
(declare (type unsigned-byte i)))
|
|
</pre></div>
|
|
|
|
<p>The rest of the processing path results from the expansion of
|
|
<code>do</code>:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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*)))))
|
|
</pre></div>
|
|
|
|
<p>In this example, the compiler descended into the <code>block</code>,
|
|
<code>let</code>, <code>tagbody</code> and <code>return-from</code> to reach the
|
|
<code>progn</code> 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 <code>*undefined*</code> itself,
|
|
but that also appeared in the explanation, so the compiler backed out
|
|
one level.
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="Handling-of-Types"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Compiler-Policy" accesskey="n" rel="next">Compiler Policy</a>, Previous: <a href="index.html#Diagnostic-Messages" accesskey="p" rel="prev">Diagnostic Messages</a>, Up: <a href="index.html#Compiler" accesskey="u" rel="up">Compiler</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Handling-of-Types-1"></span><h3 class="section">4.2 Handling of Types</h3>
|
|
|
|
<p>One of the most important features of the SBCL compiler (similar to
|
|
the original CMUCL compiler, also known as <em>Python</em>) is its fairly
|
|
sophisticated understanding of the Common Lisp type system and its
|
|
conservative approach to the implementation of type declarations.
|
|
</p>
|
|
<p>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 <a href="index.html#Efficiency">Efficiency</a>), the use
|
|
of appropriate type declarations can be very important for performance
|
|
as well.
|
|
</p>
|
|
<span id="index-satisfies-_005bcl_005d"></span>
|
|
<p>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 <code>satisfies</code> type specifier.
|
|
</p>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Declarations-as-Assertions" accesskey="1">Declarations as Assertions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Precise-Type-Checking" accesskey="2">Precise Type Checking</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Getting-Existing-Programs-to-Run" accesskey="3">Getting Existing Programs to Run</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Implementation-Limitations" accesskey="4">Implementation Limitations</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Declarations-as-Assertions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Precise-Type-Checking" accesskey="n" rel="next">Precise Type Checking</a>, Up: <a href="index.html#Handling-of-Types" accesskey="u" rel="up">Handling of Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Declarations-as-Assertions-1"></span><h4 class="subsection">4.2.1 Declarations as Assertions</h4>
|
|
<span id="index-Safety-optimization-quality"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<blockquote>
|
|
<p><em>Remaining bugs in the compiler’s handling of types unfortunately
|
|
provide some exceptions to this rule, see <a href="index.html#Implementation-Limitations">Implementation Limitations</a>.</em>
|
|
</p></blockquote>
|
|
|
|
<p>CLOS slot types form a notable exception. Types declared using the
|
|
<code>:type</code> slot option in <code>defclass</code> are asserted if and only
|
|
if the class was defined in <em>safe code</em> and the slot access
|
|
location is in <em>safe code</em> 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.
|
|
</p>
|
|
<p>There are three type checking policies available in SBCL, selectable
|
|
via <code>optimize</code> declarations.
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><strong>Full Type Checks</strong></dt>
|
|
<dd><p>All declarations are considered assertions to be checked at runtime,
|
|
and all type checks are precise. The default compilation policy
|
|
provides full type checks.
|
|
</p>
|
|
<p>Used when <code>(or (>= safety 2) (>= safety speed 1))</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Weak Type Checks</strong></dt>
|
|
<dd><p>Declared types may be simplified into faster to check supertypes: for
|
|
example, <code>(or (integer -17 -7) (integer 7 17))</code> is simplified
|
|
into <code>(integer -17 17)</code>.
|
|
</p>
|
|
<p><strong>Note</strong>: it is relatively easy to corrupt the heap when weak
|
|
type checks are used if the program contains type-errors.
|
|
</p>
|
|
<p>Used when <code>(and (< safety 2) (< safety speed))</code>
|
|
</p>
|
|
</dd>
|
|
<dt><strong>No Type Checks</strong></dt>
|
|
<dd><p>All declarations are believed without assertions. Also disables
|
|
argument count and array bounds checking.
|
|
</p>
|
|
<p><strong>Note</strong>: any type errors in code where type checks are not
|
|
performed are liable to corrupt the heap.
|
|
</p>
|
|
<p>Used when <code>(= safety 0)</code>.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<hr>
|
|
<span id="Precise-Type-Checking"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Getting-Existing-Programs-to-Run" accesskey="n" rel="next">Getting Existing Programs to Run</a>, Previous: <a href="index.html#Declarations-as-Assertions" accesskey="p" rel="prev">Declarations as Assertions</a>, Up: <a href="index.html#Handling-of-Types" accesskey="u" rel="up">Handling of Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Precise-Type-Checking-1"></span><h4 class="subsection">4.2.2 Precise Type Checking</h4>
|
|
<span id="index-Precise-type-checking"></span>
|
|
<span id="index-Type-checking_002c-precise"></span>
|
|
|
|
<p>Precise checking means that the check is done as though <code>typep</code>
|
|
had been called with the exact type specifier that appeared in the
|
|
declaration.
|
|
</p>
|
|
<p>If a variable is declared to be <code>(integer 3 17)</code> then its value
|
|
must always be an integer between <code>3</code> and <code>17</code>. 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 <code>and</code> type specifier.
|
|
</p>
|
|
<p>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 <code>or</code>,
|
|
<code>member</code>, and other list-style type specifiers.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Getting-Existing-Programs-to-Run"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Implementation-Limitations" accesskey="n" rel="next">Implementation Limitations</a>, Previous: <a href="index.html#Precise-Type-Checking" accesskey="p" rel="prev">Precise Type Checking</a>, Up: <a href="index.html#Handling-of-Types" accesskey="u" rel="up">Handling of Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Getting-Existing-Programs-to-Run-1"></span><h4 class="subsection">4.2.3 Getting Existing Programs to Run</h4>
|
|
<span id="index-Existing-programs_002c-to-run"></span>
|
|
<span id="index-Types_002c-portability"></span>
|
|
<span id="index-Compatibility-with-other-Lisps"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>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 <code>safety</code> optimization) and then test this
|
|
safe version. After the checking version has been tested, then you can
|
|
consider weakening or eliminating type checks. <em>This applies
|
|
even to previously debugged programs,</em> because the SBCL compiler does
|
|
much more type inference than other Common Lisp compilers, so an
|
|
incorrect declaration can do more damage.
|
|
</p>
|
|
<p>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:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(prog (foo)
|
|
(declare (fixnum foo))
|
|
(setq foo ...)
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>Here <code>foo</code> is given an initial value of <code>nil</code>, but is
|
|
declared to be a <code>fixnum</code>. 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
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(prog (foo)
|
|
(declare (type (or fixnum null) foo))
|
|
(setq foo ...)
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>or change the initial value
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(prog ((foo 0))
|
|
(declare (fixnum foo))
|
|
(setq foo ...)
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>Another declaration problem occasionally encountered is incorrect
|
|
declarations on <code>defmacro</code> arguments. This can happen when a
|
|
function is converted into a macro. Consider this macro:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defmacro my-1+ (x)
|
|
(declare (fixnum x))
|
|
`(the fixnum (1+ ,x)))
|
|
</pre></div>
|
|
|
|
<p>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:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(my-1+ (+ 4 5))
|
|
</pre></div>
|
|
|
|
<p>This call is illegal because the argument to the macro is <code>(+ 4
|
|
5)</code>, which is a <code>list</code>, not a <code>fixnum</code>. 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 <code>the</code> in
|
|
the expansion:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defmacro my-1+ (x)
|
|
`(the fixnum (1+ (the fixnum ,x))))
|
|
</pre></div>
|
|
|
|
<p>In this case, it would be stylistically preferable to change this
|
|
macro back to a function and declare it inline.
|
|
</p>
|
|
<p>Some more subtle problems are caused by incorrect declarations that
|
|
can’t be detected at compile time. Consider this code:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(do ((pos 0 (position #\a string :start (1+ pos))))
|
|
((null pos))
|
|
(declare (fixnum pos))
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>Although <code>pos</code> is almost always a <code>fixnum</code>, it is <code>nil</code>
|
|
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 <code>position</code> will complain
|
|
because <code>(1+ nil)</code> 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 <code>pos</code> is
|
|
always a <code>fixnum</code>, it believes that <code>pos</code> is never
|
|
<code>nil</code>, so <code>(null pos)</code> 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.
|
|
</p>
|
|
<p>In this case, the fix is to weaken the type declaration to <code>(or
|
|
fixnum null)</code> <a id="DOCF2" href="index.html#FOOT2"><sup>2</sup></a>.
|
|
</p>
|
|
<p>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 <code>fixnum</code>, since <code>nil</code> is not a
|
|
legal numeric argument. Another possible fix would be to say:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(do ((pos 0 (position #\a string :start (1+ pos))))
|
|
((null pos))
|
|
(let ((pos pos))
|
|
(declare (fixnum pos))
|
|
...))
|
|
</pre></div>
|
|
|
|
<p>This would be preferable in some circumstances, since it would allow a
|
|
non-standard representation to be used for the local <code>pos</code>
|
|
variable in the loop body.
|
|
</p>
|
|
<hr>
|
|
<span id="Implementation-Limitations"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Getting-Existing-Programs-to-Run" accesskey="p" rel="prev">Getting Existing Programs to Run</a>, Up: <a href="index.html#Handling-of-Types" accesskey="u" rel="up">Handling of Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Implementation-Limitations-1"></span><h4 class="subsection">4.2.4 Implementation Limitations</h4>
|
|
|
|
<p>Ideally, the compiler would consider <em>all</em> type declarations to
|
|
be assertions, so that adding type declarations to a program, no
|
|
matter how incorrect they might be, would <em>never</em> cause undefined
|
|
behavior. However, the compiler is known to fall short of this goal in
|
|
two areas:
|
|
</p>
|
|
<ul>
|
|
<li> <em>Proclaimed</em> constraints on argument and result types of a
|
|
function are supposed to be checked by the function. If the function
|
|
type is proclaimed before function definition, type checks are
|
|
inserted by the compiler, but the standard allows the reversed order,
|
|
in which case the compiler will trust the declaration.
|
|
|
|
</li><li> The compiler cannot check types of an unknown number of values; if the
|
|
number of generated values is unknown, but the number of consumed is
|
|
known, only consumed values are checked.
|
|
|
|
<p>For example,
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun foo (x)
|
|
(the integer (bar x)))
|
|
</pre></div>
|
|
|
|
<p>causes the following compiler diagnostic to be emitted:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; note: type assertion too complex to check:
|
|
; (VALUES INTEGER &REST T).
|
|
</pre></div>
|
|
|
|
<p>A partial workaround is instead write:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun foo (x)
|
|
(the (values integer &optional) (bar x)))
|
|
</pre></div>
|
|
|
|
</li></ul>
|
|
|
|
<p>These are important issues, but are not necessarily easy to fix, so
|
|
they may, alas, remain in the system for a while.
|
|
</p>
|
|
<hr>
|
|
<span id="Compiler-Policy"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Compiler-Errors" accesskey="n" rel="next">Compiler Errors</a>, Previous: <a href="index.html#Handling-of-Types" accesskey="p" rel="prev">Handling of Types</a>, Up: <a href="index.html#Compiler" accesskey="u" rel="up">Compiler</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Compiler-Policy-1"></span><h3 class="section">4.3 Compiler Policy</h3>
|
|
|
|
<p>Compiler policy is controlled by the <code>optimize</code> declaration,
|
|
supporting all ANSI optimization qualities (<code>debug</code>,
|
|
<code>safety</code>, <code>space</code>, and <code>speed</code>).<a id="DOCF3" href="index.html#FOOT3"><sup>3</sup></a>
|
|
</p>
|
|
<p>For effects of various optimization qualities on type-safety and
|
|
debuggability see <a href="index.html#Declarations-as-Assertions">Declarations as Assertions</a> and <a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a>.
|
|
</p>
|
|
<p>Ordinarily, when the <code>speed</code> 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 <a href="index.html#Controlling-Verbosity">Controlling Verbosity</a>.
|
|
</p>
|
|
<p>The value of <code>space</code> mostly influences the compiler’s decision
|
|
whether to inline operations, which tend to increase the size of
|
|
programs. Use the value <code>0</code> 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.
|
|
</p>
|
|
|
|
<span id="Function-sb_002dext-describe_002dcompiler_002dpolicy"></span><dl>
|
|
<dt id="index-describe_002dcompiler_002dpolicy">Function: <strong>describe-compiler-policy</strong> <em>[sb-ext] &optional spec</em></dt>
|
|
<dd><p>Print all global optimization settings, augmented by <code>spec</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-restrict_002dcompiler_002dpolicy"></span><dl>
|
|
<dt id="index-restrict_002dcompiler_002dpolicy">Function: <strong>restrict-compiler-policy</strong> <em>[sb-ext] &optional quality min max</em></dt>
|
|
<dd><p>Assign a minimum value to an optimization quality. <code>quality</code> is the name of
|
|
the optimization quality to restrict, <code>min</code> (defaulting to zero) is the
|
|
minimum allowed value, and <code>max</code> (defaults to 3) is the maximum.
|
|
</p>
|
|
<p>Returns the alist describing the current policy restrictions.
|
|
</p>
|
|
<p>If <code>quality</code> is <code>nil</code> or not given, nothing is done.
|
|
</p>
|
|
<p>Otherwise, if <code>min</code> is zero or <code>max</code> is 3 or neither are given, any
|
|
existing restrictions of <code>quality</code> are removed.
|
|
</p>
|
|
<p>See also <code>:policy</code> option in <code>with-compilation-unit</code>.
|
|
</p></dd></dl>
|
|
<span id="Macro-common_002dlisp-with_002dcompilation_002dunit"></span><dl>
|
|
<dt id="index-with_002dcompilation_002dunit">Macro: <strong>with-compilation-unit</strong> <em>[cl] options &body body</em></dt>
|
|
<dd><p>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.
|
|
</p>
|
|
<p>Following options are defined:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:override</code> Boolean-Form</em></dt>
|
|
<dd><p>One 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 <code>override</code> is <code>nil</code> (the default), then the outermost
|
|
<code>with-compilation-unit</code> form grabs the undefined warnings. Specifying
|
|
<code>override</code> true causes that form to grab any enclosed warnings, even if it
|
|
is enclosed by another <code>with-compilation-unit</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:policy</code> Optimize-Declaration-Form</em></dt>
|
|
<dd><p>Provides dynamic scoping for global compiler optimization qualities and
|
|
restrictions, limiting effects of subsequent <code>optimize</code> proclamations and
|
|
calls to <code>sb-ext:restrict-compiler-policy</code> to the dynamic scope of <code>body</code>.
|
|
</p>
|
|
<p>If <code>override</code> is false, specified <code>policy</code> is merged with current global
|
|
policy. If <code>override</code> is true, current global policy, including any
|
|
restrictions, is discarded in favor of the specified <code>policy</code>.
|
|
</p>
|
|
<p>Supplying <code>policy</code> <code>nil</code> is equivalent to the option not being supplied at
|
|
all, ie. dynamic scoping of policy does not take place.
|
|
</p>
|
|
<p>This option is an SBCL-specific experimental extension: Interface
|
|
subject to change.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:source-namestring</code> Namestring-Form</em></dt>
|
|
<dd><p>Attaches 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 <code>compile-file</code> is used: this option
|
|
can be used to provide source-file information for functions compiled
|
|
using <code>compile</code>, or to override the input-file of <code>compile-file</code>.
|
|
</p>
|
|
<p>If both an outer and an inner <code>with-compilation-unit</code> provide a
|
|
<code>source-namestring</code>, the inner one takes precedence. Unaffected
|
|
by <code>:override</code>.
|
|
</p>
|
|
<p>This is an SBCL-specific extension.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:source-plist</code> Plist-Form</em></dt>
|
|
<dd><p>Attaches the value returned by the Plist-Form to internal debug-source
|
|
information of functions compiled in within the dynamic extent of <code>body</code>.
|
|
</p>
|
|
<p>Primarily for use by development environments, in order to eg. associate
|
|
function definitions with editor-buffers. Can be accessed using
|
|
<code>sb-introspect:definition-source-plist</code>.
|
|
</p>
|
|
<p>If an outer <code>with-compilation-unit</code> form also provide a <code>source-plist</code>, it
|
|
is appended to the end of the provided <code>source-plist</code>. Unaffected
|
|
by <code>:override</code>.
|
|
</p>
|
|
<p>This is an SBCL-specific extension.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> ;; 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"))
|
|
</pre></div>
|
|
</dd></dl>
|
|
|
|
<hr>
|
|
<span id="Compiler-Errors"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Open-Coding-and-Inline-Expansion" accesskey="n" rel="next">Open Coding and Inline Expansion</a>, Previous: <a href="index.html#Compiler-Policy" accesskey="p" rel="prev">Compiler Policy</a>, Up: <a href="index.html#Compiler" accesskey="u" rel="up">Compiler</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Compiler-Errors-1"></span><h3 class="section">4.4 Compiler Errors</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Type-Errors-at-Compile-Time" accesskey="1">Type Errors at Compile Time</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Errors-During-Macroexpansion" accesskey="2">Errors During Macroexpansion</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Read-Errors" accesskey="3">Read Errors</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Type-Errors-at-Compile-Time"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Errors-During-Macroexpansion" accesskey="n" rel="next">Errors During Macroexpansion</a>, Up: <a href="index.html#Compiler-Errors" accesskey="u" rel="up">Compiler Errors</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Type-Errors-at-Compile-Time-1"></span><h4 class="subsection">4.4.1 Type Errors at Compile Time</h4>
|
|
<span id="index-Compile-time-type-errors"></span>
|
|
<span id="index-Type-checking_002c-at-compile-time"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>For example, consider this code fragment:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun raz (foo)
|
|
(let ((x (case foo
|
|
(:this 13)
|
|
(:that 9)
|
|
(:the-other 42))))
|
|
(declare (fixnum x))
|
|
(foo x)))
|
|
</pre></div>
|
|
|
|
<p>Compilation produces this warning:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; 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
|
|
</pre></div>
|
|
|
|
<p>In this case, the warning means that if <code>foo</code> isn’t any of
|
|
<code>:this</code>, <code>:that</code> or <code>:the-other</code>, then <code>x</code> will be
|
|
initialized to <code>nil</code>, which the <code>fixnum</code> declaration makes
|
|
illegal. The warning will go away if <code>ecase</code> is used instead of
|
|
<code>case</code>, or if <code>:the-other</code> is changed to <code>t</code>.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<hr>
|
|
<span id="Errors-During-Macroexpansion"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Read-Errors" accesskey="n" rel="next">Read Errors</a>, Previous: <a href="index.html#Type-Errors-at-Compile-Time" accesskey="p" rel="prev">Type Errors at Compile Time</a>, Up: <a href="index.html#Compiler-Errors" accesskey="u" rel="up">Compiler Errors</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Errors-During-Macroexpansion-1"></span><h4 class="subsection">4.4.2 Errors During Macroexpansion</h4>
|
|
<span id="index-Macroexpansion_002c-errors-during"></span>
|
|
|
|
<p>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 <code>*break-on-signals*</code> to <code>error</code>. For
|
|
example, this definition:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun foo (e l)
|
|
(do ((current l (cdr current))
|
|
((atom current) nil))
|
|
(when (eq (car current) e) (return current))))
|
|
</pre></div>
|
|
|
|
<p>gives this error:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; 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)
|
|
</pre></div>
|
|
|
|
|
|
<hr>
|
|
<span id="Read-Errors"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Errors-During-Macroexpansion" accesskey="p" rel="prev">Errors During Macroexpansion</a>, Up: <a href="index.html#Compiler-Errors" accesskey="u" rel="up">Compiler Errors</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Read-Errors-1"></span><h4 class="subsection">4.4.3 Read Errors</h4>
|
|
<span id="index-Read-errors_002c-compiler"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<hr>
|
|
<span id="Open-Coding-and-Inline-Expansion"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Interpreter" accesskey="n" rel="next">Interpreter</a>, Previous: <a href="index.html#Compiler-Errors" accesskey="p" rel="prev">Compiler Errors</a>, Up: <a href="index.html#Compiler" accesskey="u" rel="up">Compiler</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Open-Coding-and-Inline-Expansion-1"></span><h3 class="section">4.5 Open Coding and Inline Expansion</h3>
|
|
<span id="index-Open_002dcoding"></span>
|
|
<span id="index-Inline-expansion"></span>
|
|
<span id="index-Static-functions"></span>
|
|
|
|
<p>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:
|
|
</p>
|
|
<ul>
|
|
<li> Attempts to redefine standard functions may be frustrated, since the
|
|
function may never be called. Although it is technically illegal to
|
|
redefine standard functions, users sometimes want to implicitly
|
|
redefine these functions when they are debugging using the
|
|
<code>trace</code> macro. Special-casing of standard functions can be
|
|
inhibited using the <code>notinline</code> declaration, but even then some
|
|
phases of analysis such as type inferencing are applied by the
|
|
compiler.
|
|
|
|
</li><li> The compiler can have multiple alternate implementations of standard
|
|
functions that implement different trade-offs of speed, space and
|
|
safety. This selection is based on the compiler policy, <a href="index.html#Compiler-Policy">Compiler Policy</a>.
|
|
|
|
</li></ul>
|
|
|
|
<p>When a function call is <em>open coded</em>, inline code whose effect is
|
|
equivalent to the function call is substituted for that function
|
|
call. When a function call is <em>closed coded</em>, 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 <code>nthcdr</code> were to be
|
|
open coded, then
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(nthcdr 4 foobar)
|
|
</pre></div>
|
|
|
|
<p>might turn into
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(cdr (cdr (cdr (cdr foobar))))
|
|
</pre></div>
|
|
|
|
<p>or even
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(do ((i 0 (1+ i))
|
|
(list foobar (cdr foobar)))
|
|
((= i 4) list))
|
|
</pre></div>
|
|
|
|
<p>If <code>nth</code> is closed coded, then
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(nth x l)
|
|
</pre></div>
|
|
|
|
<p>might stay the same, or turn into something like
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(car (nthcdr x l))
|
|
</pre></div>
|
|
|
|
<p>In general, open coding sacrifices space for speed, but some functions
|
|
(such as <code>car</code>) 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 <em>static call</em>. Static function call uses
|
|
a more efficient calling convention that forbids redefinition.
|
|
</p>
|
|
<hr>
|
|
<span id="Interpreter"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Advanced-Compiler-Use-and-Efficiency-Hints" accesskey="n" rel="next">Advanced Compiler Use and Efficiency Hints</a>, Previous: <a href="index.html#Open-Coding-and-Inline-Expansion" accesskey="p" rel="prev">Open Coding and Inline Expansion</a>, Up: <a href="index.html#Compiler" accesskey="u" rel="up">Compiler</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Interpreter-1"></span><h3 class="section">4.6 Interpreter</h3>
|
|
<span id="index-Interpreter"></span>
|
|
<span id="index-eval-_005bcl_005d"></span>
|
|
<span id="index-_002aevaluator_002dmode_002a-_005bsb_002dext_005d"></span>
|
|
|
|
<p>By default SBCL implements <code>eval</code> by calling the native code
|
|
compiler.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002aevaluator_002dmode_002a"></span><dl>
|
|
<dt id="index-_002aevaluator_002dmode_002a">Variable: <strong>*evaluator-mode*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Toggle between different evaluator implementations. If set to <code>:compile</code>,
|
|
an implementation of <code>eval</code> that calls the compiler will be used. If set
|
|
to <code>:interpret</code>, an interpreter will be used.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Advanced-Compiler-Use-and-Efficiency-Hints"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Interpreter" accesskey="p" rel="prev">Interpreter</a>, Up: <a href="index.html#Compiler" accesskey="u" rel="up">Compiler</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Advanced-Compiler-Use-and-Efficiency-Hints-1"></span><h3 class="section">4.7 Advanced Compiler Use and Efficiency Hints</h3>
|
|
<p>For more advanced usages of the compiler, please see the chapter of the
|
|
same name in the CMUCL manual. Many aspects of the compiler have stayed
|
|
exactly the same, and there is a much more detailed explanation of the
|
|
compiler’s behavior and how to maximally optimize code in their
|
|
manual. In particular, while SBCL no longer supports byte-code
|
|
compilation, it does support CMUCL’s block compilation facility allowing
|
|
whole program optimization and increased use of the local call
|
|
convention.
|
|
</p>
|
|
<p>Unlike CMUCL, SBCL is able to open-code forward-referenced type tests
|
|
while block compiling. This helps for mutually referential
|
|
<code>defstruct</code>s in particular.
|
|
</p><hr>
|
|
<span id="Debugger"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Efficiency" accesskey="n" rel="next">Efficiency</a>, Previous: <a href="index.html#Compiler" accesskey="p" rel="prev">Compiler</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Debugger-1"></span><h2 class="chapter">5 Debugger</h2>
|
|
<span id="index-Debugger"></span>
|
|
|
|
<p>This chapter documents the debugging facilities of SBCL, including
|
|
the debugger, single-stepper and <code>trace</code>, and the effect of
|
|
<code>(optimize debug)</code> declarations.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Debugger-Entry" accesskey="1">Debugger Entry</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Debugger-Command-Loop" accesskey="2">Debugger Command Loop</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Stack-Frames" accesskey="3">Stack Frames</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Variable-Access" accesskey="4">Variable Access</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Source-Location-Printing" accesskey="5">Source Location Printing</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Debugger-Policy-Control" accesskey="6">Debugger Policy Control</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Exiting-Commands" accesskey="7">Exiting Commands</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Information-Commands" accesskey="8">Information Commands</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Function-Tracing" accesskey="9">Function Tracing</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Single-Stepping">Single Stepping</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Debugger-Entry"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Debugger-Command-Loop" accesskey="n" rel="next">Debugger Command Loop</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Debugger-Entry-1"></span><h3 class="section">5.1 Debugger Entry</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Debugger-Banner" accesskey="1">Debugger Banner</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Debugger-Invocation" accesskey="2">Debugger Invocation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Debugger-Banner"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Debugger-Invocation" accesskey="n" rel="next">Debugger Invocation</a>, Up: <a href="index.html#Debugger-Entry" accesskey="u" rel="up">Debugger Entry</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Debugger-Banner-1"></span><h4 class="subsection">5.1.1 Debugger Banner</h4>
|
|
|
|
<p>When you enter the debugger, it looks something like this:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">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]
|
|
</pre></div>
|
|
|
|
<p>The first group of lines describe what the error was that put us in
|
|
the debugger. In this case <code>car</code> was called on <code>3</code>, causing
|
|
a <code>type-error</code>.
|
|
</p>
|
|
<p>This is followed by the “beginner help line”, which appears only if
|
|
<code>sb-debug:*debug-beginner-help-p*</code> is true (default).
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>The current frame appears right underneath the restarts, immediately
|
|
followed by the debugger prompt.
|
|
</p>
|
|
<hr>
|
|
<span id="Debugger-Invocation"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Debugger-Banner" accesskey="p" rel="prev">Debugger Banner</a>, Up: <a href="index.html#Debugger-Entry" accesskey="u" rel="up">Debugger Entry</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Debugger-Invocation-1"></span><h4 class="subsection">5.1.2 Debugger Invocation</h4>
|
|
|
|
<p>The debugger is invoked when:
|
|
</p>
|
|
<ul>
|
|
<li> <code>error</code> is called, and the condition it signals is not handled.
|
|
|
|
</li><li> <code>break</code> is called, or <code>signal</code> is called with a condition
|
|
that matches the current <code>*break-on-signals*</code>.
|
|
|
|
</li><li> the debugger is explicitly entered with the <code>invoke-debugger</code>
|
|
function.
|
|
|
|
</li></ul>
|
|
|
|
<p>When the debugger is invoked by a condition, ANSI mandates that the
|
|
value of <code>*debugger-hook*</code>, if any, be called with two arguments:
|
|
the condition that caused the debugger to be invoked and the previous
|
|
value of <code>*debugger-hook*</code>. When this happens,
|
|
<code>*debugger-hook*</code> is bound to NIL to prevent recursive errors.
|
|
However, ANSI also mandates that <code>*debugger-hook*</code> not be invoked
|
|
when the debugger is to be entered by the <code>break</code> function. For
|
|
users who wish to provide an alternate debugger interface (and thus
|
|
catch <code>break</code> entries into the debugger), SBCL provides
|
|
<code>sb-ext:*invoke-debugger-hook*</code>, which is invoked during any
|
|
entry into the debugger.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002ainvoke_002ddebugger_002dhook_002a"></span><dl>
|
|
<dt id="index-_002ainvoke_002ddebugger_002dhook_002a">Variable: <strong>*invoke-debugger-hook*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>This is either <code>nil</code> 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 <code>*invoke-debugger-hook*</code> bound to <code>nil</code> to minimize recursive
|
|
errors, and receives as arguments the condition that triggered
|
|
debugger entry and the previous value of <code>*invoke-debugger-hook*</code>
|
|
</p>
|
|
<p>This mechanism is an <code>sbcl</code> extension similar to the standard <code>*debugger-hook*</code>.
|
|
In contrast to <code>*debugger-hook*</code>, it is observed by <code>invoke-debugger</code> even when
|
|
called by <code>break</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Debugger-Command-Loop"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Stack-Frames" accesskey="n" rel="next">Stack Frames</a>, Previous: <a href="index.html#Debugger-Entry" accesskey="p" rel="prev">Debugger Entry</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Debugger-Command-Loop-1"></span><h3 class="section">5.2 Debugger Command Loop</h3>
|
|
|
|
<p>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: <code>help</code>
|
|
can be typed as ‘<samp>h</samp>’, ‘<samp>he</samp>’, etc.
|
|
</p>
|
|
<p>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 <code>progn</code> to hide it from
|
|
the command loop.
|
|
</p>
|
|
<p>The debugger prompt is “<code><var>frame</var>]</code>”, where <var>frame</var> 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.
|
|
</p>
|
|
<p>It is possible to override the normal printing behaviour in the
|
|
debugger by using the <code>sb-ext:*debug-print-variable-alist*</code>.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002adebug_002dprint_002dvariable_002dalist_002a"></span><dl>
|
|
<dt id="index-_002adebug_002dprint_002dvariable_002dalist_002a">Variable: <strong>*debug-print-variable-alist*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>an association list describing new bindings for special variables
|
|
to be used within the debugger. Eg.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> ((*PRINT-LENGTH* . 10) (*PRINT-LEVEL* . 6) (*PRINT-PRETTY* . NIL))
|
|
</pre></div>
|
|
|
|
<p>The variables in the <code>car</code> positions are bound to the values in the <code>cdr</code>
|
|
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.
|
|
</p>
|
|
<p>Initially empty, <code>*debug-print-variable-alist*</code> is typically used to
|
|
provide bindings for printer control variables.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Stack-Frames"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Variable-Access" accesskey="n" rel="next">Variable Access</a>, Previous: <a href="index.html#Debugger-Command-Loop" accesskey="p" rel="prev">Debugger Command Loop</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Stack-Frames-1"></span><h3 class="section">5.3 Stack Frames</h3>
|
|
<span id="index-Stack-frames"></span>
|
|
|
|
<p>A <em>stack frame</em> 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:
|
|
</p>
|
|
<ul>
|
|
<li> <em>variables</em> (see <a href="index.html#Variable-Access">Variable Access</a>), which are the values being operated
|
|
on.
|
|
|
|
</li><li> <em>arguments</em> to the call (which are really just particularly
|
|
interesting variables).
|
|
|
|
</li><li> a current source location (see <a href="index.html#Source-Location-Printing">Source Location Printing</a>), which is
|
|
the place in the program where the function was running when it
|
|
stopped to call another function, or because of an interrupt or error.
|
|
|
|
</li></ul>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Stack-Motion" accesskey="1">Stack Motion</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#How-Arguments-are-Printed" accesskey="2">How Arguments are Printed</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Function-Names" accesskey="3">Function Names</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Debug-Tail-Recursion" accesskey="4">Debug Tail Recursion</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Unknown-Locations-and-Interrupts" accesskey="5">Unknown Locations and Interrupts</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Stack-Motion"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#How-Arguments-are-Printed" accesskey="n" rel="next">How Arguments are Printed</a>, Up: <a href="index.html#Stack-Frames" accesskey="u" rel="up">Stack Frames</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Stack-Motion-1"></span><h4 class="subsection">5.3.1 Stack Motion</h4>
|
|
|
|
<p>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:
|
|
</p>
|
|
<dl>
|
|
<dt id="index-up">Debugger Command: <strong>up</strong></dt>
|
|
<dd><p>Move up to the next higher frame. More recent function calls are
|
|
considered to be higher on the stack.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-down">Debugger Command: <strong>down</strong></dt>
|
|
<dd><p>Move down to the next lower frame.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-top">Debugger Command: <strong>top</strong></dt>
|
|
<dd><p>Move to the highest frame, that is, the frame where the debugger was
|
|
entered.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-bottom">Debugger Command: <strong>bottom</strong></dt>
|
|
<dd><p>Move to the lowest frame.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-frame">Debugger Command: <strong>frame</strong> <em>[<var>n</var>]</em></dt>
|
|
<dd><p>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.
|
|
</p></dd></dl>
|
|
|
|
|
|
<hr>
|
|
<span id="How-Arguments-are-Printed"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Function-Names" accesskey="n" rel="next">Function Names</a>, Previous: <a href="index.html#Stack-Motion" accesskey="p" rel="prev">Stack Motion</a>, Up: <a href="index.html#Stack-Frames" accesskey="u" rel="up">Stack Frames</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="How-Arguments-are-Printed-1"></span><h4 class="subsection">5.3.2 How Arguments are Printed</h4>
|
|
|
|
<p>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:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(myfun (+ 3 4) 'a)
|
|
</pre></div>
|
|
|
|
<p>would look like this:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">(MYFUN 7 A)
|
|
</pre></div>
|
|
|
|
<p>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:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(subseq "foo" 1)
|
|
</pre></div>
|
|
|
|
<p>would look like this:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">(SUBSEQ "foo" 1 3)
|
|
</pre></div>
|
|
|
|
<p>And this call:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(string-upcase "test case")
|
|
</pre></div>
|
|
|
|
<p>would look like this:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">(STRING-UPCASE "test case" :START 0 :END NIL)
|
|
</pre></div>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p><code>&rest</code> arguments are handled somewhat differently. The value of
|
|
the rest argument variable is displayed as the spread-out arguments to
|
|
the call, so:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(format t "~A is a ~A." "This" 'test)
|
|
</pre></div>
|
|
|
|
<p>would look like this:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">(FORMAT T "~A is a ~A." "This" 'TEST)
|
|
</pre></div>
|
|
|
|
<p>Rest arguments cause an exception to the normal display of keyword
|
|
arguments in functions that have both <code>&rest</code> and <code>&key</code>
|
|
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.
|
|
</p>
|
|
<p>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 ‘<samp>#<unused-arg></samp>’ 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 <a href="index.html#Variable-Access">Variable Access</a>),
|
|
then ‘<samp>#<unavailable-arg></samp>’ will be printed instead of the argument
|
|
value.
|
|
</p>
|
|
<p>Note that inline expansion and open-coding affect what frames
|
|
are present in the debugger, see <a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a>.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Function-Names"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Debug-Tail-Recursion" accesskey="n" rel="next">Debug Tail Recursion</a>, Previous: <a href="index.html#How-Arguments-are-Printed" accesskey="p" rel="prev">How Arguments are Printed</a>, Up: <a href="index.html#Stack-Frames" accesskey="u" rel="up">Stack Frames</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Function-Names-1"></span><h4 class="subsection">5.3.3 Function Names</h4>
|
|
|
|
<p>If a function is defined by <code>defun</code> it will appear in backtrace
|
|
by that name. Functions defined by <code>labels</code> and <code>flet</code> will
|
|
appear as <code>(FLET <var>name</var>)</code> and <code>(LABELS <var>name</var>)</code> respectively.
|
|
Anonymous lambdas will appear as <code>(LAMBDA <var>lambda-list</var>)</code>.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Entry-Point-Details" accesskey="1">Entry Point Details</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Entry-Point-Details"></span><div class="header">
|
|
<p>
|
|
Up: <a href="index.html#Function-Names" accesskey="u" rel="up">Function Names</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Entry-Point-Details-1"></span><h4 class="subsubsection">5.3.3.1 Entry Point Details</h4>
|
|
<span id="index-External-entry-points"></span>
|
|
<span id="index-Entry-points_002c-external"></span>
|
|
<span id="index-Block-compilation_002c-debugger-implications"></span>
|
|
<span id="index-External_002c-stack-frame-kind"></span>
|
|
<span id="index-Optional_002c-stack-frame-kind"></span>
|
|
<span id="index-Cleanup_002c-stack-frame-kind"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>With recursive or block compiled functions, an additional
|
|
<code>external</code> frame may appear before the frame representing the first
|
|
call to the recursive function or entry to the compiled block. This is a
|
|
consequence of the way the compiler works: there is nothing odd with
|
|
your program. You may also see <code>cleanup</code> frames during the
|
|
execution of <code>unwind-protect</code> cleanup code, and <code>optional</code> for
|
|
variable argument entry points.
|
|
</p>
|
|
<hr>
|
|
<span id="Debug-Tail-Recursion"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Unknown-Locations-and-Interrupts" accesskey="n" rel="next">Unknown Locations and Interrupts</a>, Previous: <a href="index.html#Function-Names" accesskey="p" rel="prev">Function Names</a>, Up: <a href="index.html#Stack-Frames" accesskey="u" rel="up">Stack Frames</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Debug-Tail-Recursion-1"></span><h4 class="subsection">5.3.4 Debug Tail Recursion</h4>
|
|
<span id="index-Tail-recursion"></span>
|
|
<span id="index-Recursion_002c-tail"></span>
|
|
|
|
<p>The compiler is “properly tail recursive.” If a function call is in
|
|
a tail-recursive position, the stack frame will be deallocated
|
|
<em>at the time of the call</em>, rather than after the call returns.
|
|
Consider this backtrace:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">(BAR ...)
|
|
(FOO ...)
|
|
</pre></div>
|
|
|
|
<p>Because of tail recursion, it is not necessarily the case that
|
|
<code>FOO</code> directly called <code>BAR</code>. It may be that <code>FOO</code>
|
|
called some other function <code>FOO2</code> which then called <code>BAR</code>
|
|
tail-recursively, as in this example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun foo ()
|
|
...
|
|
(foo2 ...)
|
|
...)
|
|
|
|
(defun foo2 (...)
|
|
...
|
|
(bar ...))
|
|
|
|
(defun bar (...)
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>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 <a href="index.html#Source-Location-Printing">Source Location Printing</a>.
|
|
</p>
|
|
<p>The elimination of tail-recursive frames can be prevented by disabling
|
|
tail-recursion optimization, which happens when the <code>debug</code>
|
|
optimization quality is greater than <code>2</code>.
|
|
See <a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a>.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Unknown-Locations-and-Interrupts"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Debug-Tail-Recursion" accesskey="p" rel="prev">Debug Tail Recursion</a>, Up: <a href="index.html#Stack-Frames" accesskey="u" rel="up">Stack Frames</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Unknown-Locations-and-Interrupts-1"></span><h4 class="subsection">5.3.5 Unknown Locations and Interrupts</h4>
|
|
<span id="index-Unknown-code-locations"></span>
|
|
<span id="index-Locations_002c-unknown"></span>
|
|
<span id="index-Interrupts"></span>
|
|
<span id="index-Errors_002c-run_002dtime"></span>
|
|
|
|
<p>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
|
|
<em>unknown</em>. If the code location for a frame is unknown, then some
|
|
variables may be inaccessible, and the source location cannot be
|
|
precisely displayed.
|
|
</p>
|
|
<p>There are three reasons why a code location could be unknown:
|
|
</p>
|
|
<ul>
|
|
<li> There is inadequate debug information due to the value of the <code>debug</code>
|
|
optimization quality. See <a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a>.
|
|
|
|
</li><li> The debugger was entered because of an interrupt such as <tt class="key">C-c</tt>.
|
|
|
|
</li><li> A hardware error such as “‘<samp>bus error</samp>’” occurred in code that was
|
|
compiled unsafely due to the value of the <code>safety</code> optimization
|
|
quality.
|
|
|
|
</li></ul>
|
|
|
|
<p>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, see <a href="index.html#Variable-Value-Availability">Variable Value Availability</a>.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Variable-Access"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Source-Location-Printing" accesskey="n" rel="next">Source Location Printing</a>, Previous: <a href="index.html#Stack-Frames" accesskey="p" rel="prev">Stack Frames</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Variable-Access-1"></span><h3 class="section">5.4 Variable Access</h3>
|
|
<span id="index-Debug-variables"></span>
|
|
<span id="index-Variables_002c-debugger-access"></span>
|
|
|
|
<p>There are two ways to access the current frame’s local variables in
|
|
the debugger: <code>list-locals</code> and <code>sb-debug:var</code>.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>When there are ambiguous variables, the evaluator assigns each one a
|
|
small integer identifier. The <code>sb-debug:var</code> function uses this
|
|
identifier to distinguish between ambiguous variables. The
|
|
<code>list-locals</code> command prints the identifier. In the
|
|
following example, there are two variables named <code>X</code>. The first
|
|
one has identifier 0 (which is not printed), the second one has
|
|
identifier 1.
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">X = 1
|
|
X#1 = 2
|
|
</pre></div>
|
|
|
|
<dl>
|
|
<dt id="index-list_002dlocals">Debugger Command: <strong>list-locals</strong> <em>[<var>prefix</var>]</em></dt>
|
|
<dd><p>This command prints the name and value of all variables in the current
|
|
frame whose name has the specified <var>prefix</var>. <var>prefix</var> may be
|
|
a string or a symbol. If no <var>prefix</var> is given, then all available
|
|
variables are printed. If a variable has a potentially ambiguous
|
|
name, then the name is printed with a “<code>#<var>identifier</var></code>”
|
|
suffix, where <var>identifier</var> is the small integer used to make the
|
|
name unique.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-var">Function: <strong>var</strong> <em>[sb-debug] <var>name</var> &optional <var>identifier</var></em></dt>
|
|
<dd><p>This function returns the value of the variable in the current frame
|
|
with the specified <var>name</var>. If supplied, <var>identifier</var>
|
|
determines which value to return when there are ambiguous variables.
|
|
</p>
|
|
<p>When <var>name</var> is a symbol, it is interpreted as the symbol name of
|
|
the variable, i.e. the package is significant. If <var>name</var> is an
|
|
uninterned symbol (gensym), then return the value of the uninterned
|
|
variable with the same name. If <var>name</var> is a string,
|
|
<code>sb-debug:var</code> interprets it as the prefix of a variable name
|
|
that must unambiguously complete to the name of a valid variable.
|
|
</p>
|
|
<p><var>identifier</var> is used to disambiguate the variable name; use
|
|
<code>list-locals</code> to find out the identifiers.
|
|
</p></dd></dl>
|
|
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Variable-Value-Availability" accesskey="1">Variable Value Availability</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Note-On-Lexical-Variable-Access" accesskey="2">Note On Lexical Variable Access</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Variable-Value-Availability"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Note-On-Lexical-Variable-Access" accesskey="n" rel="next">Note On Lexical Variable Access</a>, Up: <a href="index.html#Variable-Access" accesskey="u" rel="up">Variable Access</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Variable-Value-Availability-1"></span><h4 class="subsection">5.4.1 Variable Value Availability</h4>
|
|
<span id="index-Availability-of-debug-variables"></span>
|
|
<span id="index-Validity-of-debug-variables"></span>
|
|
<span id="index-Debug-optimization-quality"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>The one exception is this: if you interrupt (e.g., with <tt class="key">C-c</tt>) or
|
|
if there is an unexpected hardware error such as “‘<samp>bus error</samp>’”
|
|
(which should only happen in unsafe code), then the values displayed
|
|
for arguments to the interrupted frame might be
|
|
incorrect.<a id="DOCF4" href="index.html#FOOT4"><sup>4</sup></a> This exception applies only to the
|
|
interrupted frame: any frame farther down the stack will be fine.
|
|
</p>
|
|
<p>The value of a variable may be unavailable for these reasons:
|
|
</p>
|
|
<ul>
|
|
<li> The value of the <code>debug</code> 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
|
|
<code>debug</code> is at least <code>2</code>.
|
|
|
|
</li><li> The compiler did lifetime analysis and determined that the value was no longer
|
|
needed, even though its scope had not been exited. Lifetime analysis is
|
|
inhibited when the <code>debug</code> optimization quality is <code>3</code>.
|
|
|
|
</li><li> The variable’s name is an uninterned symbol (gensym). To save space, the
|
|
compiler only dumps debug information about uninterned variables when the
|
|
<code>debug</code> optimization quality is <code>3</code>.
|
|
|
|
</li><li> The frame’s location is unknown (see <a href="index.html#Unknown-Locations-and-Interrupts">Unknown Locations and Interrupts</a>) because the debugger was entered due to an interrupt or
|
|
unexpected hardware error. Under these conditions the values of
|
|
arguments will be available, but might be incorrect. This is the
|
|
exception mentioned above.
|
|
|
|
</li><li> The variable (or the code referencing it) was optimized out
|
|
of existence. Variables with no reads are always optimized away. The
|
|
degree to which the compiler deletes variables will depend on the
|
|
value of the <code>compilation-speed</code> optimization quality, but most
|
|
source-level optimizations are done under all compilation policies.
|
|
|
|
</li><li> The variable is never set and its definition looks like
|
|
<div class="lisp">
|
|
<pre class="lisp">(LET ((var1 var2))
|
|
...)
|
|
</pre></div>
|
|
<p>In this case, <code>var1</code> is substituted with <code>var2</code>.
|
|
</p>
|
|
</li><li> The variable is never set and is referenced exactly once. In this
|
|
case, the reference is substituted with the variable initial value.
|
|
|
|
</li></ul>
|
|
|
|
<p>Since it is especially useful to be able to get the arguments to a
|
|
function, argument variables are treated specially when the
|
|
<code>speed</code> optimization quality is less than <code>3</code> and the
|
|
<code>debug</code> quality is at least <code>1</code>. 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, <code>debug</code> must be at least <code>2</code> for
|
|
values to be available, and even then, values are only available at
|
|
known locations.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Note-On-Lexical-Variable-Access"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Variable-Value-Availability" accesskey="p" rel="prev">Variable Value Availability</a>, Up: <a href="index.html#Variable-Access" accesskey="u" rel="up">Variable Access</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Note-On-Lexical-Variable-Access-1"></span><h4 class="subsection">5.4.2 Note On Lexical Variable Access</h4>
|
|
|
|
<p>When the debugger command loop establishes variable bindings for
|
|
available variables, these variable bindings have lexical scope and
|
|
dynamic extent.<a id="DOCF5" href="index.html#FOOT5"><sup>5</sup></a> You can close
|
|
over them, but such closures can’t be used as upward function arguments.
|
|
</p>
|
|
<p>You can also set local variables using <code>setq</code>, 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.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Source-Location-Printing"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Debugger-Policy-Control" accesskey="n" rel="next">Debugger Policy Control</a>, Previous: <a href="index.html#Variable-Access" accesskey="p" rel="prev">Variable Access</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Source-Location-Printing-1"></span><h3 class="section">5.5 Source Location Printing</h3>
|
|
<span id="index-Source-location-printing_002c-debugger"></span>
|
|
|
|
<p>One of the debugger’s capabilities is source level debugging of
|
|
compiled code. These commands display the source location for the
|
|
current frame:
|
|
</p>
|
|
<dl>
|
|
<dt id="index-source">Debugger Command: <strong>source</strong> <em>[<var>context</var>]</em></dt>
|
|
<dd><p>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 <var>context</var> is specified, then it is an integer
|
|
specifying the number of enclosing levels of list structure to print.
|
|
</p></dd></dl>
|
|
|
|
<p>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 <code>*some-random-special*</code>, then the innermost
|
|
enclosing evaluated form will be printed. Here are some possible
|
|
enclosing forms:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(let ((a *some-random-special*))
|
|
...)
|
|
|
|
(+ *some-random-special* ...)
|
|
</pre></div>
|
|
|
|
<p>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
|
|
<samp>/usr/me/mystuff.lisp</samp> looked like this:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defmacro mymac ()
|
|
'(myfun))
|
|
|
|
(defun foo ()
|
|
(mymac)
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>If <code>foo</code> has called <code>myfun</code>, and is waiting for it to
|
|
return, then the <code>source</code> command would print:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; File: /usr/me/mystuff.lisp
|
|
|
|
(MYMAC)
|
|
</pre></div>
|
|
|
|
<p>Note that the macro use was printed, not the actual function call form,
|
|
<code>(myfun)</code>.
|
|
</p>
|
|
<p>If enclosing source is printed by giving an argument to
|
|
<code>source</code> or <code>vsource</code>, then the actual source form is
|
|
marked by wrapping it in a list whose first element is
|
|
‘<samp>#:***HERE***</samp>’. In the previous example, <code>source 1</code> would
|
|
print:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; File: /usr/me/mystuff.lisp
|
|
|
|
(DEFUN FOO ()
|
|
(#:***HERE***
|
|
(MYMAC))
|
|
...)
|
|
</pre></div>
|
|
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#How-the-Source-is-Found" accesskey="1">How the Source is Found</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Source-Location-Availability" accesskey="2">Source Location Availability</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="How-the-Source-is-Found"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Source-Location-Availability" accesskey="n" rel="next">Source Location Availability</a>, Up: <a href="index.html#Source-Location-Printing" accesskey="u" rel="up">Source Location Printing</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="How-the-Source-is-Found-1"></span><h4 class="subsection">5.5.1 How the Source is Found</h4>
|
|
|
|
<p>If the code was defined from Lisp by <code>compile</code> or
|
|
<code>eval</code>, then the source can always be reliably located. If the
|
|
code was defined from a <samp>fasl</samp> file created by
|
|
<code>compile-file</code>, 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.
|
|
</p>
|
|
<p>The source file is opened using the <code>truename</code> 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.
|
|
</p>
|
|
<p>If the source file can be found, but has been modified since the time it was
|
|
compiled, the debugger prints this warning:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">; File has been modified since compilation:
|
|
; <var>filename</var>
|
|
; Using form offset instead of character position.
|
|
</pre></div>
|
|
|
|
<p>where <var>filename</var> 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:
|
|
</p>
|
|
<ul>
|
|
<li> No top-level forms before the top-level form containing the source
|
|
have been added or deleted, and
|
|
|
|
</li><li> The top-level form containing the source has not been modified much.
|
|
(More precisely, none of the list forms beginning before the source
|
|
form have been added or deleted.)
|
|
|
|
</li></ul>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>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
|
|
<code>eq</code> list twice. If you don’t define read macros and don’t use
|
|
<code>##</code> in perverted ways, you don’t need to worry about this.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Source-Location-Availability"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#How-the-Source-is-Found" accesskey="p" rel="prev">How the Source is Found</a>, Up: <a href="index.html#Source-Location-Printing" accesskey="u" rel="up">Source Location Printing</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Source-Location-Availability-1"></span><h4 class="subsection">5.5.2 Source Location Availability</h4>
|
|
<span id="index-Debug-optimization-quality-1"></span>
|
|
<span id="index-Block_002c-basic"></span>
|
|
<span id="index-Block_002c-start-location"></span>
|
|
|
|
<p>Source location information is only available when the <code>debug</code>
|
|
optimization quality is at least <code>2</code>. If source location
|
|
information is unavailable, the source commands will give an error
|
|
message.
|
|
</p>
|
|
<p>If source location information is available, but the source location
|
|
is unknown because of an interrupt or unexpected hardware error
|
|
(see <a href="index.html#Unknown-Locations-and-Interrupts">Unknown Locations and Interrupts</a>), then the command will
|
|
print:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">Unknown location: using block start.
|
|
</pre></div>
|
|
|
|
<p>and then proceed to print the source location for the start of the
|
|
<em>basic block</em> 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:
|
|
</p>
|
|
<ul>
|
|
<li> The block start location may be the same as the true location.
|
|
|
|
</li><li> The block start location will never be later in the
|
|
program’s flow of control than the true location.
|
|
|
|
</li><li> No conditional control structures (such as <code>if</code>,
|
|
<code>cond</code>, <code>or</code>) 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 <em>do not</em> end
|
|
basic blocks.
|
|
|
|
</li><li> The head of a loop will be the start of a block.
|
|
|
|
</li><li> The programming language concept of “block structure” and the
|
|
Lisp <code>block</code> special form are totally unrelated to the compiler’s
|
|
basic block.
|
|
|
|
</li></ul>
|
|
|
|
<p>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.)
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Debugger-Policy-Control"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Exiting-Commands" accesskey="n" rel="next">Exiting Commands</a>, Previous: <a href="index.html#Source-Location-Printing" accesskey="p" rel="prev">Source Location Printing</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Debugger-Policy-Control-1"></span><h3 class="section">5.6 Debugger Policy Control</h3>
|
|
<span id="index-Policy_002c-debugger"></span>
|
|
<span id="index-Debug-optimization-quality-2"></span>
|
|
<span id="index-Optimize-declaration"></span>
|
|
<span id="index-Inline-expansion-1"></span>
|
|
<span id="index-Semi_002dinline-expansion"></span>
|
|
|
|
<p>The compilation policy specified by <code>optimize</code> declarations
|
|
affects the behavior seen in the debugger. The <code>debug</code> 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.
|
|
</p>
|
|
<p>Unlike the other optimization qualities (which are compared in relative value
|
|
to evaluate tradeoffs), the <code>debug</code> 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 <code>debug</code> quality:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><code>0</code></dt>
|
|
<dd><p>Only the function name and enough information to allow the stack to
|
|
be parsed.
|
|
</p>
|
|
</dd>
|
|
<dt><code>> 0</code></dt>
|
|
<dd><p>Any level greater than <code>0</code> gives level <code>0</code> plus all argument
|
|
variables. Values will only be accessible if the argument variable is
|
|
never set and <code>speed</code> is not <code>3</code>. SBCL allows any real
|
|
value for optimization qualities. It may be useful to specify
|
|
<code>0.5</code> to get backtrace argument display without argument
|
|
documentation.
|
|
</p>
|
|
</dd>
|
|
<dt><code>1</code></dt>
|
|
<dd><p>Level <code>1</code> provides argument documentation (printed argument lists) and
|
|
derived argument/result type information. This makes <code>describe</code>
|
|
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.
|
|
</p>
|
|
</dd>
|
|
<dt><code>2</code></dt>
|
|
<dd><p>Level <code>1</code> plus all interned local variables, source location
|
|
information, and lifetime information that tells the debugger when
|
|
arguments are available (even when <code>speed</code> is <code>3</code> or the
|
|
argument is set).
|
|
</p>
|
|
</dd>
|
|
<dt><code>> 2</code></dt>
|
|
<dd><p>Any level greater than <code>2</code> gives level <code>2</code> and in addition
|
|
disables tail-call optimization, so that the backtrace will contain
|
|
frames for all invoked functions, even those in tail positions.
|
|
</p>
|
|
</dd>
|
|
<dt><code>3</code></dt>
|
|
<dd><p>Level <code>2</code> plus all uninterned variables. In addition, lifetime
|
|
analysis is disabled (even when <code>speed</code> is <code>3</code>), 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.
|
|
</p>
|
|
<p>Inlining of local functions is inhibited so that they may be
|
|
<code>trace</code>d.
|
|
</p>
|
|
</dd>
|
|
<dt><code>> (max speed space)</code></dt>
|
|
<dd><p>If <code>debug</code> is greater than both <code>speed</code> and <code>space</code>,
|
|
the command <code>return</code> can be used to continue execution by
|
|
returning a value from the current stack frame.
|
|
</p>
|
|
</dd>
|
|
<dt><code>> (max speed space compilation-speed)</code></dt>
|
|
<dd><p>If <code>debug</code> is greater than all of <code>speed</code>, <code>space</code> and
|
|
<code>compilation-speed</code> the code will be steppable (see <a href="index.html#Single-Stepping">Single Stepping</a>).
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>As you can see, if the <code>speed</code> quality is <code>3</code>, debugger performance is
|
|
degraded. This effect comes from the elimination of argument variable
|
|
special-casing (see <a href="index.html#Variable-Value-Availability">Variable Value Availability</a>). Some degree of
|
|
speed/debuggability tradeoff is unavoidable, but the effect is not too drastic
|
|
when <code>debug</code> is at least <code>2</code>.
|
|
</p>
|
|
<p>In addition to <code>inline</code> and <code>notinline</code> declarations, the
|
|
relative values of the <code>speed</code> and <code>space</code> 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.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Exiting-Commands"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Information-Commands" accesskey="n" rel="next">Information Commands</a>, Previous: <a href="index.html#Debugger-Policy-Control" accesskey="p" rel="prev">Debugger Policy Control</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Exiting-Commands-1"></span><h3 class="section">5.7 Exiting Commands</h3>
|
|
|
|
<p>These commands get you out of the debugger.
|
|
</p>
|
|
<dl>
|
|
<dt id="index-toplevel">Debugger Command: <strong>toplevel</strong></dt>
|
|
<dd><p>Throw to top level.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-restart">Debugger Command: <strong>restart</strong> <em>[<var>n</var>]</em></dt>
|
|
<dd><p>Invokes the <var>n</var>th restart case as displayed by the <code>error</code>
|
|
command. If <var>n</var> is not specified, the available restart cases are
|
|
reported.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-continue">Debugger Command: <strong>continue</strong></dt>
|
|
<dd><p>Calls <code>continue</code> on the condition given to <code>debug</code>. If there is no
|
|
restart case named <var>continue</var>, then an error is signaled.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-abort">Debugger Command: <strong>abort</strong></dt>
|
|
<dd><p>Calls <code>abort</code> on the condition given to <code>debug</code>. This is
|
|
useful for popping debug command loop levels or aborting to top level,
|
|
as the case may be.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-return">Debugger Command: <strong>return</strong> <em><var>value</var></em></dt>
|
|
<dd><p>Returns <var>value</var> from the current stack frame. This command is
|
|
available when the <code>debug</code> optimization quality is greater than
|
|
both <code>speed</code> and <code>space</code>. Care must be taken that the value
|
|
is of the same type as SBCL expects the stack frame to return.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-restart_002dframe">Debugger Command: <strong>restart-frame</strong></dt>
|
|
<dd><p>Restarts execution of the current stack frame. This command is
|
|
available when the <code>debug</code> optimization quality is greater than
|
|
both <code>speed</code> and <code>space</code> and when the frame is for a global
|
|
function. If the function is redefined in the debugger before the frame
|
|
is restarted, the new function will be used.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Information-Commands"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Function-Tracing" accesskey="n" rel="next">Function Tracing</a>, Previous: <a href="index.html#Exiting-Commands" accesskey="p" rel="prev">Exiting Commands</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Information-Commands-1"></span><h3 class="section">5.8 Information Commands</h3>
|
|
|
|
<p>Most of these commands print information about the current frame or
|
|
function, but a few show general information.
|
|
</p>
|
|
<dl>
|
|
<dt id="index-help">Debugger Command: <strong>help</strong></dt>
|
|
<dt id="index-_003f">Debugger Command: <strong>?</strong></dt>
|
|
<dd><p>Displays a synopsis of debugger commands.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-describe">Debugger Command: <strong>describe</strong></dt>
|
|
<dd><p>Calls <code>describe</code> on the current function and displays the number of
|
|
local variables.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-print">Debugger Command: <strong>print</strong></dt>
|
|
<dd><p>Displays the current function call as it would be displayed by moving to
|
|
this frame.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-error">Debugger Command: <strong>error</strong></dt>
|
|
<dd><p>Prints the condition given to <code>invoke-debugger</code> and the active
|
|
proceed cases.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-backtrace">Debugger Command: <strong>backtrace</strong> <em>[<var>n</var>]</em></dt>
|
|
<dd><p>Displays all the frames from the current to the bottom. Only shows
|
|
<var>n</var> frames if specified. The printing is controlled by
|
|
<code>*debug-print-variable-alist*</code>.
|
|
</p></dd></dl>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="Function-Tracing"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Single-Stepping" accesskey="n" rel="next">Single Stepping</a>, Previous: <a href="index.html#Information-Commands" accesskey="p" rel="prev">Information Commands</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Function-Tracing-1"></span><h3 class="section">5.9 Function Tracing</h3>
|
|
<span id="index-Tracing"></span>
|
|
<span id="index-Function_002c-tracing"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<span id="Macro-common_002dlisp-trace"></span><dl>
|
|
<dt id="index-trace">Macro: <strong>trace</strong> <em>[cl] &rest specs</em></dt>
|
|
<dd><p><code>trace</code> {Option Global-Value}* {Name {Option Value}*}*
|
|
</p>
|
|
<p><code>trace</code> is a debugging tool that provides information when specified
|
|
functions are called. In its simplest form:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (TRACE NAME-1 NAME-2 ...)
|
|
</pre></div>
|
|
|
|
<p>The NAMEs are not evaluated. Each may be one of the following:
|
|
</p><ul>
|
|
<li> <code>symbol</code>, denoting a function or macro.
|
|
</li><li> <code>fname</code>, a valid function name, denoting a function.
|
|
</li><li> (<code>method</code> <code>fname</code> <code>qualifiers*</code> (<code>specializers*</code>)) denoting a method.
|
|
</li><li> (<code>compiler-macro</code> <code>symbol</code>) denoting a compiler macro.
|
|
</li><li> (<code>labels</code> <code>fname</code> <code>:in</code> <code>outer-name</code>) or (<code>flet</code> <code>fname</code> <code>:in</code> <code>outer-name</code>)
|
|
denoting a local function where <code>outer-name</code> may be any of the
|
|
previous names for functions, macros, methods or compiler macros.
|
|
Tracing local functions may require <code>debug</code> policy 3 to inhibit
|
|
inlining.
|
|
</li><li> <code>string</code> denoting all functions fbound to symbols whose home package
|
|
is the package with the given name.
|
|
|
|
</li></ul>
|
|
<p>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 <code>trace</code>. 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.
|
|
</p>
|
|
<p>By default, <code>trace</code> causes a printout on <code>*trace-output*</code> each time that
|
|
one of the named functions is entered or returns. (This is the basic,
|
|
<code>ansi</code> Common Lisp behavior of <code>trace</code>.)
|
|
</p>
|
|
<p>The following options are defined:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:report</code> Report-Type</em></dt>
|
|
<dd><p>If Report-Type is <code>trace</code> (the default) then information is
|
|
reported by printing immediately. If Report-Type is <code>nil</code>, then
|
|
the only effect of the trace is to execute other
|
|
options (e.g. <code>print</code> or <code>break</code>). Otherwise, Report-Type is
|
|
treated as a function designator and, for each trace event,
|
|
funcalled with 5 arguments: trace depth (a non-negative
|
|
integer), a function name or a function object, a
|
|
keyword (<code>:enter</code>, <code>:exit</code> or <code>:non-local-exit</code>), a stack frame, and
|
|
a list of values (arguments or return values).
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:condition</code> Form</em></dt>
|
|
<dt><em><code>:condition-after</code> Form</em></dt>
|
|
<dt><em><code>:condition-all</code> Form</em></dt>
|
|
<dd><p>If <code>:condition</code> is specified, then <code>trace</code> does nothing unless Form
|
|
evaluates to true at the time of the call. <code>:condition-after</code> is
|
|
similar, but suppresses the initial printout, and is tested when the
|
|
function returns. <code>:condition-all</code> tries both before and after.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:break</code> Form</em></dt>
|
|
<dt><em><code>:break-after</code> Form</em></dt>
|
|
<dt><em><code>:break-all</code> Form</em></dt>
|
|
<dd><p>If 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.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:print</code> Form</em></dt>
|
|
<dt><em><code>:print-after</code> Form</em></dt>
|
|
<dt><em><code>:print-all</code> Form</em></dt>
|
|
<dd><p>In 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.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:wherein</code> Names</em></dt>
|
|
<dd><p>If specified, Names is a function name or list of names. <code>trace</code> 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".
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:encapsulate</code> {:DEFAULT | <code>t</code> | NIL}</em></dt>
|
|
<dd><p>If <code>t</code>, the default, tracing is done via encapsulation (redefining the
|
|
function name) rather than by modifying the function. <code>:default</code> 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 <code>sb-debug:arg</code> can still be used.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:methods</code> {T | NIL}</em></dt>
|
|
<dd><p>If <code>t</code>, any function argument naming a generic function will have its
|
|
methods traced in addition to the generic function itself.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:function</code> Function-Form</em></dt>
|
|
<dd><p>This 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.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p><code>:condition</code>, <code>:break</code> and <code>:print</code> forms are evaluated in a context which
|
|
mocks up the lexical environment of the called function, so that
|
|
<code>sb-debug:var</code> and <code>sb-debug:arg</code> can be used.
|
|
The <code>-after</code> and <code>-all</code> forms can use also use <code>sb-debug:arg</code>. In forms
|
|
which are evaluated after the function call, (<code>sb-debug:arg</code> <code>n</code>) returns
|
|
the N-th value returned by the function.
|
|
</p></dd></dl>
|
|
|
|
<span id="Macro-common_002dlisp-untrace"></span><dl>
|
|
<dt id="index-untrace">Macro: <strong>untrace</strong> <em>[cl] &rest specs</em></dt>
|
|
<dd><p>Remove tracing from the specified functions. Untraces all
|
|
functions when called with no arguments.
|
|
</p></dd></dl>
|
|
|
|
<span id="Variable-sb_002ddebug-_002atrace_002dindentation_002dstep_002a"></span><dl>
|
|
<dt id="index-_002atrace_002dindentation_002dstep_002a">Variable: <strong>*trace-indentation-step*</strong> <em>[sb-debug]</em></dt>
|
|
<dd><p>the increase in trace indentation at each call level
|
|
</p></dd></dl>
|
|
|
|
<span id="Variable-sb_002ddebug-_002amax_002dtrace_002dindentation_002a"></span><dl>
|
|
<dt id="index-_002amax_002dtrace_002dindentation_002a">Variable: <strong>*max-trace-indentation*</strong> <em>[sb-debug]</em></dt>
|
|
<dd><p>If the trace indentation exceeds this value, then indentation restarts at
|
|
0.
|
|
</p></dd></dl>
|
|
|
|
<span id="Variable-sb_002ddebug-_002atrace_002dencapsulate_002ddefault_002a"></span><dl>
|
|
<dt id="index-_002atrace_002dencapsulate_002ddefault_002a">Variable: <strong>*trace-encapsulate-default*</strong> <em>[sb-debug]</em></dt>
|
|
<dd><p>the default value for the <code>:encapsulate</code> option to <code>trace</code>
|
|
</p></dd></dl>
|
|
|
|
<span id="Variable-sb_002ddebug-_002atrace_002dreport_002ddefault_002a"></span><dl>
|
|
<dt id="index-_002atrace_002dreport_002ddefault_002a">Variable: <strong>*trace-report-default*</strong> <em>[sb-debug]</em></dt>
|
|
<dd><p>the default value for the <code>:report</code> option to <code>trace</code>
|
|
</p></dd></dl>
|
|
|
|
|
|
<hr>
|
|
<span id="Single-Stepping"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Enabling-and-Disabling-the-Debugger" accesskey="n" rel="next">Enabling and Disabling the Debugger</a>, Previous: <a href="index.html#Function-Tracing" accesskey="p" rel="prev">Function Tracing</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Single-Stepping-1"></span><h3 class="section">5.10 Single Stepping</h3>
|
|
<span id="index-Stepper"></span>
|
|
<span id="index-Single-Stepping"></span>
|
|
|
|
<p>SBCL includes an instrumentation based single-stepper for compiled
|
|
code, that can be invoked via the <code>step</code> macro, or from within
|
|
the debugger. See <a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a>, for details on enabling
|
|
stepping for compiled code.
|
|
</p>
|
|
<p>The following debugger commands are used for controlling single stepping.
|
|
</p>
|
|
<dl>
|
|
<dt id="index-start">Debugger Command: <strong>start</strong></dt>
|
|
<dd><p>Selects the <code>continue</code> 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 <code>start</code> or by using the standard
|
|
<code>step</code> macro.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-step">Debugger Command: <strong>step</strong></dt>
|
|
<dd><p>Steps into the current form. Stepping will be resumed when the next
|
|
form that has been compiled with stepper instrumentation is evaluated.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-next">Debugger Command: <strong>next</strong></dt>
|
|
<dd><p>Steps over the current form. Stepping will be disabled until evaluation of
|
|
the form is complete.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-out">Debugger Command: <strong>out</strong></dt>
|
|
<dd><p>Steps out of the current frame. Stepping will be disabled until the
|
|
topmost stack frame that had been stepped into returns.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-stop">Debugger Command: <strong>stop</strong></dt>
|
|
<dd><p>Stops the single stepper and resumes normal execution.
|
|
</p></dd></dl>
|
|
|
|
<span id="Macro-common_002dlisp-step"></span><dl>
|
|
<dt id="index-step-1">Macro: <strong>step</strong> <em>[cl] form</em></dt>
|
|
<dd><p>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 <code>debug</code> policy
|
|
to be at least partially steppable.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Enabling-and-Disabling-the-Debugger"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Single-Stepping" accesskey="p" rel="prev">Single Stepping</a>, Up: <a href="index.html#Debugger" accesskey="u" rel="up">Debugger</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Enabling-and-Disabling-the-Debugger-1"></span><h3 class="section">5.11 Enabling and Disabling the Debugger</h3>
|
|
|
|
<span id="index-debugger_002c-enabling"></span>
|
|
<span id="index-debugger_002c-disabling"></span>
|
|
<span id="index-disabling-debugger"></span>
|
|
<span id="index-ldb_002c-enabling"></span>
|
|
<span id="index-ldb_002c-disabling-1"></span>
|
|
<span id="index-disabling-ldb-1"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<span id="Function-sb_002dext-disable_002ddebugger"></span><dl>
|
|
<dt id="index-disable_002ddebugger">Function: <strong>disable-debugger</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>When invoked, this function will turn off both the <code>sbcl</code> debugger
|
|
and <code>ldb</code> (the low-level debugger). See also <code>enable-debugger</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-enable_002ddebugger"></span><dl>
|
|
<dt id="index-enable_002ddebugger">Function: <strong>enable-debugger</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Restore the debugger if it has been turned off by <code>disable-debugger</code>.
|
|
</p></dd></dl>
|
|
<hr>
|
|
<span id="Efficiency"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="n" rel="next">Beyond the ANSI Standard</a>, Previous: <a href="index.html#Debugger" accesskey="p" rel="prev">Debugger</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Efficiency-1"></span><h2 class="chapter">6 Efficiency</h2>
|
|
<span id="index-Efficiency"></span>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Slot-access" accesskey="1">Slot access</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Dynamic_002dextent-allocation" accesskey="2">Dynamic-extent allocation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Modular-arithmetic" accesskey="3">Modular arithmetic</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Global-and-Always_002dBound-variables" accesskey="4">Global and Always-Bound variables</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Miscellaneous-Efficiency-Issues" accesskey="5">Miscellaneous Efficiency Issues</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Slot-access"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Dynamic_002dextent-allocation" accesskey="n" rel="next">Dynamic-extent allocation</a>, Up: <a href="index.html#Efficiency" accesskey="u" rel="up">Efficiency</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Slot-access-1"></span><h3 class="section">6.1 Slot access</h3>
|
|
<span id="index-Slot-access"></span>
|
|
|
|
<span id="Structure-object-slot-access"></span><h4 class="subsection">6.1.1 Structure object slot access</h4>
|
|
|
|
<p>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 <code>notinline</code>, or passing
|
|
it as a functional argument to another function causes severe
|
|
performance degradation.
|
|
</p>
|
|
<span id="Standard-object-slot-access"></span><h4 class="subsection">6.1.2 Standard object slot access</h4>
|
|
|
|
<p>The most efficient way to access a slot of a <code>standard-object</code> is
|
|
by using <code>slot-value</code> with a constant slot name argument inside a
|
|
<code>defmethod</code> 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.
|
|
</p>
|
|
<p>Second most efficient way is to use a CLOS slot accessor, or
|
|
<code>slot-value</code> 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.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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))
|
|
</pre></div>
|
|
|
|
<p>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.
|
|
</p>
|
|
<hr>
|
|
<span id="Dynamic_002dextent-allocation"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Modular-arithmetic" accesskey="n" rel="next">Modular arithmetic</a>, Previous: <a href="index.html#Slot-access" accesskey="p" rel="prev">Slot access</a>, Up: <a href="index.html#Efficiency" accesskey="u" rel="up">Efficiency</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Dynamic_002dextent-allocation-1"></span><h3 class="section">6.2 Dynamic-extent allocation</h3>
|
|
<span id="index-dynamic_002dextent-declaration"></span>
|
|
<span id="index-declaration_002c-dynamic_002dextent"></span>
|
|
|
|
<p>SBCL has fairly extensive support for performing allocation on the
|
|
stack when a variable is declared <code>dynamic-extent</code>. The
|
|
<code>dynamic-extent</code> declarations are not verified, but are simply
|
|
trusted as long as <code>sb-ext:*stack-allocate-dynamic-extent*</code> is
|
|
true.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002astack_002dallocate_002ddynamic_002dextent_002a"></span><dl>
|
|
<dt id="index-_002astack_002dallocate_002ddynamic_002dextent_002a">Variable: <strong>*stack-allocate-dynamic-extent*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>If true (the default), the compiler respects <code>dynamic-extent</code> 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 <code>safety</code> code, as such a vector could overflow
|
|
the stack without triggering overflow protection.
|
|
</p></dd></dl>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>In particular, it is important to realize that dynamic extend is
|
|
contagious:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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.
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>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 <code>&rest</code> arguments – but another
|
|
conforming implementation might, so portable code should not rely on
|
|
this.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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)))
|
|
</pre></div>
|
|
|
|
<p>There are many cases when <code>dynamic-extent</code> declarations could be
|
|
useful. At present, SBCL implements stack allocation for
|
|
</p>
|
|
<ul>
|
|
<li> <code>&rest</code> lists, when these are declared <code>dynamic-extent</code>.
|
|
|
|
</li><li> <span id="index-cons-_005bcl_005d"></span>
|
|
<span id="index-list-_005bcl_005d"></span>
|
|
<span id="index-list_002a-_005bcl_005d"></span>
|
|
<span id="index-vector-_005bcl_005d"></span>
|
|
<code>cons</code>, <code>list</code>, <code>list*</code>, and <code>vector</code> when the
|
|
result is bound to a variable declared <code>dynamic-extent</code>.
|
|
|
|
</li><li> <span id="index-make_002darray-_005bcl_005d"></span>
|
|
simple forms of <code>make-array</code>, whose result is bound to a variable
|
|
declared <code>dynamic-extent</code>: stack allocation is possible only if
|
|
the resulting array is known to be both simple and one-dimensional,
|
|
and has a constant <code>:element-type</code>.
|
|
|
|
<span id="index-Safety-optimization-quality-1"></span>
|
|
<p><strong>Note</strong>: 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 <code>safety</code> policies.
|
|
</p>
|
|
</li><li> <span id="index-flet-_005bcl_005d"></span>
|
|
<span id="index-labels-_005bcl_005d"></span>
|
|
<span id="index-safety-optimization-quality"></span>
|
|
<span id="index-optimization-quality_002c-safety"></span>
|
|
closures defined with <code>flet</code> or <code>labels</code>, with a bound
|
|
<code>dynamic-extent</code> declaration. Blocks and tags are also allocated
|
|
on the heap, unless all non-local control transfers to them are
|
|
compiled with zero <code>safety</code>.
|
|
|
|
</li><li> user-defined structures when the structure constructor defined using
|
|
<code>defstruct</code> has been declared <code>inline</code> and the result of the
|
|
call to the constructor is bound to a variable declared
|
|
<code>dynamic-extent</code>.
|
|
|
|
<p><strong>Note</strong>: structures with “raw” slots can currently be
|
|
stack-allocated only on x86 and x86-64. A “raw” slot is one whose
|
|
declared type is a subtype of exactly one of: <code>double-float</code>,
|
|
<code>single-float</code>, <code>(complex double-float)</code>, <code>(complex single-float)</code>,
|
|
or <code>sb-ext:word</code>; but as an exception to the preceding, any subtype
|
|
of <code>fixnum</code> is not stored as raw despite also being a subtype
|
|
of <code>sb-ext:word</code>.
|
|
</p>
|
|
</li><li> all of the above when they appear as initial parts of another
|
|
stack-allocated object.
|
|
|
|
</li></ul>
|
|
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">;;; 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))
|
|
...)
|
|
</pre></div>
|
|
|
|
<p>Future plans include
|
|
</p>
|
|
<ul>
|
|
<li> Automatic detection of the common idiom of calling quantifiers with a
|
|
closure, even when the closure is not declared <code>dynamic-extent</code>.
|
|
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="Modular-arithmetic"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Global-and-Always_002dBound-variables" accesskey="n" rel="next">Global and Always-Bound variables</a>, Previous: <a href="index.html#Dynamic_002dextent-allocation" accesskey="p" rel="prev">Dynamic-extent allocation</a>, Up: <a href="index.html#Efficiency" accesskey="u" rel="up">Efficiency</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Modular-arithmetic-1"></span><h3 class="section">6.3 Modular arithmetic</h3>
|
|
<span id="index-Modular-arithmetic"></span>
|
|
<span id="index-Arithmetic_002c-modular"></span>
|
|
<span id="index-Arithmetic_002c-hardware"></span>
|
|
<span id="index-logand-_005bcl_005d"></span>
|
|
<p>Some numeric functions have a property: <var>N</var> lower bits of the
|
|
result depend only on <var>N</var> lower bits of (all or some)
|
|
arguments. If the compiler sees an expression of form <code>(logand
|
|
<var>exp</var> <var>mask</var>)</code>, where <var>exp</var> is a tree of such “good”
|
|
functions and <var>mask</var> is known to be of type <code>(unsigned-byte
|
|
<var>w</var>)</code>, where <var>w</var> is a “good” width, all intermediate results
|
|
will be cut to <var>w</var> bits (but it is not done for variables and
|
|
constants!). This often results in an ability to use simple machine
|
|
instructions for the functions.
|
|
</p>
|
|
<p>Consider an example.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun i (x y)
|
|
(declare (type (unsigned-byte 32) x y))
|
|
(ldb (byte 32 0) (logxor x (lognot y))))
|
|
</pre></div>
|
|
|
|
<p>The result of <code>(lognot y)</code> will be negative and of type
|
|
<code>(signed-byte 33)</code>, 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 <code>logxor</code> and <code>lognot</code>
|
|
with versions cutting results to 32 bits, and because terminals
|
|
(here—expressions <code>x</code> and <code>y</code>) are also of type
|
|
<code>(unsigned-byte 32)</code>, 32-bit machine arithmetic can be used.
|
|
</p>
|
|
<p>As of SBCL 0.8.5 “good” functions are <code>+</code>, <code>-</code>;
|
|
<code>logand</code>, <code>logior</code>, <code>logxor</code>, <code>lognot</code> and their
|
|
combinations; and <code>ash</code> with the positive second
|
|
argument. “Good” widths are 32 on 32-bit CPUs and 64 on 64-bit CPUs.
|
|
While it is possible to support smaller widths as well,
|
|
currently this is not implemented.
|
|
</p>
|
|
<hr>
|
|
<span id="Global-and-Always_002dBound-variables"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Miscellaneous-Efficiency-Issues" accesskey="n" rel="next">Miscellaneous Efficiency Issues</a>, Previous: <a href="index.html#Modular-arithmetic" accesskey="p" rel="prev">Modular arithmetic</a>, Up: <a href="index.html#Efficiency" accesskey="u" rel="up">Efficiency</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Global-and-Always_002dBound-variables-1"></span><h3 class="section">6.4 Global and Always-Bound variables</h3>
|
|
|
|
<span id="Macro-sb_002dext-defglobal"></span><dl>
|
|
<dt id="index-defglobal">Macro: <strong>defglobal</strong> <em>[sb-ext] name value &optional doc</em></dt>
|
|
<dd><p>Defines <code>name</code> as a global variable that is always bound. <code>value</code> is evaluated
|
|
and assigned to <code>name</code> both at compile- and load-time, but only if <code>name</code> is not
|
|
already bound.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>See also the declarations <code>sb-ext:global</code> and <code>sb-ext:always-bound</code>.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-global">Declaration: <strong>global</strong> <em>[sb-ext]</em></dt>
|
|
<dd>
|
|
<p>Syntax: <code>(sb-ext:global symbol*)</code>
|
|
</p>
|
|
<p>Only valid as a global proclamation.
|
|
</p>
|
|
<p>Specifies that the named symbols cannot be proclaimed or locally
|
|
declared <code>special</code>. Proclaiming an already special or constant
|
|
variable name as <code>global</code> signal an error. Allows more efficient
|
|
value lookup in threaded environments in addition to expressing
|
|
programmer intention.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-always_002dbound">Declaration: <strong>always-bound</strong> <em>[sb-ext]</em></dt>
|
|
<dd>
|
|
<p>Syntax: <code>(sb-ext:always-bound symbol*)</code>
|
|
</p>
|
|
<p>Only valid as a global proclamation.
|
|
</p>
|
|
<p>Specifies that the named symbols are always bound. Inhibits
|
|
<code>makunbound</code> of the named symbols. Proclaiming an unbound symbol
|
|
as <code>always-bound</code> signals an error. Allows the compiler to elide
|
|
boundness checks from value lookups.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Miscellaneous-Efficiency-Issues"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Global-and-Always_002dBound-variables" accesskey="p" rel="prev">Global and Always-Bound variables</a>, Up: <a href="index.html#Efficiency" accesskey="u" rel="up">Efficiency</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Miscellaneous-Efficiency-Issues-1"></span><h3 class="section">6.5 Miscellaneous Efficiency Issues</h3>
|
|
|
|
<p>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
|
|
</p>
|
|
<ul>
|
|
<li> Advanced Compiler Use and Efficiency Hints
|
|
</li><li> Advanced Compiler Introduction
|
|
</li><li> More About Types in Python
|
|
</li><li> Type Inference
|
|
</li><li> Source Optimization
|
|
</li><li> Tail Recursion
|
|
</li><li> Local Call
|
|
</li><li> Block Compilation
|
|
</li><li> Inline Expansion
|
|
</li><li> Object Representation
|
|
</li><li> Numbers
|
|
</li><li> General Efficiency Hints
|
|
</li><li> Efficiency Notes
|
|
</li></ul>
|
|
|
|
<p>Besides this information from the CMUCL manual, there are a few other
|
|
points to keep in mind.
|
|
</p>
|
|
<ul>
|
|
<li> <span id="index-let-_005bcl_005d"></span>
|
|
<span id="index-let_002a-_005bcl_005d"></span>
|
|
<span id="index-setq-_005bcl_005d"></span>
|
|
<span id="index-setf-_005bcl_005d"></span>
|
|
The CMUCL manual doesn’t seem to state it explicitly, but Python has a
|
|
mental block about type inference when assignment is involved. Python
|
|
is very aggressive and clever about inferring the types of values
|
|
bound with <code>let</code>, <code>let*</code>, inline function call, and so
|
|
forth. However, it’s much more passive and dumb about inferring the
|
|
types of values assigned with <code>setq</code>, <code>setf</code>, 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.)
|
|
|
|
|
|
</li><li> Since the time the CMUCL manual was written, CMUCL (and thus SBCL) has
|
|
gotten a generational garbage collector. This means that there are
|
|
some efficiency implications of various patterns of memory usage which
|
|
aren’t discussed in the CMUCL manual. (Some new material should be
|
|
written about this.)
|
|
|
|
</li><li> SBCL has some important known efficiency problems. Perhaps the most
|
|
important are
|
|
|
|
<ul class="no-bullet">
|
|
<li>- The garbage collector is not particularly efficient, at least on
|
|
platforms without the generational collector (as of SBCL 0.8.9, all
|
|
except x86).
|
|
|
|
</li><li>- Various aspects of the PCL implementation of CLOS are more inefficient
|
|
than necessary.
|
|
|
|
</li></ul>
|
|
|
|
</li></ul>
|
|
|
|
<p>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
|
|
</p>
|
|
<ul>
|
|
<li> <code>(reduce #'f x)</code> where the type of <code>x</code> is known at compile
|
|
time
|
|
|
|
</li><li> various bit vector operations, e.g. <code>(position 0
|
|
some-bit-vector)</code>
|
|
|
|
</li><li> specialized sequence idioms, e.g. <code>(remove item list :count 1)</code>
|
|
|
|
</li><li> cases where local compilation policy does not require excessive type
|
|
checking, e.g. <code>(locally (declare (safety 1)) (assoc item
|
|
list))</code> (which currently performs safe <code>endp</code> checking internal
|
|
to assoc).
|
|
|
|
</li></ul>
|
|
|
|
<p>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 “<code>deftransform</code>” to find many
|
|
examples (some straightforward, some less so).
|
|
</p><hr>
|
|
<span id="Beyond-the-ANSI-Standard"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#External-Formats" accesskey="n" rel="next">External Formats</a>, Previous: <a href="index.html#Efficiency" accesskey="p" rel="prev">Efficiency</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Beyond-the-ANSI-Standard-1"></span><h2 class="chapter">7 Beyond the ANSI Standard</h2>
|
|
|
|
<p>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 <a href="index.html#Contributed-Modules">Contributed Modules</a>.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Reader-Extensions" accesskey="1">Reader Extensions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package_002dLocal-Nicknames" accesskey="2">Package-Local Nicknames</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package-Variance" accesskey="3">Package Variance</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Garbage-Collection" accesskey="4">Garbage Collection</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Metaobject-Protocol" accesskey="5">Metaobject Protocol</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Extensible-Sequences" accesskey="6">Extensible Sequences</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Support-For-Unix" accesskey="7">Support For Unix</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Unicode-Support" accesskey="8">Unicode Support</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Customization-Hooks-for-Users" accesskey="9">Customization Hooks for Users</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Tools-To-Help-Developers">Tools To Help Developers</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Resolution-of-Name-Conflicts">Resolution of Name Conflicts</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Random-Number-Generation">Random Number Generation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Timeouts-and-Deadlines">Timeouts and Deadlines</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Miscellaneous-Extensions">Miscellaneous Extensions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Stale-Extensions">Stale Extensions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Efficiency-Hacks">Efficiency Hacks</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Reader-Extensions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Package_002dLocal-Nicknames" accesskey="n" rel="next">Package-Local Nicknames</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Reader-Extensions-1"></span><h3 class="section">7.1 Reader Extensions</h3>
|
|
<span id="index-Reader-Extensions"></span>
|
|
|
|
<span id="Extended-Package-Prefix-Syntax"></span><h4 class="subsection">7.1.1 Extended Package Prefix Syntax</h4>
|
|
<span id="index-Extended-Package-Prefix-Syntax"></span>
|
|
<span id="index-Package-Prefix-Syntax_002c-extended"></span>
|
|
|
|
<span id="index-_002apackage_002a-_005bcl_005d"></span>
|
|
<span id="index-Interning-Symbols"></span>
|
|
<span id="index-Symbols_002c-interning"></span>
|
|
<span id="index-intern-_005bcl_005d"></span>
|
|
<p>SBCL supports extended package prefix syntax, which allows specifying
|
|
an alternate package instead of <code>*package*</code> for the reader to use
|
|
as the default package for interning symbols:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"><var>package-name</var>::<var>form-with-interning-into-package</var>
|
|
</pre></div>
|
|
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> 'foo::(bar quux zot) == '(foo::bar foo::quux foo::zot)
|
|
</pre></div>
|
|
|
|
<span id="index-Package-Locks"></span>
|
|
<span id="index-_002apackage_002a-_005bcl_005d-1"></span>
|
|
<p><code>*package*</code> is not rebound during the course of reading a form
|
|
with extended package prefix syntax; if <code>foo::bar</code> would cause a
|
|
read-time package lock violation, so does <code>foo::(bar)</code>.
|
|
</p>
|
|
<span id="Symbol-Name-Normalization"></span><h4 class="subsection">7.1.2 Symbol Name Normalization</h4>
|
|
<span id="index-Symbol-Name-Normalization"></span>
|
|
<span id="index-Normalization_002c-Symbol-Name"></span>
|
|
<span id="index-Unicode"></span>
|
|
<span id="index-NFKC"></span>
|
|
|
|
<p>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
|
|
</p>
|
|
<span id="Function-sb_002dext-readtable_002dnormalization"></span><dl>
|
|
<dt id="index-readtable_002dnormalization">Function: <strong>readtable-normalization</strong> <em>[sb-ext] readtable</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>readtable</code> normalizes symbols to <code>nfkc</code>, and <code>nil</code> otherwise.
|
|
The <code>readtable-normalization</code> of the standard readtable is <code>t</code>.
|
|
</p></dd></dl>
|
|
|
|
<p>Symbols created by
|
|
<span id="index-intern-_005bcl_005d-1"></span>
|
|
<code>intern</code> and similar functions are not affected by this setting. If
|
|
<code>sb-ext:readtable-normalization</code> is <code>t</code>, symbols that are not
|
|
normalized are escaped during printing.
|
|
</p>
|
|
<span id="Decimal-Syntax-for-Rationals"></span><h4 class="subsection">7.1.3 Decimal Syntax for Rationals</h4>
|
|
<span id="index-Decimal-Syntax-for-Rationals"></span>
|
|
<span id="index-Rational_002c-decimal-syntax-for"></span>
|
|
<span id="index-float-_005bcl_005d"></span>
|
|
|
|
<p>SBCL supports a decimal syntax for rationals, modelled after the
|
|
standard syntax for floating-point numbers. If a number with
|
|
floating-point syntax has an exponent marker of <code>r</code> or <code>R</code>
|
|
(rather than one of the standard exponent markers), it is read as the
|
|
rational with the exact value of the decimal number expressed as a
|
|
float.
|
|
</p>
|
|
<span id="index-_002aread_002ddefault_002dfloat_002dformat_002a-_005bcl_005d"></span>
|
|
<span id="index-rational-_005bcl_005d"></span>
|
|
<span id="index-read-_005bcl_005d"></span>
|
|
<span id="index-read_002dfrom_002dstring-_005bcl_005d"></span>
|
|
<p>In addition, setting or binding the value of
|
|
<code>*read-default-float-format*</code> to <code>rational</code> around a call to
|
|
<code>read</code> or <code>read-from-string</code> has the effect that
|
|
floating-point numbers without exponent markers are read as rational
|
|
numbers, as if there had been an explicit <code>r</code> or <code>R</code> marker.
|
|
</p>
|
|
<span id="index-_002aread_002ddefault_002dfloat_002dformat_002a-_005bcl_005d-1"></span>
|
|
<span id="index-rational-_005bcl_005d-1"></span>
|
|
<p>Floating point numbers of all types are printed with an exponent
|
|
marker while the value of <code>*read-default-float-format*</code> is
|
|
<code>rational</code>; however, rational numbers are printed in their
|
|
standard syntax, irrespective of the value of
|
|
<code>*read-default-float-format*</code>.
|
|
</p>
|
|
<hr>
|
|
<span id="Package_002dLocal-Nicknames"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Package-Variance" accesskey="n" rel="next">Package Variance</a>, Previous: <a href="index.html#Reader-Extensions" accesskey="p" rel="prev">Reader Extensions</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package_002dLocal-Nicknames-1"></span><h3 class="section">7.2 Package-Local Nicknames</h3>
|
|
<span id="index-Package_002dLocal-Nicknames"></span>
|
|
<span id="index-Nicknames_002c-Package_002dlocal"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<span id="index-_002afeatures_002a-_005bcl_005d"></span>
|
|
<p>Symbol <code>:package-local-nicknames</code> in <code>*features*</code> denotes
|
|
the support for this feature.
|
|
</p>
|
|
<span id="index-defpackage-_005bcl_005d"></span>
|
|
<dl>
|
|
<dt id="index-defpackage">Macro: <strong>defpackage</strong> <em>[cl] name [[option]]* ⇒ package</em></dt>
|
|
<dd>
|
|
<p>Options are extended to include
|
|
</p>
|
|
<ul>
|
|
<li> <code>:local-nicknames (<var>local-nickname</var> <var>actual-package-name</var>)*</code>
|
|
|
|
<p>The package has the specified local nicknames for the corresponding
|
|
actual packages.
|
|
</p></li></ul>
|
|
|
|
<p>Example:
|
|
</p>
|
|
<span id="index-find_002dsymbol-_005bcl_005d"></span>
|
|
<span id="index-find_002dpackage-_005bcl_005d"></span>
|
|
<span id="index-_002apackage_002a-_005bcl_005d-2"></span>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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
|
|
</pre></div>
|
|
</dd></dl>
|
|
|
|
<span id="Function-sb_002dext-package_002dlocal_002dnicknames"></span><dl>
|
|
<dt id="index-package_002dlocal_002dnicknames">Function: <strong>package-local-nicknames</strong> <em>[sb-ext] package-designator</em></dt>
|
|
<dd><p>Returns an alist of (local-nickname . actual-package) describing the
|
|
nicknames local to the designated package.
|
|
</p>
|
|
<p>When in the designated package, calls to <code>find-package</code> with the any of the
|
|
local-nicknames will return the corresponding actual-package instead. This
|
|
also affects all implied calls to <code>find-package</code>, including those performed by
|
|
the reader.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>See also: <code>add-package-local-nickname</code>, <code>package-locally-nicknamed-by-list</code>,
|
|
<code>remove-package-local-nickname</code>, and the <code>defpackage</code> option <code>:local-nicknames</code>.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-package_002dlocally_002dnicknamed_002dby_002dlist"></span><dl>
|
|
<dt id="index-package_002dlocally_002dnicknamed_002dby_002dlist">Function: <strong>package-locally-nicknamed-by-list</strong> <em>[sb-ext] package-designator</em></dt>
|
|
<dd><p>Returns a list of packages which have a local nickname for the designated
|
|
package.
|
|
</p>
|
|
<p>See also: <code>add-package-local-nickname</code>, <code>package-local-nicknames</code>,
|
|
<code>remove-package-local-nickname</code>, and the <code>defpackage</code> option <code>:local-nicknames</code>.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-add_002dpackage_002dlocal_002dnickname"></span><dl>
|
|
<dt id="index-add_002dpackage_002dlocal_002dnickname">Function: <strong>add-package-local-nickname</strong> <em>[sb-ext] local-nickname actual-package &optional package-designator</em></dt>
|
|
<dd><p>Adds <code>local-nickname</code> for <code>actual-package</code> in the designated package, defaulting
|
|
to current package. <code>local-nickname</code> must be a string designator, and
|
|
<code>actual-package</code> must be a package designator.
|
|
</p>
|
|
<p>Returns the designated package.
|
|
</p>
|
|
<p>Signals a continuable error if <code>local-nickname</code> is already a package local
|
|
nickname for a different package, or if <code>local-nickname</code> is one of "CL",
|
|
"COMMON-LISP", or, "KEYWORD", or if <code>local-nickname</code> is a global name or
|
|
nickname for the package to which the nickname would be added.
|
|
</p>
|
|
<p>When in the designated package, calls to <code>find-package</code> with the <code>local-nickname</code>
|
|
will return the package the designated <code>actual-package</code> instead. This also
|
|
affects all implied calls to <code>find-package</code>, including those performed by the
|
|
reader.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>See also: <code>package-local-nicknames</code>, <code>package-locally-nicknamed-by-list</code>,
|
|
<code>remove-package-local-nickname</code>, and the <code>defpackage</code> option <code>:local-nicknames</code>.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-remove_002dpackage_002dlocal_002dnickname"></span><dl>
|
|
<dt id="index-remove_002dpackage_002dlocal_002dnickname">Function: <strong>remove-package-local-nickname</strong> <em>[sb-ext] old-nickname &optional package-designator</em></dt>
|
|
<dd><p>If the designated package had <code>old-nickname</code> as a local nickname for
|
|
another package, it is removed. Returns true if the nickname existed and was
|
|
removed, and <code>nil</code> otherwise.
|
|
</p>
|
|
<p>See also: <code>add-package-local-nickname</code>, <code>package-local-nicknames</code>,
|
|
<code>package-locally-nicknamed-by-list</code>, and the <code>defpackage</code> option <code>:local-nicknames</code>.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Package-Variance"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Garbage-Collection" accesskey="n" rel="next">Garbage Collection</a>, Previous: <a href="index.html#Package_002dLocal-Nicknames" accesskey="p" rel="prev">Package-Local Nicknames</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package-Variance-1"></span><h3 class="section">7.3 Package Variance</h3>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>This can be adjusted using <code>sb-ext:*on-package-variance*</code>:
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002aon_002dpackage_002dvariance_002a"></span><dl>
|
|
<dt id="index-_002aon_002dpackage_002dvariance_002a">Variable: <strong>*on-package-variance*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Specifies behavior when redefining a package using <code>defpackage</code> and the
|
|
definition is in variance with the current state of the package.
|
|
</p>
|
|
<p>The value should be of the form:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (:WARN [T | packages-names] :ERROR [T | package-names])
|
|
</pre></div>
|
|
|
|
<p>specifying which packages get which behaviour <code>--</code> with <code>t</code> signifying the default unless
|
|
otherwise specified. If default is not specified, <code>:warn</code> is used.
|
|
</p>
|
|
<p><code>:warn</code> keeps as much state as possible and causes <code>sbcl</code> to signal a full warning.
|
|
</p>
|
|
<p><code>:error</code> causes <code>sbcl</code> to signal an error when the variant <code>defpackage</code> form is executed,
|
|
with restarts provided for user to specify what action should be taken.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (setf *on-package-variance* '(:warn (:swank :swank-backend) :error t))
|
|
</pre></div>
|
|
|
|
<p>specifies to signal a warning if <code>swank</code> package is in variance, and an error otherwise.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Garbage-Collection"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Metaobject-Protocol" accesskey="n" rel="next">Metaobject Protocol</a>, Previous: <a href="index.html#Package-Variance" accesskey="p" rel="prev">Package Variance</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Garbage-Collection-1"></span><h3 class="section">7.4 Garbage Collection</h3>
|
|
<span id="index-Garbage-collection"></span>
|
|
|
|
<p>SBCL provides additional garbage collection functionality not
|
|
specified by ANSI.
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002aafter_002dgc_002dhooks_002a"></span><dl>
|
|
<dt id="index-_002aafter_002dgc_002dhooks_002a">Variable: <strong>*after-gc-hooks*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Called after each garbage collection, except for garbage collections
|
|
triggered during thread exits. In a multithreaded environment these hooks may
|
|
run in any thread.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-gc"></span><dl>
|
|
<dt id="index-gc">Function: <strong>gc</strong> <em>[sb-ext] &key full gen &allow-other-keys</em></dt>
|
|
<dd><p>Initiate a garbage collection.
|
|
</p>
|
|
<p>The default is to initiate a nursery collection, which may in turn
|
|
trigger a collection of one or more older generations as well. If <code>full</code>
|
|
is true, all generations are collected. If <code>gen</code> is provided, it can be
|
|
used to specify the oldest generation guaranteed to be collected.
|
|
</p>
|
|
<p>On CheneyGC platforms arguments <code>full</code> and <code>gen</code> take no effect: a full
|
|
collection is always performed.
|
|
</p></dd></dl>
|
|
|
|
<span id="Finalization"></span><h4 class="subsection">7.4.1 Finalization</h4>
|
|
<span id="index-Finalization"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<span id="Function-sb_002dext-finalize"></span><dl>
|
|
<dt id="index-finalize">Function: <strong>finalize</strong> <em>[sb-ext] object function &key dont-save</em></dt>
|
|
<dd><p>Arrange for the designated <code>function</code> to be called when there
|
|
are no more references to <code>object</code>, including references in
|
|
<code>function</code> itself.
|
|
</p>
|
|
<p>If <code>dont-save</code> is true, the finalizer will be cancelled when
|
|
<code>save-lisp-and-die</code> is called: this is useful for finalizers
|
|
deallocating system memory, which might otherwise be called
|
|
with addresses from the old image.
|
|
</p>
|
|
<p>In a multithreaded environment <code>function</code> may be called in any
|
|
thread. In both single and multithreaded environments <code>function</code>
|
|
may be called in any dynamic scope: consequences are unspecified
|
|
if <code>function</code> is not fully re-entrant.
|
|
</p>
|
|
<p>Errors from <code>function</code> are handled and cause a <code>warning</code> to be
|
|
signalled in whichever thread the <code>function</code> was called in.
|
|
</p>
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> ;;; 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
|
|
</pre></div>
|
|
</dd></dl>
|
|
<span id="Function-sb_002dext-cancel_002dfinalization"></span><dl>
|
|
<dt id="index-cancel_002dfinalization">Function: <strong>cancel-finalization</strong> <em>[sb-ext] object</em></dt>
|
|
<dd><p>Cancel all finalizations for <code>object</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Weak-Pointers"></span><h4 class="subsection">7.4.2 Weak Pointers</h4>
|
|
<span id="index-Weak-pointers"></span>
|
|
|
|
<p>Weak pointers allow references to objects to be maintained without
|
|
keeping them from being garbage collected: useful for building caches
|
|
among other things.
|
|
</p>
|
|
<p>Hash tables can also have weak keys and values: see <a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a>.
|
|
</p>
|
|
<span id="Function-sb_002dext-make_002dweak_002dpointer"></span><dl>
|
|
<dt id="index-make_002dweak_002dpointer">Function: <strong>make-weak-pointer</strong> <em>[sb-ext] object</em></dt>
|
|
<dd><p>Allocate and return a weak pointer which points to <code>object</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-weak_002dpointer_002dvalue"></span><dl>
|
|
<dt id="index-weak_002dpointer_002dvalue">Function: <strong>weak-pointer-value</strong> <em>[sb-ext] weak-pointer</em></dt>
|
|
<dd><p>If <code>weak-pointer</code> is valid, return the value of <code>weak-pointer</code> and <code>t</code>.
|
|
If the referent of <code>weak-pointer</code> has been garbage collected,
|
|
returns the values <code>nil</code> and <code>nil</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Introspection-and-Tuning"></span><h4 class="subsection">7.4.3 Introspection and Tuning</h4>
|
|
|
|
<span id="Variable-sb_002dext-_002agc_002drun_002dtime_002a"></span><dl>
|
|
<dt id="index-_002agc_002drun_002dtime_002a">Variable: <strong>*gc-run-time*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Total <code>cpu</code> time spent doing garbage collection (as reported by
|
|
<code>get-internal-run-time</code>.) Initialized to zero on startup. It is safe to bind
|
|
this to zero in order to measure <code>gc</code> time inside a certain section of code, but
|
|
doing so may interfere with results reported by eg. <code>time</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-bytes_002dconsed_002dbetween_002dgcs"></span><dl>
|
|
<dt id="index-bytes_002dconsed_002dbetween_002dgcs">Function: <strong>bytes-consed-between-gcs</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>The amount of memory that will be allocated before the next garbage
|
|
collection is initiated. This can be set with <code>setf</code>.
|
|
</p>
|
|
<p>On <code>gencgc</code> platforms this is the nursery size, and defaults to 5% of dynamic
|
|
space size.
|
|
</p>
|
|
<p>Note: currently changes to this value are lost when saving core.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-dynamic_002dspace_002dsize"></span><dl>
|
|
<dt id="index-dynamic_002dspace_002dsize">Function: <strong>dynamic-space-size</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Size of the dynamic space in bytes.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-get_002dbytes_002dconsed"></span><dl>
|
|
<dt id="index-get_002dbytes_002dconsed">Function: <strong>get-bytes-consed</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Return the number of bytes consed since the program began. Typically
|
|
this result will be a consed bignum, so if you have an application (e.g.
|
|
profiling) which can’t tolerate the overhead of consing bignums, you’ll
|
|
probably want either to hack in at a lower level (as the code in the
|
|
<code>sb-profile</code> package does), or to design a more microefficient interface
|
|
and submit it as a patch.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-gc_002dlogfile"></span><dl>
|
|
<dt id="index-gc_002dlogfile">Function: <strong>gc-logfile</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Return the pathname used to log garbage collections. Can be <code>setf</code>.
|
|
Default is <code>nil</code>, 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.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-generation_002daverage_002dage"></span><dl>
|
|
<dt id="index-generation_002daverage_002dage">Function: <strong>generation-average-age</strong> <em>[sb-ext] generation</em></dt>
|
|
<dd><p>Average age of memory allocated to <code>generation:</code> average number of times
|
|
objects allocated to the generation have seen younger objects promoted to it.
|
|
Available on <code>gencgc</code> platforms only.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-generation_002dbytes_002dallocated"></span><dl>
|
|
<dt id="index-generation_002dbytes_002dallocated">Function: <strong>generation-bytes-allocated</strong> <em>[sb-ext] generation</em></dt>
|
|
<dd><p>Number of bytes allocated to <code>generation</code> currently. Available on <code>gencgc</code>
|
|
platforms only.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-generation_002dbytes_002dconsed_002dbetween_002dgcs"></span><dl>
|
|
<dt id="index-generation_002dbytes_002dconsed_002dbetween_002dgcs">Function: <strong>generation-bytes-consed-between-gcs</strong> <em>[sb-ext] generation</em></dt>
|
|
<dd><p>Number of bytes that can be allocated to <code>generation</code> before that
|
|
generation is considered for garbage collection. This value is meaningless for
|
|
generation 0 (the nursery)<code>:</code> see <code>bytes-consed-between-gcs</code> instead. Default is
|
|
5% of the dynamic space size divided by the number of non-nursery generations.
|
|
Can be assigned to using <code>setf</code>. Available on <code>gencgc</code> platforms only.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-generation_002dminimum_002dage_002dbefore_002dgc"></span><dl>
|
|
<dt id="index-generation_002dminimum_002dage_002dbefore_002dgc">Function: <strong>generation-minimum-age-before-gc</strong> <em>[sb-ext] generation</em></dt>
|
|
<dd><p>Minimum average age of objects allocated to <code>generation</code> before that
|
|
generation is may be garbage collected. Default is 0.75. See also
|
|
<code>generation-average-age</code>. Can be assigned to using <code>setf</code>. Available on <code>gencgc</code>
|
|
platforms only.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-generation_002dnumber_002dof_002dgcs_002dbefore_002dpromotion"></span><dl>
|
|
<dt id="index-generation_002dnumber_002dof_002dgcs_002dbefore_002dpromotion">Function: <strong>generation-number-of-gcs-before-promotion</strong> <em>[sb-ext] generation</em></dt>
|
|
<dd><p>Number of times garbage collection is done on <code>generation</code> before
|
|
automatic promotion to the next generation is triggered. Default is 1. Can be
|
|
assigned to using <code>setf</code>. Available on <code>gencgc</code> platforms only.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-generation_002dnumber_002dof_002dgcs"></span><dl>
|
|
<dt id="index-generation_002dnumber_002dof_002dgcs">Function: <strong>generation-number-of-gcs</strong> <em>[sb-ext] generation</em></dt>
|
|
<dd><p>Number of times garbage collection has been done on <code>generation</code> without
|
|
promotion. Available on <code>gencgc</code> platforms only.
|
|
</p>
|
|
<p>Experimental: interface subject to change.
|
|
</p></dd></dl>
|
|
|
|
<span id="Tracing-Live-Objects-Back-to-Roots"></span><h4 class="subsection">7.4.4 Tracing Live Objects Back to Roots</h4>
|
|
|
|
<blockquote>
|
|
<p><b>note:</b> This feature is intended to help expert users diagnose rare low-level
|
|
issues and should not be needed during normal usage. On top of that,
|
|
the interface and implementation are experimental and may change at any
|
|
time without further notice.
|
|
</p></blockquote>
|
|
|
|
<p>It is sometimes important to understand why a given object is retained
|
|
in the Lisp image instead of being garbage collected. To help with this
|
|
problem, SBCL provides a mechanism that searches through the different
|
|
memory spaces, builds a path of references from a root to the object in
|
|
question and finally reports this paths:
|
|
</p>
|
|
<span id="Function-sb_002dext-search_002droots"></span><dl>
|
|
<dt id="index-search_002droots">Function: <strong>search-roots</strong> <em>[sb-ext] weak-pointers &key criterion gc ignore print</em></dt>
|
|
<dd><p>Find roots keeping the targets of <code>weak-pointers</code> alive.
|
|
</p>
|
|
<p><code>weak-pointers</code> must be a single <code>sb-ext:weak-pointer</code> or a list of those,
|
|
pointing to objects for which roots should be searched.
|
|
</p>
|
|
<p><code>gc</code> controls whether the search is performed in the context of a
|
|
garbage collection, that is with all Lisp threads stopped. Possible
|
|
values are:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>t</code></em></dt>
|
|
<dd><p>This is the more accurate of the object liveness proof generators,
|
|
as there is no chance for other code to execute in between the
|
|
garbage collection and production of the chain of referencing
|
|
objects.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>nil</code></em></dt>
|
|
<dd><p>This works well enough, but might be adversely affected by actions
|
|
of concurrent threads.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p><code>criterion</code> determines just how rooty (how deep) a root must be in order
|
|
to be considered. Possible values are:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:oldest</code></em></dt>
|
|
<dd><p>This says we can stop upon seeing an object in the oldest gen to
|
|
<code>gc</code>, or older. This is the easiest test to satisfy.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:pseudo-static</code></em></dt>
|
|
<dd><p>This is usually the same as <code>:oldest</code>, unless the oldest gen to <code>gc</code>
|
|
has been decreased.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:static</code></em></dt>
|
|
<dd><p>To find a root of an image-backed object, you want to stop only at
|
|
a truly <code>:static</code> object.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p><code>ignore</code> is a list of objects to treat as if nonexistent in the heap.
|
|
It can often be useful for finding a path to an interned symbol other than
|
|
through its package by specifying the package as an ignored object.
|
|
</p>
|
|
<p><code>print</code> controls whether discovered paths should be returned or
|
|
printed. Possible values are
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:verbose</code></em></dt>
|
|
<dd><p>Return no values. Print discovered paths using a verbose format
|
|
with each node of each path on a separate line.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em>true (other than <code>:verbose</code>)</em></dt>
|
|
<dd><p>Return no values. Print discovered paths using a compact format
|
|
with all nodes of each path on a single line.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>nil</code></em></dt>
|
|
<dd><p>Do not print any output. Instead return the discovered paths as a
|
|
list of lists. Each list has the form
|
|
</p>
|
|
<p>(<code>target</code> . (<code>root</code> <code>node*</code>))
|
|
</p>
|
|
<p>where <code>target</code> is one of the target of one of the <code>weak-pointers</code>.
|
|
</p>
|
|
<p><code>root</code> is a description of the root at which the path starts and has
|
|
one of the following forms:
|
|
</p>
|
|
<p><code>:static</code>
|
|
If the root of the path is a non-collectible heap object.
|
|
</p>
|
|
<p><code>:pinned</code>
|
|
If an unknown thread stack pins the root of the path.
|
|
</p>
|
|
<p>((<code>thread-name</code> | <code>thread-object</code>) <code>symbol</code> <code>currentp</code>)
|
|
If the path begins at a special binding of <code>symbol</code> in a
|
|
thread. <code>currentp</code> is a <code>boolean</code> indicating whether the value is
|
|
current or shadowed by another binding.
|
|
</p>
|
|
<p>((<code>thread-name</code> | <code>thread-object</code>) <code>guessed-pc</code>)
|
|
If the path begins at a lexical variable in the function whose
|
|
code contains <code>guessed-pc</code>.
|
|
</p>
|
|
<p>Each <code>node</code> in the remainder of the path is a cons (<code>object</code> . <code>slot</code>)
|
|
indicating that the slot at index <code>slot</code> in <code>object</code> references the
|
|
next path node.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>Experimental: subject to change without prior notice.
|
|
</p></dd></dl>
|
|
|
|
<p>An example of using this could look like this:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">* (defvar *my-string* (list 1 2 "my string"))
|
|
*MY-STRING*
|
|
|
|
* (sb-ext:search-roots (sb-ext:make-weak-pointer (third *my-string*)))
|
|
-> ((SIMPLE-VECTOR 3)) #x10004E9EAF[2] -> (SYMBOL) #x5044100F[1] -> (CONS) #x100181FAE7[1] -> (CONS) #x100181FAF7[1] -> (CONS) #x100181FB07[0] -> #x100181F9AF
|
|
</pre></div>
|
|
|
|
<p>The single line of output on <code>cl:*standard-output*</code> shows the path
|
|
from a root to <tt>"my string"</tt>: the path starts with SBCL’s internal
|
|
package system data structures followed by the symbol
|
|
(<tt>cl-user:*my-string*</tt>) followed the three cons cells of the list.
|
|
</p>
|
|
<p>The <code>:print :verbose</code> argument produces similar behavior but
|
|
describe the path elements in more detail:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">* (sb-ext:search-roots (sb-ext:make-weak-pointer (third *my-string*)) :print :verbose)
|
|
Path to "my string":
|
|
6 10004E9EAF [ 2] a (simple-vector 3)
|
|
0 5044100F [ 1] COMMON-LISP-USER::*MY-STRING*
|
|
0 100181FAE7 [ 1] a cons
|
|
0 100181FAF7 [ 1] a cons
|
|
0 100181FB07 [ 0] a cons
|
|
</pre></div>
|
|
|
|
<p>The <code>:print nil</code> argument is a bit different:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">* (sb-ext:search-roots (sb-ext:make-weak-pointer (third *my-string*)) :print nil)
|
|
(("my string" :STATIC (#(*MY-STRING* 0 0) . 2) (*MY-STRING* . 1)
|
|
((1 2 "my string") . 1) ((2 "my string") . 1) (("my string") . 0)))
|
|
</pre></div>
|
|
|
|
<p>There is no output on <code>cl:*standard-output*</code> and the return value
|
|
is a single path for the target object <tt>"my string"</tt>. As before, the
|
|
path shows the symbol and the three cons cells.
|
|
</p>
|
|
<hr>
|
|
<span id="Metaobject-Protocol"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Extensible-Sequences" accesskey="n" rel="next">Extensible Sequences</a>, Previous: <a href="index.html#Garbage-Collection" accesskey="p" rel="prev">Garbage Collection</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Metaobject-Protocol-1"></span><h3 class="section">7.5 Metaobject Protocol</h3>
|
|
|
|
<span id="AMOP-Compatibility-of-Metaobject-Protocol"></span><h4 class="subsection">7.5.1 AMOP Compatibility of Metaobject Protocol</h4>
|
|
|
|
<p>SBCL supports a metaobject protocol which is intended to be compatible
|
|
with AMOP; present exceptions to this (as distinct from current bugs)
|
|
are:
|
|
</p>
|
|
<ul>
|
|
<li> <span id="index-compute_002deffective_002dmethod-_005bsb_002dmop_005d"></span>
|
|
<code>compute-effective-method</code> only returns one value, not two.
|
|
|
|
<p>There is no record of what the second return value was meant to
|
|
indicate, and apparently no clients for it.
|
|
</p>
|
|
</li><li> <span id="index-generic_002dfunction-_005bcl_005d"></span>
|
|
<span id="index-standard_002dgeneric_002dfunction-_005bcl_005d"></span>
|
|
<span id="index-funcallable_002dstandard_002dobject-_005bsb_002dmop_005d"></span>
|
|
<span id="index-standard_002dobject-_005bcl_005d"></span>
|
|
<span id="index-function-_005bcl_005d"></span>
|
|
The direct superclasses of <code>funcallable-standard-object</code> are
|
|
<code>(function standard-object)</code>, not <code>(standard-object function)</code>.
|
|
|
|
<p>This is to ensure that the <code>standard-object</code> class is the last of
|
|
the standardized classes before <code>t</code> appearing in the class
|
|
precedence list of <code>generic-function</code> and
|
|
<code>standard-generic-function</code>, as required by section 1.4.4.5 of the
|
|
ANSI specification.
|
|
</p>
|
|
</li><li> <span id="index-ensure_002dgeneric_002dfunction-_005bcl_005d"></span>
|
|
<span id="index-generic_002dfunction_002ddeclarations-_005bsb_002dmop_005d"></span>
|
|
the arguments <code>:declare</code> and <code>:declarations</code> to
|
|
<code>ensure-generic-function</code> are both accepted, with the leftmost
|
|
argument defining the declarations to be stored and returned by
|
|
<code>generic-function-declarations</code>.
|
|
|
|
<p>Where AMOP specifies <code>:declarations</code> as the keyword argument to
|
|
<code>ensure-generic-function</code>, the Common Lisp standard specifies
|
|
<code>:declare</code>. Portable code should use <code>:declare</code>.
|
|
</p>
|
|
</li><li> <span id="index-validate_002dsuperclass-_005bsb_002dmop_005d"></span>
|
|
<span id="index-finalize_002dinheritance-_005bsb_002dmop_005d"></span>
|
|
<span id="index-standard_002dclass-_005bcl_005d"></span>
|
|
<span id="index-funcallable_002dstandard_002dclass-_005bsb_002dmop_005d"></span>
|
|
<span id="index-function-_005bcl_005d-1"></span>
|
|
<span id="index-class_002dprototype-_005bsb_002dmop_005d"></span>
|
|
although SBCL obeys the requirement in AMOP that
|
|
<code>validate-superclass</code> should treat <code>standard-class</code> and
|
|
<code>funcallable-standard-class</code> as compatible metaclasses, we
|
|
impose an additional requirement at class finalization time: a class
|
|
of metaclass <code>funcallable-standard-class</code> must have
|
|
<code>function</code> in its superclasses, and a class of metaclass
|
|
<code>standard-class</code> must not.
|
|
|
|
<span id="index-typep-_005bcl_005d"></span>
|
|
<span id="index-class_002dof-_005bcl_005d"></span>
|
|
<span id="index-subtypep-_005bcl_005d"></span>
|
|
<p>After a class has been finalized, it is associated with a class
|
|
prototype which is accessible by a standard mop function
|
|
<code>class-prototype</code>. The user can then ask whether this object is a
|
|
<code>function</code> or not in several different ways: whether it is a
|
|
function according to <code>typep</code>; whether its <code>class-of</code> is
|
|
<code>subtypep</code> <code>function</code>, or whether <code>function</code> appears in
|
|
the superclasses of the class. The additional consistency requirement
|
|
comes from the desire to make all of these answers the same.
|
|
</p>
|
|
<p>The following class definitions are bad, and will lead to errors
|
|
either immediately or if an instance is created:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(defclass bad-object (funcallable-standard-object)
|
|
()
|
|
(:metaclass standard-class))
|
|
</pre></div>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defclass bad-funcallable-object (standard-object)
|
|
()
|
|
(:metaclass funcallable-standard-class))
|
|
</pre></div>
|
|
<p>The following definition is acceptable:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(defclass mixin ()
|
|
((slot :initarg slot)))
|
|
(defclass funcallable-object (funcallable-standard-object mixin)
|
|
()
|
|
(:metaclass funcallable-standard-class))
|
|
</pre></div>
|
|
<p>and leads to a class whose instances are funcallable and have one slot.
|
|
</p>
|
|
<span id="index-funcallable_002dstandard_002dobject-_005bsb_002dmop_005d-1"></span>
|
|
<p>Note that this requirement also applies to the class
|
|
<code>funcallable-standard-object</code>, which has metaclass
|
|
<code>funcallable-standard-class</code> rather than
|
|
<code>standard-class</code> as AMOP specifies.
|
|
</p>
|
|
</li><li> the requirement that “No portable class <em>C_p</em> may inherit, by
|
|
virtue of being a direct or indirect subclass of a specified class, any
|
|
slot for which the name is a symbol accessible in the
|
|
<code>common-lisp-user</code> 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.
|
|
|
|
<p>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.
|
|
</p>
|
|
</li><li> <span id="index-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d"></span>
|
|
<span id="index-_0028setf-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d_0029"></span>
|
|
<span id="index-slot_002dboundp_002dusing_002dclass-_005bsb_002dmop_005d"></span>
|
|
specializations of the <code>new-value</code> argument to <code>(setf
|
|
slot-value-using-class)</code> are not allowed: all user-defined methods must
|
|
have a specializer of the class <code>t</code>.
|
|
|
|
<p>This prohibition is motivated by a separation of layers: the
|
|
<code>slot-value-using-class</code> family of functions is intended for use in
|
|
implementing different and new slot allocation strategies, rather than
|
|
in performing application-level dispatching. Additionally, with this
|
|
requirement, there is a one-to-one mapping between metaclass, class and
|
|
slot-definition-class tuples and effective methods of <code>(setf
|
|
slot-value-using-class)</code>, which permits optimization of <code>(setf
|
|
slot-value-using-class)</code>’s discriminating function in the same manner as
|
|
for <code>slot-value-using-class</code> and <code>slot-boundp-using-class</code>.
|
|
</p>
|
|
<p>Note that application code may specialize on the <code>new-value</code>
|
|
argument of slot accessors.
|
|
</p>
|
|
</li><li> <span id="index-defclass-_005bcl_005d"></span>
|
|
<span id="index-ensure_002dclass-_005bsb_002dmop_005d"></span>
|
|
<span id="index-ensure_002dclass_002dusing_002dclass-_005bsb_002dmop_005d"></span>
|
|
<span id="index-find_002dclass-_005bcl_005d"></span>
|
|
<span id="index-class_002dname-_005bcl_005d"></span>
|
|
the class named by the <code>name</code> argument to <code>ensure-class</code>, if
|
|
any, is only redefined if it is the proper name of that class;
|
|
otherwise, a new class is created.
|
|
|
|
<p>This is consistent with the description of <code>ensure-class</code> in AMOP
|
|
as the functional version of <code>defclass</code>, which has this behaviour;
|
|
however, it is not consistent with the weaker requirement in AMOP, which
|
|
states that any class found by <code>find-class</code>, no matter what its
|
|
<code>class-name</code>, is redefined.
|
|
</p>
|
|
</li><li> <span id="index-slot_002ddefinition_002dname-_005bsb_002dmop_005d"></span>
|
|
<span id="index-structure_002dclass-_005bcl_005d"></span>
|
|
<span id="index-defstruct-_005bcl_005d"></span>
|
|
an error is not signaled in the case of the <code>:name</code> initialization
|
|
argument for <code>slot-definition</code> objects being a constant, when the
|
|
slot definition is of type <code>structure-slot-definition</code> (i.e. it is
|
|
associated with a class of type <code>structure-class</code>).
|
|
|
|
<p>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.
|
|
</p>
|
|
</li><li> <span id="index-t-_005bcl_005d"></span>
|
|
<span id="index-built_002din_002dclass-_005bcl_005d"></span>
|
|
<span id="index-validate_002dsuperclass-_005bsb_002dmop_005d-1"></span>
|
|
<span id="index-defclass-_005bcl_005d-1"></span>
|
|
the class named <code>t</code> is not an instance of the <code>built-in-class</code>
|
|
metaclass.
|
|
|
|
<p>AMOP specifies, in the “Inheritance Structure of Metaobject Classes”
|
|
section, that the class named <code>t</code> should be an instance of
|
|
<code>built-in-class</code>. However, it also specifies that
|
|
<code>validate-superclass</code> should return true (indicating that a direct
|
|
superclass relationship is permissible) if the second argument is the
|
|
class named <code>t</code>. Also, ANSI specifies that classes with metaclass
|
|
<code>built-in-class</code> may not be subclassed using <code>defclass</code>, and
|
|
also that the class named <code>t</code> is the universal superclass,
|
|
inconsistent with it being a <code>built-in-class</code>.
|
|
</p>
|
|
</li><li> <span id="index-change_002dclass-_005bcl_005d"></span>
|
|
<span id="index-defclass-_005bcl_005d-2"></span>
|
|
<span id="index-ensure_002dclass-_005bsb_002dmop_005d-1"></span>
|
|
<span id="index-ensure_002dclass_002dusing_002dclass-_005bsb_002dmop_005d-1"></span>
|
|
<span id="index-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d-1"></span>
|
|
<span id="index-_0028setf-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d_0029-1"></span>
|
|
<span id="index-slot_002dboundp_002dusing_002dclass-_005bsb_002dmop_005d-1"></span>
|
|
<span id="index-slot_002ddefinition_002dallocation-_005bsb_002dmop_005d"></span>
|
|
uses of <code>change-class</code> and redefinitions of classes with
|
|
<code>defclass</code> (or the functional interfaces <code>ensure-class</code> or
|
|
<code>ensure-class-using-class</code>) must ensure that for each slot with
|
|
allocation <code>:instance</code> or <code>:class</code>, the set of applicable
|
|
methods on the <code>slot-value-using-class</code> family of generic
|
|
functions is the same before and after the change.
|
|
|
|
<p>This is required for correct operation of the protocol to update
|
|
instances for the new or redefined class, and can be seen as part of
|
|
the contract of the <code>:instance</code> or <code>:class</code> allocations.
|
|
</p>
|
|
</li></ul>
|
|
|
|
<span id="Metaobject-Protocol-Extensions"></span><h4 class="subsection">7.5.2 Metaobject Protocol Extensions</h4>
|
|
|
|
<p>In addition, SBCL supports extensions to the Metaobject protocol from
|
|
AMOP; at present, they are:
|
|
</p>
|
|
<ul>
|
|
<li> <span id="index-defmethod-_005bcl_005d"></span>
|
|
<span id="index-find_002dclass-_005bcl_005d-1"></span>
|
|
<span id="index-intern_002deql_002dspecializer-_005bsb_002dmop_005d"></span>
|
|
<span id="index-make_002dmethod_002dspecializers_002dform-_005bsb_002dpcl_005d"></span>
|
|
<span id="index-make_002dmethod_002dlambda-_005bsb_002dmop_005d"></span>
|
|
compile-time support for generating specializer metaobjects from
|
|
specializer names in <code>defmethod</code> forms is provided by the
|
|
<code>make-method-specializers-form</code> function, which returns a form
|
|
which, when evaluated in the lexical environment of the
|
|
<code>defmethod</code>, returns a list of specializer metaobjects. This
|
|
operator suffers from similar restrictions to those affecting
|
|
<code>make-method-lambda</code>, namely that the generic function must be
|
|
defined when the <code>defmethod</code> form is expanded, so that the
|
|
correct method of <code>make-method-specializers-form</code> is invoked.
|
|
The system-provided method on <code>make-method-specializers-form</code>
|
|
generates a call to <code>find-class</code> for each symbol specializer
|
|
name, and a call to <code>intern-eql-specializer</code> for each <code>(eql
|
|
<var>x</var>)</code> specializer name.
|
|
|
|
</li><li> <span id="index-find_002dmethod-_005bcl_005d"></span>
|
|
<span id="index-parse_002dspecializer_002dusing_002dclass-_005bsb_002dpcl_005d"></span>
|
|
<span id="index-unparse_002dspecializer_002dusing_002dclass-_005bsb_002dpcl_005d"></span>
|
|
run-time support for converting between specializer names and
|
|
specializer metaobjects, mostly for the purposes of
|
|
<code>find-method</code>, is provided by
|
|
<code>parse-specializer-using-class</code> and
|
|
<code>unparse-specializer-using-class</code>, which dispatch on their first
|
|
argument, the generic function associated with a method with the given
|
|
specializer. The system-provided methods on those methods convert
|
|
between classes and proper names and between lists of the form
|
|
<code>(eql <var>x</var>)</code> and interned eql specializer objects.
|
|
|
|
</li><li> <span id="index-_002bslot_002dunbound_002b-_005bsb_002dpcl_005d"></span>
|
|
<span id="index-standard_002dinstance_002daccess-_005bsb_002dmop_005d"></span>
|
|
<span id="index-funcallable_002dstandard_002dinstance_002daccess-_005bsb_002dmop_005d"></span>
|
|
distinguishing unbound instance allocated slots from bound ones when
|
|
using <code>standard-instance-access</code> and
|
|
<code>funcallable-standard-instance-access</code> is possible by comparison
|
|
to the symbol-macro <code>+slot-unbound+</code>.
|
|
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="Extensible-Sequences"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Support-For-Unix" accesskey="n" rel="next">Support For Unix</a>, Previous: <a href="index.html#Metaobject-Protocol" accesskey="p" rel="prev">Metaobject Protocol</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Extensible-Sequences-1"></span><h3 class="section">7.6 Extensible Sequences</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Iterator-Protocol" accesskey="1">Iterator Protocol</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Simple-Iterator-Protocol" accesskey="2">Simple Iterator Protocol</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<span id="index-sequence-_005bcl_005d"></span>
|
|
<span id="index-vector-_005bcl_005d-1"></span>
|
|
<span id="index-find-_005bcl_005d"></span>
|
|
<span id="index-subseq-_005bcl_005d"></span>
|
|
<p>ANSI Common Lisp has a class <code>sequence</code> with subclasses <code>list</code> and
|
|
<code>vector</code> on which the “sequence functions” like <code>find</code>,
|
|
<code>subseq</code>, etc. operate. As an extension to the ANSI specification,
|
|
SBCL allows additional subclasses of <code>sequence</code> to be defined
|
|
<a id="DOCF6" href="index.html#FOOT6"><sup>6</sup></a>.
|
|
</p>
|
|
<span id="index-coerce-_005bcl_005d"></span>
|
|
<span id="index-subseq-_005bcl_005d-1"></span>
|
|
<span id="index-make_002dinstance-_005bcl_005d"></span>
|
|
<span id="index-list-_005bcl_005d-1"></span>
|
|
<p>Users of this extension just make instances of <code>sequence</code> subclasses
|
|
and transparently operate on them using sequence functions:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(coerce (subseq (make-instance 'my-sequence) 5 10) 'list)
|
|
</pre></div>
|
|
<p>From this perspective, no distinction between builtin and user-defined
|
|
<code>sequence</code> subclasses should be necessary.
|
|
</p>
|
|
<p>Providers of the extension, that is of user-defined <code>sequence</code>
|
|
subclasses, have to adhere to a “sequence protocol” which consists of
|
|
a set of generic functions in the <code>sequence</code> package.
|
|
</p>
|
|
<span id="index-sequence-_005bcl_005d-1"></span>
|
|
<span id="index-standard_002dobject-_005bcl_005d-1"></span>
|
|
<p>A minimal <code>sequence</code> subclass has to specify <code>standard-object</code> and
|
|
<code>sequence</code> as its superclasses and has to be the specializer of the
|
|
<code>sequence</code> parameter of methods on at least the following generic
|
|
functions:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dsequence-length"></span><dl>
|
|
<dt id="index-length">Generic Function: <strong>length</strong> <em>[sb-sequence] sequence</em></dt>
|
|
<dd><p>Returns the length of <code>sequence</code> or signals a <code>protocol-unimplemented</code>
|
|
error if the sequence protocol is not implemented for the class of
|
|
<code>sequence</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dsequence-elt"></span><dl>
|
|
<dt id="index-elt">Generic Function: <strong>elt</strong> <em>[sb-sequence] sequence index</em></dt>
|
|
<dd><p>Returns the element at position <code>index</code> of <code>sequence</code> or signals a
|
|
<code>protocol-unimplemented</code> error if the sequence protocol is not
|
|
implemented for the class of <code>sequence</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-_0028setf-sb_002dsequence-elt_0029"></span><dl>
|
|
<dt id="index-_0028setf">Generic Function: <strong>(setf</strong> <em>elt [sb-sequence])</em></dt>
|
|
<dd><p>Replaces the element at position <code>index</code> of <code>sequence</code> with <code>new-value</code>
|
|
and returns <code>new-value</code> or signals a <code>protocol-unimplemented</code> error if
|
|
the sequence protocol is not implemented for the class of
|
|
<code>sequence</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dsequence-adjust_002dsequence"></span><dl>
|
|
<dt id="index-adjust_002dsequence">Generic Function: <strong>adjust-sequence</strong> <em>[sb-sequence] sequence length &key initial-element initial-contents</em></dt>
|
|
<dd><p>Return destructively modified <code>sequence</code> or a freshly allocated
|
|
sequence of the same class as <code>sequence</code> of length <code>length</code>. Elements
|
|
of the returned sequence are initialized to <code>initial-element</code>, if
|
|
supplied, initialized to <code>initial-contents</code> if supplied, or identical
|
|
to the elements of <code>sequence</code> if neither is supplied. Signals a
|
|
<code>protocol-unimplemented</code> error if the sequence protocol is not
|
|
implemented for the class of <code>sequence</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dsequence-make_002dsequence_002dlike"></span><dl>
|
|
<dt id="index-make_002dsequence_002dlike">Generic Function: <strong>make-sequence-like</strong> <em>[sb-sequence] sequence length &key initial-element initial-contents</em></dt>
|
|
<dd><p>Returns a freshly allocated sequence of length <code>length</code> and of the
|
|
same class as <code>sequence</code>. Elements of the new sequence are
|
|
initialized to <code>initial-element</code>, if supplied, initialized to
|
|
<code>initial-contents</code> if supplied, or identical to the elements of
|
|
<code>sequence</code> if neither is supplied. Signals a <code>protocol-unimplemented</code>
|
|
error if the sequence protocol is not implemented for the class of
|
|
<code>sequence</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="index-sequence-_005bcl_005d-2"></span>
|
|
<span id="index-make_002dsequence_002dlike-_005bsb_002dsequence_005d"></span>
|
|
<span id="index-subseq-_005bcl_005d-2"></span>
|
|
<span id="index-copy_002dseq-_005bcl_005d"></span>
|
|
<span id="index-adjust_002dsequence-_005bsb_002dsequence_005d"></span>
|
|
<p><code>make-sequence-like</code> is needed for functions returning
|
|
freshly-allocated sequences such as <code>subseq</code> or
|
|
<code>copy-seq</code>. <code>adjust-sequence</code> is needed for functions which
|
|
destructively modify their arguments such as <code>delete</code>. 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 <a href="index.html#Iterator-Protocol">Iterator Protocol</a>.
|
|
</p>
|
|
<p>When the sequence protocol is only partially implemented for a given
|
|
<code>sequence</code> subclass, an attempt to apply one of the missing
|
|
operations to instances of that class signals the following condition:
|
|
</p>
|
|
<span id="Condition-sb_002dsequence-protocol_002dunimplemented"></span><dl>
|
|
<dt id="index-protocol_002dunimplemented">Condition: <strong>protocol-unimplemented</strong> <em>[sb-sequence]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">protocol-unimplemented</span><!-- /@w --></code>, <code><span class="nolinebreak">type-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>This error is signaled if a sequence operation is applied to an
|
|
instance of a sequence class that does not support the
|
|
operation.
|
|
</p></dd></dl>
|
|
|
|
<p>In addition to the mandatory functions above, methods on the sequence
|
|
functions listed below can be defined.
|
|
</p>
|
|
<p>There are two noteworthy irregularities:
|
|
</p><ul>
|
|
<li> The function <code>sb-sequence:emptyp</code> does not have a counterpart in
|
|
the <code>cl</code> package. It is intended to be used instead of
|
|
<code>length</code> when working with lazy or infinite sequences.
|
|
|
|
</li><li> The functions <code>map</code>, <code>concatenate</code> and <code>merge</code> receive a
|
|
type designator specifying the type of the constructed sequence as their
|
|
first argument. However, the corresponding generic functions
|
|
<code>sb-sequence:map</code>, <code>sb-sequence:concatenate</code> and
|
|
<code>sb-sequence:merge</code> receive a prototype instance of the requested
|
|
<code>sequence</code> subclass instead.
|
|
</li></ul>
|
|
|
|
<span id="Generic_002dFunction-sb_002dsequence-emptyp"></span><dl>
|
|
<dt id="index-emptyp">Generic Function: <strong>emptyp</strong> <em>[sb-sequence] sequence</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>sequence</code> is an empty sequence and <code>nil</code>
|
|
otherwise. Signals an error if <code>sequence</code> is not a sequence.
|
|
</p></dd></dl>
|
|
|
|
<ul>
|
|
<li> <code>sb-sequence:count</code>, <code>sb-sequence:count-if</code>, <code>sb-sequence:count-if-not</code>
|
|
|
|
</li><li> <code>sb-sequence:find</code>, <code>sb-sequence:find-if</code>, <code>sb-sequence:find-if-not</code>
|
|
|
|
</li><li> <code>sb-sequence:position</code>, <code>sb-sequence:position-if</code>, <code>sb-sequence:position-if-not</code>
|
|
|
|
</li><li> <code>sb-sequence:subseq</code>
|
|
|
|
</li><li> <code>sb-sequence:copy-seq</code>
|
|
|
|
</li><li> <code>sb-sequence:fill</code>
|
|
|
|
</li><li> <span id="Generic_002dFunction-sb_002dsequence-map"></span><dl>
|
|
<dt id="index-map">Generic Function: <strong>map</strong> <em>[sb-sequence] result-prototype function sequence &rest sequences</em></dt>
|
|
<dd><p>Implements <code>cl:map</code> for extended sequences.
|
|
</p>
|
|
<p><code>result-prototype</code> corresponds to the <code>result-type</code> of <code>cl:map</code> but
|
|
receives a prototype instance of an extended sequence class
|
|
instead of a type specifier. By dispatching on <code>result-prototype</code>,
|
|
methods on this generic function specify how extended sequence
|
|
classes act when they are specified as the result type in a <code>cl:map</code>
|
|
call. <code>result-prototype</code> may not be fully initialized and thus
|
|
should only be used for dispatch and to determine its class.
|
|
</p>
|
|
<p>Another difference to <code>cl:map</code> is that <code>function</code> is a function, not a
|
|
function designator.
|
|
</p></dd></dl>
|
|
|
|
</li><li> <code>sb-sequence:nsubstitute</code>, <code>sb-sequence:nsubstitute-if</code>,
|
|
<code>sb-sequence:nsubstitute-if-not</code>, <code>sb-sequence:substitute</code>,
|
|
<code>sb-sequence:substitute-if</code>, <code>sb-sequence:substitute-if-not</code>
|
|
|
|
</li><li> <code>sb-sequence:replace</code>
|
|
|
|
</li><li> <code>sb-sequence:nreverse</code>, <code>sb-sequence:reverse</code>
|
|
|
|
</li><li> <span id="Generic_002dFunction-sb_002dsequence-concatenate"></span><dl>
|
|
<dt id="index-concatenate">Generic Function: <strong>concatenate</strong> <em>[sb-sequence] result-prototype &rest sequences</em></dt>
|
|
<dd><p>Implements <code>cl:concatenate</code> for extended sequences.
|
|
</p>
|
|
<p><code>result-prototype</code> corresponds to the <code>result-type</code> of <code>cl:concatenate</code>
|
|
but receives a prototype instance of an extended sequence class
|
|
instead of a type specifier. By dispatching on <code>result-prototype</code>,
|
|
methods on this generic function specify how extended sequence
|
|
classes act when they are specified as the result type in a
|
|
<code>cl:concatenate</code> call. <code>result-prototype</code> may not be fully initialized
|
|
and thus should only be used for dispatch and to determine its
|
|
class.
|
|
</p></dd></dl>
|
|
|
|
</li><li> <code>sb-sequence:reduce</code>
|
|
|
|
</li><li> <code>sb-sequence:mismatch</code>
|
|
|
|
</li><li> <code>sb-sequence:search</code>
|
|
|
|
</li><li> <code>sb-sequence:delete</code>, <code>sb-sequence:delete-if</code>, <code>sb-sequence:delete-if-not</code>,
|
|
<code>sb-sequence:remove</code>, <code>sb-sequence:remove-if</code>, <code>sb-sequence:remove-if-not</code>,
|
|
|
|
</li><li> <code>sb-sequence:delete-duplicates</code>, <code>sb-sequence:remove-duplicates</code>
|
|
|
|
</li><li> <code>sb-sequence:sort</code>, <code>sb-sequence:stable-sort</code>
|
|
|
|
</li><li> <span id="Generic_002dFunction-sb_002dsequence-merge"></span><dl>
|
|
<dt id="index-merge">Generic Function: <strong>merge</strong> <em>[sb-sequence] result-prototype sequence1 sequence2 predicate &key key</em></dt>
|
|
<dd><p>Implements <code>cl:merge</code> for extended sequences.
|
|
</p>
|
|
<p><code>result-prototype</code> corresponds to the <code>result-type</code> of <code>cl:merge</code> but
|
|
receives a prototype instance of an extended sequence class
|
|
instead of a type specifier. By dispatching on <code>result-prototype</code>,
|
|
methods on this generic function specify how extended sequence
|
|
classes act when they are specified as the result type in a
|
|
<code>cl:merge</code> call. <code>result-prototype</code> may not be fully initialized and
|
|
thus should only be used for dispatch and to determine its class.
|
|
</p>
|
|
<p>Another difference to <code>cl:merge</code> is that <code>predicate</code> is a function,
|
|
not a function designator.
|
|
</p></dd></dl>
|
|
</li></ul>
|
|
|
|
<span id="index-dolist-_005bcl_005d"></span>
|
|
<p>In the spirit of <code>dolist</code>, generic sequences can be traversed using
|
|
the macro
|
|
</p>
|
|
<span id="Macro-sb_002dsequence-dosequence"></span><dl>
|
|
<dt id="index-dosequence">Macro: <strong>dosequence</strong> <em>[sb-sequence] (element sequence &optional return) &body body</em></dt>
|
|
<dd><p>Executes <code>body</code> with <code>element</code> subsequently bound to each element of
|
|
<code>sequence</code>, then returns <code>return</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Iterator-Protocol"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Simple-Iterator-Protocol" accesskey="n" rel="next">Simple Iterator Protocol</a>, Up: <a href="index.html#Extensible-Sequences" accesskey="u" rel="up">Extensible Sequences</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Iterator-Protocol-1"></span><h4 class="subsection">7.6.1 Iterator Protocol</h4>
|
|
|
|
<p>The iterator protocol allows subsequently accessing some or all elements
|
|
of a sequence in forward or reverse direction. Users first call
|
|
<code>make-sequence-iterator</code> 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:
|
|
<span id="index-make_002dsequence_002diterator-_005bsb_002dsequence_005d"></span>
|
|
</p><dl>
|
|
<dt id="index-step-function">Function: <strong><code>step function</code></strong> <em>sequence iterator from-end</em></dt>
|
|
<dd><p>Moves the iterator one position forward or backward in the associated
|
|
sequence depending on the iteration direction.
|
|
</p></dd></dl>
|
|
<dl>
|
|
<dt id="index-endp-function">Function: <strong><code>endp function</code></strong> <em>sequence iterator limit from-end</em></dt>
|
|
<dd><p>Returns non-<code>nil</code> when the iterator has reached the end of the
|
|
associated sequence with respect to the iteration direction.
|
|
</p></dd></dl>
|
|
<dl>
|
|
<dt id="index-element-function">Function: <strong><code>element function</code></strong> <em>sequence iterator</em></dt>
|
|
<dd><p>Returns the sequence element associated to the current position of the
|
|
iteration.
|
|
</p></dd></dl>
|
|
<dl>
|
|
<dt id="index-setf-element-function">Function: <strong><code>setf element function</code></strong> <em>new-value sequence iterator</em></dt>
|
|
<dd><p>Destructively modifies the associates sequence by replacing the sequence
|
|
element associated to the current iteration position with a new value.
|
|
</p></dd></dl>
|
|
<dl>
|
|
<dt id="index-index-function">Function: <strong><code>index function</code></strong> <em>sequence iterator</em></dt>
|
|
<dd><p>Returns the position of the iteration in the associated sequence.
|
|
</p></dd></dl>
|
|
<dl>
|
|
<dt id="index-copy-function">Function: <strong><code>copy function</code></strong> <em>sequence iterator</em></dt>
|
|
<dd><p>Returns a copy of the iteration state which can be mutated independently
|
|
of the copied iteration state.
|
|
</p></dd></dl>
|
|
|
|
<p>An iterator is created by calling:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dsequence-make_002dsequence_002diterator"></span><dl>
|
|
<dt id="index-make_002dsequence_002diterator">Generic Function: <strong>make-sequence-iterator</strong> <em>[sb-sequence] sequence &key from-end start end</em></dt>
|
|
<dd><p>Returns a sequence iterator for <code>sequence</code> or, if <code>start</code> and/or <code>end</code>
|
|
are supplied, the subsequence bounded by <code>start</code> and <code>end</code> as nine
|
|
values:
|
|
</p>
|
|
<p>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
|
|
</p>
|
|
<p>If <code>from-end</code> is <code>nil</code>, the constructed iterator visits the specified
|
|
elements in the order in which they appear in <code>sequence</code>. Otherwise,
|
|
the elements are visited in the opposite order.
|
|
</p></dd></dl>
|
|
|
|
<span id="index-make_002dsequence_002diterator-_005bsb_002dsequence_005d-1"></span>
|
|
<span id="index-make_002dsimple_002dsequence_002diterator-_005bsb_002dsequence_005d"></span>
|
|
<span id="index-sequence-_005bcl_005d-3"></span>
|
|
<p>Note that <code>make-sequence-iterator</code> calls
|
|
<code>make-simple-sequence-iterator</code> when there is no specialized
|
|
method for a particular <code>sequence</code> subclass. See <a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a>.
|
|
</p>
|
|
<p>The following convenience macros simplify traversing sequences using
|
|
iterators:
|
|
</p>
|
|
<span id="Macro-sb_002dsequence-with_002dsequence_002diterator"></span><dl>
|
|
<dt id="index-with_002dsequence_002diterator">Macro: <strong>with-sequence-iterator</strong> <em>[sb-sequence] (&optional iterator limit from-end-p step endp element set-element index copy) (sequence &key from-end start end) &body body</em></dt>
|
|
<dd><p>Executes <code>body</code> with the elements of <code>vars</code> bound to the iteration
|
|
state returned by <code>make-sequence-iterator</code> for <code>sequence</code> and
|
|
<code>args</code>. Elements of <code>vars</code> may be <code>nil</code> in which case the corresponding
|
|
value returned by <code>make-sequence-iterator</code> is ignored.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dsequence-with_002dsequence_002diterator_002dfunctions"></span><dl>
|
|
<dt id="index-with_002dsequence_002diterator_002dfunctions">Macro: <strong>with-sequence-iterator-functions</strong> <em>[sb-sequence] (step endp elt setf index copy) (sequence &rest args &key from-end start end) &body body</em></dt>
|
|
<dd><p>Executes <code>body</code> with the names <code>step</code>, <code>endp</code>, <code>elt</code>, <code>setf</code>, <code>index</code> and <code>copy</code>
|
|
bound to local functions which execute the iteration state query and
|
|
mutation functions returned by <code>make-sequence-iterator</code> for <code>sequence</code>
|
|
and <code>args</code>. <code>step</code>, <code>endp</code>, <code>elt</code>, <code>setf</code>, <code>index</code> and <code>copy</code> have dynamic
|
|
extent.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Simple-Iterator-Protocol"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Iterator-Protocol" accesskey="p" rel="prev">Iterator Protocol</a>, Up: <a href="index.html#Extensible-Sequences" accesskey="u" rel="up">Extensible Sequences</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Simple-Iterator-Protocol-1"></span><h4 class="subsection">7.6.2 Simple Iterator Protocol</h4>
|
|
|
|
<p>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:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dsequence-iterator_002dstep"></span><dl>
|
|
<dt id="index-iterator_002dstep">Generic Function: <strong>iterator-step</strong> <em>[sb-sequence] sequence iterator from-end</em></dt>
|
|
<dd><p>Moves <code>iterator</code> one position forward or backward in <code>sequence</code>
|
|
depending on the iteration direction encoded in <code>from-end</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dsequence-iterator_002dendp"></span><dl>
|
|
<dt id="index-iterator_002dendp">Generic Function: <strong>iterator-endp</strong> <em>[sb-sequence] sequence iterator limit from-end</em></dt>
|
|
<dd><p>Returns non-NIL when <code>iterator</code> has reached <code>limit</code> (which may
|
|
correspond to the end of <code>sequence</code>) with respect to the iteration
|
|
direction encoded in <code>from-end</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dsequence-iterator_002delement"></span><dl>
|
|
<dt id="index-iterator_002delement">Generic Function: <strong>iterator-element</strong> <em>[sb-sequence] sequence iterator</em></dt>
|
|
<dd><p>Returns the element of <code>sequence</code> associated to the position of
|
|
<code>iterator</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-_0028setf-sb_002dsequence-iterator_002delement_0029"></span><dl>
|
|
<dt id="index-_0028setf-1">Generic Function: <strong>(setf</strong> <em>iterator-element [sb-sequence])</em></dt>
|
|
<dd><p>Destructively modifies <code>sequence</code> by replacing the sequence element
|
|
associated to position of <code>iterator</code> with <code>new-value</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dsequence-iterator_002dindex"></span><dl>
|
|
<dt id="index-iterator_002dindex">Generic Function: <strong>iterator-index</strong> <em>[sb-sequence] sequence iterator</em></dt>
|
|
<dd><p>Returns the position of <code>iterator</code> in <code>sequence</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dsequence-iterator_002dcopy"></span><dl>
|
|
<dt id="index-iterator_002dcopy">Generic Function: <strong>iterator-copy</strong> <em>[sb-sequence] sequence iterator</em></dt>
|
|
<dd><p>Returns a copy of <code>iterator</code> which also traverses <code>sequence</code> but can
|
|
be mutated independently of <code>iterator</code>.
|
|
</p></dd></dl>
|
|
|
|
<p>Iterator objects implementing the above simple iteration protocol are
|
|
created by calling the following generic function:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dsequence-make_002dsimple_002dsequence_002diterator"></span><dl>
|
|
<dt id="index-make_002dsimple_002dsequence_002diterator">Generic Function: <strong>make-simple-sequence-iterator</strong> <em>[sb-sequence] sequence &key from-end start end</em></dt>
|
|
<dd><p>Returns a sequence iterator for <code>sequence</code>, <code>start</code>, <code>end</code> and <code>from-end</code>
|
|
as three values:
|
|
</p>
|
|
<p>1. iterator state
|
|
2. limit
|
|
3. from-end
|
|
</p>
|
|
<p>The returned iterator can be used with the generic iterator
|
|
functions <code>iterator-step</code>, <code>iterator-endp</code>, <code>iterator-element</code>, (<code>setf</code>
|
|
<code>iterator-element</code>), <code>iterator-index</code> and <code>iterator-copy</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Support-For-Unix"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Unicode-Support" accesskey="n" rel="next">Unicode Support</a>, Previous: <a href="index.html#Extensible-Sequences" accesskey="p" rel="prev">Extensible Sequences</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Support-For-Unix-1"></span><h3 class="section">7.7 Support For Unix</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Command_002dline-arguments" accesskey="1">Command-line arguments</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Querying-the-process-environment" accesskey="2">Querying the process environment</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Running-external-programs" accesskey="3">Running external programs</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Command_002dline-arguments"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Querying-the-process-environment" accesskey="n" rel="next">Querying the process environment</a>, Up: <a href="index.html#Support-For-Unix" accesskey="u" rel="up">Support For Unix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Command_002dline-arguments-1"></span><h4 class="subsection">7.7.1 Command-line arguments</h4>
|
|
<span id="index-_002aposix_002dargv_002a-_005bsb_002dext_005d-1"></span>
|
|
|
|
<p>The UNIX command line can be read from the variable
|
|
<code>sb-ext:*posix-argv*</code>.
|
|
</p>
|
|
<hr>
|
|
<span id="Querying-the-process-environment"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Running-external-programs" accesskey="n" rel="next">Running external programs</a>, Previous: <a href="index.html#Command_002dline-arguments" accesskey="p" rel="prev">Command-line arguments</a>, Up: <a href="index.html#Support-For-Unix" accesskey="u" rel="up">Support For Unix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Querying-the-process-environment-1"></span><h4 class="subsection">7.7.2 Querying the process environment</h4>
|
|
|
|
<p>The UNIX environment can be queried with the
|
|
<code>sb-ext:posix-getenv</code> function.
|
|
</p>
|
|
<span id="Function-sb_002dext-posix_002dgetenv"></span><dl>
|
|
<dt id="index-posix_002dgetenv">Function: <strong>posix-getenv</strong> <em>[sb-ext] name</em></dt>
|
|
<dd><p>Return the "value" part of the environment string "name=value" which
|
|
corresponds to <code>name</code>, or <code>nil</code> if there is none.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Running-external-programs"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Querying-the-process-environment" accesskey="p" rel="prev">Querying the process environment</a>, Up: <a href="index.html#Support-For-Unix" accesskey="u" rel="up">Support For Unix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Running-external-programs-1"></span><h4 class="subsection">7.7.3 Running external programs</h4>
|
|
|
|
<p>External programs can be run with <code>sb-ext:run-program</code>.
|
|
<a id="DOCF7" href="index.html#FOOT7"><sup>7</sup></a>
|
|
</p>
|
|
<span id="Function-sb_002dext-run_002dprogram"></span><dl>
|
|
<dt id="index-run_002dprogram">Function: <strong>run-program</strong> <em>[sb-ext] program args &key env environment wait search pty input if-input-does-not-exist output if-output-exists error if-error-exists status-hook external-format directory preserve-fds</em></dt>
|
|
<dd><p><code>run-program</code> creates a new process specified by <code>program</code>.
|
|
<code>args</code> is a list of strings to be passed literally to the new program.
|
|
In <code>posix</code> environments, this list becomes the array supplied as the second
|
|
parameter to the execv() or execvp() system call, each list element becoming
|
|
one array element. The strings should not contain shell escaping, as there is
|
|
no shell involvement. Further note that while conventionally the process
|
|
receives its own pathname in argv[0], that is automatic, and the 0th string
|
|
should not be present in <code>args</code>.
|
|
</p>
|
|
<p>The program arguments and the environment are encoded using the
|
|
default external format for streams.
|
|
</p>
|
|
<p><code>run-program</code> will return a <code>process</code> structure. See the <code>cmu</code> Common Lisp
|
|
Users Manual for details about the <code>process</code> structure.
|
|
</p>
|
|
<p>Notes about Unix environments (as in the <code>:environment</code> and <code>:env</code> args)<code>:</code>
|
|
</p>
|
|
<ul>
|
|
<li> The <code>sbcl</code> implementation of <code>run-program</code>, like Perl and many other
|
|
programs, but unlike the original <code>cmu</code> <code>cl</code> implementation, copies
|
|
the Unix environment by default.
|
|
</li><li> Running Unix programs from a setuid process, or in any other
|
|
situation where the Unix environment is under the control of someone
|
|
else, is a mother lode of security problems. If you are contemplating
|
|
doing this, read about it first. (The Perl community has a lot of good
|
|
documentation about this and other security issues in script-like
|
|
programs.)
|
|
|
|
</li></ul>
|
|
|
|
<dl compact="compact">
|
|
<dt><em>The <code>&key</code> arguments have the following meanings:</em></dt>
|
|
<dt><em><code>:environment</code></em></dt>
|
|
<dd><p>a list of STRINGs describing the new Unix environment
|
|
(as in "man environ"). The default is to copy the environment of
|
|
the current process.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:env</code></em></dt>
|
|
<dd><p>an alternative lossy representation of the new Unix environment,
|
|
for compatibility with <code>cmu</code> <code>cl</code>
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:search</code></em></dt>
|
|
<dd><p>Look for <code>program</code> in each of the directories in the child’s $PATH
|
|
environment variable. Otherwise an absolute pathname is required.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:wait</code></em></dt>
|
|
<dd><p>If non-NIL (default), wait until the created process finishes. If
|
|
<code>nil</code>, continue running Lisp until the program finishes.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:pty</code> (not supported on win32)</em></dt>
|
|
<dd><p>Either <code>t</code>, <code>nil</code>, or a stream. Unless <code>nil</code>, the subprocess is established
|
|
under a <code>pty</code>. If :pty is a stream, all output to this pty is sent to
|
|
this stream, otherwise the <code>process-pty</code> slot is filled in with a stream
|
|
connected to pty that can read output and write input.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:input</code></em></dt>
|
|
<dd><p>Either <code>t</code>, <code>nil</code>, a pathname, a stream, or <code>:stream</code>.
|
|
<code>t:</code> the standard input for the current process is inherited.
|
|
<code>nil:</code> /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.
|
|
<code>:stream:</code> the <code>process-input</code> slot is filled in with a stream that sends
|
|
its output to the process.
|
|
Defaults to <code>nil</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:if-input-does-not-exist</code> (when <code>:input</code> is the name of a file)</em></dt>
|
|
<dd><p>can be one of:
|
|
<code>:error</code> to generate an error
|
|
<code>:create</code> to create an empty file
|
|
<code>nil</code> (the default) to return <code>nil</code> from <code>run-program</code>
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:output</code></em></dt>
|
|
<dd><p>Either <code>t</code>, <code>nil</code>, a pathname, a stream, or <code>:stream</code>.
|
|
<code>t:</code> the standard output for the current process is inherited.
|
|
<code>nil:</code> /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.
|
|
<code>:stream:</code> the <code>process-output</code> slot is filled in with a stream that can be
|
|
read to get the output.
|
|
Defaults to <code>nil</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:error</code></em></dt>
|
|
<dd><p>Same as <code>:output</code>, additionally accepts <code>:output</code>, making all error
|
|
output routed to the same place as normal output.
|
|
Defaults to <code>:output</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:if-output-exists</code> (when <code>:output</code> is the name of a file)</em></dt>
|
|
<dd><p>can be one of:
|
|
<code>:error</code> (the default) to generate an error
|
|
<code>:supersede</code> to supersede the file with output from the program
|
|
<code>:append</code> to append output from the program to the file
|
|
<code>nil</code> to return <code>nil</code> from <code>run-program</code>, without doing anything
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:if-error-exists</code></em></dt>
|
|
<dd><p>Same as <code>:if-output-exists</code>, controlling <code>:error</code> output to files.
|
|
Ignored when <code>:error</code> <code>:output</code>.
|
|
Defaults to <code>:error</code>.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:status-hook</code></em></dt>
|
|
<dd><p>This is a function the system calls whenever the status of the
|
|
process changes. The function takes the process as an argument.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:external-format</code></em></dt>
|
|
<dd><p>The external-format to use for <code>:input</code>, <code>:output</code>, and <code>:error</code> :STREAMs.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:directory</code></em></dt>
|
|
<dd><p>Specifies the directory in which the program should be run.
|
|
<code>nil</code> (the default) means the directory is unchanged.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:preserve-fds</code></em></dt>
|
|
<dd><p>A sequence of file descriptors which should remain open in the child
|
|
process.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em>Windows specific options:</em></dt>
|
|
<dt><em><code>:escape-arguments</code> (default <code>t</code>)</em></dt>
|
|
<dd><p>Controls escaping of the arguments passed to CreateProcess.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:window</code> (default <code>nil</code>)</em></dt>
|
|
<dd><p>When <code>nil</code>, the subprocess decides how it will display its window. The
|
|
following options control how the subprocess window should be displayed:
|
|
<code>:hide</code>, <code>:show-normal</code>, <code>:show-maximized</code>, <code>:show-minimized</code>, <code>:show-no-activate</code>,
|
|
<code>:show-min-no-active</code>, <code>:show-na</code>.
|
|
Note: console application subprocesses may or may not display a console
|
|
window depending on whether the <code>sbcl</code> runtime is itself a console or <code>gui</code>
|
|
application. Invoke <code>cmd</code> /C <code>start</code> to consistently display a console window
|
|
or use the <code>:window</code> <code>:hide</code> option to consistently hide the console window.
|
|
</p></dd>
|
|
</dl>
|
|
|
|
</dd></dl>
|
|
|
|
<p>When <code>sb-ext:run-program</code> is called with <code>wait</code> equal to
|
|
NIL, an instance of class <var>sb-ext:process</var> is returned. The
|
|
following functions are available for use with processes:
|
|
</p>
|
|
<span id="Function-sb_002dext-process_002dp"></span><dl>
|
|
<dt id="index-process_002dp">Function: <strong>process-p</strong> <em>[sb-ext] object</em></dt>
|
|
<dd><p><code>t</code> if <code>object</code> is a <code>process</code>, <code>nil</code> otherwise.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dinput"></span><dl>
|
|
<dt id="index-process_002dinput">Function: <strong>process-input</strong> <em>[sb-ext] instance</em></dt>
|
|
<dd><p>The input stream of the process or <code>nil</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002doutput"></span><dl>
|
|
<dt id="index-process_002doutput">Function: <strong>process-output</strong> <em>[sb-ext] instance</em></dt>
|
|
<dd><p>The output stream of the process or <code>nil</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002derror"></span><dl>
|
|
<dt id="index-process_002derror">Function: <strong>process-error</strong> <em>[sb-ext] instance</em></dt>
|
|
<dd><p>The error stream of the process or <code>nil</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dalive_002dp"></span><dl>
|
|
<dt id="index-process_002dalive_002dp">Function: <strong>process-alive-p</strong> <em>[sb-ext] process</em></dt>
|
|
<dd><p>Return <code>t</code> if <code>process</code> is still alive, <code>nil</code> otherwise.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dstatus"></span><dl>
|
|
<dt id="index-process_002dstatus">Function: <strong>process-status</strong> <em>[sb-ext] process</em></dt>
|
|
<dd><p>Return the current status of <code>process</code>. The result is one of <code>:running</code>,
|
|
<code>:stopped</code>, <code>:exited</code>, or <code>:signaled</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dwait"></span><dl>
|
|
<dt id="index-process_002dwait">Function: <strong>process-wait</strong> <em>[sb-ext] process &optional check-for-stopped</em></dt>
|
|
<dd><p>Wait for <code>process</code> to quit running for some reason. When
|
|
<code>check-for-stopped</code> is <code>t</code>, also returns when <code>process</code> is stopped. Returns
|
|
<code>process</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dexit_002dcode"></span><dl>
|
|
<dt id="index-process_002dexit_002dcode">Function: <strong>process-exit-code</strong> <em>[sb-ext] process</em></dt>
|
|
<dd><p>The exit code or the signal of a stopped process.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dcore_002ddumped"></span><dl>
|
|
<dt id="index-process_002dcore_002ddumped">Function: <strong>process-core-dumped</strong> <em>[sb-ext] instance</em></dt>
|
|
<dd><p><code>t</code> if a core image was dumped by the process.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dclose"></span><dl>
|
|
<dt id="index-process_002dclose">Function: <strong>process-close</strong> <em>[sb-ext] process</em></dt>
|
|
<dd><p>Close all streams connected to <code>process</code> and stop maintaining the
|
|
status slot.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-process_002dkill"></span><dl>
|
|
<dt id="index-process_002dkill">Function: <strong>process-kill</strong> <em>[sb-ext] process signal &optional whom</em></dt>
|
|
<dd><p>Hand <code>signal</code> to <code>process</code>. If <code>whom</code> is <code>:pid</code>, use the kill Unix system call. If
|
|
<code>whom</code> is <code>:process-group</code>, use the killpg Unix system call. If <code>whom</code> is
|
|
<code>:pty-process-group</code> deliver the signal to whichever process group is
|
|
currently in the foreground.
|
|
Returns <code>t</code> if successful, otherwise returns <code>nil</code> and error number (two values).
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Unicode-Support"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Customization-Hooks-for-Users" accesskey="n" rel="next">Customization Hooks for Users</a>, Previous: <a href="index.html#Support-For-Unix" accesskey="p" rel="prev">Support For Unix</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Unicode-Support-1"></span><h3 class="section">7.8 Unicode Support</h3>
|
|
<span id="index-Unicode-1"></span>
|
|
|
|
<p>SBCL provides support for working with Unicode text and querying the
|
|
standard Unicode database for information about individual codepoints.
|
|
Unicode-related functions are located in the <code>sb-unicode</code> package.
|
|
</p>
|
|
<span id="index-Character-Names"></span>
|
|
<span id="index-Name_002c-of-character"></span>
|
|
<span id="index-name_002dchar-_005bcl_005d"></span>
|
|
<span id="index-char_002dname-_005bcl_005d"></span>
|
|
<p>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 <a id="DOCF8" href="index.html#FOOT8"><sup>8</sup></a> 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”).
|
|
</p>
|
|
<p>For example, you can specify the codepoint U+00E1 (“Latin
|
|
Small Letter A With Acute”) as
|
|
</p><ul>
|
|
<li> <code>#\LATIN_SMALL_LETTER_A_WITH_ACUTE</code>
|
|
</li><li> <code>#\LATIN_SMALL_LETTER_A_ACUTE</code>
|
|
</li><li> <code>#\á</code> assuming a Unicode source file
|
|
</li><li> <code>#\U00E1</code>
|
|
</li><li> <code>#\UE1</code>
|
|
</li><li> <code>#\U+00E1</code>
|
|
</li></ul>
|
|
|
|
<span id="Unicode-property-access"></span><h4 class="subsection">7.8.1 Unicode property access</h4>
|
|
|
|
<p>The following functions can be used to find information about a Unicode
|
|
codepoint.
|
|
</p>
|
|
<span id="Function-sb_002dunicode-general_002dcategory"></span><dl>
|
|
<dt id="index-general_002dcategory">Function: <strong>general-category</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the general category of <code>character</code> as it appears in UnicodeData.txt
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-bidi_002dclass"></span><dl>
|
|
<dt id="index-bidi_002dclass">Function: <strong>bidi-class</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the bidirectional class of <code>character</code>
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-combining_002dclass"></span><dl>
|
|
<dt id="index-combining_002dclass">Function: <strong>combining-class</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the canonical combining class (<code>ccc</code>) of <code>character</code>
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-decimal_002dvalue"></span><dl>
|
|
<dt id="index-decimal_002dvalue">Function: <strong>decimal-value</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the decimal digit value associated with <code>character</code> or <code>nil</code> if
|
|
there is no such value.
|
|
</p>
|
|
<p>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
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-digit_002dvalue"></span><dl>
|
|
<dt id="index-digit_002dvalue">Function: <strong>digit-value</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the Unicode digit value of <code>character</code> or <code>nil</code> if it doesn’t exist.
|
|
</p>
|
|
<p>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
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-numeric_002dvalue"></span><dl>
|
|
<dt id="index-numeric_002dvalue">Function: <strong>numeric-value</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the numeric value of <code>character</code> or <code>nil</code> 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.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-mirrored_002dp"></span><dl>
|
|
<dt id="index-mirrored_002dp">Function: <strong>mirrored-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> needs to be mirrored in bidirectional text.
|
|
Otherwise, returns <code>nil</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-bidi_002dmirroring_002dglyph"></span><dl>
|
|
<dt id="index-bidi_002dmirroring_002dglyph">Function: <strong>bidi-mirroring-glyph</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the mirror image of <code>character</code> if it exists.
|
|
Otherwise, returns <code>nil</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-age"></span><dl>
|
|
<dt id="index-age">Function: <strong>age</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the version of Unicode in which <code>character</code> was assigned as a pair
|
|
of values, both integers, representing the major and minor version respectively.
|
|
If <code>character</code> is not assigned in Unicode, returns <code>nil</code> for both values.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-hangul_002dsyllable_002dtype"></span><dl>
|
|
<dt id="index-hangul_002dsyllable_002dtype">Function: <strong>hangul-syllable-type</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the Hangul syllable type of <code>character</code>.
|
|
The syllable type can be one of <code>:l</code>, <code>:v</code>, <code>:t</code>, <code>:lv</code>, or <code>:lvt</code>.
|
|
If the character is not a Hangul syllable or Jamo, returns <code>nil</code>
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-east_002dasian_002dwidth"></span><dl>
|
|
<dt id="index-east_002dasian_002dwidth">Function: <strong>east-asian-width</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the East Asian Width property of <code>character</code> as
|
|
one of the keywords <code>:n</code> (Narrow), <code>:a</code> (Ambiguous), <code>:h</code> (Halfwidth),
|
|
<code>:w</code> (Wide), <code>:f</code> (Fullwidth), or <code>:na</code> (Not applicable)
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-script"></span><dl>
|
|
<dt id="index-script">Function: <strong>script</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the Script property of <code>character</code> as a keyword.
|
|
If <code>character</code> does not have a known script, returns <code>:unknown</code>
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-char_002dblock"></span><dl>
|
|
<dt id="index-char_002dblock">Function: <strong>char-block</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the Unicode block in which <code>character</code> resides as a keyword.
|
|
If <code>character</code> does not have a known block, returns <code>:no-block</code>
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-unicode_002d1_002dname"></span><dl>
|
|
<dt id="index-unicode_002d1_002dname">Function: <strong>unicode-1-name</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns the name assigned to <code>character</code> in Unicode 1.0 if it is distinct
|
|
from the name currently assigned to <code>character</code>. Otherwise, returns <code>nil</code>.
|
|
This property has been officially obsoleted by the Unicode standard, and
|
|
is only included for backwards compatibility.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-proplist_002dp"></span><dl>
|
|
<dt id="index-proplist_002dp">Function: <strong>proplist-p</strong> <em>[sb-unicode] character property</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> has the specified <code>property</code>.
|
|
<code>property</code> is a keyword representing one of the properties from PropList.txt,
|
|
with underscores replaced by dashes.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-uppercase_002dp"></span><dl>
|
|
<dt id="index-uppercase_002dp">Function: <strong>uppercase-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> has the Unicode property Uppercase and <code>nil</code> otherwise
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-lowercase_002dp"></span><dl>
|
|
<dt id="index-lowercase_002dp">Function: <strong>lowercase-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> has the Unicode property Lowercase and <code>nil</code> otherwise
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-cased_002dp"></span><dl>
|
|
<dt id="index-cased_002dp">Function: <strong>cased-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> has a (Unicode) case, and <code>nil</code> otherwise
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-case_002dignorable_002dp"></span><dl>
|
|
<dt id="index-case_002dignorable_002dp">Function: <strong>case-ignorable-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> is Case Ignorable as defined in Unicode 6.3, Chapter
|
|
3
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-alphabetic_002dp"></span><dl>
|
|
<dt id="index-alphabetic_002dp">Function: <strong>alphabetic-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> is Alphabetic according to the Unicode standard
|
|
and <code>nil</code> otherwise
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-ideographic_002dp"></span><dl>
|
|
<dt id="index-ideographic_002dp">Function: <strong>ideographic-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> has the Unicode property Ideographic,
|
|
which loosely corresponds to the set of "Chinese characters"
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-math_002dp"></span><dl>
|
|
<dt id="index-math_002dp">Function: <strong>math-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> is a mathematical symbol according to Unicode and
|
|
<code>nil</code> otherwise
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-whitespace_002dp"></span><dl>
|
|
<dt id="index-whitespace_002dp">Function: <strong>whitespace-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> is whitespace according to Unicode
|
|
and <code>nil</code> otherwise
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-soft_002ddotted_002dp"></span><dl>
|
|
<dt id="index-soft_002ddotted_002dp">Function: <strong>soft-dotted-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> has a soft dot (such as the dots on i and j) which
|
|
disappears when accents are placed on top of it. and <code>nil</code> otherwise
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-hex_002ddigit_002dp"></span><dl>
|
|
<dt id="index-hex_002ddigit_002dp">Function: <strong>hex-digit-p</strong> <em>[sb-unicode] character &key ascii</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> is a hexadecimal digit and <code>nil</code> otherwise.
|
|
If <code>:ascii</code> is non-NIL, fullwidth equivalents of the Latin letters A through <code>f</code>
|
|
are excluded.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-default_002dignorable_002dp"></span><dl>
|
|
<dt id="index-default_002dignorable_002dp">Function: <strong>default-ignorable-p</strong> <em>[sb-unicode] character</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>character</code> is a Default_Ignorable_Code_Point
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-grapheme_002dbreak_002dclass"></span><dl>
|
|
<dt id="index-grapheme_002dbreak_002dclass">Function: <strong>grapheme-break-class</strong> <em>[sb-unicode] char</em></dt>
|
|
<dd><p>Returns the grapheme breaking class of <code>character</code>, as specified in <code>uax</code> #29.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-word_002dbreak_002dclass"></span><dl>
|
|
<dt id="index-word_002dbreak_002dclass">Function: <strong>word-break-class</strong> <em>[sb-unicode] char</em></dt>
|
|
<dd><p>Returns the word breaking class of <code>character</code>, as specified in <code>uax</code> #29.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-sentence_002dbreak_002dclass"></span><dl>
|
|
<dt id="index-sentence_002dbreak_002dclass">Function: <strong>sentence-break-class</strong> <em>[sb-unicode] char</em></dt>
|
|
<dd><p>Returns the sentence breaking class of <code>character</code>, as specified in <code>uax</code> #29.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-line_002dbreak_002dclass"></span><dl>
|
|
<dt id="index-line_002dbreak_002dclass">Function: <strong>line-break-class</strong> <em>[sb-unicode] character &key resolve</em></dt>
|
|
<dd><p>Returns the line breaking class of <code>character</code>, as specified in <code>uax</code> #14.
|
|
If <code>:resolve</code> is <code>nil</code>, returns the character class found in the property file.
|
|
If <code>:resolve</code> is non-NIL, certain line-breaking classes will be mapped to other
|
|
classes as specified in the applicable standards. Additionally, if <code>:resolve</code>
|
|
is <code>:east-asian</code>, Ambigious (class <code>:ai</code>) characters will be mapped to the
|
|
Ideographic (<code>:id</code>) class instead of Alphabetic (<code>:al</code>).
|
|
</p></dd></dl>
|
|
|
|
<span id="String-operations"></span><h4 class="subsection">7.8.2 String operations</h4>
|
|
<span id="index-Normalization_002c-String"></span>
|
|
|
|
<p>SBCL can normalize strings using:
|
|
</p>
|
|
<span id="Function-sb_002dunicode-normalize_002dstring"></span><dl>
|
|
<dt id="index-normalize_002dstring">Function: <strong>normalize-string</strong> <em>[sb-unicode] string &optional form filter</em></dt>
|
|
<dd><p>Normalize <code>string</code> to the Unicode normalization form form.
|
|
Acceptable values for form are <code>:nfd</code>, <code>:nfc</code>, <code>:nfkd</code>, and <code>:nfkc</code>.
|
|
If <code>filter</code> is a function it is called on each decomposed character and
|
|
only characters for which it returns <code>t</code> are collected.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-normalized_002dp"></span><dl>
|
|
<dt id="index-normalized_002dp">Function: <strong>normalized-p</strong> <em>[sb-unicode] string &optional form</em></dt>
|
|
<dd><p>Tests if <code>string</code> is normalized to <code>form</code>
|
|
</p></dd></dl>
|
|
|
|
<p>SBCL implements the full range of Unicode case operations with the
|
|
functions
|
|
</p>
|
|
<span id="Function-sb_002dunicode-uppercase"></span><dl>
|
|
<dt id="index-uppercase">Function: <strong>uppercase</strong> <em>[sb-unicode] string &key locale</em></dt>
|
|
<dd><p>Returns the full uppercase of <code>string</code> according to the Unicode standard.
|
|
The result is not guaranteed to have the same length as the input. If <code>:locale</code>
|
|
is <code>nil</code>, no language-specific case transformations are applied. If <code>:locale</code> is a
|
|
keyword representing a two-letter <code>iso</code> country code, the case transforms of that
|
|
locale are used. If <code>:locale</code> is <code>t</code>, the user’s current locale is used (Unix and
|
|
Win32 only).
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-lowercase"></span><dl>
|
|
<dt id="index-lowercase">Function: <strong>lowercase</strong> <em>[sb-unicode] string &key locale</em></dt>
|
|
<dd><p>Returns the full lowercase of <code>string</code> according to the Unicode standard.
|
|
The result is not guaranteed to have the same length as the input.
|
|
<code>:locale</code> has the same semantics as the <code>:locale</code> argument to <code>uppercase</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-titlecase"></span><dl>
|
|
<dt id="index-titlecase">Function: <strong>titlecase</strong> <em>[sb-unicode] string &key locale</em></dt>
|
|
<dd><p>Returns the titlecase of <code>string</code>. The resulting string can
|
|
be longer than the input.
|
|
<code>:locale</code> has the same semantics as the <code>:locale</code> argument to <code>uppercase</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-casefold"></span><dl>
|
|
<dt id="index-casefold">Function: <strong>casefold</strong> <em>[sb-unicode] string</em></dt>
|
|
<dd><p>Returns the full casefolding of <code>string</code> 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.
|
|
</p></dd></dl>
|
|
|
|
<span id="index-string_002dupcase-_005bcl_005d"></span>
|
|
<span id="index-char_002ddowncase-_005bcl_005d"></span>
|
|
<span id="index-both_002dcase_002dp-_005bcl_005d"></span>
|
|
<p>It also extends standard Common Lisp case functions such as
|
|
<code>string-upcase</code> and <code>string-downcase</code> to support a subset of
|
|
Unicode’s casing behavior. Specifically, a character is
|
|
<code>both-case-p</code> if its case mapping in Unicode is one-to-one and
|
|
invertable.
|
|
</p>
|
|
<p>The <code>sb-unicode</code> package also provides functions for
|
|
collating/sorting strings according to the Unicode Collation Algorithm.
|
|
</p>
|
|
<span id="Function-sb_002dunicode-unicode_003c"></span><dl>
|
|
<dt id="index-unicode_003c">Function: <strong>unicode<</strong> <em>[sb-unicode] string1 string2 &key start1 end1 start2 end2</em></dt>
|
|
<dd><p>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 <code>uts</code> #10
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-unicode_003d"></span><dl>
|
|
<dt id="index-unicode_003d">Function: <strong>unicode=</strong> <em>[sb-unicode] string1 string2 &key start1 end1 start2 end2 strict</em></dt>
|
|
<dd><p>Determines whether STRING1 and STRING2 are canonically equivalent according
|
|
to Unicode. The <code>start</code> and <code>end</code> arguments behave like the arguments to STRING=.
|
|
If <code>:strict</code> is <code>nil</code>, UNICODE= tests compatibility equavalence instead.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-unicode_002dequal"></span><dl>
|
|
<dt id="index-unicode_002dequal">Function: <strong>unicode-equal</strong> <em>[sb-unicode] string1 string2 &key start1 end1 start2 end2 strict</em></dt>
|
|
<dd><p>Determines whether STRING1 and STRING2 are canonically equivalent after
|
|
casefolding (that is, ignoring case differences) according to Unicode. The
|
|
<code>start</code> and <code>end</code> arguments behave like the arguments to STRING=. If <code>:strict</code> is
|
|
<code>nil</code>, UNICODE= tests compatibility equavalence instead.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-unicode_003c_003d"></span><dl>
|
|
<dt id="index-unicode_003c_003d">Function: <strong>unicode<=</strong> <em>[sb-unicode] string1 string2 &key start1 end1 start2 end2</em></dt>
|
|
<dd><p>Tests if STRING1 and STRING2 are either UNICODE< or UNICODE=
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-unicode_003e"></span><dl>
|
|
<dt id="index-unicode_003e">Function: <strong>unicode></strong> <em>[sb-unicode] string1 string2 &key start1 end1 start2 end2</em></dt>
|
|
<dd><p>Tests if STRING2 is UNICODE< STRING1.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-unicode_003e_003d"></span><dl>
|
|
<dt id="index-unicode_003e_003d">Function: <strong>unicode>=</strong> <em>[sb-unicode] string1 string2 &key start1 end1 start2 end2</em></dt>
|
|
<dd><p>Tests if STRING1 and STRING2 are either UNICODE= or UNICODE>
|
|
</p></dd></dl>
|
|
|
|
<p>The following functions are provided for detecting visually confusable strings:
|
|
</p>
|
|
<span id="Function-sb_002dunicode-confusable_002dp"></span><dl>
|
|
<dt id="index-confusable_002dp">Function: <strong>confusable-p</strong> <em>[sb-unicode] string1 string2 &key start1 end1 start2 end2</em></dt>
|
|
<dd><p>Determines whether STRING1 and STRING2 could be visually confusable
|
|
according to the <code>idna</code> confusableSummary.txt table
|
|
</p></dd></dl>
|
|
|
|
<span id="Breaking-strings"></span><h4 class="subsection">7.8.3 Breaking strings</h4>
|
|
|
|
<p>The <code>sb-unicode</code> package includes several functions for breaking a
|
|
Unicode string into useful parts.
|
|
</p>
|
|
<span id="Function-sb_002dunicode-graphemes"></span><dl>
|
|
<dt id="index-graphemes">Function: <strong>graphemes</strong> <em>[sb-unicode] string</em></dt>
|
|
<dd><p>Breaks <code>string</code> into graphemes according to the default
|
|
grapheme breaking rules specified in <code>uax</code> #29, returning a list of strings.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-words"></span><dl>
|
|
<dt id="index-words">Function: <strong>words</strong> <em>[sb-unicode] string</em></dt>
|
|
<dd><p>Breaks <code>string</code> into words according to the default
|
|
word breaking rules specified in <code>uax</code> #29. Returns a list of strings
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-sentences"></span><dl>
|
|
<dt id="index-sentences">Function: <strong>sentences</strong> <em>[sb-unicode] string</em></dt>
|
|
<dd><p>Breaks <code>string</code> into sentences according to the default
|
|
sentence breaking rules specified in <code>uax</code> #29
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dunicode-lines"></span><dl>
|
|
<dt id="index-lines">Function: <strong>lines</strong> <em>[sb-unicode] string &key margin</em></dt>
|
|
<dd><p>Breaks <code>string</code> into lines that are no wider than <code>:margin</code> according to the
|
|
line breaking rules outlined in <code>uax</code> #14. Combining marks will always be kept
|
|
together with their base characters, and spaces (but not other types of
|
|
whitespace) will be removed from the end of lines. If <code>:margin</code> is unspecified,
|
|
it defaults to 80 characters
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Customization-Hooks-for-Users"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Tools-To-Help-Developers" accesskey="n" rel="next">Tools To Help Developers</a>, Previous: <a href="index.html#Unicode-Support" accesskey="p" rel="prev">Unicode Support</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Customization-Hooks-for-Users-1"></span><h3 class="section">7.9 Customization Hooks for Users</h3>
|
|
|
|
<p>The toplevel repl prompt may be customized, and the function
|
|
that reads user input may be replaced completely.
|
|
</p>
|
|
<p>The behaviour of <code>require</code> when called with only one argument is
|
|
implementation-defined. In SBCL, <code>require</code> behaves in the
|
|
following way:
|
|
</p>
|
|
<span id="Function-common_002dlisp-require"></span><dl>
|
|
<dt id="index-require">Function: <strong>require</strong> <em>[cl] module-name &optional pathnames</em></dt>
|
|
<dd><p>Loads a module, unless it already has been loaded. <code>pathnames</code>, if supplied,
|
|
is a designator for a list of pathnames to be loaded if the module
|
|
needs to be. If <code>pathnames</code> is not supplied, functions from the list
|
|
<code>*module-provider-functions*</code> are called in order with <code>module-name</code>
|
|
as an argument, until one of them returns non-NIL. User code is
|
|
responsible for calling <code>provide</code> to indicate a successful load of the
|
|
module.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002dext-_002amodule_002dprovider_002dfunctions_002a"></span><dl>
|
|
<dt id="index-_002amodule_002dprovider_002dfunctions_002a">Variable: <strong>*module-provider-functions*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>See function documentation for <code>require</code>.
|
|
</p></dd></dl>
|
|
|
|
<p>Although SBCL does not provide a resident editor, the <code>ed</code>
|
|
function can be customized to hook into user-provided editing
|
|
mechanisms as follows:
|
|
</p>
|
|
<span id="Function-common_002dlisp-ed"></span><dl>
|
|
<dt id="index-ed">Function: <strong>ed</strong> <em>[cl] &optional x</em></dt>
|
|
<dd><p>Starts the editor (on a file or a function if named). Functions
|
|
from the list <code>*ed-functions*</code> are called in order with <code>x</code> as an argument
|
|
until one of them returns non-NIL; these functions are responsible for
|
|
signalling a <code>file-error</code> to indicate failure to perform an operation on
|
|
the file system.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002dext-_002aed_002dfunctions_002a"></span><dl>
|
|
<dt id="index-_002aed_002dfunctions_002a">Variable: <strong>*ed-functions*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>See function documentation for <code>ed</code>.
|
|
</p></dd></dl>
|
|
|
|
<p>Conditions of type <code>warning</code> and <code>style-warning</code> are
|
|
sometimes signaled at runtime, especially during execution of Common
|
|
Lisp defining forms such as <code>defun</code>, <code>defmethod</code>, etc. To
|
|
muffle these warnings at runtime, SBCL provides a variable
|
|
<code>sb-ext:*muffled-warnings*</code>:
|
|
</p>
|
|
<span id="Variable-sb_002dext-_002amuffled_002dwarnings_002a"></span><dl>
|
|
<dt id="index-_002amuffled_002dwarnings_002a">Variable: <strong>*muffled-warnings*</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>A type that ought to specify a subtype of <code>warning</code>. Whenever a
|
|
warning is signaled, if the warning is of this type and is not
|
|
handled by any other handler, it will be muffled.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Tools-To-Help-Developers"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Resolution-of-Name-Conflicts" accesskey="n" rel="next">Resolution of Name Conflicts</a>, Previous: <a href="index.html#Customization-Hooks-for-Users" accesskey="p" rel="prev">Customization Hooks for Users</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Tools-To-Help-Developers-1"></span><h3 class="section">7.10 Tools To Help Developers</h3>
|
|
<span id="index-trace-_005bcl_005d"></span>
|
|
<span id="index-inspect-_005bcl_005d"></span>
|
|
|
|
<p>SBCL provides a profiler and other extensions to the ANSI <code>trace</code>
|
|
facility. For more information, see <a href="index.html#Macro-common_002dlisp-trace">Macro common-lisp trace</a>.
|
|
</p>
|
|
<p>The debugger supports a number of options. Its documentation is
|
|
accessed by typing <kbd>help</kbd> at the debugger prompt. See <a href="index.html#Debugger">Debugger</a>.
|
|
</p>
|
|
<p>Documentation for <code>inspect</code> is accessed by typing <kbd>help</kbd> at
|
|
the <code>inspect</code> prompt.
|
|
</p>
|
|
<hr>
|
|
<span id="Resolution-of-Name-Conflicts"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Hash-Table-Extensions" accesskey="n" rel="next">Hash Table Extensions</a>, Previous: <a href="index.html#Tools-To-Help-Developers" accesskey="p" rel="prev">Tools To Help Developers</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Resolution-of-Name-Conflicts-1"></span><h3 class="section">7.11 Resolution of Name Conflicts</h3>
|
|
<span id="index-name_002dconflict-_005bsb_002dext_005d"></span>
|
|
<span id="index-name_002dconflict_002dsymbols-_005bsb_002dext_005d"></span>
|
|
|
|
<p>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 <code>sb-ext:resolve-conflict</code> restart should be invoked with one
|
|
argument, which should be a member of the list returned by the condition
|
|
accessor <code>sb-ext:name-conflict-symbols</code>.
|
|
</p>
|
|
<hr>
|
|
<span id="Hash-Table-Extensions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Random-Number-Generation" accesskey="n" rel="next">Random Number Generation</a>, Previous: <a href="index.html#Resolution-of-Name-Conflicts" accesskey="p" rel="prev">Resolution of Name Conflicts</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Hash-Table-Extensions-1"></span><h3 class="section">7.12 Hash Table Extensions</h3>
|
|
<span id="index-Hash-tables"></span>
|
|
|
|
<p>Hash table extensions supported by SBCL are all controlled by keyword
|
|
arguments to <code>make-hash-table</code>.
|
|
</p>
|
|
<span id="Function-common_002dlisp-make_002dhash_002dtable"></span><dl>
|
|
<dt id="index-make_002dhash_002dtable">Function: <strong>make-hash-table</strong> <em>[cl] &key test size rehash-size rehash-threshold hash-function weakness synchronized</em></dt>
|
|
<dd><p>Create and return a new hash table. The keywords are as follows:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:test</code></em></dt>
|
|
<dd><p>Determines how keys are compared. Must a designator for one of the
|
|
standard hash table tests, or a hash table test defined using
|
|
<code>sb-ext:define-hash-table-test</code>. Additionally, when an explicit
|
|
<code>hash-function</code> is provided (see below), any two argument equivalence
|
|
predicate can be used as the <code>test</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:size</code></em></dt>
|
|
<dd><p>A hint as to how many elements will be put in this hash table.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:rehash-size</code></em></dt>
|
|
<dd><p>Indicates how to expand the table when it fills up. If an integer, add
|
|
space for that many elements. If a floating point number (which must be
|
|
greater than 1.0), multiply the size by that amount.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:rehash-threshold</code></em></dt>
|
|
<dd><p>Indicates how dense the table can become before forcing a rehash. Can be
|
|
any positive number <=1, with density approaching zero as the threshold
|
|
approaches 0. Density 1 means an average of one entry per bucket.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:hash-function</code></em></dt>
|
|
<dd><p>If unsupplied, a hash function based on the <code>test</code> argument is used,
|
|
which then must be one of the standardized hash table test functions, or
|
|
one for which a default hash function has been defined using
|
|
<code>sb-ext:define-hash-table-test</code>. If <code>hash-function</code> is specified, the <code>test</code>
|
|
argument can be any two argument predicate consistent with it. The
|
|
<code>hash-function</code> is expected to return a non-negative fixnum hash code.
|
|
If <code>test</code> is neither standard nor defined by <code>define-hash-table-test</code>,
|
|
then the <code>hash-function</code> must be specified.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:weakness</code></em></dt>
|
|
<dd><p>When <code>:weakness</code> is not <code>nil</code>, garbage collection may remove entries from the
|
|
hash table. The value of <code>:weakness</code> specifies how the presence of a key or
|
|
value in the hash table preserves their entries from garbage collection.
|
|
</p>
|
|
<p>Valid values are:
|
|
</p>
|
|
<p><code>:key</code> means that the key of an entry must be live to guarantee that the
|
|
entry is preserved.
|
|
</p>
|
|
<p><code>:value</code> means that the value of an entry must be live to guarantee that
|
|
the entry is preserved.
|
|
</p>
|
|
<p><code>:key-and-value</code> means that both the key and the value must be live to
|
|
guarantee that the entry is preserved.
|
|
</p>
|
|
<p><code>:key-or-value</code> means that either the key or the value must be live to
|
|
guarantee that the entry is preserved.
|
|
</p>
|
|
<p><code>nil</code> (the default) means that entries are always preserved.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:synchronized</code></em></dt>
|
|
<dd><p>If <code>nil</code> (the default), the hash-table may have multiple concurrent readers,
|
|
but results are undefined if a thread writes to the hash-table
|
|
concurrently with another reader or writer. If <code>t</code>, all concurrent accesses
|
|
are safe, but note that <code>clhs</code> 3.6 (Traversal Rules and Side Effects)
|
|
remains in force. See also: <code>sb-ext:with-locked-hash-table</code>.
|
|
</p></dd>
|
|
</dl>
|
|
|
|
</dd></dl>
|
|
|
|
<span id="Macro-sb_002dext-define_002dhash_002dtable_002dtest"></span><dl>
|
|
<dt id="index-define_002dhash_002dtable_002dtest">Macro: <strong>define-hash-table-test</strong> <em>[sb-ext] name hash-function</em></dt>
|
|
<dd><p>Defines <code>name</code> as a new kind of hash table test for use with the <code>:test</code>
|
|
argument to <code>make-hash-table</code>, and associates a default <code>hash-function</code> with it.
|
|
</p>
|
|
<p><code>name</code> must be a symbol naming a global two argument equivalence predicate.
|
|
Afterwards both <code>'name</code> and <code>#'name</code> can be used with <code>:test</code> argument. In both
|
|
cases <code>hash-table-test</code> will return the symbol <code>name</code>.
|
|
</p>
|
|
<p><code>hash-function</code> must be a symbol naming a global hash function consistent with
|
|
the predicate, or be a <code>lambda</code> form implementing one in the current lexical
|
|
environment. The hash function must compute the same hash code for any two
|
|
objects for which <code>name</code> returns true, and subsequent calls with already hashed
|
|
objects must always return the same hash code.
|
|
</p>
|
|
<p>Note: The <code>:hash-function</code> keyword argument to <code>make-hash-table</code> can be used to
|
|
override the specified default hash-function.
|
|
</p>
|
|
<p>Attempting to define <code>name</code> in a locked package as hash-table test causes a
|
|
package lock violation.
|
|
</p>
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> ;;; 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 '==))
|
|
</pre></div>
|
|
</dd></dl>
|
|
|
|
<span id="Macro-sb_002dext-with_002dlocked_002dhash_002dtable"></span><dl>
|
|
<dt id="index-with_002dlocked_002dhash_002dtable">Macro: <strong>with-locked-hash-table</strong> <em>[sb-ext] (hash-table) &body body</em></dt>
|
|
<dd><p>Limits concurrent accesses to <code>hash-table</code> for the duration of <code>body</code>.
|
|
If <code>hash-table</code> is synchronized, <code>body</code> will execute with exclusive
|
|
ownership of the table. If <code>hash-table</code> is not synchronized, <code>body</code> will
|
|
execute with other <code>with-locked-hash-table</code> bodies excluded <code>--</code> exclusion
|
|
of hash-table accesses not surrounded by <code>with-locked-hash-table</code> is
|
|
unspecified.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-hash_002dtable_002dsynchronized_002dp"></span><dl>
|
|
<dt id="index-hash_002dtable_002dsynchronized_002dp">Function: <strong>hash-table-synchronized-p</strong> <em>[sb-ext] ht</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>hash-table</code> is synchronized.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-hash_002dtable_002dweakness"></span><dl>
|
|
<dt id="index-hash_002dtable_002dweakness">Function: <strong>hash-table-weakness</strong> <em>[sb-ext] ht</em></dt>
|
|
<dd><p>Return the <code>weakness</code> of <code>hash-table</code> which is one of <code>nil</code>, <code>:key</code>,
|
|
<code>:value</code>, <code>:key-and-value</code>, <code>:key-or-value</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Random-Number-Generation"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Timeouts-and-Deadlines" accesskey="n" rel="next">Timeouts and Deadlines</a>, Previous: <a href="index.html#Hash-Table-Extensions" accesskey="p" rel="prev">Hash Table Extensions</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Random-Number-Generation-1"></span><h3 class="section">7.13 Random Number Generation</h3>
|
|
<span id="index-Random-Number-Generation"></span>
|
|
|
|
<span id="index-_002arandom_002dstate_002a-_005bcl_005d"></span>
|
|
<span id="index-make_002drandom_002dstate-_005bcl_005d"></span>
|
|
<p>The initial value of <code>*random-state*</code> is the same each time SBCL
|
|
is started. This makes it possible for user code to obtain repeatable
|
|
pseudo random numbers using only standard-provided functionality. See
|
|
<code>seed-random-state</code> below for an SBCL extension that allows to
|
|
seed the random number generator from given data for an additional
|
|
possibility to achieve this. Non-repeatable random numbers can always
|
|
be obtained using <code>(make-random-state t)</code>.
|
|
</p>
|
|
<span id="index-random-_005bcl_005d"></span>
|
|
<p>The sequence of numbers produced by repeated calls to <code>random</code>
|
|
starting with the same random state and using the same sequence of
|
|
<code>limit</code> arguments is guaranteed to be reproducible only in the
|
|
same version of SBCL on the same platform, using the same code under
|
|
the same evaluator mode and compiler optimization qualities. Just two
|
|
examples of differences that may occur otherwise: calls to
|
|
<code>random</code> can be compiled differently depending on how much is
|
|
known about the <code>limit</code> 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.
|
|
</p>
|
|
<span id="Function-sb_002dext-seed_002drandom_002dstate"></span><dl>
|
|
<dt id="index-seed_002drandom_002dstate">Function: <strong>seed-random-state</strong> <em>[sb-ext] &optional state</em></dt>
|
|
<dd><p>Make a random state object. The optional <code>state</code> argument specifies a seed
|
|
for deterministic pseudo-random number generation.
|
|
</p>
|
|
<p>As per the Common Lisp standard for <code>make-random-state</code>,
|
|
</p><ul>
|
|
<li> If <code>state</code> is <code>nil</code> or not supplied, return a copy of the default
|
|
<code>*random-state*</code>.
|
|
</li><li> If <code>state</code> is a random state, return a copy of it.
|
|
</li><li> If <code>state</code> is <code>t</code>, return a randomly initialized state (using operating-system
|
|
provided randomness where available, otherwise a poor substitute based on
|
|
internal time and pid).
|
|
|
|
</li></ul>
|
|
<p>As a supported <code>sbcl</code> extension, we also support receiving as a seed an object
|
|
of the following types:
|
|
</p><ul>
|
|
<li> (<code>simple-array</code> (<code>unsigned-byte</code> 8) (<code>*</code>))
|
|
</li><li> <code>unsigned-byte</code>
|
|
</li></ul>
|
|
<p>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.
|
|
</p>
|
|
<p>This particular <code>sbcl</code> version also accepts an argument of the following type:
|
|
(<code>simple-array</code> (<code>unsigned-byte</code> 32) (<code>*</code>))
|
|
</p>
|
|
<p>This particular <code>sbcl</code> version uses the popular MT19937 <code>prng</code> 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
|
|
</p></dd></dl>
|
|
|
|
<span id="index-float-_005bcl_005d-1"></span>
|
|
<p>Some notes on random floats: The standard doesn’t prescribe a specific
|
|
method of generating random floats. The following paragraph describes
|
|
SBCL’s current implementation and should be taken as purely
|
|
informational, that is, user code should not depend on any of its
|
|
specific properties. The method used has been chosen because it is
|
|
common, conceptually simple and fast.
|
|
</p>
|
|
<span id="index-expt-_005bcl_005d"></span>
|
|
<span id="index-random-_005bcl_005d-1"></span>
|
|
<p>To generate random floats, SBCL evaluates code that has an equivalent
|
|
effect as
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(* limit
|
|
(float (/ (random (expt 2 23)) (expt 2 23)) 1.0f0))
|
|
</pre></div>
|
|
<p>(for single-floats) and correspondingly (with <code>52</code> and
|
|
<code>1.0d0</code> instead of <code>23</code> and <code>1.0f0</code>) for double-floats.
|
|
Note especially that this means that zero is a possible return value
|
|
occurring with probability <code>(expt 2 -23)</code> respectively
|
|
<code>(expt 2 -52)</code>. Also note that there exist twice as many
|
|
equidistant floats between 0 and 1 as are generated. For example, the
|
|
largest number that <code>(random 1.0f0)</code> ever returns is
|
|
<code>(float (/ (1- (expt 2 23)) (expt 2 23)) 1.0f0)</code> while
|
|
<code>(float (/ (1- (expt 2 24)) (expt 2 24)) 1.0f0)</code> 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.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>While the Mersenne Twister generates random numbers of much better
|
|
statistical quality than other widely used generators, it uses only
|
|
linear operations modulo 2 and thus fails some statistical
|
|
tests<a id="DOCF9" href="index.html#FOOT9"><sup>9</sup></a>.
|
|
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.
|
|
</p>
|
|
<hr>
|
|
<span id="Timeouts-and-Deadlines"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Miscellaneous-Extensions" accesskey="n" rel="next">Miscellaneous Extensions</a>, Previous: <a href="index.html#Random-Number-Generation" accesskey="p" rel="prev">Random Number Generation</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Timeouts-and-Deadlines-1"></span><h3 class="section">7.14 Timeouts and Deadlines</h3>
|
|
|
|
<p>SBCL supports three different ways of restricting the execution time
|
|
available to individual operations or parts of computations:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><strong>Timeout Parameters</strong></dt>
|
|
<dd><p>Some operations such as thread synchronization primitives accept a
|
|
<code>:timeout</code> parameter. See <a href="index.html#Timeout-Parameters">Timeout Parameters</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Synchronous Timeouts (Deadlines)</strong></dt>
|
|
<dd><span id="index-sleep-_005bcl_005d"></span>
|
|
<p>Certain operations that may suspend execution for extended periods of
|
|
time such as <code>cl:sleep</code>, thread synchronization primitives, IO and
|
|
waiting for external processes respect deadlines established for a part
|
|
of a computation. See <a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a>.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Asynchronous Timeouts</strong></dt>
|
|
<dd><p>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 <a href="index.html#Asynchronous-Timeouts">Asynchronous Timeouts</a>.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Timeout-Parameters" accesskey="1">Timeout Parameters</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029" accesskey="2">Synchronous Timeouts (Deadlines)</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Asynchronous-Timeouts" accesskey="3">Asynchronous Timeouts</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Operations-Supporting-Timeouts-and-Deadlines" accesskey="4">Operations Supporting Timeouts and Deadlines</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Timeout-Parameters"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029" accesskey="n" rel="next">Synchronous Timeouts (Deadlines)</a>, Up: <a href="index.html#Timeouts-and-Deadlines" accesskey="u" rel="up">Timeouts and Deadlines</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Timeout-Parameters-1"></span><h4 class="subsection">7.14.1 Timeout Parameters</h4>
|
|
<span id="index-Timeout"></span>
|
|
|
|
<span id="index-join_002dthread_002derror-_005bsb_002dthread_005d"></span>
|
|
<p>Certain operations accept <code>:timeout</code> keyword arguments. These
|
|
only affect the specific operation and must be specified at each call
|
|
site by passing a <code>:timeout</code> keyword argument and a corresponding
|
|
timeout value to the respective operation. Expiration of the timeout
|
|
before the operation completes results in either a normal return with
|
|
a return value indicating the timeout or in the signaling of a
|
|
specialized condition such as <code>sb-thread:join-thread-error</code>.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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))
|
|
</pre></div>
|
|
|
|
<span id="index-join_002dthread-_005bsb_002dthread_005d"></span>
|
|
<p>The above code attempts to join the specified thread for up to five
|
|
seconds, returning its value in case of success. If the thread is
|
|
still running after the five seconds have elapsed,
|
|
<code>sb-thread:join-thread</code> indicates the timeout in its second
|
|
return value. If a <code>:default</code> value was not provided,
|
|
<code>sb-thread:join-thread</code> would signal a
|
|
<code>sb-thread:join-thread-error</code> instead.
|
|
</p>
|
|
<p>To wait for an arbitrary condition, optionally with a timeout, the
|
|
<code>sb-ext:wait-for</code> macro can be used:
|
|
</p>
|
|
<span id="Macro-sb_002dext-wait_002dfor"></span><dl>
|
|
<dt id="index-wait_002dfor">Macro: <strong>wait-for</strong> <em>[sb-ext] test-form &key timeout</em></dt>
|
|
<dd><p>Wait until <code>test-form</code> evaluates to true, then return its primary value.
|
|
If <code>timeout</code> is provided, waits at most approximately <code>timeout</code> seconds before
|
|
returning <code>nil</code>.
|
|
</p>
|
|
<p>If <code>with-deadline</code> has been used to provide a global deadline, signals a
|
|
<code>deadline-timeout</code> if <code>test-form</code> doesn’t evaluate to true before the
|
|
deadline.
|
|
</p>
|
|
<p>Experimental: subject to change without prior notice.
|
|
</p></dd></dl>
|
|
|
|
|
|
<hr>
|
|
<span id="Synchronous-Timeouts-_0028Deadlines_0029"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Asynchronous-Timeouts" accesskey="n" rel="next">Asynchronous Timeouts</a>, Previous: <a href="index.html#Timeout-Parameters" accesskey="p" rel="prev">Timeout Parameters</a>, Up: <a href="index.html#Timeouts-and-Deadlines" accesskey="u" rel="up">Timeouts and Deadlines</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Synchronous-Timeouts-_0028Deadlines_0029-1"></span><h4 class="subsection">7.14.2 Synchronous Timeouts (Deadlines)</h4>
|
|
<span id="index-Timeout-1"></span>
|
|
<span id="index-Synchronous-Timeout"></span>
|
|
<span id="index-Deadline"></span>
|
|
|
|
<p>Deadlines, in contrast to timeout parameters, are established for a
|
|
dynamic scope using the <code>sb-sys:with-deadline</code> 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.
|
|
</p>
|
|
<span id="Macro-sb_002dsys-with_002ddeadline"></span><dl>
|
|
<dt id="index-with_002ddeadline">Macro: <strong>with-deadline</strong> <em>[sb-sys] (&key seconds override) &body body</em></dt>
|
|
<dd><p>Arranges for a <code>timeout</code> 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.
|
|
</p>
|
|
<p>Currently only <code>sleep</code>, blocking <code>io</code> operations, <code>get-mutex</code>, and
|
|
<code>condition-wait</code> respect deadlines, but this includes their implicit
|
|
uses inside <code>sbcl</code> itself.
|
|
</p>
|
|
<p>Unless <code>override</code> is true, existing deadlines can only be restricted,
|
|
not extended. Deadlines are per thread: children are unaffected by
|
|
their parent’s deadlines.
|
|
</p>
|
|
<p>Experimental.
|
|
</p></dd></dl>
|
|
|
|
<p>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 <a href="index.html#Operations-Supporting-Timeouts-and-Deadlines">Operations Supporting Timeouts and Deadlines</a>). In this case, a
|
|
<code>sb-sys:deadline-timeout</code> is signaled. A handler for this condition
|
|
type may use the <code>sb-sys:defer-deadline</code> or
|
|
<code>sb-sys:cancel-deadline</code> restarts to defer or cancel the deadline
|
|
respectively and resume execution of the interrupted operation.
|
|
</p>
|
|
<span id="Condition-sb_002dsys-deadline_002dtimeout"></span><dl>
|
|
<dt id="index-deadline_002dtimeout">Condition: <strong>deadline-timeout</strong> <em>[sb-sys]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">deadline-timeout</span><!-- /@w --></code>, <code>timeout<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Signaled when an operation in the context of a deadline takes
|
|
longer than permitted by the deadline.
|
|
</p></dd></dl>
|
|
|
|
<p>When a thread is executing the debugger, signaling of
|
|
<code>sb-sys:deadline-timeout</code> conditions for that thread is deferred
|
|
until it exits the debugger.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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"))
|
|
</pre></div>
|
|
|
|
<span id="index-read_002dline-_005bcl_005d"></span>
|
|
<span id="index-sleep-_005bcl_005d-1"></span>
|
|
<span id="index-run_002dprogram-_005bsb_002dext_005d"></span>
|
|
<p>The above code establishes a deadline of five seconds within which the
|
|
body of the <code>do-it</code> function should execute. All calls of
|
|
deadline-aware functions in the dynamic scope, in this case two
|
|
<code>read-line</code> calls, a <code>sleep</code> call and a
|
|
<code>sb-ext:run-program</code> call, are affected by the deadline. If, for
|
|
example, the first <code>read-line</code> call completes in one second and the
|
|
second <code>read-line</code> call completes in three seconds, a
|
|
<code>sb-sys:deadline-timeout</code> condition will be signaled after the
|
|
<code>sleep</code> call has been executing for one second.
|
|
</p>
|
|
<hr>
|
|
<span id="Asynchronous-Timeouts"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Operations-Supporting-Timeouts-and-Deadlines" accesskey="n" rel="next">Operations Supporting Timeouts and Deadlines</a>, Previous: <a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029" accesskey="p" rel="prev">Synchronous Timeouts (Deadlines)</a>, Up: <a href="index.html#Timeouts-and-Deadlines" accesskey="u" rel="up">Timeouts and Deadlines</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Asynchronous-Timeouts-1"></span><h4 class="subsection">7.14.3 Asynchronous Timeouts</h4>
|
|
<span id="index-Timeout-2"></span>
|
|
<span id="index-Asynchronous-Timeout"></span>
|
|
|
|
<p>Asynchronous timeouts are established for a dynamic scope using the
|
|
<code>sb-sys:with-timeout</code> macro:
|
|
</p>
|
|
<span id="Macro-sb_002dext-with_002dtimeout"></span><dl>
|
|
<dt id="index-with_002dtimeout">Macro: <strong>with-timeout</strong> <em>[sb-ext] expires &body body</em></dt>
|
|
<dd><p>Execute the body, asynchronously interrupting it and signalling a <code>timeout</code>
|
|
condition after at least <code>expires</code> seconds have passed.
|
|
</p>
|
|
<p>Note that it is never safe to unwind from an asynchronous condition. Consider:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (defun call-with-foo (function)
|
|
(let (foo)
|
|
(unwind-protect
|
|
(progn
|
|
(setf foo (get-foo))
|
|
(funcall function foo))
|
|
(when foo
|
|
(release-foo foo)))))
|
|
</pre></div>
|
|
|
|
<p>If <code>timeout</code> occurs after <code>get-foo</code> has executed, but before the assignment, then
|
|
<code>release-foo</code> 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 <code>--</code> and in essence proofing everything will make
|
|
the system uninterruptible.
|
|
</p></dd></dl>
|
|
|
|
<p>Expiration of the timeout will cause the operation being executed at
|
|
that moment to be interrupted by an asynchronously signaled
|
|
<code>sb-ext:timeout</code> condition, (almost) irregardless of the operation
|
|
and its context.
|
|
</p>
|
|
<span id="Condition-sb_002dext-timeout"></span><dl>
|
|
<dt id="index-timeout">Condition: <strong>timeout</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code>timeout<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Signaled when an operation does not complete within an allotted time budget.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Operations-Supporting-Timeouts-and-Deadlines"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Asynchronous-Timeouts" accesskey="p" rel="prev">Asynchronous Timeouts</a>, Up: <a href="index.html#Timeouts-and-Deadlines" accesskey="u" rel="up">Timeouts and Deadlines</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Operations-Supporting-Timeouts-and-Deadlines-1"></span><h4 class="subsection">7.14.4 Operations Supporting Timeouts and Deadlines</h4>
|
|
|
|
<table>
|
|
<thead><tr><th width="50%">Operation</th><th width="25%">Timeout Parameter</th><th width="25%">Affected by Deadlines</th></tr></thead>
|
|
<tr><td width="50%"><code>cl:sleep</code></td><td width="25%">-</td><td width="25%">since SBCL 1.4.3</td></tr>
|
|
<tr><td width="50%"><code>cl:read-line</code>, etc.</td><td width="25%">no</td><td width="25%">yes</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Macro-sb_002dext-wait_002dfor"><code>wait-for</code></a></td><td width="25%">yes</td><td width="25%">yes</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dext-process_002dwait"><code>process-wait</code></a></td><td width="25%">no</td><td width="25%">yes</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dthread-grab_002dmutex"><code>grab-mutex</code></a></td><td width="25%">yes</td><td width="25%">yes</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dthread-condition_002dwait"><code>condition-wait</code></a></td><td width="25%">yes</td><td width="25%">yes</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dthread-wait_002don_002dsemaphore"><code>wait-on-semaphore</code></a></td><td width="25%">yes</td><td width="25%">yes</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dthread-join_002dthread"><code>join-thread</code></a></td><td width="25%">yes</td><td width="25%">yes</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dconcurrency-receive_002dmessage"><code>receive-message</code></a></td><td width="25%">yes</td><td width="25%">yes?</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dconcurrency-wait_002don_002dgate"><code>wait-on-gate</code></a></td><td width="25%">yes</td><td width="25%">yes?</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Macro-sb_002dconcurrency-frlock_002dwrite"><code>frlock-write</code></a></td><td width="25%">yes</td><td width="25%">yes?</td></tr>
|
|
<tr><td width="50%"><a href="index.html#Function-sb_002dconcurrency-grab_002dfrlock_002dwrite_002dlock"><code>grab-frlock-write-lock</code></a></td><td width="25%">yes</td><td width="25%">yes?</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Miscellaneous-Extensions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Stale-Extensions" accesskey="n" rel="next">Stale Extensions</a>, Previous: <a href="index.html#Timeouts-and-Deadlines" accesskey="p" rel="prev">Timeouts and Deadlines</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Miscellaneous-Extensions-1"></span><h3 class="section">7.15 Miscellaneous Extensions</h3>
|
|
|
|
<span id="Function-sb_002dext-array_002dstorage_002dvector"></span><dl>
|
|
<dt id="index-array_002dstorage_002dvector">Function: <strong>array-storage-vector</strong> <em>[sb-ext] array</em></dt>
|
|
<dd><p>Returns the underlying storage vector of <code>array</code>, which must be a non-displaced array.
|
|
</p>
|
|
<p>In <code>sbcl</code>, if <code>array</code> is a of type (<code>simple-array</code> <code>*</code> (<code>*</code>)), it is its own storage
|
|
vector. Multidimensional arrays, arrays with fill pointers, and adjustable
|
|
arrays have an underlying storage vector with the same <code>array-element-type</code> as
|
|
<code>array</code>, which this function returns.
|
|
</p>
|
|
<p>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.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-delete_002ddirectory"></span><dl>
|
|
<dt id="index-delete_002ddirectory">Function: <strong>delete-directory</strong> <em>[sb-ext] pathspec &key recursive</em></dt>
|
|
<dd><p>Deletes the directory designated by <code>pathspec</code> (a pathname designator).
|
|
Returns the truename of the directory deleted.
|
|
</p>
|
|
<p>If <code>recursive</code> is false (the default), signals an error unless the directory is
|
|
empty. If <code>recursive</code> is true, first deletes all files and subdirectories. If
|
|
<code>recursive</code> is true and the directory contains symbolic links, the links are
|
|
deleted, not the files and directories they point to.
|
|
</p>
|
|
<p>Signals an error if <code>pathspec</code> designates a file or a symbolic link instead of a
|
|
directory, or if the directory could not be deleted for any reason.
|
|
</p>
|
|
<p>Both
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (DELETE-DIRECTORY "/tmp/foo")
|
|
(DELETE-DIRECTORY "/tmp/foo/")
|
|
</pre></div>
|
|
|
|
<p>delete the "foo" subdirectory of "/tmp", or signal an error if it does not
|
|
exist or if is a file or a symbolic link.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-get_002dtime_002dof_002dday"></span><dl>
|
|
<dt id="index-get_002dtime_002dof_002dday">Function: <strong>get-time-of-day</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Return the number of seconds and microseconds since the beginning of
|
|
the <code>unix</code> epoch (January 1st 1970.)
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-assert_002dversion_002d_003e_003d"></span><dl>
|
|
<dt id="index-assert_002dversion_002d_003e_003d">Function: <strong>assert-version->=</strong> <em>[sb-ext] &rest subversions</em></dt>
|
|
<dd><p>Asserts that the current <code>sbcl</code> is of version equal to or greater than
|
|
the version specified in the arguments. A continuable error is signaled
|
|
otherwise.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>For example, (assert-version->= 1 1 4) asserts that the current <code>sbcl</code> is
|
|
version 1.1.4[.0.0...] or greater, and (assert-version->= 1) that it is
|
|
version 1[.0.0...] or greater.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Stale-Extensions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Efficiency-Hacks" accesskey="n" rel="next">Efficiency Hacks</a>, Previous: <a href="index.html#Miscellaneous-Extensions" accesskey="p" rel="prev">Miscellaneous Extensions</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Stale-Extensions-1"></span><h3 class="section">7.16 Stale Extensions</h3>
|
|
|
|
<p>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 <samp>src/code/gc.lisp</samp>
|
|
and bring it up on the developers’ mailing list.
|
|
</p>
|
|
<span id="index-float_002ddenormalized_002dp-_005bsb_002dext_005d"></span>
|
|
<p>SBCL has various hooks inherited from CMUCL, like
|
|
<code>sb-ext:float-denormalized-p</code>, 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.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Efficiency-Hacks"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Stale-Extensions" accesskey="p" rel="prev">Stale Extensions</a>, Up: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="u" rel="up">Beyond the ANSI Standard</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Efficiency-Hacks-1"></span><h3 class="section">7.17 Efficiency Hacks</h3>
|
|
|
|
<span id="index-purify-_005bsb_002dext_005d"></span>
|
|
<p>The <code>sb-ext:purify</code> 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.
|
|
</p>
|
|
|
|
<p>The <code>sb-ext:truly-the</code> 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.
|
|
</p>
|
|
<span id="Special_002dOperator-sb_002dext-truly_002dthe"></span><dl>
|
|
<dt id="index-truly_002dthe">Special Operator: <strong>truly-the</strong> <em>[sb-ext] value-type form</em></dt>
|
|
<dd><p>Specifies that the values returned by <code>form</code> conform to the
|
|
<code>value-type</code>, and causes the compiler to trust this information
|
|
unconditionally.
|
|
</p>
|
|
<p>Consequences are undefined if any result is not of the declared type
|
|
<code>--</code> typical symptoms including memory corruptions. Use with great
|
|
care.
|
|
</p></dd></dl>
|
|
|
|
<span id="index-freeze_002dtype-declaration"></span>
|
|
<span id="index-Declaration_002c-freeze_002dtype"></span>
|
|
<p>The <code>sb-ext:freeze-type</code> declaration declares that a
|
|
type will never change, which can make type testing
|
|
(<code>typep</code>, etc.) more efficient for structure types.
|
|
</p><hr>
|
|
<span id="External-Formats"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Function-Interface" accesskey="n" rel="next">Foreign Function Interface</a>, Previous: <a href="index.html#Beyond-the-ANSI-Standard" accesskey="p" rel="prev">Beyond the ANSI Standard</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="External-Formats-1"></span><h2 class="chapter">8 External Formats</h2>
|
|
|
|
<p>External formats determine the coding of characters from/to sequences of
|
|
octets when exchanging data with the outside world. Examples of such
|
|
exchanges are:
|
|
</p>
|
|
<ol>
|
|
<li> Character streams associated with files, sockets and process
|
|
input/output (See <a href="index.html#Stream-External-Formats">Stream External Formats</a> and <a href="index.html#Running-external-programs">Running external programs</a>)
|
|
|
|
</li><li> Names of files
|
|
|
|
</li><li> Foreign strings (See <a href="index.html#Foreign-Types-and-Lisp-Types">Foreign Types and Lisp Types</a>)
|
|
|
|
</li><li> Posix interface (See <a href="index.html#sb_002dposix">sb-posix</a>)
|
|
|
|
</li><li> Hostname- and protocol-related functions of the BSD-socket interface
|
|
(See <a href="index.html#Networking">Networking</a>)
|
|
|
|
</li></ol>
|
|
|
|
<p>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.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#The-Default-External-Format" accesskey="1">The Default External Format</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#External-Format-Designators" accesskey="2">External Format Designators</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Character-Coding-Conditions" accesskey="3">Character Coding Conditions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Converting-between-Strings-and-Octet-Vectors" accesskey="4">Converting between Strings and Octet Vectors</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Supported-External-Formats" accesskey="5">Supported External Formats</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="The-Default-External-Format"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#External-Format-Designators" accesskey="n" rel="next">External Format Designators</a>, Up: <a href="index.html#External-Formats" accesskey="u" rel="up">External Formats</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="The-Default-External-Format-1"></span><h3 class="section">8.1 The Default External Format</h3>
|
|
<span id="index-The-Default-External-Format"></span>
|
|
|
|
<p>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.
|
|
</p>
|
|
<p>The default external format is UTF-8. It can be changed via
|
|
</p>
|
|
<p><var>sb-ext:*default-external-format*</var>
|
|
and
|
|
<var>sb-ext:*default-c-string-external-format*</var>
|
|
</p>
|
|
<hr>
|
|
<span id="External-Format-Designators"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Character-Coding-Conditions" accesskey="n" rel="next">Character Coding Conditions</a>, Previous: <a href="index.html#The-Default-External-Format" accesskey="p" rel="prev">The Default External Format</a>, Up: <a href="index.html#External-Formats" accesskey="u" rel="up">External Formats</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="External-Format-Designators-1"></span><h3 class="section">8.2 External Format Designators</h3>
|
|
<span id="index-External-Format-Designators"></span>
|
|
|
|
<span id="index-open-_005bcl_005d"></span>
|
|
<span id="index-with_002dopen_002dfile-_005bcl_005d"></span>
|
|
<p>In situations where an external format designator is required, such as
|
|
the <code>:external-format</code> argument in calls to <code>open</code> or
|
|
<code>with-open-file</code>, users may supply the name of an encoding to
|
|
denote the external format which is applying that encoding to Lisp
|
|
characters.
|
|
</p>
|
|
<p>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.
|
|
</p>
|
|
<p>More specifically, external format designators can take the following
|
|
forms:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><code>:default</code></dt>
|
|
<dd><p>Designates the current default external format (See <a href="index.html#The-Default-External-Format">The Default External Format</a>).
|
|
</p>
|
|
</dd>
|
|
<dt><code><var>keyword</var></code></dt>
|
|
<dd><p>Designates the supported external format that has <var>keyword</var> as one
|
|
of its names. (See <a href="index.html#Supported-External-Formats">Supported External Formats</a>).
|
|
</p>
|
|
</dd>
|
|
<dt><code>(<var>keyword</var> :replacement <var>replacement</var>)</code></dt>
|
|
<dd><p>Designates an external format that is like the one designated by
|
|
<var>keyword</var> but does not signal an error in case a character or octet
|
|
sequence cannot be en- or decoded. Instead, it inserts <var>replacement</var>
|
|
at the position in question. <var>replacement</var> has to be a string
|
|
designator, that is a character or string.
|
|
</p>
|
|
<p>For example:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(with-open-file (stream pathname :external-format '(:utf-8 :replacement #\?))
|
|
(read-line stream))
|
|
</pre></div>
|
|
<p>will read the first line of <var>pathname</var>, replacing any octet sequence
|
|
that is not valid in the UTF-8 external format with a question mark
|
|
character.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<hr>
|
|
<span id="Character-Coding-Conditions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Converting-between-Strings-and-Octet-Vectors" accesskey="n" rel="next">Converting between Strings and Octet Vectors</a>, Previous: <a href="index.html#External-Format-Designators" accesskey="p" rel="prev">External Format Designators</a>, Up: <a href="index.html#External-Formats" accesskey="u" rel="up">External Formats</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Character-Coding-Conditions-1"></span><h3 class="section">8.3 Character Coding Conditions</h3>
|
|
<span id="index-Character-Coding-Conditions"></span>
|
|
|
|
<p>De- or encoding characters using a given external format is not always
|
|
possible:
|
|
</p>
|
|
<ul>
|
|
<li> Decoding an octet vector using a given external format can fail if it
|
|
contains an octet or sequence of octets that does not have an
|
|
interpretation as a character according to the external format.
|
|
|
|
</li><li> Conversely, a string may contain characters that a given external format
|
|
cannot encode. For example, the ASCII external format cannot encode the
|
|
character <code>#\ö</code>.
|
|
|
|
</li></ul>
|
|
|
|
<p>Unless the external format governing the coding uses the
|
|
<code>:replacement</code> 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.
|
|
</p>
|
|
<hr>
|
|
<span id="Converting-between-Strings-and-Octet-Vectors"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Supported-External-Formats" accesskey="n" rel="next">Supported External Formats</a>, Previous: <a href="index.html#Character-Coding-Conditions" accesskey="p" rel="prev">Character Coding Conditions</a>, Up: <a href="index.html#External-Formats" accesskey="u" rel="up">External Formats</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Converting-between-Strings-and-Octet-Vectors-1"></span><h3 class="section">8.4 Converting between Strings and Octet Vectors</h3>
|
|
<span id="index-Converting-between-Strings-and-Octet-Vectors"></span>
|
|
|
|
<p>To encode Lisp strings as octet vectors and decode octet vectors as Lisp
|
|
strings, the following SBCL-specific functions can be used:
|
|
</p>
|
|
<span id="Function-sb_002dext-string_002dto_002doctets"></span><dl>
|
|
<dt id="index-string_002dto_002doctets">Function: <strong>string-to-octets</strong> <em>[sb-ext] string &key external-format start end null-terminate</em></dt>
|
|
<dd><p>Return an octet vector that is <code>string</code> encoded according to <code>external-format</code>.
|
|
</p>
|
|
<p>If <code>external-format</code> is given, it must designate an external format.
|
|
</p>
|
|
<p>If given, <code>start</code> and <code>end</code> must be bounding index designators and
|
|
designate a subsequence of <code>string</code> that should be encoded.
|
|
</p>
|
|
<p>If <code>null-terminate</code> is true, the returned octet vector ends with an
|
|
additional 0 element that does not correspond to any part of <code>string</code>.
|
|
</p>
|
|
<p>If some of the characters of <code>string</code> (or the subsequence bounded by
|
|
<code>start</code> and <code>end</code>) cannot be encoded by <code>external-format</code> an error of a
|
|
subtype of <code>sb-int:character-encoding-error</code> is signaled.
|
|
</p>
|
|
<p>Note that for some values of <code>external-format</code> and <code>null-terminate</code> the
|
|
length of the returned vector may be different from the length of
|
|
<code>string</code> (or the subsequence bounded by <code>start</code> and <code>end</code>).
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-octets_002dto_002dstring"></span><dl>
|
|
<dt id="index-octets_002dto_002dstring">Function: <strong>octets-to-string</strong> <em>[sb-ext] vector &key external-format start end</em></dt>
|
|
<dd><p>Return a string obtained by decoding <code>vector</code> according to <code>external-format</code>.
|
|
</p>
|
|
<p>If <code>external-format</code> is given, it must designate an external format.
|
|
</p>
|
|
<p>If given, <code>start</code> and <code>end</code> must be bounding index designators and
|
|
designate a subsequence of <code>vector</code> that should be decoded.
|
|
</p>
|
|
<p>If some of the octets of <code>vector</code> (or the subsequence bounded by <code>start</code>
|
|
and <code>end</code>) cannot be decoded by <code>external-format</code> an error of a subtype of
|
|
<code>sb-int:character-decoding-error</code> is signaled.
|
|
</p>
|
|
<p>Note that for some values of <code>external-format</code> the length of the
|
|
returned string may be different from the length of <code>vector</code> (or the
|
|
subsequence bounded by <code>start</code> and <code>end</code>).
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Supported-External-Formats"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Converting-between-Strings-and-Octet-Vectors" accesskey="p" rel="prev">Converting between Strings and Octet Vectors</a>, Up: <a href="index.html#External-Formats" accesskey="u" rel="up">External Formats</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Supported-External-Formats-1"></span><h3 class="section">8.5 Supported External Formats</h3>
|
|
<span id="index-Supported-External-Formats"></span>
|
|
|
|
<p>The following table lists the external formats supported by SBCL in the
|
|
form of the respective canonical name followed by the list of aliases:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><code>:ASCII</code></dt>
|
|
<dd><p><code>:US-ASCII</code>, <code>:ANSI_X3.4-1968</code>, <code>:ISO-646</code>, <code>:ISO-646-US</code>, <code>:|646|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1250</code></dt>
|
|
<dd><p><code>:|cp1250|</code>, <code>:WINDOWS-1250</code>, <code>:|windows-1250|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1251</code></dt>
|
|
<dd><p><code>:|cp1251|</code>, <code>:WINDOWS-1251</code>, <code>:|windows-1251|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1252</code></dt>
|
|
<dd><p><code>:|cp1252|</code>, <code>:WINDOWS-1252</code>, <code>:|windows-1252|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1253</code></dt>
|
|
<dd><p><code>:|cp1253|</code>, <code>:WINDOWS-1253</code>, <code>:|windows-1253|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1254</code></dt>
|
|
<dd><p><code>:|cp1254|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1255</code></dt>
|
|
<dd><p><code>:|cp1255|</code>, <code>:WINDOWS-1255</code>, <code>:|windows-1255|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1256</code></dt>
|
|
<dd><p><code>:|cp1256|</code>, <code>:WINDOWS-1256</code>, <code>:|windows-1256|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1257</code></dt>
|
|
<dd><p><code>:|cp1257|</code>, <code>:WINDOWS-1257</code>, <code>:|windows-1257|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP1258</code></dt>
|
|
<dd><p><code>:|cp1258|</code>, <code>:WINDOWS-1258</code>, <code>:|windows-1258|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP437</code></dt>
|
|
<dd><p><code>:|cp437|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP850</code></dt>
|
|
<dd><p><code>:|cp850|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP852</code></dt>
|
|
<dd><p><code>:|cp852|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP855</code></dt>
|
|
<dd><p><code>:|cp855|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP857</code></dt>
|
|
<dd><p><code>:|cp857|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP860</code></dt>
|
|
<dd><p><code>:|cp860|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP861</code></dt>
|
|
<dd><p><code>:|cp861|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP862</code></dt>
|
|
<dd><p><code>:|cp862|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP863</code></dt>
|
|
<dd><p><code>:|cp863|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP864</code></dt>
|
|
<dd><p><code>:|cp864|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP865</code></dt>
|
|
<dd><p><code>:|cp865|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP866</code></dt>
|
|
<dd><p><code>:|cp866|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP869</code></dt>
|
|
<dd><p><code>:|cp869|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:CP874</code></dt>
|
|
<dd><p><code>:|cp874|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:EBCDIC-US</code></dt>
|
|
<dd><p><code>:CP037</code>, <code>:|cp037|</code>, <code>:IBM-037</code>, <code>:IBM037</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:EUC-JP</code></dt>
|
|
<dd><p><code>:EUCJP</code>, <code>:|eucJP|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:GBK</code></dt>
|
|
<dd><p><code>:CP936</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-10</code></dt>
|
|
<dd><p><code>:|iso-8859-10|</code>, <code>:LATIN-6</code>, <code>:|latin-6|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-11</code></dt>
|
|
<dd><p><code>:|iso-8859-11|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-13</code></dt>
|
|
<dd><p><code>:|iso-8859-13|</code>, <code>:LATIN-7</code>, <code>:|latin-7|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-14</code></dt>
|
|
<dd><p><code>:|iso-8859-14|</code>, <code>:LATIN-8</code>, <code>:|latin-8|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-2</code></dt>
|
|
<dd><p><code>:|iso-8859-2|</code>, <code>:LATIN-2</code>, <code>:|latin-2|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-3</code></dt>
|
|
<dd><p><code>:|iso-8859-3|</code>, <code>:LATIN-3</code>, <code>:|latin-3|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-4</code></dt>
|
|
<dd><p><code>:|iso-8859-4|</code>, <code>:LATIN-4</code>, <code>:|latin-4|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-5</code></dt>
|
|
<dd><p><code>:|iso-8859-5|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-6</code></dt>
|
|
<dd><p><code>:|iso-8859-6|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-7</code></dt>
|
|
<dd><p><code>:|iso-8859-7|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-8</code></dt>
|
|
<dd><p><code>:|iso-8859-8|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:ISO-8859-9</code></dt>
|
|
<dd><p><code>:|iso-8859-9|</code>, <code>:LATIN-5</code>, <code>:|latin-5|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:KOI8-R</code></dt>
|
|
<dd><p><code>:|koi8-r|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:KOI8-U</code></dt>
|
|
<dd><p><code>:|koi8-u|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:LATIN-1</code></dt>
|
|
<dd><p><code>:LATIN1</code>, <code>:ISO-8859-1</code>, <code>:ISO8859-1</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:LATIN-9</code></dt>
|
|
<dd><p><code>:LATIN9</code>, <code>:ISO-8859-15</code>, <code>:ISO8859-15</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:MAC-ROMAN</code></dt>
|
|
<dd><p><code>:|mac-roman|</code>, <code>:|MacRoman|</code>, <code>:MAC</code>, <code>:|mac|</code>, <code>:MACINTOSH</code>, <code>:|macintosh|</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:SHIFT_JIS</code></dt>
|
|
<dd><p><code>:SJIS</code>, <code>:|Shift_JIS|</code>, <code>:CP932</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UCS-2BE</code></dt>
|
|
<dd><p><code>:UCS2BE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UCS-2LE</code></dt>
|
|
<dd><p><code>:UCS2LE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UCS-4BE</code></dt>
|
|
<dd><p><code>:UCS4BE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UCS-4LE</code></dt>
|
|
<dd><p><code>:UCS4LE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UTF-16BE</code></dt>
|
|
<dd><p><code>:UTF16BE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UTF-16LE</code></dt>
|
|
<dd><p><code>:UTF16LE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UTF-32BE</code></dt>
|
|
<dd><p><code>:UTF32BE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:UTF-32LE</code></dt>
|
|
<dd><p><code>:UTF32LE</code>
|
|
</p>
|
|
</dd>
|
|
<dt><code>:X-MAC-CYRILLIC</code></dt>
|
|
<dd><p><code>:|x-mac-cyrillic|</code>
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
<hr>
|
|
<span id="Foreign-Function-Interface"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Pathnames" accesskey="n" rel="next">Pathnames</a>, Previous: <a href="index.html#External-Formats" accesskey="p" rel="prev">External Formats</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Function-Interface-1"></span><h2 class="chapter">9 Foreign Function Interface</h2>
|
|
|
|
<p>This chapter describes SBCL’s interface to C programs and
|
|
libraries (and, since C interfaces are a sort of <em>lingua
|
|
franca</em> of the Unix world, to other programs and libraries in
|
|
general.)
|
|
</p>
|
|
<blockquote>
|
|
<p>Note: In the modern Lisp world, the usual term for this functionality
|
|
is Foreign Function Interface, or <acronym>FFI</acronym>, where despite the
|
|
mention of “function” in this term, <acronym>FFI</acronym> 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 <code>SB-ALIEN</code> package.
|
|
</p></blockquote>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Introduction-to-the-Foreign-Function-Interface" accesskey="1">Introduction to the Foreign Function Interface</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Types" accesskey="2">Foreign Types</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Operations-On-Foreign-Values" accesskey="3">Operations On Foreign Values</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Variables" accesskey="4">Foreign Variables</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Data-Structure-Examples" accesskey="5">Foreign Data Structure Examples</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Loading-Shared-Object-Files" accesskey="6">Loading Shared Object Files</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Function-Calls" accesskey="7">Foreign Function Calls</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Calling-Lisp-From-C" accesskey="8">Calling Lisp From C</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Step_002dBy_002dStep-Example-of-the-Foreign-Function-Interface" accesskey="9">Step-By-Step Example of the Foreign Function Interface</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Introduction-to-the-Foreign-Function-Interface"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Types" accesskey="n" rel="next">Foreign Types</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Introduction-to-the-Foreign-Function-Interface-1"></span><h3 class="section">9.1 Introduction to the Foreign Function Interface</h3>
|
|
|
|
<p>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:
|
|
</p>
|
|
<ul>
|
|
<li> The burden can be placed on the foreign program (and programmer) by
|
|
requiring the knowledge and use of the representations used internally
|
|
by the Lisp implementation. This can require a considerable amount of
|
|
“glue” code on the C side, and that code tends to be sensitively
|
|
dependent on the internal implementation details of the Lisp system.
|
|
|
|
</li><li> The Lisp system can automatically convert objects back and forth between
|
|
the Lisp and foreign representations. This is convenient, but
|
|
translation becomes prohibitively slow when large or complex data
|
|
structures must be shared. This approach is supported by the SBCL
|
|
<acronym>FFI</acronym>, and used automatically when passing integers and strings.
|
|
|
|
</li><li> The Lisp program can directly manipulate foreign objects through the
|
|
use of extensions to the Lisp language.
|
|
|
|
</li></ul>
|
|
|
|
<p>SBCL, like CMUCL before it, relies primarily on the automatic
|
|
conversion and direct manipulation approaches. The <code>SB-ALIEN</code>
|
|
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 <acronym>SAP</acronym>s) can be used where
|
|
necessary to provide untyped access to foreign memory.
|
|
</p>
|
|
<p>Any foreign objects that can’t automatically be converted into Lisp
|
|
values are represented by objects of type <code>alien-value</code>. 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 <code>alien-value</code> object.
|
|
</p>
|
|
<p>The type language and operations on foreign types are
|
|
intentionally similar to those of the C language.
|
|
</p>
|
|
<hr>
|
|
<span id="Foreign-Types"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Operations-On-Foreign-Values" accesskey="n" rel="next">Operations On Foreign Values</a>, Previous: <a href="index.html#Introduction-to-the-Foreign-Function-Interface" accesskey="p" rel="prev">Introduction to the Foreign Function Interface</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Types-1"></span><h3 class="section">9.2 Foreign Types</h3>
|
|
|
|
<p>Alien types have a description language based on nested list
|
|
structure. For example the C type
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">struct foo {
|
|
int a;
|
|
struct foo *b[100];
|
|
};
|
|
</pre></div>
|
|
|
|
<p>has the corresponding SBCL <acronym>FFI</acronym> type
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(struct foo
|
|
(a int)
|
|
(b (array (* (struct foo)) 100)))
|
|
</pre></div>
|
|
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Defining-Foreign-Types" accesskey="1">Defining Foreign Types</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Types-and-Lisp-Types" accesskey="2">Foreign Types and Lisp Types</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Type-Specifiers" accesskey="3">Foreign Type Specifiers</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Defining-Foreign-Types"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Types-and-Lisp-Types" accesskey="n" rel="next">Foreign Types and Lisp Types</a>, Up: <a href="index.html#Foreign-Types" accesskey="u" rel="up">Foreign Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Defining-Foreign-Types-1"></span><h4 class="subsection">9.2.1 Defining Foreign Types</h4>
|
|
|
|
<p>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:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(struct foo (a (* (struct foo))))
|
|
</pre></div>
|
|
|
|
<p>An anonymous structure or union type is specified by using the name
|
|
<code>nil</code>. The <code>with-alien</code> 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
|
|
<code>define-alien-type</code> macro.
|
|
</p>
|
|
<hr>
|
|
<span id="Foreign-Types-and-Lisp-Types"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Type-Specifiers" accesskey="n" rel="next">Foreign Type Specifiers</a>, Previous: <a href="index.html#Defining-Foreign-Types" accesskey="p" rel="prev">Defining Foreign Types</a>, Up: <a href="index.html#Foreign-Types" accesskey="u" rel="up">Foreign Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Types-and-Lisp-Types-1"></span><h4 class="subsection">9.2.2 Foreign Types and Lisp Types</h4>
|
|
|
|
<p>The foreign types form a subsystem of the SBCL type system. An
|
|
<code>alien</code> type specifier provides a way to use any foreign type as a
|
|
Lisp type specifier. For example,
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(typep <var>foo</var> '(alien (* int)))
|
|
</pre></div>
|
|
|
|
<p>can be used to determine whether <var>foo</var> is a pointer to a foreign
|
|
<code>int</code>. <code>alien</code> type specifiers can be used in the same ways
|
|
as ordinary Lisp type specifiers (like <code>string</code>.) Alien type
|
|
declarations are subject to the same precise type checking as any
|
|
other declaration. See <a href="index.html#Precise-Type-Checking">Precise Type Checking</a>.
|
|
</p>
|
|
<p>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 <code>(alien single-float)</code> is identical to
|
|
<code>single-float</code>, since foreign floats are automatically converted
|
|
to Lisp floats. When <code>type-of</code> is called on an alien value that
|
|
is not automatically converted to a Lisp value, then it will return an
|
|
<code>alien</code> type specifier.
|
|
</p>
|
|
<hr>
|
|
<span id="Foreign-Type-Specifiers"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Foreign-Types-and-Lisp-Types" accesskey="p" rel="prev">Foreign Types and Lisp Types</a>, Up: <a href="index.html#Foreign-Types" accesskey="u" rel="up">Foreign Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Type-Specifiers-1"></span><h4 class="subsection">9.2.3 Foreign Type Specifiers</h4>
|
|
|
|
<p>Note: All foreign type names are exported from the <code>sb-alien</code>
|
|
package. Some foreign type names are also symbols in
|
|
the <code>common-lisp</code> package, in which case they are
|
|
reexported from the <code>sb-alien</code> package, so that
|
|
e.g. it is legal to refer to <code>sb-alien:single-float</code>.
|
|
</p>
|
|
<p>These are the basic foreign type specifiers:
|
|
</p>
|
|
<ul>
|
|
<li> The foreign type specifier <code>(* <var>foo</var>)</code> describes a pointer to
|
|
an object of type <var>foo</var>. A pointed-to type <var>foo</var> of <code>t</code>
|
|
indicates a pointer to anything, similar to <code>void *</code> in
|
|
ANSI C. A null alien pointer can be detected with the
|
|
<code>sb-alien:null-alien</code> function.
|
|
|
|
</li><li> The foreign type specifier <code>(array <var>foo</var> &rest
|
|
dimensions)</code> describes array of the specified <code>dimensions</code>,
|
|
holding elements of type <var>foo</var>. Note that (unlike in C) <code>(*
|
|
<var>foo</var>)</code> and <code>(array <var>foo</var>)</code> 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
|
|
<code>sb-alien:cast</code>.
|
|
|
|
<p>Arrays are accessed using <code>sb-alien:deref</code>, 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 <code>nil</code>
|
|
as the first dimension. Fixed-size arrays can be allocated as array
|
|
elements, structure slots or <code>sb-alien:with-alien</code>
|
|
variables. Dynamic arrays can only be allocated using
|
|
<code>sb-alien:make-alien</code>.
|
|
</p>
|
|
</li><li> The foreign type specifier <code>(sb-alien:struct <var>name</var> &rest
|
|
<var>fields</var>)</code> describes a structure type with the specified
|
|
<var>name</var> and <var>fields</var>. Fields are allocated at the same offsets
|
|
used by the implementation’s C compiler, as guessed by the SBCL
|
|
internals. An optional <code>:alignment</code> keyword argument can be
|
|
specified for each field to explicitly control the alignment of a
|
|
field. If <var>name</var> is <code>nil</code> then the structure is anonymous.
|
|
|
|
<p>If a named foreign <code>struct</code> specifier is passed to
|
|
<code>define-alien-type</code> or <code>with-alien</code>, then this defines,
|
|
respectively, a new global or local foreign structure type. If no
|
|
<var>fields</var> are specified, then the fields are taken
|
|
from the current (local or global) alien structure type definition of
|
|
<var>name</var>.
|
|
</p>
|
|
</li><li> The foreign type specifier <code>(sb-alien:union <var>name</var> &rest
|
|
<var>fields</var>)</code> is similar to <code>sb-alien:struct</code>, 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.
|
|
|
|
</li><li> The foreign type specifier <code>(sb-alien:enum <var>name</var> &rest
|
|
<var>specs</var>)</code> describes an enumeration type that maps between integer
|
|
values and symbols. If <var>name</var> is <code>nil</code>, then the type is
|
|
anonymous. Each element of the <var>specs</var> list is either a Lisp
|
|
symbol, or a list <code>(<var>symbol</var> <var>value</var>)</code>. <var>value</var> is
|
|
an integer. If <var>value</var> 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).
|
|
|
|
</li><li> The foreign type specifier <code>(sb-alien:signed &optional
|
|
<var>bits</var>)</code> specifies a signed integer with the specified number of
|
|
<var>bits</var> precision. The upper limit on integer
|
|
precision is determined by the machine’s word size. If
|
|
<var>bits</var> is not specified, the maximum size will be
|
|
used.
|
|
|
|
</li><li> The foreign type specifier <code>(integer &optional <var>bits</var>)</code>
|
|
is equivalent to the corresponding type specifier using
|
|
<code>sb-alien:signed</code> instead of <code>integer</code>.
|
|
|
|
</li><li> The foreign type specifier <code>(sb-alien:unsigned &optional
|
|
<var>bits</var>)</code> is like corresponding type specifier using
|
|
<code>sb-alien:signed</code> except that the variable is treated as an
|
|
unsigned integer.
|
|
|
|
</li><li> The foreign type specifier <code>(boolean &optional <var>bits</var>)</code> is
|
|
similar to an enumeration type, but maps from Lisp <code>nil</code> and
|
|
<code>t</code> to C <code>0</code> and <code>1</code> respectively. <var>bits</var>
|
|
determines the amount of storage allocated to hold the truth value.
|
|
|
|
</li><li> The foreign type specifier <code>single-float</code> describes a
|
|
floating-point number in IEEE single-precision format.
|
|
|
|
</li><li> The foreign type specifier <code>double-float</code> describes a
|
|
floating-point number in IEEE double-precision format.
|
|
|
|
</li><li> The foreign type specifier <code>(function <var>result-type</var> &rest
|
|
<var>arg-types</var>)</code> describes a foreign function that takes arguments of
|
|
the specified <var>arg-types</var> and returns a result of type
|
|
<var>result-type</var>. Note that the only context where a foreign
|
|
<code>function</code> type is directly specified is in the argument to
|
|
<code>sb-alien:alien-funcall</code>. In all other contexts, foreign
|
|
functions are represented by foreign function pointer types: <code>(*
|
|
(function …))</code>.
|
|
|
|
</li><li> The foreign type specifier <code>sb-alien:system-area-pointer</code>
|
|
describes a pointer which is represented in Lisp as a
|
|
<code>system-area-pointer</code> object. SBCL exports this type from
|
|
<code>sb-alien</code> 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.
|
|
|
|
</li><li> The foreign type specifier <code>sb-alien:void</code> is used in function
|
|
types to declare that no useful value is returned. Using
|
|
<code>alien-funcall</code> to call a <code>void</code> foreign function will
|
|
return zero values.
|
|
|
|
</li><li> <span id="index-External-formats"></span>
|
|
The foreign type specifier <code>(sb-alien:c-string &key
|
|
external-format element-type not-null)</code> is similar to
|
|
<code>(* char)</code>, but is interpreted as a null-terminated string, and
|
|
is automatically converted into a Lisp string when accessed; or if the
|
|
pointer is C <code>NULL</code> or <code>0</code>, then accessing it gives Lisp
|
|
<code>nil</code> unless <code>not-null</code> is true, in which case a type-error
|
|
is signalled.
|
|
|
|
<p>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 <code>external-format</code>, 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
|
|
<code>ebcdic</code> octet representation.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(define-alien-routine test int (str (c-string :external-format :ebcdic-us)))
|
|
</pre></div>
|
|
|
|
<p>Lisp strings of type <code>base-string</code> 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
|
|
<code>external-format</code> and <code>element-type</code> of the <code>c-string</code>
|
|
type are compatible with the internal representation of the string. For
|
|
an SBCL built with Unicode support that means an <code>external-format</code>
|
|
of <code>:ascii</code> and an <code>element-type</code> of <code>base-char</code>. Without
|
|
Unicode support the <code>external-format</code> can also be
|
|
<code>:iso-8859-1</code>, and the <code>element-type</code> can also be
|
|
<code>character</code>. If the <code>external-format</code> or <code>element-type</code>
|
|
is not compatible, or the string is a <code>(simple-array character
|
|
(*))</code>, this data is copied by the implementation as required.
|
|
</p>
|
|
<p>Assigning a Lisp string to a <code>c-string</code> 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 <code>(*
|
|
char)</code> is assigned to a <code>c-string</code>, then the
|
|
<code>c-string</code> pointer is assigned to. This allows
|
|
<code>c-string</code> pointers to be initialized. For example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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))
|
|
</pre></div>
|
|
|
|
<p>Storing Lisp <code>NIL</code> in a <code>c-string</code> writes C <code>NULL</code> to
|
|
the variable.
|
|
</p>
|
|
</li><li> <code>sb-alien</code> also exports translations of these C type
|
|
specifiers as foreign type specifiers:
|
|
<code>char</code>,
|
|
<code>short</code>,
|
|
<code>int</code>,
|
|
<code>long</code>,
|
|
<code>unsigned-char</code>,
|
|
<code>unsigned-short</code>,
|
|
<code>unsigned-int</code>,
|
|
<code>unsigned-long</code>,
|
|
<code>float</code>, <code>double</code>,
|
|
<code>size-t</code>, and <code>off-t</code>.
|
|
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="Operations-On-Foreign-Values"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Variables" accesskey="n" rel="next">Foreign Variables</a>, Previous: <a href="index.html#Foreign-Types" accesskey="p" rel="prev">Foreign Types</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Operations-On-Foreign-Values-1"></span><h3 class="section">9.3 Operations On Foreign Values</h3>
|
|
|
|
<p>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.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Accessing-Foreign-Values" accesskey="1">Accessing Foreign Values</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Coercing-Foreign-Values" accesskey="2">Coercing Foreign Values</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-Dynamic-Allocation" accesskey="3">Foreign Dynamic Allocation</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Accessing-Foreign-Values"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Coercing-Foreign-Values" accesskey="n" rel="next">Coercing Foreign Values</a>, Up: <a href="index.html#Operations-On-Foreign-Values" accesskey="u" rel="up">Operations On Foreign Values</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Accessing-Foreign-Values-1"></span><h4 class="subsection">9.3.1 Accessing Foreign Values</h4>
|
|
|
|
<dl>
|
|
<dt id="index-deref">Function: <strong>deref</strong> <em>[sb-alien] <var>pointer-or-array</var> &rest <var>indices</var></em></dt>
|
|
<dd>
|
|
<p>The <code>sb-alien:deref</code> 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. <code>deref</code> can be set with <code>setf</code> to assign a new
|
|
value.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-slot">Function: <strong>slot</strong> <em>[sb-alien] <var>struct-or-union</var> <var>slot-name</var></em></dt>
|
|
<dd>
|
|
<p>The <code>sb-alien:slot</code> function extracts the value of the slot named
|
|
<var>slot-name</var> from a foreign <code>struct</code> or <code>union</code>. If
|
|
<var>struct-or-union</var> is a pointer to a structure or union, then it is
|
|
automatically dereferenced. <code>sb-alien:slot</code> can be set with
|
|
<code>setf</code> to assign a new value. Note that <var>slot-name</var> is
|
|
evaluated, and need not be a compile-time constant (but only constant
|
|
slot accesses are efficiently compiled).
|
|
</p></dd></dl>
|
|
|
|
|
|
<span id="Untyped-memory"></span><h4 class="subsubsection">9.3.1.1 Untyped memory</h4>
|
|
|
|
<p>As noted at the beginning of the chapter, the System Area Pointer
|
|
facilities allow untyped access to foreign memory. <acronym>SAP</acronym>s can
|
|
be converted to and from the usual typed foreign values using
|
|
<code>sap-alien</code> and <code>alien-sap</code> (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
|
|
<acronym>SAP</acronym>s is trivial.
|
|
</p>
|
|
<dl>
|
|
<dt id="index-int_002dsap">Function: <strong>int-sap</strong> <em>[sb-sys] <var>machine-address</var></em></dt>
|
|
<dd>
|
|
<p>Creates a <acronym>SAP</acronym> pointing at the virtual address
|
|
<var>machine-address</var>.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-sap_002dref_002d32">Function: <strong>sap-ref-32</strong> <em>[sb-sys] <var>sap</var> <var>offset</var></em></dt>
|
|
<dd>
|
|
<p>Access the value of the memory location at <var>offset</var> bytes from
|
|
<var>sap</var>. This form may also be used with <code>setf</code> to alter the
|
|
memory at that location.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-sap_003d">Function: <strong>sap=</strong> <em>[sb-sys] <var>sap1</var> <var>sap2</var></em></dt>
|
|
<dd>
|
|
<p>Compare <var>sap1</var> and <var>sap2</var> for equality.
|
|
</p></dd></dl>
|
|
|
|
<p>Similarly named functions exist for accessing other sizes of word,
|
|
other comparisons, and other conversions. The reader is invited to
|
|
use <code>apropos</code> and <code>describe</code> for more details
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(apropos "sap" :sb-sys)
|
|
</pre></div>
|
|
|
|
|
|
<hr>
|
|
<span id="Coercing-Foreign-Values"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Dynamic-Allocation" accesskey="n" rel="next">Foreign Dynamic Allocation</a>, Previous: <a href="index.html#Accessing-Foreign-Values" accesskey="p" rel="prev">Accessing Foreign Values</a>, Up: <a href="index.html#Operations-On-Foreign-Values" accesskey="u" rel="up">Operations On Foreign Values</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Coercing-Foreign-Values-1"></span><h4 class="subsection">9.3.2 Coercing Foreign Values</h4>
|
|
|
|
<dl>
|
|
<dt id="index-addr">Macro: <strong>addr</strong> <em>[sb-alien] <var>alien-expr</var></em></dt>
|
|
<dd>
|
|
<p>The <code>sb-alien:addr</code> macro returns a pointer to the location
|
|
specified by <var>alien-expr</var>, which must be either a foreign
|
|
variable, a use of <code>sb-alien:deref</code>, a use of
|
|
<code>sb-alien:slot</code>, or a use of <code>sb-alien:extern-alien</code>.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-cast">Macro: <strong>cast</strong> <em>[sb-alien] <var>foreign-value</var> <var>new-type</var></em></dt>
|
|
<dd>
|
|
<p>The <code>sb-alien:cast</code> macro converts <var>foreign-value</var> to a new
|
|
foreign value with the specified <var>new-type</var>. Both types, old and
|
|
new, must be foreign pointer, array or function types. Note that the
|
|
resulting Lisp foreign variable object is not <code>eq</code> to the
|
|
argument, but it does refer to the same foreign data bits.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-sap_002dalien">Macro: <strong>sap-alien</strong> <em>[sb-alien] <var>sap</var> <var>type</var></em></dt>
|
|
<dd>
|
|
<p>The <code>sb-alien:sap-alien</code> macro converts <var>sap</var> (a system
|
|
area pointer) to a foreign value with the specified
|
|
<var>type</var>. <var>type</var> is not evaluated.
|
|
</p>
|
|
<p>The <var>type</var> must be some foreign pointer, array, or record type.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-alien_002dsap">Function: <strong>alien-sap</strong> <em>[sb-alien] <var>foreign-value</var></em></dt>
|
|
<dd>
|
|
<p>The <code>sb-alien:alien-sap</code> function returns the <acronym>SAP</acronym> which
|
|
points to <var>alien-value</var>’s data.
|
|
</p>
|
|
<p>The <var>foreign-value</var> must be of some foreign pointer, array, or
|
|
record type.
|
|
</p></dd></dl>
|
|
|
|
|
|
<hr>
|
|
<span id="Foreign-Dynamic-Allocation"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Coercing-Foreign-Values" accesskey="p" rel="prev">Coercing Foreign Values</a>, Up: <a href="index.html#Operations-On-Foreign-Values" accesskey="u" rel="up">Operations On Foreign Values</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Dynamic-Allocation-1"></span><h4 class="subsection">9.3.3 Foreign Dynamic Allocation</h4>
|
|
|
|
<p>Lisp code can call the C standard library functions <code>malloc</code> and
|
|
<code>free</code> 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 <code>free</code> on the result of Lisp
|
|
<code>sb-alien:make-alien</code>, or for Lisp code to call
|
|
<code>sb-alien:free-alien</code> on foreign objects allocated by C code.
|
|
</p>
|
|
<span id="Macro-sb_002dalien-make_002dalien"></span><dl>
|
|
<dt id="index-make_002dalien">Macro: <strong>make-alien</strong> <em>[sb-alien] type &optional size</em></dt>
|
|
<dd><p>Allocate an alien of type <code>type</code> 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
|
|
<code>free-alien</code>.
|
|
</p>
|
|
<p>For alien stack allocation, see macro <code>with-alien</code>.
|
|
</p>
|
|
<p>The <code>type</code> argument is not evaluated. If <code>size</code> is supplied, how it is
|
|
interpreted depends on <code>type:</code>
|
|
</p>
|
|
<ul>
|
|
<li> When <code>type</code> is a foreign array type, an array of that type is
|
|
allocated, and a pointer to it is returned. Note that you
|
|
must use <code>deref</code> to first access the array through the pointer.
|
|
|
|
<p>If supplied, <code>size</code> is used as the first dimension for the array.
|
|
</p>
|
|
</li><li> When <code>type</code> 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 (<code>*</code> int).
|
|
|
|
<p>If <code>size</code> is specified, then a block of that many objects is
|
|
allocated, with the result pointing to the first one.
|
|
</p>
|
|
</li></ul>
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (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)))
|
|
</pre></div>
|
|
</dd></dl>
|
|
<span id="Function-sb_002dalien-make_002dalien_002dstring"></span><dl>
|
|
<dt id="index-make_002dalien_002dstring">Function: <strong>make-alien-string</strong> <em>[sb-alien] string &rest rest &key start end external-format null-terminate</em></dt>
|
|
<dd><p>Copy part of <code>string</code> delimited by <code>start</code> and <code>end</code> into freshly
|
|
allocated foreign memory, freeable using free(3) or <code>free-alien</code>.
|
|
Returns the allocated string as a (<code>*</code> <code>char</code>) alien, and the number of
|
|
bytes allocated as secondary value.
|
|
</p>
|
|
<p>The string is encoded using <code>external-format</code>. If <code>null-terminate</code> is
|
|
true (the default), the alien string is terminated by an additional
|
|
null byte.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dalien-free_002dalien"></span><dl>
|
|
<dt id="index-free_002dalien">Function: <strong>free-alien</strong> <em>[sb-alien] alien</em></dt>
|
|
<dd><p>Dispose of the storage pointed to by <code>alien</code>. The <code>alien</code> must have been
|
|
allocated by <code>make-alien</code>, <code>make-alien-string</code> or malloc(3).
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Foreign-Variables"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Data-Structure-Examples" accesskey="n" rel="next">Foreign Data Structure Examples</a>, Previous: <a href="index.html#Operations-On-Foreign-Values" accesskey="p" rel="prev">Operations On Foreign Values</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Variables-1"></span><h3 class="section">9.4 Foreign Variables</h3>
|
|
|
|
<p>Both local (stack allocated) and external (C global) foreign variables
|
|
are supported.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Local-Foreign-Variables" accesskey="1">Local Foreign Variables</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#External-Foreign-Variables" accesskey="2">External Foreign Variables</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Local-Foreign-Variables"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#External-Foreign-Variables" accesskey="n" rel="next">External Foreign Variables</a>, Up: <a href="index.html#Foreign-Variables" accesskey="u" rel="up">Foreign Variables</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Local-Foreign-Variables-1"></span><h4 class="subsection">9.4.1 Local Foreign Variables</h4>
|
|
|
|
<dl>
|
|
<dt id="index-with_002dalien">Macro: <strong>with-alien</strong> <em>[sb-alien] <var>var-definitions</var> &body <var>body</var></em></dt>
|
|
<dd>
|
|
<p>The <code>with-alien</code> 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
|
|
<code>LET</code>-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.
|
|
</p>
|
|
<p>The <var>var-definitions</var> argument is a list of
|
|
variable definitions, each of the form
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(<var>name</var> <var>type</var> &optional <var>initial-value</var>)
|
|
</pre></div>
|
|
|
|
<p>The names of the variables are established as symbol-macros; the
|
|
bindings have lexical scope, and may be assigned with <code>setq</code> or
|
|
<code>setf</code>.
|
|
</p>
|
|
<p>The <code>with-alien</code> macro also establishes a new scope for named
|
|
structures and unions. Any <var>type</var> 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 <var>foo</var> can be referenced by its name
|
|
using <code>(struct <var>foo</var>)</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="External-Foreign-Variables"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Local-Foreign-Variables" accesskey="p" rel="prev">Local Foreign Variables</a>, Up: <a href="index.html#Foreign-Variables" accesskey="u" rel="up">Foreign Variables</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="External-Foreign-Variables-1"></span><h4 class="subsection">9.4.2 External Foreign Variables</h4>
|
|
|
|
<p>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 <code>extern-alien</code>, <code>define-alien-variable</code> and
|
|
<code>define-alien-routine</code> use this conversion heuristic:
|
|
</p>
|
|
<ul>
|
|
<li> Alien names are converted to Lisp names by uppercasing and replacing
|
|
underscores with hyphens.
|
|
|
|
</li><li> Conversely, Lisp names are converted to alien names by lowercasing and
|
|
replacing hyphens with underscores.
|
|
|
|
</li><li> Both the Lisp symbol and alien string names may be separately
|
|
specified by using a list of the form
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">(alien-string lisp-symbol)
|
|
</pre></div>
|
|
|
|
</li></ul>
|
|
|
|
<dl>
|
|
<dt id="index-define_002dalien_002dvariable">Macro: <strong>define-alien-variable</strong> <em>[sb-alien] <var>name</var> <var>type</var></em></dt>
|
|
<dd>
|
|
<p>The <code>define-alien-variable</code> macro defines <var>name</var> as an
|
|
external foreign variable of the specified foreign <code>type</code>.
|
|
<var>name</var> and <code>type</code> 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 <code>type</code>. Someday, they may well be implemented
|
|
using the <acronym>ANSI</acronym> <code>define-symbol-macro</code> mechanism, but as
|
|
of SBCL 0.7.5, they are still implemented using an older more-or-less
|
|
parallel mechanism inherited from CMUCL.
|
|
</p>
|
|
<p>For example, to access a C-level counter <var>foo</var>, one could write
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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)
|
|
</pre></div>
|
|
</dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-get_002derrno">Function: <strong>get-errno</strong> <em>[sb-alien]</em></dt>
|
|
<dd>
|
|
<p>Since in modern C libraries, the <code>errno</code> “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
|
|
<code>define-alien-variable</code> mechanism. Instead, SBCL provides
|
|
the operator <code>sb-alien:get-errno</code> to allow Lisp code to read it.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-extern_002dalien">Macro: <strong>extern-alien</strong> <em>[sb-alien] <var>name</var> <var>type</var></em></dt>
|
|
<dd>
|
|
<p>The <code>extern-alien</code> macro returns an alien with the specified
|
|
<var>type</var> which points to an externally defined value. <var>name</var> is
|
|
not evaluated, and may be either a string or a symbol. <var>type</var> is
|
|
an unevaluated alien type specifier.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Foreign-Data-Structure-Examples"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Loading-Shared-Object-Files" accesskey="n" rel="next">Loading Shared Object Files</a>, Previous: <a href="index.html#Foreign-Variables" accesskey="p" rel="prev">Foreign Variables</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Data-Structure-Examples-1"></span><h3 class="section">9.5 Foreign Data Structure Examples</h3>
|
|
|
|
<p>Now that we have alien types, operations and variables, we can
|
|
manipulate foreign data structures. This C declaration
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">struct foo {
|
|
int a;
|
|
struct foo *b[100];
|
|
};
|
|
</pre></div>
|
|
|
|
<p>can be translated into the following alien type:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(define-alien-type nil
|
|
(struct foo
|
|
(a int)
|
|
(b (array (* (struct foo)) 100))))
|
|
</pre></div>
|
|
|
|
<p>Once the <code>foo</code> alien type has been defined as above, the C
|
|
expression
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">struct foo f;
|
|
f.b[7].a;
|
|
</pre></div>
|
|
|
|
<p>can be translated in this way:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(with-alien ((f (struct foo)))
|
|
(slot (deref (slot f 'b) 7) 'a)
|
|
;;
|
|
;; Do something with f...
|
|
)
|
|
</pre></div>
|
|
|
|
<p>Or consider this example of an external C variable and some accesses:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">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;
|
|
</pre></div>
|
|
|
|
<p>which can be manipulated in Lisp like this:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(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))
|
|
</pre></div>
|
|
|
|
<hr>
|
|
<span id="Loading-Shared-Object-Files"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-Function-Calls" accesskey="n" rel="next">Foreign Function Calls</a>, Previous: <a href="index.html#Foreign-Data-Structure-Examples" accesskey="p" rel="prev">Foreign Data Structure Examples</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Loading-Shared-Object-Files-1"></span><h3 class="section">9.6 Loading Shared Object Files</h3>
|
|
|
|
<p>Foreign object files can be loaded into the running Lisp process by
|
|
calling <code>load-shared-object</code>.
|
|
</p>
|
|
<span id="Function-sb_002dalien-load_002dshared_002dobject"></span><dl>
|
|
<dt id="index-load_002dshared_002dobject">Function: <strong>load-shared-object</strong> <em>[sb-alien] pathname &key dont-save</em></dt>
|
|
<dd><p>Load a shared library / dynamic shared object file / similar foreign
|
|
container specified by designated <code>pathname</code>, such as a .so on an <code>elf</code> platform.
|
|
</p>
|
|
<p>Locating the shared object follows standard rules of the platform, consult the
|
|
manual page for dlopen(3) for details. Typically paths specified by
|
|
environment variables such as LD_LIBRARY_PATH are searched if the <code>pathname</code> has
|
|
no directory, but on some systems (eg. Mac <code>os</code> <code>x</code>) search may happen even if
|
|
<code>pathname</code> is absolute. (On Windows LoadLibrary is used instead of dlopen(3).)
|
|
</p>
|
|
<p>On non-Windows platforms calling <code>load-shared-object</code> again with a <code>pathname</code>
|
|
<code>equal</code> to the designated pathname of a previous call will replace the old
|
|
definitions; if a symbol was previously referenced through the object and
|
|
is not present in the reloaded version an error will be signalled. Reloading
|
|
may not work as expected if user or library-code has called dlopen(3) on the
|
|
same shared object or running on a system where dlclose(3) is a noop.
|
|
</p>
|
|
<p><code>load-shared-object</code> interacts with <code>sb-ext:save-lisp-and-die:</code>
|
|
</p>
|
|
<p>1. If <code>dont-save</code> is true (default is <code>nil</code>), the shared object will be dropped
|
|
when <code>save-lisp-and-die</code> is called <code>--</code> otherwise shared objects are reloaded
|
|
automatically when a saved core starts up. Specifying <code>dont-save</code> can be useful
|
|
when the location of the shared object on startup is uncertain.
|
|
</p>
|
|
<p>2. On most platforms references in compiled code to foreign symbols in shared
|
|
objects (such as those generated by <code>define-alien-routine</code>) remain valid across
|
|
<code>save-lisp-and-die</code>. On those platforms where this is not supported, a <code>warning</code>
|
|
will be signalled when the core is saved <code>--</code> this is orthogonal from <code>dont-save</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dalien-unload_002dshared_002dobject"></span><dl>
|
|
<dt id="index-unload_002dshared_002dobject">Function: <strong>unload-shared-object</strong> <em>[sb-alien] pathname</em></dt>
|
|
<dd><p>Unloads the shared object loaded earlier using the designated <code>pathname</code> with
|
|
<code>load-shared-object</code>, to the degree supported on the platform.
|
|
</p>
|
|
<p>Experimental.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Foreign-Function-Calls"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Calling-Lisp-From-C" accesskey="n" rel="next">Calling Lisp From C</a>, Previous: <a href="index.html#Loading-Shared-Object-Files" accesskey="p" rel="prev">Loading Shared Object Files</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-Function-Calls-1"></span><h3 class="section">9.7 Foreign Function Calls</h3>
|
|
|
|
<p>The foreign function call interface allows a Lisp program to call
|
|
many functions written in languages that use the C calling convention.
|
|
</p>
|
|
<p>Lisp sets up various signal handling routines and other environment
|
|
information when it first starts up, and expects these to be in place
|
|
at all times. The C functions called by Lisp should not change the
|
|
environment, especially the signal handlers: the signal handlers
|
|
installed by Lisp typically have interesting flags set (e.g to request
|
|
machine context information, or for signal delivery on an alternate
|
|
stack) which the Lisp runtime relies on for correct operation.
|
|
Precise details of how this works may change without notice between
|
|
versions; the source, or the brain of a friendly SBCL developer, is
|
|
the only documentation. Users of a Lisp built with the
|
|
<code>:sb-thread</code> feature should also read the section about threads,
|
|
<a href="index.html#Threading">Threading</a>.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#The-alien_002dfuncall-Primitive" accesskey="1">The alien-funcall Primitive</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#The-define_002dalien_002droutine-Macro" accesskey="2">The define-alien-routine Macro</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#define_002dalien_002droutine-Example" accesskey="3">define-alien-routine Example</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="The-alien_002dfuncall-Primitive"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#The-define_002dalien_002droutine-Macro" accesskey="n" rel="next">The define-alien-routine Macro</a>, Up: <a href="index.html#Foreign-Function-Calls" accesskey="u" rel="up">Foreign Function Calls</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="The-alien_002dfuncall-Primitive-1"></span><h4 class="subsection">9.7.1 The <code>alien-funcall</code> Primitive</h4>
|
|
|
|
<dl>
|
|
<dt id="index-alien_002dfuncall">Function: <strong>alien-funcall</strong> <em>[sb-alien] <var>alien-function</var> &rest <var>arguments</var></em></dt>
|
|
<dd>
|
|
<p>The <code>alien-funcall</code> function is the foreign function call
|
|
primitive: <var>alien-function</var> is called with the supplied
|
|
<var>arguments</var> and its C return value is returned as a Lisp value.
|
|
The <var>alien-function</var> is an arbitrary run-time expression; to refer
|
|
to a constant function, use <code>extern-alien</code> or a value defined by
|
|
<code>define-alien-routine</code>.
|
|
</p>
|
|
<p>The type of <code>alien-function</code> must be <code>(alien (function
|
|
...))</code> or <code>(alien (* (function ...)))</code>. The function type is
|
|
used to determine how to call the function (as though it was declared
|
|
with a prototype.) The type need not be known at compile time, but
|
|
only known-type calls are efficiently compiled. Limitations:
|
|
</p>
|
|
<ul>
|
|
<li> Structure type return values are not implemented.
|
|
|
|
</li><li> Passing of structures by value is not implemented.
|
|
|
|
</li></ul>
|
|
|
|
</dd></dl>
|
|
|
|
<p>Here is an example which allocates a <code>(struct foo)</code>, calls a
|
|
foreign function to initialize it, then returns a Lisp vector of all
|
|
the <code>(* (struct foo))</code> objects filled in by the foreign call:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">;; Allocate a foo on the stack.
|
|
(with-alien ((f (struct foo)))
|
|
;; Call some C function to fill in foo fields.
|
|
(alien-funcall (extern-alien "mangle_foo" (function void (* foo)))
|
|
(addr f))
|
|
;; Find how many foos to use by getting the A field.
|
|
(let* ((num (slot f 'a))
|
|
(result (make-array num)))
|
|
;; Get a pointer to the array so that we don't have to keep extracting it:
|
|
(with-alien ((a (* (array (* (struct foo)) 100)) (addr (slot f 'b))))
|
|
;; Loop over the first N elements and stash them in the result vector.
|
|
(dotimes (i num)
|
|
(setf (svref result i) (deref (deref a) i)))
|
|
;; Voila.
|
|
result)))
|
|
</pre></div>
|
|
|
|
<hr>
|
|
<span id="The-define_002dalien_002droutine-Macro"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#define_002dalien_002droutine-Example" accesskey="n" rel="next">define-alien-routine Example</a>, Previous: <a href="index.html#The-alien_002dfuncall-Primitive" accesskey="p" rel="prev">The alien-funcall Primitive</a>, Up: <a href="index.html#Foreign-Function-Calls" accesskey="u" rel="up">Foreign Function Calls</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="The-define_002dalien_002droutine-Macro-1"></span><h4 class="subsection">9.7.2 The <code>define-alien-routine</code> Macro</h4>
|
|
|
|
<dl>
|
|
<dt id="index-define_002dalien_002droutine">Macro: <strong>define-alien-routine</strong> <em>[sb-alien] <var>name</var> <var>result-type</var> &rest <var>arg-specifiers</var></em></dt>
|
|
<dd>
|
|
<p>The <code>define-alien-routine</code> macro is a convenience for
|
|
automatically generating Lisp interfaces to simple foreign functions.
|
|
The primary feature is the parameter style specification, which
|
|
translates the C pass-by-reference idiom into additional return
|
|
values.
|
|
</p>
|
|
<p><var>name</var> is usually a string external symbol, but may also be a
|
|
symbol Lisp name or a list of the foreign name and the Lisp name. If
|
|
only one name is specified, the other is automatically derived as for
|
|
<code>extern-alien</code>. <var>result-type</var> is the alien type of the
|
|
return value.
|
|
</p>
|
|
<p>Each element of the <var>arg-specifiers</var> list
|
|
specifies an argument to the foreign function, and is
|
|
of the form
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(aname atype &amp;optional style)
|
|
</pre></div>
|
|
|
|
<p><var>aname</var> is the symbol name of the argument to the constructed
|
|
function (for documentation). <var>atype</var> is the alien type of
|
|
corresponding foreign argument. The semantics of the actual call are
|
|
the same as for <code>alien-funcall</code>. <var>style</var> specifies how this
|
|
argument should be handled at call and return time, and should be one
|
|
of the following:
|
|
</p>
|
|
<ul>
|
|
<li> <code>:in</code> specifies that the argument is passed by value. This is the
|
|
default. <code>:in</code> arguments have no corresponding return value from
|
|
the Lisp function.
|
|
|
|
</li><li> <code>:copy</code> is similar to <code>:in</code>, but the argument is copied to a
|
|
pre-allocated object and a pointer to this object is passed to the
|
|
foreign routine.
|
|
|
|
</li><li> <code>:out</code> specifies a pass-by-reference output value. The type of
|
|
the argument must be a pointer to a fixed-sized object (such as an
|
|
integer or pointer). <code>:out</code> and <code>:in-out</code> style cannot be
|
|
used with pointers to arrays, records or functions. An object of the
|
|
correct size is allocated on the stack, and its address is passed to
|
|
the foreign function. When the function returns, the contents of this
|
|
location are returned as one of the values of the Lisp function (and
|
|
the location is automatically deallocated).
|
|
|
|
</li><li> <code>:in-out</code> is a combination of <code>:copy</code> and <code>:out</code>. The
|
|
argument is copied to a pre-allocated object and a pointer to this
|
|
object is passed to the foreign routine. On return, the contents of
|
|
this location is returned as an additional value.
|
|
|
|
</li></ul>
|
|
|
|
<blockquote>
|
|
<p>Note: Any efficiency-critical foreign interface function should be inline
|
|
expanded, which can be done by preceding the
|
|
<code>define-alien-routine</code> call with:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(declaim (inline lisp-name))
|
|
</pre></div>
|
|
|
|
<p>In addition to avoiding the Lisp call overhead, this allows
|
|
pointers, word-integers and floats to be passed using non-descriptor
|
|
representations, avoiding consing.)
|
|
</p></blockquote>
|
|
|
|
</dd></dl>
|
|
|
|
<hr>
|
|
<span id="define_002dalien_002droutine-Example"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#The-define_002dalien_002droutine-Macro" accesskey="p" rel="prev">The define-alien-routine Macro</a>, Up: <a href="index.html#Foreign-Function-Calls" accesskey="u" rel="up">Foreign Function Calls</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="define_002dalien_002droutine-Example-1"></span><h4 class="subsection">9.7.3 <code>define-alien-routine</code> Example</h4>
|
|
|
|
<p>Consider the C function <code>cfoo</code> with the following calling
|
|
convention:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">void
|
|
cfoo (str, a, i)
|
|
char *str;
|
|
char *a; /* update */
|
|
int *i; /* out */
|
|
{
|
|
/* body of cfoo(...) */
|
|
}
|
|
</pre></div>
|
|
|
|
<p>This can be described by the following call to
|
|
<code>define-alien-routine</code>:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(define-alien-routine "cfoo" void
|
|
(str c-string)
|
|
(a char :in-out)
|
|
(i int :out))
|
|
</pre></div>
|
|
|
|
<p>The Lisp function <code>cfoo</code> will have two arguments (<var>str</var> and
|
|
<var>a</var>) and two return values (<var>a</var> and <var>i</var>).
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="Calling-Lisp-From-C"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Step_002dBy_002dStep-Example-of-the-Foreign-Function-Interface" accesskey="n" rel="next">Step-By-Step Example of the Foreign Function Interface</a>, Previous: <a href="index.html#Foreign-Function-Calls" accesskey="p" rel="prev">Foreign Function Calls</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Calling-Lisp-From-C-1"></span><h3 class="section">9.8 Calling Lisp From C</h3>
|
|
|
|
<p>SBCL supports the calling of Lisp functions using the C calling
|
|
convention. This is useful for both defining callbacks and for creating
|
|
an interface for calling into Lisp as a shared library directly from C.
|
|
</p>
|
|
<p>The <code>define-alien-callable</code> macro wraps Lisp code and creates a C
|
|
foreign function which can be called with the C calling convention.
|
|
</p>
|
|
<span id="Macro-sb_002dalien-define_002dalien_002dcallable"></span><dl>
|
|
<dt id="index-define_002dalien_002dcallable">Macro: <strong>define-alien-callable</strong> <em>[sb-alien] name result-type typed-lambda-list &body body</em></dt>
|
|
<dd><p>Define an alien callable function in the alien callable namespace with result
|
|
type <code>result-type</code> and with lambda list specifying the alien types of the
|
|
arguments.
|
|
</p></dd></dl>
|
|
|
|
<p>The <code>alien-callable-function</code> function returns the foreign callable
|
|
value associated with any name defined by <code>define-alien-callable</code>,
|
|
so that we can, for example, pass the callable value to C as a callback.
|
|
</p>
|
|
<span id="Function-sb_002dalien-alien_002dcallable_002dfunction"></span><dl>
|
|
<dt id="index-alien_002dcallable_002dfunction">Function: <strong>alien-callable-function</strong> <em>[sb-alien] name</em></dt>
|
|
<dd><p>Return the alien callable function associated with <code>name</code>.
|
|
</p></dd></dl>
|
|
|
|
<p>Note that the garbage collector moves objects, and won’t be able to fix
|
|
up any references in C variables. There are three mechanisms for coping
|
|
with this:
|
|
</p>
|
|
<ol>
|
|
<li> The <code>sb-ext:purify</code> moves all live Lisp data into static or
|
|
read-only areas such that it will never be moved (or freed) again in the
|
|
life of the Lisp session
|
|
|
|
</li><li> <code>sb-sys:with-pinned-objects</code> is a macro which arranges for some set
|
|
of objects to be pinned in memory for the dynamic extent of its body
|
|
forms. On ports which use the generational garbage collector (most, as
|
|
of this writing) this affects exactly the specified objects. On other
|
|
ports it is implemented by turning off GC for the duration (so could be
|
|
said to have a whole-world granularity).
|
|
|
|
</li><li> Disable GC, using the <code>without-gcing</code> macro.
|
|
</li></ol>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Lisp-as-a-Shared-Library" accesskey="1">Lisp as a Shared Library</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Lisp-as-a-Shared-Library"></span><div class="header">
|
|
<p>
|
|
Up: <a href="index.html#Calling-Lisp-From-C" accesskey="u" rel="up">Calling Lisp From C</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Lisp-as-a-Shared-Library-1"></span><h4 class="subsection">9.8.1 Lisp as a Shared Library</h4>
|
|
<p>SBCL supports the use of Lisp as a shared library that can be used by C
|
|
programs using the <code>define-alien-callable</code> interface. See the
|
|
<code>:callable-exports</code> keyword to <code>save-lisp-and-die</code> for how to
|
|
save the Lisp image in a way that allows a C program to initialize the
|
|
Lisp runtime and the exported symbols. When SBCL is built as a library,
|
|
it exposes the symbol <code>initialize_lisp</code> which can be used in
|
|
conjunction with a core initializing global symbols to foreign callables
|
|
as function pointers and with object code allocating those symbols to
|
|
initialize the runtime properly. The arguments to <code>initialize_lisp</code>
|
|
are the same as the arguments to the main <code>sbcl</code>
|
|
program.
|
|
</p>
|
|
<p>Note: There is currently no way to run exit hooks or otherwise undo
|
|
Lisp initialization gracefully from C.
|
|
</p>
|
|
<hr>
|
|
<span id="Step_002dBy_002dStep-Example-of-the-Foreign-Function-Interface"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Calling-Lisp-From-C" accesskey="p" rel="prev">Calling Lisp From C</a>, Up: <a href="index.html#Foreign-Function-Interface" accesskey="u" rel="up">Foreign Function Interface</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Step_002dBy_002dStep-Example-of-the-Foreign-Function-Interface-1"></span><h3 class="section">9.9 Step-By-Step Example of the Foreign Function Interface</h3>
|
|
|
|
<p>This section presents a complete example of an interface to a somewhat
|
|
complicated C function.
|
|
</p>
|
|
<p>Suppose you have the following C function which you want to be able to
|
|
call from Lisp in the file <samp>test.c</samp>
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">struct c_struct
|
|
{
|
|
int x;
|
|
char *s;
|
|
};
|
|
|
|
struct c_struct *c_function (i, s, r, a)
|
|
int i;
|
|
char *s;
|
|
struct c_struct *r;
|
|
int a[10];
|
|
{
|
|
int j;
|
|
struct c_struct *r2;
|
|
|
|
printf("i = %d\n", i);
|
|
printf("s = %s\n", s);
|
|
printf("r->x = %d\n", r->x);
|
|
printf("r->s = %s\n", r->s);
|
|
for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
|
|
r2 = (struct c_struct *) malloc (sizeof(struct c_struct));
|
|
r2->x = i + 5;
|
|
r2->s = "a C string";
|
|
return(r2);
|
|
};
|
|
</pre></div>
|
|
|
|
<p>It is possible to call this C function from Lisp using the file
|
|
<samp>test.lisp</samp> containing
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(cl:defpackage "TEST-C-CALL" (:use "CL" "SB-ALIEN" "SB-C-CALL"))
|
|
(cl:in-package "TEST-C-CALL")
|
|
|
|
;;; Define the record C-STRUCT in Lisp.
|
|
(define-alien-type nil
|
|
(struct c-struct
|
|
(x int)
|
|
(s c-string)))
|
|
|
|
;;; Define the Lisp function interface to the C routine. It returns a
|
|
;;; pointer to a record of type C-STRUCT. It accepts four parameters:
|
|
;;; I, an int; S, a pointer to a string; R, a pointer to a C-STRUCT
|
|
;;; record; and A, a pointer to the array of 10 ints.
|
|
;;;
|
|
;;; The INLINE declaration eliminates some efficiency notes about heap
|
|
;;; allocation of alien values.
|
|
(declaim (inline c-function))
|
|
(define-alien-routine c-function
|
|
(* (struct c-struct))
|
|
(i int)
|
|
(s c-string)
|
|
(r (* (struct c-struct)))
|
|
(a (array int 10)))
|
|
|
|
;;; a function which sets up the parameters to the C function and
|
|
;;; actually calls it
|
|
(defun call-cfun ()
|
|
(with-alien ((ar (array int 10))
|
|
(c-struct (struct c-struct)))
|
|
(dotimes (i 10) ; Fill array.
|
|
(setf (deref ar i) i))
|
|
(setf (slot c-struct 'x) 20)
|
|
(setf (slot c-struct 's) "a Lisp string")
|
|
|
|
(with-alien ((res (* (struct c-struct))
|
|
(c-function 5 "another Lisp string" (addr c-struct) ar)))
|
|
(format t "~&amp;back from C function~%")
|
|
(multiple-value-prog1
|
|
(values (slot res 'x)
|
|
(slot res 's))
|
|
|
|
;; Deallocate result. (after we are done referring to it:
|
|
;; "Pillage, *then* burn.")
|
|
(free-alien res)))))
|
|
</pre></div>
|
|
|
|
<p>To execute the above example, it is necessary to compile the C
|
|
routine, e.g.: ‘<samp>cc -c test.c && ld -shared -o test.so test.o</samp>’ (In
|
|
order to enable incremental loading with some linkers, you may need to
|
|
say ‘<samp>cc -G 0 -c test.c</samp>’)
|
|
</p>
|
|
<p>Once the C code has been compiled, you can start up Lisp and load it in:
|
|
‘<samp>sbcl</samp>’. Lisp should start up with its normal prompt.
|
|
</p>
|
|
<p>Within Lisp, compile the Lisp file. (This step can be done
|
|
separately. You don’t have to recompile every time.)
|
|
‘<samp>(compile-file "test.lisp")</samp>’
|
|
</p>
|
|
<p>Within Lisp, load the foreign object file to define the necessary
|
|
symbols: ‘<samp>(load-shared-object "test.so")</samp>’.
|
|
</p>
|
|
<p>Now you can load the compiled Lisp (“fasl”) file into Lisp:
|
|
‘<samp>(load "test.fasl")</samp>’
|
|
And once the Lisp file is loaded, you can call the
|
|
Lisp routine that sets up the parameters and calls the C
|
|
function:
|
|
‘<samp>(test-c-call::call-cfun)</samp>’
|
|
</p>
|
|
<p>The C routine should print the following information to standard output:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">i = 5
|
|
s = another Lisp string
|
|
r->x = 20
|
|
r->s = a Lisp string
|
|
a[0] = 0.
|
|
a[1] = 1.
|
|
a[2] = 2.
|
|
a[3] = 3.
|
|
a[4] = 4.
|
|
a[5] = 5.
|
|
a[6] = 6.
|
|
a[7] = 7.
|
|
a[8] = 8.
|
|
a[9] = 9.
|
|
</pre></div>
|
|
|
|
<p>After return from the C function,
|
|
the Lisp wrapper function should print the following output:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">back from C function
|
|
</pre></div>
|
|
|
|
<p>And upon return from the Lisp wrapper function,
|
|
before the next prompt is printed, the
|
|
Lisp read-eval-print loop should print the following return values:
|
|
</p>
|
|
<div class="example">
|
|
<pre class="example">10
|
|
"a C string"
|
|
</pre></div>
|
|
<hr>
|
|
<span id="Pathnames"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Streams" accesskey="n" rel="next">Streams</a>, Previous: <a href="index.html#Foreign-Function-Interface" accesskey="p" rel="prev">Foreign Function Interface</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Pathnames-1"></span><h2 class="chapter">10 Pathnames</h2>
|
|
|
|
<span id="index-Pathnames"></span>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Lisp-Pathnames" accesskey="1">Lisp Pathnames</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Native-Filenames" accesskey="2">Native Filenames</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Lisp-Pathnames"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Native-Filenames" accesskey="n" rel="next">Native Filenames</a>, Up: <a href="index.html#Pathnames" accesskey="u" rel="up">Pathnames</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Lisp-Pathnames-1"></span><h3 class="section">10.1 Lisp Pathnames</h3>
|
|
|
|
<p>There are many aspects of ANSI Common Lisp’s pathname support which are
|
|
implementation-defined and so need documentation.
|
|
</p>
|
|
|
|
<span id="Home-Directory-Specifiers"></span><h4 class="subsection">10.1.1 Home Directory Specifiers</h4>
|
|
|
|
<p>SBCL accepts the keyword <code>:home</code> and a list of the form
|
|
<code>(:home "username")</code> as a directory component immediately
|
|
following <code>:absolute</code>.
|
|
</p>
|
|
<p><code>:home</code> is represented in namestrings by <code>~/</code> and
|
|
<code>(:home "username"</code> by <code>~username/</code> at the start of the
|
|
namestring. Tilde-characters elsewhere in namestrings represent
|
|
themselves.
|
|
</p>
|
|
<p>Home directory specifiers are resolved to home directory of the
|
|
current or specified user by <code>native-namestring</code>, which is used
|
|
by the implementation to translate pathnames before passing them on to
|
|
operating system specific routines.
|
|
</p>
|
|
<p>Using <code>(:home "user")</code> form on Windows signals an error.
|
|
</p>
|
|
<span id="The-SYS-Logical-Pathname-Host"></span><h4 class="subsection">10.1.2 The SYS Logical Pathname Host</h4>
|
|
|
|
<span id="index-Logical-pathnames"></span>
|
|
<span id="index-Pathnames_002c-logical"></span>
|
|
<span id="index-logical_002dpathname_002dtranslations-_005bcl_005d"></span>
|
|
<span id="index-_0028setf-logical_002dpathname_002dtranslations-_005bcl_005d_0029"></span>
|
|
|
|
|
|
<p>The logical pathname host named by <code>"SYS"</code> exists in SBCL. Its
|
|
<code>logical-pathname-translations</code> may be set by the site or the user
|
|
applicable to point to the locations of the system’s sources; in
|
|
particular, the core system’s source files match the logical pathname
|
|
<code>"SYS:SRC;**;*.*.*"</code>, and the contributed modules’ source files
|
|
match <code>"SYS:CONTRIB;**;*.*.*"</code>.
|
|
</p>
|
|
<span id="Function-sb_002dext-set_002dsbcl_002dsource_002dlocation"></span><dl>
|
|
<dt id="index-set_002dsbcl_002dsource_002dlocation">Function: <strong>set-sbcl-source-location</strong> <em>[sb-ext] pathname</em></dt>
|
|
<dd><p>Initialize the <code>sys</code> logical host based on <code>pathname</code>, which should be
|
|
the top-level directory of the <code>sbcl</code> sources. This will replace any
|
|
existing translations for "SYS:SRC;", "SYS:CONTRIB;", and
|
|
"SYS:OUTPUT;". Other "SYS:" translations are preserved.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Native-Filenames"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Lisp-Pathnames" accesskey="p" rel="prev">Lisp Pathnames</a>, Up: <a href="index.html#Pathnames" accesskey="u" rel="up">Pathnames</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Native-Filenames-1"></span><h3 class="section">10.2 Native Filenames</h3>
|
|
|
|
<p>In some circumstances, what is wanted is a Lisp pathname object which
|
|
corresponds to a string produced by the Operating System. In this case,
|
|
some of the default parsing rules are inappropriate: most filesystems do
|
|
not have a native understanding of wild pathnames; such functionality is
|
|
often provided by shells above the OS, often in mutually-incompatible
|
|
ways.
|
|
</p>
|
|
<p>To allow the user to deal with this, the following functions are
|
|
provided: <code>parse-native-namestring</code> and <code>native-pathname</code>
|
|
return the closest equivalent Lisp pathname to a given string
|
|
(appropriate for the Operating System), while <code>native-namestring</code>
|
|
converts a non-wild pathname designator to the equivalent native
|
|
namestring, if possible. Some Lisp pathname concepts (such as the
|
|
<code>:back</code> directory component) have no direct equivalents in most
|
|
Operating Systems; the behaviour of <code>native-namestring</code> is
|
|
unspecified if an inappropriate pathname designator is passed to it.
|
|
Additionally, note that conversion from pathname to native filename
|
|
and back to pathname should not be expected to preserve equivalence
|
|
under <code>equal</code>.
|
|
</p>
|
|
<span id="Function-sb_002dext-parse_002dnative_002dnamestring"></span><dl>
|
|
<dt id="index-parse_002dnative_002dnamestring">Function: <strong>parse-native-namestring</strong> <em>[sb-ext] thing &optional host defaults &key start end junk-allowed as-directory</em></dt>
|
|
<dd><p>Convert <code>thing</code> into a pathname, using the native conventions
|
|
appropriate for the pathname host <code>host</code>, or if not specified the
|
|
host of <code>defaults</code>. If <code>thing</code> is a string, the parse is bounded by
|
|
<code>start</code> and <code>end</code>, and error behaviour is controlled by <code>junk-allowed</code>,
|
|
as with <code>parse-namestring</code>. For file systems whose native
|
|
conventions allow directories to be indicated as files, if
|
|
<code>as-directory</code> is true, return a pathname denoting <code>thing</code> as a
|
|
directory.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-native_002dpathname"></span><dl>
|
|
<dt id="index-native_002dpathname">Function: <strong>native-pathname</strong> <em>[sb-ext] pathspec</em></dt>
|
|
<dd><p>Convert <code>pathspec</code> (a pathname designator) into a pathname, assuming
|
|
the operating system native pathname conventions.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-native_002dnamestring"></span><dl>
|
|
<dt id="index-native_002dnamestring">Function: <strong>native-namestring</strong> <em>[sb-ext] pathname &key as-file</em></dt>
|
|
<dd><p>Construct the full native (name)string form of <code>pathname</code>. For
|
|
file systems whose native conventions allow directories to be
|
|
indicated as files, if <code>as-file</code> is true and the name, type, and
|
|
version components of <code>pathname</code> are all <code>nil</code> or <code>:unspecific</code>,
|
|
construct a string that names the directory according to the file
|
|
system’s syntax for files.
|
|
</p></dd></dl>
|
|
|
|
<p>Because some file systems permit the names of directories to be
|
|
expressed in multiple ways, it is occasionally necessary to parse a
|
|
native file name “as a directory name” or to produce a native file
|
|
name that names a directory “as a file”. For these cases,
|
|
<code>parse-native-namestring</code> accepts the keyword argument
|
|
<code>as-directory</code> to force a filename to parse as a directory, and
|
|
<code>native-namestring</code> accepts the keyword argument <code>as-file</code>
|
|
to force a pathname to unparse as a file. For example,
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">; On Unix, the directory "/tmp/" can be denoted by "/tmp/" or "/tmp".
|
|
; Under the default rules for native filenames, these parse and
|
|
; unparse differently.
|
|
(defvar *p*)
|
|
(setf *p* (parse-native-namestring "/tmp/")) ⇒ #P"/tmp/"
|
|
(pathname-name *p*) ⇒ NIL
|
|
(pathname-directory *p*) ⇒ (:ABSOLUTE "tmp")
|
|
(native-namestring *p*) ⇒ "/tmp/"
|
|
|
|
(setf *p* (parse-native-namestring "/tmp")) ⇒ #P"/tmp"
|
|
(pathname-name *p*) ⇒ "tmp"
|
|
(pathname-directory *p*) ⇒ (:ABSOLUTE)
|
|
(native-namestring *p*) ⇒ "/tmp"
|
|
|
|
; A non-NIL AS-DIRECTORY argument to PARSE-NATIVE-NAMESTRING forces
|
|
; both the second string to parse the way the first does.
|
|
(setf *p* (parse-native-namestring "/tmp"
|
|
nil *default-pathname-defaults*
|
|
:as-directory t)) ⇒ #P"/tmp/"
|
|
(pathname-name *p*) ⇒ NIL
|
|
(pathname-directory *p*) ⇒ (:ABSOLUTE "tmp")
|
|
|
|
; A non-NIL AS-FILE argument to NATIVE-NAMESTRING forces the pathname
|
|
; parsed from the first string to unparse as the second string.
|
|
(setf *p* (parse-native-namestring "/tmp/")) ⇒ #P"/tmp/"
|
|
(native-namestring *p* :as-file t) ⇒ "/tmp"
|
|
</pre></div>
|
|
<hr>
|
|
<span id="Streams"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Package-Locks" accesskey="n" rel="next">Package Locks</a>, Previous: <a href="index.html#Pathnames" accesskey="p" rel="prev">Pathnames</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Streams-1"></span><h2 class="chapter">11 Streams</h2>
|
|
|
|
<p>Streams which read or write Lisp character data from or to the outside
|
|
world – files, sockets or other external entities – require the
|
|
specification of a conversion between the external, binary data and the
|
|
Lisp characters. In ANSI Common Lisp, this is done by specifying the
|
|
<code>:external-format</code> argument when the stream is created. The major
|
|
information required is an <em>encoding</em>, specified by a keyword
|
|
naming that encoding; however, it is also possible to specify
|
|
refinements to that encoding as additional options to the external
|
|
format designator.
|
|
</p>
|
|
<p>In addition, SBCL supports various extensions of ANSI Common Lisp
|
|
streams:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><strong>Bivalent Streams</strong></dt>
|
|
<dd><p>A type of stream that can read and write both <code>character</code> and
|
|
<code>(unsigned-byte 8)</code> values.
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Gray Streams</strong></dt>
|
|
<dd><p>User-overloadable CLOS classes whose instances can be used as Lisp
|
|
streams (e.g. passed as the first argument to <code>format</code>).
|
|
</p>
|
|
</dd>
|
|
<dt><strong>Simple Streams</strong></dt>
|
|
<dd><p>The bundled contrib module <em>sb-simple-streams</em> implements a subset
|
|
of the Franz Allegro simple-streams proposal.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Stream-External-Formats" accesskey="1">Stream External Formats</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Bivalent-Streams" accesskey="2">Bivalent Streams</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Gray-Streams" accesskey="3">Gray Streams</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Simple-Streams" accesskey="4">Simple Streams</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Stream-External-Formats"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Bivalent-Streams" accesskey="n" rel="next">Bivalent Streams</a>, Up: <a href="index.html#Streams" accesskey="u" rel="up">Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Stream-External-Formats-1"></span><h3 class="section">11.1 Stream External Formats</h3>
|
|
<span id="index-Stream-External-formats"></span>
|
|
|
|
<span id="index-stream_002dexternal_002dformat-_005bcl_005d"></span>
|
|
<p>The function <code>stream-external-format</code> returns the canonical name of
|
|
the external format (See <a href="index.html#External-Formats">External Formats</a>) used by the stream for
|
|
character-based input and/or output.
|
|
</p>
|
|
<span id="index-open-_005bcl_005d-1"></span>
|
|
<span id="index-with_002dopen_002dfile-_005bcl_005d-1"></span>
|
|
<p>When constructing file streams, for example using <code>open</code> or
|
|
<code>with-open-file</code>, the external format to use is specified via the
|
|
<code>:external-format</code> argument which accepts an external format
|
|
designator (See <a href="index.html#External-Format-Designators">External Format Designators</a>).
|
|
</p>
|
|
<hr>
|
|
<span id="Bivalent-Streams"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Gray-Streams" accesskey="n" rel="next">Gray Streams</a>, Previous: <a href="index.html#Stream-External-Formats" accesskey="p" rel="prev">Stream External Formats</a>, Up: <a href="index.html#Streams" accesskey="u" rel="up">Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Bivalent-Streams-1"></span><h3 class="section">11.2 Bivalent Streams</h3>
|
|
|
|
<p>A <em>bivalent stream</em> can be used to read and write both
|
|
<code>character</code> and <code>(unsigned-byte 8)</code> values. A bivalent
|
|
stream is created by calling <code>open</code> with the argument <code>:element-type
|
|
:default</code>. On such a stream, both binary and character data can be
|
|
read and written with the usual input and output functions.
|
|
</p>
|
|
<blockquote>
|
|
<p>Streams are <em>not</em> created bivalent by default for performance
|
|
reasons. Bivalent streams are incompatible with
|
|
<code>fast-read-char</code>, an internal optimization in SBCL’s stream
|
|
machinery that bulk-converts octets to characters and implements a
|
|
fast path through <code>read-char</code>.
|
|
</p></blockquote>
|
|
|
|
<hr>
|
|
<span id="Gray-Streams"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Simple-Streams" accesskey="n" rel="next">Simple Streams</a>, Previous: <a href="index.html#Bivalent-Streams" accesskey="p" rel="prev">Bivalent Streams</a>, Up: <a href="index.html#Streams" accesskey="u" rel="up">Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Gray-Streams-1"></span><h3 class="section">11.3 Gray Streams</h3>
|
|
|
|
|
|
<p>The Gray Streams interface is a widely supported extension that
|
|
provides for definition of CLOS-extensible stream classes. Gray
|
|
stream classes are implemented by adding methods to generic functions
|
|
analogous to Common Lisp’s standard I/O functions. Instances of Gray
|
|
stream classes may be used with any I/O operation where a non-Gray
|
|
stream can, provided that all required methods have been implemented
|
|
suitably.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Gray-Streams-classes" accesskey="1">Gray Streams classes</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Methods-common-to-all-streams" accesskey="2">Methods common to all streams</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Input-stream-methods" accesskey="3">Input stream methods</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Character-input-stream-methods" accesskey="4">Character input stream methods</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Output-stream-methods" accesskey="5">Output stream methods</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Character-output-stream-methods" accesskey="6">Character output stream methods</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Binary-stream-methods" accesskey="7">Binary stream methods</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Gray-Streams-examples" accesskey="8">Gray Streams examples</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Gray-Streams-classes"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Methods-common-to-all-streams" accesskey="n" rel="next">Methods common to all streams</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Gray-Streams-classes-1"></span><h4 class="subsection">11.3.1 Gray Streams classes</h4>
|
|
|
|
<p>The defined Gray Stream classes are these:
|
|
</p>
|
|
<span id="Class-sb_002dgray-fundamental_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dstream">Class: <strong>fundamental-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Base class for all Gray streams.
|
|
</p></dd></dl>
|
|
<span id="Class-sb_002dgray-fundamental_002dinput_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dinput_002dstream">Class: <strong>fundamental-input-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-input-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray input streams.
|
|
</p></dd></dl>
|
|
|
|
<p>The function input-stream-p will return true of any generalized
|
|
instance of fundamental-input-stream.
|
|
</p>
|
|
<span id="Class-sb_002dgray-fundamental_002doutput_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002doutput_002dstream">Class: <strong>fundamental-output-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-output-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray output streams.
|
|
</p></dd></dl>
|
|
|
|
<p>The function output-stream-p will return true of any generalized
|
|
instance of fundamental-output-stream.
|
|
</p>
|
|
<span id="Class-sb_002dgray-fundamental_002dbinary_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dbinary_002dstream">Class: <strong>fundamental-binary-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-binary-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray streams whose element-type
|
|
is a subtype of unsigned-byte or signed-byte.
|
|
</p></dd></dl>
|
|
|
|
<p>Note that instantiable subclasses of fundamental-binary-stream should
|
|
provide (or inherit) an applicable method for the generic function
|
|
stream-element-type.
|
|
</p>
|
|
<span id="Class-sb_002dgray-fundamental_002dcharacter_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dcharacter_002dstream">Class: <strong>fundamental-character-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-character-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray streams whose element-type is a subtype of character.
|
|
</p></dd></dl>
|
|
<span id="Class-sb_002dgray-fundamental_002dbinary_002dinput_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dbinary_002dinput_002dstream">Class: <strong>fundamental-binary-input-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-binary-input-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-input-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-binary-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray input streams whose element-type
|
|
is a subtype of unsigned-byte or signed-byte.
|
|
</p></dd></dl>
|
|
<span id="Class-sb_002dgray-fundamental_002dbinary_002doutput_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dbinary_002doutput_002dstream">Class: <strong>fundamental-binary-output-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-binary-output-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-output-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-binary-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray output streams whose element-type
|
|
is a subtype of unsigned-byte or signed-byte.
|
|
</p></dd></dl>
|
|
<span id="Class-sb_002dgray-fundamental_002dcharacter_002dinput_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dcharacter_002dinput_002dstream">Class: <strong>fundamental-character-input-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-character-input-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-input-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-character-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray input streams whose element-type
|
|
is a subtype of character.
|
|
</p></dd></dl>
|
|
<span id="Class-sb_002dgray-fundamental_002dcharacter_002doutput_002dstream"></span><dl>
|
|
<dt id="index-fundamental_002dcharacter_002doutput_002dstream">Class: <strong>fundamental-character-output-stream</strong> <em>[sb-gray]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">fundamental-character-output-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-output-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-character-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">fundamental-stream</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>stream<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass of all Gray output streams whose element-type
|
|
is a subtype of character.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Methods-common-to-all-streams"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Input-stream-methods" accesskey="n" rel="next">Input stream methods</a>, Previous: <a href="index.html#Gray-Streams-classes" accesskey="p" rel="prev">Gray Streams classes</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Methods-common-to-all-streams-1"></span><h4 class="subsection">11.3.2 Methods common to all streams</h4>
|
|
|
|
<p>These generic functions can be specialized on any generalized instance
|
|
of fundamental-stream.
|
|
</p>
|
|
<span id="Generic_002dFunction-common_002dlisp-stream_002delement_002dtype"></span><dl>
|
|
<dt id="index-stream_002delement_002dtype">Generic Function: <strong>stream-element-type</strong> <em>[cl] stream</em></dt>
|
|
<dd><p>Return a type specifier for the kind of object returned by the
|
|
<code>stream</code>. The class <code>fundamental-character-stream</code> provides a default method
|
|
which returns <code>character</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-common_002dlisp-close"></span><dl>
|
|
<dt id="index-close">Generic Function: <strong>close</strong> <em>[cl] stream &key abort</em></dt>
|
|
<dd><p>Close the given <code>stream</code>. No more I/O may be performed, but
|
|
inquiries may still be made. If <code>:abort</code> is true, an attempt is made
|
|
to clean up the side effects of having created the stream.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dfile_002dposition"></span><dl>
|
|
<dt id="index-stream_002dfile_002dposition">Generic Function: <strong>stream-file-position</strong> <em>[sb-gray] stream &optional position-spec</em></dt>
|
|
<dd><p>Used by <code>file-position</code>. Returns or changes the current position within <code>stream</code>.
|
|
</p></dd></dl>
|
|
|
|
|
|
|
|
<hr>
|
|
<span id="Input-stream-methods"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Character-input-stream-methods" accesskey="n" rel="next">Character input stream methods</a>, Previous: <a href="index.html#Methods-common-to-all-streams" accesskey="p" rel="prev">Methods common to all streams</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Input-stream-methods-1"></span><h4 class="subsection">11.3.3 Input stream methods</h4>
|
|
|
|
<p>These generic functions may be specialized on any generalized instance
|
|
of fundamental-input-stream.
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dclear_002dinput"></span><dl>
|
|
<dt id="index-stream_002dclear_002dinput">Generic Function: <strong>stream-clear-input</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>This is like <code>cl:clear-input</code>, but for Gray streams, returning <code>nil</code>.
|
|
The default method does nothing.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dread_002dsequence"></span><dl>
|
|
<dt id="index-stream_002dread_002dsequence">Generic Function: <strong>stream-read-sequence</strong> <em>[sb-gray] stream seq &optional start end</em></dt>
|
|
<dd><p>This is like <code>cl:read-sequence</code>, but for Gray streams.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Character-input-stream-methods"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Output-stream-methods" accesskey="n" rel="next">Output stream methods</a>, Previous: <a href="index.html#Input-stream-methods" accesskey="p" rel="prev">Input stream methods</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Character-input-stream-methods-1"></span><h4 class="subsection">11.3.4 Character input stream methods</h4>
|
|
|
|
<p>These generic functions are used to implement subclasses of
|
|
fundamental-input-stream:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dpeek_002dchar"></span><dl>
|
|
<dt id="index-stream_002dpeek_002dchar">Generic Function: <strong>stream-peek-char</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>This is used to implement <code>peek-char</code>; this corresponds to <code>peek-type</code> of <code>nil</code>.
|
|
It returns either a character or <code>:eof</code>. The default method calls
|
|
<code>stream-read-char</code> and <code>stream-unread-char</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dread_002dchar_002dno_002dhang"></span><dl>
|
|
<dt id="index-stream_002dread_002dchar_002dno_002dhang">Generic Function: <strong>stream-read-char-no-hang</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>This is used to implement <code>read-char-no-hang</code>. It returns either a
|
|
character, or <code>nil</code> if no input is currently available, or <code>:eof</code> if
|
|
end-of-file is reached. The default method provided by
|
|
<code>fundamental-character-input-stream</code> simply calls <code>stream-read-char</code>; this
|
|
is sufficient for file streams, but interactive streams should define
|
|
their own method.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dread_002dchar"></span><dl>
|
|
<dt id="index-stream_002dread_002dchar">Generic Function: <strong>stream-read-char</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Read one character from the stream. Return either a
|
|
character object, or the symbol <code>:eof</code> if the stream is at end-of-file.
|
|
Every subclass of <code>fundamental-character-input-stream</code> must define a
|
|
method for this function.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dread_002dline"></span><dl>
|
|
<dt id="index-stream_002dread_002dline">Generic Function: <strong>stream-read-line</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>This is used by <code>read-line</code>. A string is returned as the first value. The
|
|
second value is true if the string was terminated by end-of-file
|
|
instead of the end of a line. The default method uses repeated
|
|
calls to <code>stream-read-char</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dlisten"></span><dl>
|
|
<dt id="index-stream_002dlisten">Generic Function: <strong>stream-listen</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>This is used by <code>listen</code>. It returns true or false. The default method uses
|
|
<code>stream-read-char-no-hang</code> and <code>stream-unread-char</code>. Most streams should
|
|
define their own method since it will usually be trivial and will
|
|
always be more efficient than the default method.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dunread_002dchar"></span><dl>
|
|
<dt id="index-stream_002dunread_002dchar">Generic Function: <strong>stream-unread-char</strong> <em>[sb-gray] stream character</em></dt>
|
|
<dd><p>Undo the last call to <code>stream-read-char</code>, as in <code>unread-char</code>.
|
|
Return <code>nil</code>. Every subclass of <code>fundamental-character-input-stream</code>
|
|
must define a method for this function.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Output-stream-methods"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Character-output-stream-methods" accesskey="n" rel="next">Character output stream methods</a>, Previous: <a href="index.html#Character-input-stream-methods" accesskey="p" rel="prev">Character input stream methods</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Output-stream-methods-1"></span><h4 class="subsection">11.3.5 Output stream methods</h4>
|
|
|
|
<p>These generic functions are used to implement subclasses of
|
|
fundamental-output-stream:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dclear_002doutput"></span><dl>
|
|
<dt id="index-stream_002dclear_002doutput">Generic Function: <strong>stream-clear-output</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>This is like <code>cl:clear-output</code>, but for Gray streams: clear the given
|
|
output <code>stream</code>. The default method does nothing.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dfinish_002doutput"></span><dl>
|
|
<dt id="index-stream_002dfinish_002doutput">Generic Function: <strong>stream-finish-output</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Attempts to ensure that all output sent to the Stream has reached
|
|
its destination, and only then returns false. Implements
|
|
<code>finish-output</code>. The default method does nothing.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dforce_002doutput"></span><dl>
|
|
<dt id="index-stream_002dforce_002doutput">Generic Function: <strong>stream-force-output</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Attempts to force any buffered output to be sent. Implements
|
|
<code>force-output</code>. The default method does nothing.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dwrite_002dsequence"></span><dl>
|
|
<dt id="index-stream_002dwrite_002dsequence">Generic Function: <strong>stream-write-sequence</strong> <em>[sb-gray] stream seq &optional start end</em></dt>
|
|
<dd><p>This is like <code>cl:write-sequence</code>, but for Gray streams.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Character-output-stream-methods"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Binary-stream-methods" accesskey="n" rel="next">Binary stream methods</a>, Previous: <a href="index.html#Output-stream-methods" accesskey="p" rel="prev">Output stream methods</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Character-output-stream-methods-1"></span><h4 class="subsection">11.3.6 Character output stream methods</h4>
|
|
|
|
<p>These generic functions are used to implement subclasses of
|
|
fundamental-character-output-stream:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dadvance_002dto_002dcolumn"></span><dl>
|
|
<dt id="index-stream_002dadvance_002dto_002dcolumn">Generic Function: <strong>stream-advance-to-column</strong> <em>[sb-gray] stream column</em></dt>
|
|
<dd><p>Write enough blank space so that the next character will be
|
|
written at the specified column. Returns true if the operation is
|
|
successful, or <code>nil</code> if it is not supported for this stream. This is
|
|
intended for use by by <code>pprint</code> and <code>format</code> ~T. The default method uses
|
|
<code>stream-line-column</code> and repeated calls to <code>stream-write-char</code> with a
|
|
<code>#space</code> character; it returns <code>nil</code> if <code>stream-line-column</code> returns <code>nil</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dfresh_002dline"></span><dl>
|
|
<dt id="index-stream_002dfresh_002dline">Generic Function: <strong>stream-fresh-line</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Outputs a new line to the Stream if it is not positioned at the
|
|
beginning of a line. Returns <code>t</code> if it output a new line, nil
|
|
otherwise. Used by <code>fresh-line</code>. The default method uses
|
|
<code>stream-start-line-p</code> and <code>stream-terpri</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dline_002dcolumn"></span><dl>
|
|
<dt id="index-stream_002dline_002dcolumn">Generic Function: <strong>stream-line-column</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Return the column number where the next character
|
|
will be written, or <code>nil</code> if that is not meaningful for this stream.
|
|
The first column on a line is numbered 0. This function is used in
|
|
the implementation of <code>pprint</code> and the <code>format</code> ~T directive. For every
|
|
character output stream class that is defined, a method must be
|
|
defined for this function, although it is permissible for it to
|
|
always return <code>nil</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dline_002dlength"></span><dl>
|
|
<dt id="index-stream_002dline_002dlength">Generic Function: <strong>stream-line-length</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Return the stream line length or <code>nil</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dstart_002dline_002dp"></span><dl>
|
|
<dt id="index-stream_002dstart_002dline_002dp">Generic Function: <strong>stream-start-line-p</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Is <code>stream</code> known to be positioned at the beginning of a line?
|
|
It is permissible for an implementation to always return
|
|
<code>nil</code>. This is used in the implementation of <code>fresh-line</code>. Note that
|
|
while a value of 0 from <code>stream-line-column</code> also indicates the
|
|
beginning of a line, there are cases where <code>stream-start-line-p</code> can be
|
|
meaningfully implemented although <code>stream-line-column</code> can’t be. For
|
|
example, for a window using variable-width characters, the column
|
|
number isn’t very meaningful, but the beginning of the line does have
|
|
a clear meaning. The default method for <code>stream-start-line-p</code> on class
|
|
<code>fundamental-character-output-stream</code> uses <code>stream-line-column</code>, so if
|
|
that is defined to return <code>nil</code>, then a method should be provided for
|
|
either <code>stream-start-line-p</code> or <code>stream-fresh-line</code>.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dterpri"></span><dl>
|
|
<dt id="index-stream_002dterpri">Generic Function: <strong>stream-terpri</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Writes an end of line, as for <code>terpri</code>. Returns <code>nil</code>. The default
|
|
method does (<code>stream-write-char</code> stream <code>#newline</code>).
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dwrite_002dchar"></span><dl>
|
|
<dt id="index-stream_002dwrite_002dchar">Generic Function: <strong>stream-write-char</strong> <em>[sb-gray] stream character</em></dt>
|
|
<dd><p>Write <code>character</code> to <code>stream</code> and return <code>character</code>. Every
|
|
subclass of <code>fundamental-character-output-stream</code> must have a method
|
|
defined for this function.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dwrite_002dstring"></span><dl>
|
|
<dt id="index-stream_002dwrite_002dstring">Generic Function: <strong>stream-write-string</strong> <em>[sb-gray] stream string &optional start end</em></dt>
|
|
<dd><p>This is used by <code>write-string</code>. It writes the string to the stream,
|
|
optionally delimited by start and end, which default to 0 and <code>nil</code>.
|
|
The string argument is returned. The default method provided by
|
|
<code>fundamental-character-output-stream</code> uses repeated calls to
|
|
<code>stream-write-char</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Binary-stream-methods"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Gray-Streams-examples" accesskey="n" rel="next">Gray Streams examples</a>, Previous: <a href="index.html#Character-output-stream-methods" accesskey="p" rel="prev">Character output stream methods</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Binary-stream-methods-1"></span><h4 class="subsection">11.3.7 Binary stream methods</h4>
|
|
|
|
<p>The following generic functions are available for subclasses of
|
|
fundamental-binary-stream:
|
|
</p>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dread_002dbyte"></span><dl>
|
|
<dt id="index-stream_002dread_002dbyte">Generic Function: <strong>stream-read-byte</strong> <em>[sb-gray] stream</em></dt>
|
|
<dd><p>Used by <code>read-byte</code>; returns either an integer, or the symbol <code>:eof</code>
|
|
if the stream is at end-of-file.
|
|
</p></dd></dl>
|
|
<span id="Generic_002dFunction-sb_002dgray-stream_002dwrite_002dbyte"></span><dl>
|
|
<dt id="index-stream_002dwrite_002dbyte">Generic Function: <strong>stream-write-byte</strong> <em>[sb-gray] stream integer</em></dt>
|
|
<dd><p>Implements <code>write-byte</code>; writes the integer to the stream and
|
|
returns the integer as the result.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Gray-Streams-examples"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Binary-stream-methods" accesskey="p" rel="prev">Binary stream methods</a>, Up: <a href="index.html#Gray-Streams" accesskey="u" rel="up">Gray Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Gray-Streams-examples-1"></span><h4 class="subsection">11.3.8 Gray Streams examples</h4>
|
|
|
|
|
|
<p>Below are two classes of stream that can be conveniently defined as
|
|
wrappers for Common Lisp streams. These are meant to serve as
|
|
examples of minimal implementations of the protocols that must be
|
|
followed when defining Gray streams. Realistic uses of the Gray
|
|
Streams API would implement the various methods that can do I/O in
|
|
batches, such as <code><span class="nolinebreak">stream-read-line</span><!-- /@w --></code>, <code><span class="nolinebreak">stream-write-string</span><!-- /@w --></code>,
|
|
<code><span class="nolinebreak">stream-read-sequence</span><!-- /@w --></code>, and <code><span class="nolinebreak">stream-write-sequence</span><!-- /@w --></code>.
|
|
</p>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Character-counting-input-stream" accesskey="1">Character counting input stream</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Output-prefixing-character-stream" accesskey="2">Output prefixing character stream</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Character-counting-input-stream"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Output-prefixing-character-stream" accesskey="n" rel="next">Output prefixing character stream</a>, Up: <a href="index.html#Gray-Streams-examples" accesskey="u" rel="up">Gray Streams examples</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Character-counting-input-stream-1"></span><h4 class="subsubsection">11.3.8.1 Character counting input stream</h4>
|
|
|
|
<p>It is occasionally handy for programs that process input files to
|
|
count the number of characters and lines seen so far, and the number
|
|
of characters seen on the current line, so that useful messages may be
|
|
reported in case of parsing errors, etc. Here is a character input
|
|
stream class that keeps track of these counts. Note that all
|
|
character input streams must implement <code><span class="nolinebreak">stream-read-char</span><!-- /@w --></code> and
|
|
<code><span class="nolinebreak">stream-unread-char</span><!-- /@w --></code>.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defclass wrapped-stream (fundamental-stream)
|
|
((stream :initarg :stream :reader stream-of)))
|
|
</pre><pre class="lisp">(defmethod stream-element-type ((stream wrapped-stream))
|
|
(stream-element-type (stream-of stream)))
|
|
</pre><pre class="lisp">(defmethod close ((stream wrapped-stream) &key abort)
|
|
(close (stream-of stream) :abort abort))
|
|
</pre><pre class="lisp">(defclass wrapped-character-input-stream
|
|
(wrapped-stream fundamental-character-input-stream)
|
|
())
|
|
</pre><pre class="lisp">(defmethod stream-read-char ((stream wrapped-character-input-stream))
|
|
(read-char (stream-of stream) nil :eof))
|
|
</pre><pre class="lisp">(defmethod stream-unread-char ((stream wrapped-character-input-stream)
|
|
char)
|
|
(unread-char char (stream-of stream)))
|
|
</pre><pre class="lisp">(defclass counting-character-input-stream
|
|
(wrapped-character-input-stream)
|
|
((char-count :initform 1 :accessor char-count-of)
|
|
(line-count :initform 1 :accessor line-count-of)
|
|
(col-count :initform 1 :accessor col-count-of)
|
|
(prev-col-count :initform 1 :accessor prev-col-count-of)))
|
|
</pre><pre class="lisp">(defmethod stream-read-char ((stream counting-character-input-stream))
|
|
(with-accessors ((inner-stream stream-of) (chars char-count-of)
|
|
(lines line-count-of) (cols col-count-of)
|
|
(prev prev-col-count-of)) stream
|
|
(let ((char (call-next-method)))
|
|
(cond ((eql char :eof)
|
|
:eof)
|
|
((char= char #\Newline)
|
|
(incf lines)
|
|
(incf chars)
|
|
(setf prev cols)
|
|
(setf cols 1)
|
|
char)
|
|
(t
|
|
(incf chars)
|
|
(incf cols)
|
|
char)))))
|
|
</pre><pre class="lisp">(defmethod stream-unread-char ((stream counting-character-input-stream)
|
|
char)
|
|
(with-accessors ((inner-stream stream-of) (chars char-count-of)
|
|
(lines line-count-of) (cols col-count-of)
|
|
(prev prev-col-count-of)) stream
|
|
(cond ((char= char #\Newline)
|
|
(decf lines)
|
|
(decf chars)
|
|
(setf cols prev))
|
|
(t
|
|
(decf chars)
|
|
(decf cols)
|
|
char))
|
|
(call-next-method)))
|
|
</pre></div>
|
|
|
|
<p>The default methods for <code><span class="nolinebreak">stream-read-char-no-hang</span><!-- /@w --></code>,
|
|
<code><span class="nolinebreak">stream-peek-char</span><!-- /@w --></code>, <code><span class="nolinebreak">stream-listen</span><!-- /@w --></code>,
|
|
<code><span class="nolinebreak">stream-clear-input</span><!-- /@w --></code>, <code><span class="nolinebreak">stream-read-line</span><!-- /@w --></code>, and
|
|
<code><span class="nolinebreak">stream-read-sequence</span><!-- /@w --></code> should be sufficient (though the last two
|
|
will probably be slower than methods that forwarded directly).
|
|
</p>
|
|
<p>Here’s a sample use of this class:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(with-input-from-string (input "1 2
|
|
3 :foo ")
|
|
(let ((counted-stream (make-instance 'counting-character-input-stream
|
|
:stream input)))
|
|
(loop for thing = (read counted-stream) while thing
|
|
unless (numberp thing) do
|
|
(error "Non-number ~S (line ~D, column ~D)" thing
|
|
(line-count-of counted-stream)
|
|
(- (col-count-of counted-stream)
|
|
(length (format nil "~S" thing))))
|
|
end
|
|
do (print thing))))
|
|
</pre><pre class="verbatim">1
|
|
2
|
|
3
|
|
Non-number :FOO (line 2, column 5)
|
|
[Condition of type SIMPLE-ERROR]
|
|
</pre></div>
|
|
|
|
<hr>
|
|
<span id="Output-prefixing-character-stream"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Character-counting-input-stream" accesskey="p" rel="prev">Character counting input stream</a>, Up: <a href="index.html#Gray-Streams-examples" accesskey="u" rel="up">Gray Streams examples</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Output-prefixing-character-stream-1"></span><h4 class="subsubsection">11.3.8.2 Output prefixing character stream</h4>
|
|
|
|
<p>One use for a wrapped output stream might be to prefix each line of
|
|
text with a timestamp, e.g., for a logging stream. Here’s a simple
|
|
stream that does this, though without any fancy line-wrapping. Note
|
|
that all character output stream classes must implement
|
|
<code><span class="nolinebreak">stream-write-char</span><!-- /@w --></code> and <code><span class="nolinebreak">stream-line-column</span><!-- /@w --></code>.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defclass wrapped-stream (fundamental-stream)
|
|
((stream :initarg :stream :reader stream-of)))
|
|
</pre><pre class="lisp">(defmethod stream-element-type ((stream wrapped-stream))
|
|
(stream-element-type (stream-of stream)))
|
|
</pre><pre class="lisp">(defmethod close ((stream wrapped-stream) &key abort)
|
|
(close (stream-of stream) :abort abort))
|
|
</pre><pre class="lisp">(defclass wrapped-character-output-stream
|
|
(wrapped-stream fundamental-character-output-stream)
|
|
((col-index :initform 0 :accessor col-index-of)))
|
|
</pre><pre class="lisp">(defmethod stream-line-column ((stream wrapped-character-output-stream))
|
|
(col-index-of stream))
|
|
</pre><pre class="lisp">(defmethod stream-write-char ((stream wrapped-character-output-stream)
|
|
char)
|
|
(with-accessors ((inner-stream stream-of) (cols col-index-of)) stream
|
|
(write-char char inner-stream)
|
|
(if (char= char #\Newline)
|
|
(setf cols 0)
|
|
(incf cols))))
|
|
</pre><pre class="lisp">(defclass prefixed-character-output-stream
|
|
(wrapped-character-output-stream)
|
|
((prefix :initarg :prefix :reader prefix-of)))
|
|
</pre><pre class="lisp">(defgeneric write-prefix (prefix stream)
|
|
(:method ((prefix string) stream) (write-string prefix stream))
|
|
(:method ((prefix function) stream) (funcall prefix stream)))
|
|
</pre><pre class="lisp">(defmethod stream-write-char ((stream prefixed-character-output-stream)
|
|
char)
|
|
(with-accessors ((inner-stream stream-of) (cols col-index-of)
|
|
(prefix prefix-of)) stream
|
|
(when (zerop cols)
|
|
(write-prefix prefix inner-stream))
|
|
(call-next-method)))
|
|
</pre></div>
|
|
|
|
<p>As with the example input stream, this implements only the minimal
|
|
protocol. A production implementation should also provide methods for
|
|
at least <code><span class="nolinebreak">stream-write-line</span><!-- /@w --></code>, <code><span class="nolinebreak">stream-write-sequence</span><!-- /@w --></code>.
|
|
</p>
|
|
<p>And here’s a sample use of this class:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(flet ((format-timestamp (stream)
|
|
(apply #'format stream "[~2@*~2,' D:~1@*~2,'0D:~0@*~2,'0D] "
|
|
(multiple-value-list (get-decoded-time)))))
|
|
(let ((output (make-instance 'prefixed-character-output-stream
|
|
:stream *standard-output*
|
|
:prefix #'format-timestamp)))
|
|
(loop for string in '("abc" "def" "ghi") do
|
|
(write-line string output)
|
|
(sleep 1))))
|
|
</pre><pre class="verbatim">[ 0:30:05] abc
|
|
[ 0:30:06] def
|
|
[ 0:30:07] ghi
|
|
NIL
|
|
</pre></div>
|
|
|
|
<hr>
|
|
<span id="Simple-Streams"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Gray-Streams" accesskey="p" rel="prev">Gray Streams</a>, Up: <a href="index.html#Streams" accesskey="u" rel="up">Streams</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Simple-Streams-1"></span><h3 class="section">11.4 Simple Streams</h3>
|
|
<p>Simple streams are an extensible streams protocol that avoids some
|
|
problems with Gray streams.
|
|
</p>
|
|
<p>Documentation about simple streams is available at:
|
|
</p>
|
|
<p><a href="http://www.franz.com/support/documentation/6.2/doc/streams.htm">http://www.franz.com/support/documentation/6.2/doc/streams.htm</a>
|
|
</p>
|
|
<p>The implementation should be considered Alpha-quality; the basic
|
|
framework is there, but many classes are just stubs at the moment.
|
|
</p>
|
|
<p>See <samp>SYS:CONTRIB;SB-SIMPLE-STREAMS;SIMPLE-STREAM-TEST.LISP</samp> for
|
|
things that should work.
|
|
</p>
|
|
<p>Known differences to the ACL behaviour:
|
|
</p>
|
|
<ul>
|
|
<li> <code>open</code> not return a simple-stream by default. This can be
|
|
adjusted; see default-open-class in the file cl.lisp
|
|
|
|
</li><li> <code>write-vector</code> is unimplemented.
|
|
|
|
</li></ul>
|
|
<hr>
|
|
<span id="Package-Locks"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Threading" accesskey="n" rel="next">Threading</a>, Previous: <a href="index.html#Streams" accesskey="p" rel="prev">Streams</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package-Locks-1"></span><h2 class="chapter">12 Package Locks</h2>
|
|
<span id="index-Packages_002c-locked"></span>
|
|
|
|
<p>None of the following sections apply to SBCL built without package
|
|
locking support.
|
|
</p>
|
|
<blockquote>
|
|
<p><b>warning:</b> The interface described here is experimental: incompatible changes in
|
|
future SBCL releases are possible, even expected: the concept of
|
|
“implementation packages” and the associated operators may be renamed;
|
|
more operations (such as naming restarts or catch tags) may be added to
|
|
the list of operations violating package locks.
|
|
</p></blockquote>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package-Lock-Concepts" accesskey="1">Package Lock Concepts</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package-Lock-Dictionary" accesskey="2">Package Lock Dictionary</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Package-Lock-Concepts"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Package-Lock-Dictionary" accesskey="n" rel="next">Package Lock Dictionary</a>, Up: <a href="index.html#Package-Locks" accesskey="u" rel="up">Package Locks</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package-Lock-Concepts-1"></span><h3 class="section">12.1 Package Lock Concepts</h3>
|
|
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package-Lock-Overview" accesskey="1">Package Lock Overview</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Implementation-Packages" accesskey="2">Implementation Packages</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package-Lock-Violations" accesskey="3">Package Lock Violations</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Package-Locks-in-Compiled-Code" accesskey="4">Package Locks in Compiled Code</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Operations-Violating-Package-Locks" accesskey="5">Operations Violating Package Locks</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Package-Lock-Overview"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Implementation-Packages" accesskey="n" rel="next">Implementation Packages</a>, Up: <a href="index.html#Package-Lock-Concepts" accesskey="u" rel="up">Package Lock Concepts</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package-Locking-Overview"></span><h4 class="subsection">12.1.1 Package Locking Overview</h4>
|
|
|
|
<p>Package locks protect against unintentional modifications of a package:
|
|
they provide similar protection to user packages as is mandated to
|
|
<code>common-lisp</code> package by the ANSI specification. They are not, and
|
|
should not be used as, a security measure.
|
|
</p>
|
|
<p>Newly created packages are by default unlocked (see the <code>:lock</code>
|
|
option to <code>defpackage</code>).
|
|
</p>
|
|
<p>The package <code>common-lisp</code> and SBCL internal implementation
|
|
packages are locked by default, including <code>sb-ext</code>.
|
|
</p>
|
|
<p>It may be beneficial to lock <code>common-lisp-user</code> as well, to
|
|
ensure that various libraries don’t pollute it without asking,
|
|
but this is not currently done by default.
|
|
</p>
|
|
<hr>
|
|
<span id="Implementation-Packages"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Package-Lock-Violations" accesskey="n" rel="next">Package Lock Violations</a>, Previous: <a href="index.html#Package-Lock-Overview" accesskey="p" rel="prev">Package Lock Overview</a>, Up: <a href="index.html#Package-Lock-Concepts" accesskey="u" rel="up">Package Lock Concepts</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Implementation-Packages-1"></span><h4 class="subsection">12.1.2 Implementation Packages</h4>
|
|
<span id="index-_002apackage_002a-_005bcl_005d-3"></span>
|
|
<span id="index-defpackage-_005bcl_005d-1"></span>
|
|
|
|
<p>Each package has a list of associated implementation packages. A
|
|
locked package, and the symbols whose home package it is, can be
|
|
modified without violating package locks only when <code>*package*</code> is
|
|
bound to one of the implementation packages of the locked package.
|
|
</p>
|
|
<p>Unless explicitly altered by <code>defpackage</code>,
|
|
<code>sb-ext:add-implementation-package</code>, or
|
|
<code>sb-ext:remove-implementation-package</code> each package is its own
|
|
(only) implementation package.
|
|
</p>
|
|
<hr>
|
|
<span id="Package-Lock-Violations"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Package-Locks-in-Compiled-Code" accesskey="n" rel="next">Package Locks in Compiled Code</a>, Previous: <a href="index.html#Implementation-Packages" accesskey="p" rel="prev">Implementation Packages</a>, Up: <a href="index.html#Package-Lock-Concepts" accesskey="u" rel="up">Package Lock Concepts</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package-Lock-Violations-1"></span><h4 class="subsection">12.1.3 Package Lock Violations</h4>
|
|
<span id="index-package_002dlock_002dviolation-_005bsb_002dext_005d"></span>
|
|
<span id="index-package_002dlocked_002derror-_005bsb_002dext_005d"></span>
|
|
<span id="index-symbol_002dpackage_002dlocked_002derror-_005bsb_002dext_005d"></span>
|
|
<span id="index-package_002derror-_005bcl_005d"></span>
|
|
|
|
<span id="Lexical-Bindings-and-Declarations"></span><h4 class="subsubsection">12.1.3.1 Lexical Bindings and Declarations</h4>
|
|
<span id="index-let-_005bcl_005d-1"></span>
|
|
<span id="index-let_002a-_005bcl_005d-1"></span>
|
|
<span id="index-flet-_005bcl_005d-1"></span>
|
|
<span id="index-labels-_005bcl_005d-1"></span>
|
|
<span id="index-macrolet-_005bcl_005d"></span>
|
|
<span id="index-symbol_002dmacrolet-_005bcl_005d"></span>
|
|
<span id="index-declare-_005bcl_005d"></span>
|
|
<span id="index-Declarations"></span>
|
|
<span id="index-disable_002dpackage_002dlocks-_005bsb_002dext_005d"></span>
|
|
<span id="index-enable_002dpackage_002dlocks-_005bsb_002dext_005d"></span>
|
|
|
|
<p>Lexical bindings or declarations that violate package locks cause a
|
|
compile-time warning, and a runtime <code>program-error</code> when the form
|
|
that violates package locks would be executed.
|
|
</p>
|
|
<p>A complete listing of operators affect by this is: <code>let</code>,
|
|
<code>let*</code>, <code>flet</code>, <code>labels</code>, <code>macrolet</code>, and
|
|
<code>symbol-macrolet</code>, <code>declare</code>.
|
|
</p>
|
|
<p>Package locks affecting both lexical bindings and declarations can be
|
|
disabled locally with <code>sb-ext:disable-package-locks</code> declaration,
|
|
and re-enabled with <code>sb-ext:enable-package-locks</code> declaration.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(in-package :locked)
|
|
|
|
(defun foo () ...)
|
|
|
|
(defmacro with-foo (&body body)
|
|
`(locally (declare (disable-package-locks locked:foo))
|
|
(flet ((foo () ...))
|
|
(declare (enable-package-locks locked:foo)) ; re-enable for body
|
|
,@body)))
|
|
</pre></div>
|
|
|
|
<span id="Other-Operations"></span><h4 class="subsubsection">12.1.3.2 Other Operations</h4>
|
|
|
|
<p>If an non-lexical operation violates a package lock, a continuable
|
|
error that is of a subtype of <code>sb-ext:package-lock-violation</code>
|
|
(subtype of <code>package-error</code>) is signalled when the operation is
|
|
attempted.
|
|
</p>
|
|
<p>Additional restarts may be established for continuable package lock
|
|
violations for interactive use.
|
|
</p>
|
|
<p>The actual type of the error depends on circumstances that caused the
|
|
violation: operations on packages signal errors of type
|
|
<code>sb-ext:package-locked-error</code>, and operations on symbols signal
|
|
errors of type <code>sb-ext:symbol-package-locked-error</code>.
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="Package-Locks-in-Compiled-Code"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Operations-Violating-Package-Locks" accesskey="n" rel="next">Operations Violating Package Locks</a>, Previous: <a href="index.html#Package-Lock-Violations" accesskey="p" rel="prev">Package Lock Violations</a>, Up: <a href="index.html#Package-Lock-Concepts" accesskey="u" rel="up">Package Lock Concepts</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package-Locks-in-Compiled-Code-1"></span><h4 class="subsection">12.1.4 Package Locks in Compiled Code</h4>
|
|
|
|
<span id="Interned-Symbols"></span><h4 class="subsubsection">12.1.4.1 Interned Symbols</h4>
|
|
|
|
<p>If file-compiled code contains interned symbols, then loading that code
|
|
into an image without the said symbols will not cause a package lock
|
|
violation, even if the packages in question are locked.
|
|
</p>
|
|
<span id="Other-Limitations-on-Compiled-Code"></span><h4 class="subsubsection">12.1.4.2 Other Limitations on Compiled Code</h4>
|
|
|
|
<p>With the exception of interned symbols, behaviour is unspecified if
|
|
package locks affecting compiled code are not the same during loading
|
|
of the code or execution.
|
|
</p>
|
|
<p>Specifically, code compiled with packages unlocked may or may not fail
|
|
to signal package-lock-violations even if the packages are locked at
|
|
runtime, and code compiled with packages locked may or may not signal
|
|
spurious package-lock-violations at runtime even if the packages are
|
|
unlocked.
|
|
</p>
|
|
<p>In practice all this means that package-locks have a negligible
|
|
performance penalty in compiled code as long as they are not violated.
|
|
</p>
|
|
<hr>
|
|
<span id="Operations-Violating-Package-Locks"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Package-Locks-in-Compiled-Code" accesskey="p" rel="prev">Package Locks in Compiled Code</a>, Up: <a href="index.html#Package-Lock-Concepts" accesskey="u" rel="up">Package Lock Concepts</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Operations-Violating-Package-Locks-1"></span><h4 class="subsection">12.1.5 Operations Violating Package Locks</h4>
|
|
|
|
<span id="Operations-on-Packages"></span><h4 class="subsubsection">12.1.5.1 Operations on Packages</h4>
|
|
|
|
<p>The following actions cause a package lock violation if the package
|
|
operated on is locked, and <code>*package*</code> is not an implementation
|
|
package of that package, and the action would cause a change in the
|
|
state of the package (so e.g. exporting already external symbols is
|
|
never a violation). Package lock violations caused by these operations
|
|
signal errors of type <code>sb-ext:package-locked-error</code>.
|
|
</p>
|
|
<ol>
|
|
<li> Shadowing a symbol in a package.
|
|
|
|
</li><li> Importing a symbol to a package.
|
|
|
|
</li><li> Uninterning a symbol from a package.
|
|
|
|
</li><li> Exporting a symbol from a package.
|
|
|
|
</li><li> Unexporting a symbol from a package.
|
|
|
|
</li><li> Changing the packages used by a package.
|
|
|
|
</li><li> Renaming a package.
|
|
|
|
</li><li> Deleting a package.
|
|
|
|
</li><li> Adding a new package local nickname to a package.
|
|
|
|
</li><li> Removing an existing package local nickname to a package.
|
|
|
|
</li></ol>
|
|
|
|
<span id="Operations-on-Symbols"></span><h4 class="subsubsection">12.1.5.2 Operations on Symbols</h4>
|
|
|
|
<p>Following actions cause a package lock violation if the home package
|
|
of the symbol operated on is locked, and <code>*package*</code> is not an
|
|
implementation package of that package. Package lock violations caused
|
|
by these action signal errors of type
|
|
<code>sb-ext:symbol-package-locked-error</code>.
|
|
</p>
|
|
<p>These actions cause only one package lock violation per lexically
|
|
apparent violated package.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">;;; Packages FOO and BAR are locked.
|
|
;;;
|
|
;;; Two lexically apparent violated packages: exactly two
|
|
;;; package-locked-errors will be signalled.
|
|
|
|
(defclass foo:point ()
|
|
((x :accessor bar:x)
|
|
(y :accessor bar:y)))
|
|
</pre></div>
|
|
|
|
<ol>
|
|
<li> Binding or altering its value lexically or dynamically, or
|
|
establishing it as a symbol-macro.
|
|
|
|
<p>Exceptions:
|
|
</p>
|
|
<ul class="no-bullet">
|
|
<li>- If the symbol is not defined as a constant, global symbol-macro or a
|
|
global dynamic variable, it may be lexically bound or established as a
|
|
local symbol macro.
|
|
|
|
</li><li>- If the symbol is defined as a global dynamic variable, it may be
|
|
assigned or bound.
|
|
|
|
</li></ul>
|
|
|
|
</li><li> Defining, undefining, or binding it, or its setf name as a function.
|
|
|
|
<p>Exceptions:
|
|
</p>
|
|
<ul class="no-bullet">
|
|
<li>- If the symbol is not defined as a function, macro, or special operator
|
|
it and its setf name may be lexically bound as a function.
|
|
|
|
</li></ul>
|
|
|
|
</li><li> Defining, undefining, or binding it as a macro or compiler macro.
|
|
|
|
<p>Exceptions:
|
|
</p>
|
|
<ul class="no-bullet">
|
|
<li>- If the symbol is not defined as a function, macro, or special operator
|
|
it may be lexically bound as a macro.
|
|
|
|
</li></ul>
|
|
|
|
</li><li> Defining it as a type specifier or structure.
|
|
|
|
</li><li> Defining it as a declaration with a declaration proclamation.
|
|
|
|
</li><li> Declaring or proclaiming it special.
|
|
|
|
</li><li> Declaring or proclaiming its type or ftype.
|
|
|
|
<p>Exceptions:
|
|
</p>
|
|
<ul class="no-bullet">
|
|
<li>- If the symbol may be lexically bound, the type of that binding may be
|
|
declared.
|
|
|
|
</li><li>- If the symbol may be lexically bound as a function, the ftype of that
|
|
binding may be declared.
|
|
|
|
</li></ul>
|
|
|
|
</li><li> Defining a setf expander for it.
|
|
|
|
</li><li> Defining it as a method combination type.
|
|
|
|
</li><li> Using it as the class-name argument to setf of find-class.
|
|
|
|
</li><li> Defining it as a hash table test using <code>sb-ext:define-hash-table-test</code>.
|
|
|
|
</li></ol>
|
|
|
|
<hr>
|
|
<span id="Package-Lock-Dictionary"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Package-Lock-Concepts" accesskey="p" rel="prev">Package Lock Concepts</a>, Up: <a href="index.html#Package-Locks" accesskey="u" rel="up">Package Locks</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Package-Lock-Dictionary-1"></span><h3 class="section">12.2 Package Lock Dictionary</h3>
|
|
|
|
<dl>
|
|
<dt id="index-disable_002dpackage_002dlocks">Declaration: <strong>disable-package-locks</strong> <em>[sb-ext]</em></dt>
|
|
<dd>
|
|
<p>Syntax: <code>(sb-ext:disable-package-locks symbol*)</code>
|
|
</p>
|
|
<p>Disables package locks affecting the named symbols during compilation
|
|
in the lexical scope of the declaration. Disabling locks on symbols
|
|
whose home package is unlocked, or disabling an already disabled lock,
|
|
has no effect.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-enable_002dpackage_002dlocks">Declaration: <strong>enable-package-locks</strong> <em>[sb-ext]</em></dt>
|
|
<dd>
|
|
<p>Syntax: <code>(sb-ext:enable-package-locks symbol*)</code>
|
|
</p>
|
|
<p>Re-enables package locks affecting the named symbols during compilation
|
|
in the lexical scope of the declaration. Enabling locks that were not
|
|
first disabled with <code>sb-ext:disable-package-locks</code> declaration, or
|
|
enabling locks that are already enabled has no effect.
|
|
</p></dd></dl>
|
|
|
|
<span id="Condition-sb_002dext-package_002dlock_002dviolation"></span><dl>
|
|
<dt id="index-package_002dlock_002dviolation">Condition: <strong>package-lock-violation</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">package-lock-violation</span><!-- /@w --></code>, <code><span class="nolinebreak">package-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Subtype of <code>cl:package-error</code>. A subtype of this error is signalled
|
|
when a package-lock is violated.
|
|
</p></dd></dl>
|
|
<span id="Condition-sb_002dext-package_002dlocked_002derror"></span><dl>
|
|
<dt id="index-package_002dlocked_002derror">Condition: <strong>package-locked-error</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">package-locked-error</span><!-- /@w --></code>, <code><span class="nolinebreak">package-lock-violation</span><!-- /@w --></code>, <code><span class="nolinebreak">package-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Subtype of <code>sb-ext:package-lock-violation</code>. An error of this type is
|
|
signalled when an operation on a package violates a package lock.
|
|
</p></dd></dl>
|
|
<span id="Condition-sb_002dext-symbol_002dpackage_002dlocked_002derror"></span><dl>
|
|
<dt id="index-symbol_002dpackage_002dlocked_002derror">Condition: <strong>symbol-package-locked-error</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">symbol-package-locked-error</span><!-- /@w --></code>, <code><span class="nolinebreak">package-lock-violation</span><!-- /@w --></code>, <code><span class="nolinebreak">package-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Subtype of <code>sb-ext:package-lock-violation</code>. An error of this type is
|
|
signalled when an operation on a symbol violates a package lock. The
|
|
symbol that caused the violation is accessed by the function
|
|
<code>sb-ext:package-locked-error-symbol</code>.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-package_002dlocked_002derror_002dsymbol">Function: <strong>package-locked-error-symbol</strong> <em>[sb-ext] symbol-package-locked-error</em></dt>
|
|
<dd>
|
|
<p>Returns the symbol that caused the <code>symbol-package-locked-error</code>
|
|
condition.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dext-package_002dlocked_002dp"></span><dl>
|
|
<dt id="index-package_002dlocked_002dp">Function: <strong>package-locked-p</strong> <em>[sb-ext] package</em></dt>
|
|
<dd><p>Returns <code>t</code> when <code>package</code> is locked, <code>nil</code> otherwise. Signals an error
|
|
if <code>package</code> doesn’t designate a valid package.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-lock_002dpackage"></span><dl>
|
|
<dt id="index-lock_002dpackage">Function: <strong>lock-package</strong> <em>[sb-ext] package</em></dt>
|
|
<dd><p>Locks <code>package</code> and returns <code>t</code>. Has no effect if <code>package</code> was already
|
|
locked. Signals an error if <code>package</code> is not a valid package designator
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-unlock_002dpackage"></span><dl>
|
|
<dt id="index-unlock_002dpackage">Function: <strong>unlock-package</strong> <em>[sb-ext] package</em></dt>
|
|
<dd><p>Unlocks <code>package</code> and returns <code>t</code>. Has no effect if <code>package</code> was already
|
|
unlocked. Signals an error if <code>package</code> is not a valid package designator.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-package_002dimplemented_002dby_002dlist"></span><dl>
|
|
<dt id="index-package_002dimplemented_002dby_002dlist">Function: <strong>package-implemented-by-list</strong> <em>[sb-ext] package</em></dt>
|
|
<dd><p>Returns a list containing the implementation packages of
|
|
<code>package</code>. Signals an error if <code>package</code> is not a valid package designator.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-package_002dimplements_002dlist"></span><dl>
|
|
<dt id="index-package_002dimplements_002dlist">Function: <strong>package-implements-list</strong> <em>[sb-ext] package</em></dt>
|
|
<dd><p>Returns the packages that <code>package</code> is an implementation package
|
|
of. Signals an error if <code>package</code> is not a valid package designator.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-add_002dimplementation_002dpackage"></span><dl>
|
|
<dt id="index-add_002dimplementation_002dpackage">Function: <strong>add-implementation-package</strong> <em>[sb-ext] packages-to-add &optional package</em></dt>
|
|
<dd><p>Adds <code>packages-to-add</code> as implementation packages of <code>package</code>. Signals
|
|
an error if <code>package</code> or any of the <code>packages-to-add</code> is not a valid
|
|
package designator.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-remove_002dimplementation_002dpackage"></span><dl>
|
|
<dt id="index-remove_002dimplementation_002dpackage">Function: <strong>remove-implementation-package</strong> <em>[sb-ext] packages-to-remove &optional package</em></dt>
|
|
<dd><p>Removes <code>packages-to-remove</code> from the implementation packages of
|
|
<code>package</code>. Signals an error if <code>package</code> or any of the <code>packages-to-remove</code>
|
|
is not a valid package designator.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dext-without_002dpackage_002dlocks"></span><dl>
|
|
<dt id="index-without_002dpackage_002dlocks">Macro: <strong>without-package-locks</strong> <em>[sb-ext] &body body</em></dt>
|
|
<dd><p>Ignores all runtime package lock violations during the execution of
|
|
body. Body can begin with declarations.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dext-with_002dunlocked_002dpackages"></span><dl>
|
|
<dt id="index-with_002dunlocked_002dpackages">Macro: <strong>with-unlocked-packages</strong> <em>[sb-ext] (&rest packages) &body forms</em></dt>
|
|
<dd><p>Unlocks <code>packages</code> for the dynamic scope of the body. Signals an
|
|
error if any of <code>packages</code> is not a valid package designator.
|
|
</p></dd></dl>
|
|
|
|
<dl>
|
|
<dt id="index-defpackage-1">Macro: <strong>defpackage</strong> <em>[cl] name [[option]]* ⇒ package</em></dt>
|
|
<dd>
|
|
<p>Options are extended to include the following:
|
|
</p>
|
|
<ul>
|
|
<li> <code>:lock</code> <var>boolean</var>
|
|
|
|
<p>If the argument to <code>:lock</code> is <code>t</code>, the package is initially
|
|
locked. If <code>:lock</code> is not provided it defaults to <code>nil</code>.
|
|
</p>
|
|
</li><li> <code>:implement</code> <var>package-designator</var>*
|
|
|
|
<p>The package is added as an implementation package to the packages
|
|
named. If <code>:implement</code> is not provided, it defaults to the
|
|
package itself.
|
|
</p></li></ul>
|
|
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defpackage "FOO" (:export "BAR") (:lock t) (:implement))
|
|
(defpackage "FOO-INT" (:use "FOO") (:implement "FOO" "FOO-INT"))
|
|
|
|
;;; is equivalent to
|
|
|
|
(defpackage "FOO") (:export "BAR"))
|
|
(lock-package "FOO")
|
|
(remove-implementation-package "FOO" "FOO")
|
|
(defpackage "FOO-INT" (:use "BAR"))
|
|
(add-implementation-package "FOO-INT" "FOO")
|
|
</pre></div>
|
|
</dd></dl>
|
|
<hr>
|
|
<span id="Threading"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Timers" accesskey="n" rel="next">Timers</a>, Previous: <a href="index.html#Package-Locks" accesskey="p" rel="prev">Package Locks</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Threading-1"></span><h2 class="chapter">13 Threading</h2>
|
|
|
|
<p>SBCL supports a fairly low-level threading interface that maps onto
|
|
the host operating system’s concept of threads or lightweight
|
|
processes. This means that threads may take advantage of hardware
|
|
multiprocessing on machines that have more than one CPU, but it does
|
|
not allow Lisp control of the scheduler. This is found in the
|
|
SB-THREAD package.
|
|
</p>
|
|
<p>Threads are part of the default build on x86[-64]/ARM64 Linux and Windows.
|
|
</p>
|
|
<p>They are also supported on: x86[-64] Darwin (Mac OS X), x86[-64]
|
|
FreeBSD, x86 SunOS (Solaris), PPC Linux, ARM64 Linux, RISC-V Linux. On
|
|
these platforms threads must be explicitly enabled at build-time, see
|
|
<samp>INSTALL</samp> for directions.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Threading-basics" accesskey="1">Threading basics</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Special-Variables" accesskey="2">Special Variables</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Atomic-Operations" accesskey="3">Atomic Operations</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Mutex-Support" accesskey="4">Mutex Support</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Semaphores" accesskey="5">Semaphores</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Waitqueue_002fcondition-variables" accesskey="6">Waitqueue/condition variables</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Barriers" accesskey="7">Barriers</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Sessions_002fDebugging" accesskey="8">Sessions/Debugging</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Foreign-threads" accesskey="9">Foreign threads</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Implementation-_0028Linux-x86_002fx86_002d64_0029">Implementation (Linux x86/x86-64)</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Threading-basics"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Special-Variables" accesskey="n" rel="next">Special Variables</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Threading-basics-1"></span><h3 class="section">13.1 Threading basics</h3>
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">(make-thread (lambda () (write-line "Hello, world")))
|
|
</pre></div>
|
|
|
|
<span id="Thread-Objects"></span><h4 class="subsection">13.1.1 Thread Objects</h4>
|
|
|
|
<span id="Structure-sb_002dthread-thread"></span><dl>
|
|
<dt id="index-thread">Structure: <strong>thread</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code>thread<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Thread type. Do not rely on threads being structs as it may change
|
|
in future versions.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002dthread-_002acurrent_002dthread_002a"></span><dl>
|
|
<dt id="index-_002acurrent_002dthread_002a">Variable: <strong>*current-thread*</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Bound in each thread to the thread itself.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-list_002dall_002dthreads"></span><dl>
|
|
<dt id="index-list_002dall_002dthreads">Function: <strong>list-all-threads</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Return a list of the live threads. Note that the return value is
|
|
potentially stale even before the function returns, as new threads may be
|
|
created and old ones may exit at any time.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-thread_002dalive_002dp"></span><dl>
|
|
<dt id="index-thread_002dalive_002dp">Function: <strong>thread-alive-p</strong> <em>[sb-thread] thread</em></dt>
|
|
<dd><p>Return <code>t</code> if <code>thread</code> is still alive. Note that the return value is
|
|
potentially stale even before the function returns, as the thread may exit at
|
|
any time.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-thread_002dname"></span><dl>
|
|
<dt id="index-thread_002dname">Function: <strong>thread-name</strong> <em>[sb-thread] instance</em></dt>
|
|
<dd><p>Name of the thread. Can be assigned to using <code>setf</code>. A thread name must be
|
|
a simple-string (not necessarily unique) or <code>nil</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-main_002dthread_002dp"></span><dl>
|
|
<dt id="index-main_002dthread_002dp">Function: <strong>main-thread-p</strong> <em>[sb-thread] &optional thread</em></dt>
|
|
<dd><p>True if <code>thread</code>, defaulting to current thread, is the main thread of the process.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-main_002dthread"></span><dl>
|
|
<dt id="index-main_002dthread">Function: <strong>main-thread</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Returns the main thread of the process.
|
|
</p></dd></dl>
|
|
|
|
<span id="Making_002c-Returning-From_002c-Joining_002c-and-Yielding-Threads"></span><h4 class="subsection">13.1.2 Making, Returning From, Joining, and Yielding Threads</h4>
|
|
|
|
<span id="Function-sb_002dthread-make_002dthread"></span><dl>
|
|
<dt id="index-make_002dthread">Function: <strong>make-thread</strong> <em>[sb-thread] function &key name arguments</em></dt>
|
|
<dd><p>Create a new thread of <code>name</code> that runs <code>function</code> with the argument
|
|
list designator provided (defaults to no argument). Thread exits when
|
|
the function returns. The return values of <code>function</code> are kept around
|
|
and can be retrieved by <code>join-thread</code>.
|
|
</p>
|
|
<p>Invoking the initial <code>abort</code> restart established by <code>make-thread</code>
|
|
terminates the thread.
|
|
</p>
|
|
<p>See also: <code>return-from-thread</code>, <code>abort-thread</code>.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dthread-return_002dfrom_002dthread"></span><dl>
|
|
<dt id="index-return_002dfrom_002dthread">Macro: <strong>return-from-thread</strong> <em>[sb-thread] values-form &key allow-exit</em></dt>
|
|
<dd><p>Unwinds from and terminates the current thread, with values from
|
|
<code>values-form</code> as the results visible to <code>join-thread</code>.
|
|
</p>
|
|
<p>If current thread is the main thread of the process (see
|
|
<code>main-thread-p</code>), signals an error unless <code>allow-exit</code> is true, as
|
|
terminating the main thread would terminate the entire process. If
|
|
<code>allow-exit</code> is true, returning from the main thread is equivalent to
|
|
calling <code>sb-ext:exit</code> with <code>:code</code> 0 and <code>:abort</code> <code>nil</code>.
|
|
</p>
|
|
<p>See also: <code>abort-thread</code> and <code>sb-ext:exit</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-abort_002dthread"></span><dl>
|
|
<dt id="index-abort_002dthread">Function: <strong>abort-thread</strong> <em>[sb-thread] &key allow-exit</em></dt>
|
|
<dd><p>Unwinds from and terminates the current thread abnormally, causing
|
|
<code>join-thread</code> on current thread to signal an error unless a
|
|
default-value is provided.
|
|
</p>
|
|
<p>If current thread is the main thread of the process (see
|
|
<code>main-thread-p</code>), signals an error unless <code>allow-exit</code> is true, as
|
|
terminating the main thread would terminate the entire process. If
|
|
<code>allow-exit</code> is true, aborting the main thread is equivalent to calling
|
|
<code>sb-ext:exit</code> code 1 and <code>:abort</code> <code>nil</code>.
|
|
</p>
|
|
<p>Invoking the initial <code>abort</code> restart established by <code>make-thread</code> is
|
|
equivalent to calling <code>abort-thread</code> in other than main threads.
|
|
However, whereas <code>abort</code> restart may be rebound, <code>abort-thread</code> always
|
|
unwinds the entire thread. (Behaviour of the initial <code>abort</code> restart for
|
|
main thread depends on the <code>:toplevel</code> argument to
|
|
<code>sb-ext:save-lisp-and-die</code>.)
|
|
</p>
|
|
<p>See also: <code>return-from-thread</code> and <code>sb-ext:exit</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-join_002dthread"></span><dl>
|
|
<dt id="index-join_002dthread">Function: <strong>join-thread</strong> <em>[sb-thread] thread &key default timeout</em></dt>
|
|
<dd><p>Suspend current thread until <code>thread</code> exits. Return the result values
|
|
of the thread function.
|
|
</p>
|
|
<p>If <code>thread</code> does not exit within <code>timeout</code> seconds and <code>default</code> is
|
|
supplied, return two values: 1) <code>default</code> 2) <code>:timeout</code>. If <code>default</code> is not
|
|
supplied, signal a <code>join-thread-error</code> with <code>join-thread-problem</code> equal
|
|
to <code>:timeout</code>.
|
|
</p>
|
|
<p>If <code>thread</code> does not exit normally (i.e. aborted) and <code>default</code> is
|
|
supplied, return two values: 1) <code>default</code> 2) <code>:abort</code>. If <code>default</code> is not
|
|
supplied, signal a <code>join-thread-error</code> with <code>join-thread-problem</code> equal
|
|
to <code>:abort</code>.
|
|
</p>
|
|
<p>If <code>thread</code> is the current thread, signal a <code>join-thread-error</code> with
|
|
<code>join-thread-problem</code> equal to <code>:self-join</code>.
|
|
</p>
|
|
<p>Trying to join the main thread causes <code>join-thread</code> to block until
|
|
<code>timeout</code> occurs or the process exits: when the main thread exits, the
|
|
entire process exits.
|
|
</p>
|
|
<p>Users should not rely on the ability to join a chosen <code>thread</code> from more
|
|
than one other thread simultaneously. Future changes to <code>join-thread</code> may
|
|
directly call the underlying thread library, and not all threading
|
|
implementations consider such usage to be well-defined.
|
|
</p>
|
|
<p><code>note:</code> Return convention in case of a timeout is experimental and
|
|
subject to change.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-thread_002dyield"></span><dl>
|
|
<dt id="index-thread_002dyield">Function: <strong>thread-yield</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Yield the processor to other threads.
|
|
</p></dd></dl>
|
|
|
|
<span id="Asynchronous-Operations"></span><h4 class="subsection">13.1.3 Asynchronous Operations</h4>
|
|
|
|
<span id="Function-sb_002dthread-interrupt_002dthread"></span><dl>
|
|
<dt id="index-interrupt_002dthread">Function: <strong>interrupt-thread</strong> <em>[sb-thread] thread function</em></dt>
|
|
<dd><p>Interrupt <code>thread</code> and make it run <code>function</code>.
|
|
</p>
|
|
<p>The interrupt is asynchronous, and can occur anywhere with the exception of
|
|
sections protected using <code>sb-sys:without-interrupts</code>.
|
|
</p>
|
|
<p><code>function</code> is called with interrupts disabled, under
|
|
<code>sb-sys:allow-with-interrupts</code>. Since functions such as <code>grab-mutex</code> may try to
|
|
enable interrupts internally, in most cases <code>function</code> should either enter
|
|
<code>sb-sys:with-interrupts</code> to allow nested interrupts, or
|
|
<code>sb-sys:without-interrupts</code> to prevent them completely.
|
|
</p>
|
|
<p>When a thread receives multiple interrupts, they are executed in the order
|
|
they were sent <code>--</code> first in, first out.
|
|
</p>
|
|
<p>This means that a great degree of care is required to use <code>interrupt-thread</code>
|
|
safely and sanely in a production environment. The general recommendation is
|
|
to limit uses of <code>interrupt-thread</code> for interactive debugging, banning it
|
|
entirely from production environments <code>--</code> it is simply exceedingly hard to use
|
|
correctly.
|
|
</p>
|
|
<p>With those caveats in mind, what you need to know when using it:
|
|
</p>
|
|
<ul>
|
|
<li> If calling <code>function</code> causes a non-local transfer of control (ie. an
|
|
unwind), all normal cleanup forms will be executed.
|
|
|
|
<p>However, if the interrupt occurs during cleanup forms of an <code>unwind-protect</code>,
|
|
it is just as if that had happened due to a regular <code>go</code>, <code>throw</code>, or
|
|
<code>return-from:</code> the interrupted cleanup form and those following it in the
|
|
same <code>unwind-protect</code> do not get executed.
|
|
</p>
|
|
<p><code>sbcl</code> tries to keep its own internals asynch-unwind-safe, but this is
|
|
frankly an unreasonable expectation for third party libraries, especially
|
|
given that asynch-unwind-safety does not compose: a function calling
|
|
only asynch-unwind-safe function isn’t automatically asynch-unwind-safe.
|
|
</p>
|
|
<p>This means that in order for an asynch unwind to be safe, the entire
|
|
callstack at the point of interruption needs to be asynch-unwind-safe.
|
|
</p>
|
|
</li><li> In addition to asynch-unwind-safety you must consider the issue of
|
|
reentrancy. <code>interrupt-thread</code> can cause function that are never normally
|
|
called recursively to be re-entered during their dynamic contour,
|
|
which may cause them to misbehave. (Consider binding of special variables,
|
|
values of global variables, etc.)
|
|
|
|
</li></ul>
|
|
<p>Taken together, these two restrict the "safe" things to do using
|
|
<code>interrupt-thread</code> to a fairly minimal set. One useful one <code>--</code> exclusively for
|
|
interactive development use is using it to force entry to debugger to inspect
|
|
the state of a thread:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (interrupt-thread thread #'break)
|
|
</pre></div>
|
|
|
|
<p>Short version: be careful out there.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-terminate_002dthread"></span><dl>
|
|
<dt id="index-terminate_002dthread">Function: <strong>terminate-thread</strong> <em>[sb-thread] thread</em></dt>
|
|
<dd><p>Terminate the thread identified by <code>thread</code>, by interrupting it and
|
|
causing it to call <code>sb-ext:abort-thread</code> with <code>:allow-exit</code> <code>t</code>.
|
|
</p>
|
|
<p>The unwind caused by <code>terminate-thread</code> is asynchronous, meaning that
|
|
eg. thread executing
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (let (foo)
|
|
(unwind-protect
|
|
(progn
|
|
(setf foo (get-foo))
|
|
(work-on-foo foo))
|
|
(when foo
|
|
;; An interrupt occurring inside the cleanup clause
|
|
;; will cause cleanups from the current UNWIND-PROTECT
|
|
;; to be dropped.
|
|
(release-foo foo))))
|
|
</pre></div>
|
|
|
|
<p>might miss calling <code>release-foo</code> despite <code>get-foo</code> having returned true if
|
|
the interrupt occurs inside the cleanup clause, eg. during execution
|
|
of <code>release-foo</code>.
|
|
</p>
|
|
<p>Thus, in order to write an asynch unwind safe <code>unwind-protect</code> you need
|
|
to use <code>without-interrupts:</code>
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (let (foo)
|
|
(sb-sys:without-interrupts
|
|
(unwind-protect
|
|
(progn
|
|
(setf foo (sb-sys:allow-with-interrupts
|
|
(get-foo)))
|
|
(sb-sys:with-local-interrupts
|
|
(work-on-foo foo)))
|
|
(when foo
|
|
(release-foo foo)))))
|
|
</pre></div>
|
|
|
|
<p>Since most libraries using <code>unwind-protect</code> do not do this, you should never
|
|
assume that unknown code can safely be terminated using <code>terminate-thread</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Miscellaneous-Operations"></span><h4 class="subsection">13.1.4 Miscellaneous Operations</h4>
|
|
|
|
<span id="Function-sb_002dthread-symbol_002dvalue_002din_002dthread"></span><dl>
|
|
<dt id="index-symbol_002dvalue_002din_002dthread">Function: <strong>symbol-value-in-thread</strong> <em>[sb-thread] symbol thread &optional errorp</em></dt>
|
|
<dd><p>Return the local value of <code>symbol</code> in <code>thread</code>, and a secondary value of <code>t</code>
|
|
on success.
|
|
</p>
|
|
<p>If the value cannot be retrieved (because the thread has exited or because it
|
|
has no local binding for <code>name</code>) and <code>errorp</code> is true signals an error of type
|
|
<code>symbol-value-in-thread-error</code>; if <code>errorp</code> is false returns a primary value of
|
|
<code>nil</code>, and a secondary value of <code>nil</code>.
|
|
</p>
|
|
<p>Can also be used with <code>setf</code> to change the thread-local value of <code>symbol</code>.
|
|
</p>
|
|
<p><code>symbol-value-in-thread</code> is primarily intended as a debugging tool, and not as a
|
|
mechanism for inter-thread communication.
|
|
</p></dd></dl>
|
|
|
|
<span id="Error-Conditions"></span><h4 class="subsection">13.1.5 Error Conditions</h4>
|
|
|
|
<span id="Condition-sb_002dthread-thread_002derror"></span><dl>
|
|
<dt id="index-thread_002derror">Condition: <strong>thread-error</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">thread-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Conditions of type <code>thread-error</code> are signalled when thread operations fail.
|
|
The offending thread is initialized by the <code>:thread</code> initialization argument and
|
|
read by the function <code>thread-error-thread</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-thread_002derror_002dthread"></span><dl>
|
|
<dt id="index-thread_002derror_002dthread">Function: <strong>thread-error-thread</strong> <em>[sb-thread] condition</em></dt>
|
|
<dd><p>Return the offending thread that the <code>thread-error</code> pertains to.
|
|
</p></dd></dl>
|
|
|
|
<span id="Condition-sb_002dthread-interrupt_002dthread_002derror"></span><dl>
|
|
<dt id="index-interrupt_002dthread_002derror">Condition: <strong>interrupt-thread-error</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">interrupt-thread-error</span><!-- /@w --></code>, <code><span class="nolinebreak">thread-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Signalled when interrupting a thread fails because the thread has already
|
|
exited. The offending thread can be accessed using <code>thread-error-thread</code>.
|
|
</p></dd></dl>
|
|
<span id="Condition-sb_002dthread-join_002dthread_002derror"></span><dl>
|
|
<dt id="index-join_002dthread_002derror">Condition: <strong>join-thread-error</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">join-thread-error</span><!-- /@w --></code>, <code><span class="nolinebreak">thread-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Signalled when joining a thread fails due to abnormal exit of the thread
|
|
to be joined. The offending thread can be accessed using
|
|
<code>thread-error-thread</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Special-Variables"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Atomic-Operations" accesskey="n" rel="next">Atomic Operations</a>, Previous: <a href="index.html#Threading-basics" accesskey="p" rel="prev">Threading basics</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Special-Variables-1"></span><h3 class="section">13.2 Special Variables</h3>
|
|
|
|
<p>The interaction of special variables with multiple threads is mostly
|
|
as one would expect, with behaviour very similar to other
|
|
implementations.
|
|
</p>
|
|
<ul>
|
|
<li> global special values are visible across all threads;
|
|
</li><li> bindings (e.g. using LET) are local to the thread;
|
|
</li><li> threads do not inherit dynamic bindings from the parent thread
|
|
</li></ul>
|
|
|
|
<p>The last point means that
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defparameter *x* 0)
|
|
(let ((*x* 1))
|
|
(sb-thread:make-thread (lambda () (print *x*))))
|
|
</pre></div>
|
|
|
|
<p>prints <code>0</code> and not <code>1</code> as of 0.9.6.
|
|
</p>
|
|
<hr>
|
|
<span id="Atomic-Operations"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Mutex-Support" accesskey="n" rel="next">Mutex Support</a>, Previous: <a href="index.html#Special-Variables" accesskey="p" rel="prev">Special Variables</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Atomic-Operations-1"></span><h3 class="section">13.3 Atomic Operations</h3>
|
|
|
|
<p>Following atomic operations are particularly useful for implementing
|
|
lockless algorithms.
|
|
</p>
|
|
<span id="Macro-sb_002dext-atomic_002ddecf"></span><dl>
|
|
<dt id="index-atomic_002ddecf">Macro: <strong>atomic-decf</strong> <em>[sb-ext] place &optional diff</em></dt>
|
|
<dd><p>Atomically decrements <code>place</code> by <code>diff</code>, and returns the value of <code>place</code> before
|
|
the decrement.
|
|
</p>
|
|
<p><code>place</code> must access one of the following:
|
|
</p><ul>
|
|
<li> a <code>defstruct</code> slot with declared type (<code>unsigned-byte</code> 64)
|
|
or <code>aref</code> of a (<code>simple-array</code> (<code>unsigned-byte</code> 64) (<code>*</code>))
|
|
The type <code>sb-ext:word</code> can be used for these purposes.
|
|
</li><li> <code>car</code> or <code>cdr</code> (respectively <code>first</code> or <code>rest</code>) of a <code>cons</code>.
|
|
</li><li> a variable defined using <code>defglobal</code> with a proclaimed type of <code>fixnum</code>.
|
|
</li></ul>
|
|
<p>Macroexpansion is performed on <code>place</code> before expanding <code>atomic-decf</code>.
|
|
</p>
|
|
<p>Decrementing is done using modular arithmetic,
|
|
which is well-defined over two different domains:
|
|
</p><ul>
|
|
<li> For structures and arrays, the operation accepts and produces
|
|
an (<code>unsigned-byte</code> 64), and <code>diff</code> must be of type (<code>signed-byte</code> 64).
|
|
<code>atomic-decf</code> of #x0 by one results in #xFFFFFFFFFFFFFFFF being stored in <code>place</code>.
|
|
</li><li> For other places, the domain is <code>fixnum</code>, and <code>diff</code> must be a <code>fixnum</code>.
|
|
<code>atomic-decf</code> of #x-4000000000000000 by one results in #x3FFFFFFFFFFFFFFF
|
|
being stored in <code>place</code>.
|
|
|
|
</li></ul>
|
|
<p><code>diff</code> defaults to 1.
|
|
</p>
|
|
<p><code>experimental:</code> Interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dext-atomic_002dincf"></span><dl>
|
|
<dt id="index-atomic_002dincf">Macro: <strong>atomic-incf</strong> <em>[sb-ext] place &optional diff</em></dt>
|
|
<dd><p>Atomically increments <code>place</code> by <code>diff</code>, and returns the value of <code>place</code> before
|
|
the increment.
|
|
</p>
|
|
<p><code>place</code> must access one of the following:
|
|
</p><ul>
|
|
<li> a <code>defstruct</code> slot with declared type (<code>unsigned-byte</code> 64)
|
|
or <code>aref</code> of a (<code>simple-array</code> (<code>unsigned-byte</code> 64) (<code>*</code>))
|
|
The type <code>sb-ext:word</code> can be used for these purposes.
|
|
</li><li> <code>car</code> or <code>cdr</code> (respectively <code>first</code> or <code>rest</code>) of a <code>cons</code>.
|
|
</li><li> a variable defined using <code>defglobal</code> with a proclaimed type of <code>fixnum</code>.
|
|
</li></ul>
|
|
<p>Macroexpansion is performed on <code>place</code> before expanding <code>atomic-incf</code>.
|
|
</p>
|
|
<p>Incrementing is done using modular arithmetic,
|
|
which is well-defined over two different domains:
|
|
</p><ul>
|
|
<li> For structures and arrays, the operation accepts and produces
|
|
an (<code>unsigned-byte</code> 64), and <code>diff</code> must be of type (<code>signed-byte</code> 64).
|
|
<code>atomic-incf</code> of #xFFFFFFFFFFFFFFFF by one results in #x0 being stored in <code>place</code>.
|
|
</li><li> For other places, the domain is <code>fixnum</code>, and <code>diff</code> must be a <code>fixnum</code>.
|
|
<code>atomic-incf</code> of #x3FFFFFFFFFFFFFFF by one results in #x-4000000000000000
|
|
being stored in <code>place</code>.
|
|
|
|
</li></ul>
|
|
<p><code>diff</code> defaults to 1.
|
|
</p>
|
|
<p><code>experimental:</code> Interface subject to change.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dext-atomic_002dpop"></span><dl>
|
|
<dt id="index-atomic_002dpop">Macro: <strong>atomic-pop</strong> <em>[sb-ext] place</em></dt>
|
|
<dd><p>Like <code>pop</code>, but atomic. <code>place</code> may be read multiple times before
|
|
the operation completes <code>--</code> the write does not occur until such time
|
|
that no other thread modified <code>place</code> between the read and the write.
|
|
</p>
|
|
<p>Works on all CASable places.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dext-atomic_002dpush"></span><dl>
|
|
<dt id="index-atomic_002dpush">Macro: <strong>atomic-push</strong> <em>[sb-ext] obj place</em></dt>
|
|
<dd><p>Like <code>push</code>, but atomic. <code>place</code> may be read multiple times before
|
|
the operation completes <code>--</code> the write does not occur until such time
|
|
that no other thread modified <code>place</code> between the read and the write.
|
|
</p>
|
|
<p>Works on all CASable places.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dext-atomic_002dupdate"></span><dl>
|
|
<dt id="index-atomic_002dupdate">Macro: <strong>atomic-update</strong> <em>[sb-ext] place update-fn &rest arguments</em></dt>
|
|
<dd><p>Updates <code>place</code> atomically to the value returned by calling function
|
|
designated by <code>update-fn</code> with <code>arguments</code> and the previous value of <code>place</code>.
|
|
</p>
|
|
<p><code>place</code> may be read and <code>update-fn</code> evaluated and called multiple times before the
|
|
update succeeds: atomicity in this context means that the value of <code>place</code> did
|
|
not change between the time it was read, and the time it was replaced with the
|
|
computed value.
|
|
</p>
|
|
<p><code>place</code> can be any place supported by <code>sb-ext:compare-and-swap</code>.
|
|
</p>
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> ;;; Conses T to the head of FOO-LIST.
|
|
(defstruct foo list)
|
|
(defvar *foo* (make-foo))
|
|
(atomic-update (foo-list *foo*) #'cons t)
|
|
|
|
(let ((x (cons :count 0)))
|
|
(mapc #'sb-thread:join-thread
|
|
(loop repeat 1000
|
|
collect (sb-thread:make-thread
|
|
(lambda ()
|
|
(loop repeat 1000
|
|
do (atomic-update (cdr x) #'1+)
|
|
(sleep 0.00001))))))
|
|
;; Guaranteed to be (:COUNT . 1000000) -- if you replace
|
|
;; atomic update with (INCF (CDR X)) above, the result becomes
|
|
;; unpredictable.
|
|
x)
|
|
</pre></div>
|
|
</dd></dl>
|
|
<span id="Macro-sb_002dext-compare_002dand_002dswap"></span><dl>
|
|
<dt id="index-compare_002dand_002dswap">Macro: <strong>compare-and-swap</strong> <em>[sb-ext] place old new</em></dt>
|
|
<dd><p>Atomically stores <code>new</code> in <code>place</code> if <code>old</code> matches the current value of <code>place</code>.
|
|
Two values are considered to match if they are <code>eq</code>. Returns the previous value
|
|
of <code>place:</code> if the returned value is <code>eq</code> to <code>old</code>, the swap was carried out.
|
|
</p>
|
|
<p><code>place</code> must be an CAS-able place. Built-in CAS-able places are accessor forms
|
|
whose <code>car</code> is one of the following:
|
|
</p>
|
|
<p><code>car</code>, <code>cdr</code>, <code>first</code>, <code>rest</code>, <code>svref</code>, <code>symbol-plist</code>, <code>symbol-value</code>, <code>svref</code>, <code>slot-value</code>
|
|
<code>sb-mop:standard-instance-access</code>, <code>sb-mop:funcallable-standard-instance-access</code>,
|
|
</p>
|
|
<p>or the name of a <code>defstruct</code> created accessor for a slot whose storage type
|
|
is not raw. (Refer to the the "Efficiency" chapter of the manual
|
|
for the list of raw slot types. Future extensions to this macro may allow
|
|
it to work on some raw slot types.)
|
|
</p>
|
|
<p>In case of <code>slot-value</code>, if the slot is unbound, <code>slot-unbound</code> is called unless
|
|
<code>old</code> is <code>eq</code> to <code>sb-pcl:+slot-unbound+</code> in which case <code>sb-pcl:+slot-unbound+</code> is
|
|
returned and <code>new</code> is assigned to the slot. Additionally, the results are
|
|
unspecified if there is an applicable method on either
|
|
<code>sb-mop:slot-value-using-class</code>, (<code>setf</code> <code>sb-mop:slot-value-using-class</code>), or
|
|
<code>sb-mop:slot-boundp-using-class</code>.
|
|
</p>
|
|
<p>Additionally, the <code>place</code> can be a anything for which a CAS-function has
|
|
been defined. (See <code>sb-ext:cas</code> for more information.)
|
|
</p></dd></dl>
|
|
|
|
<span id="CAS-Protocol"></span><h4 class="unnumberedsubsec">CAS Protocol</h4>
|
|
|
|
<p>Our <code>compare-and-swap</code> is user-extensible by defining functions
|
|
named (CAS place), allowing users to add CAS support to new
|
|
places.
|
|
</p>
|
|
<span id="Macro-sb_002dext-cas"></span><dl>
|
|
<dt id="index-cas">Macro: <strong>cas</strong> <em>[sb-ext] place old new</em></dt>
|
|
<dd><p>Synonym for <code>compare-and-swap</code>.
|
|
</p>
|
|
<p>Additionally <code>defun</code>, <code>defgeneric</code>, <code>defmethod</code>, <code>flet</code>, and <code>labels</code> can be also used to
|
|
define CAS-functions analogously to SETF-functions:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (defvar *foo* nil)
|
|
|
|
(defun (cas foo) (old new)
|
|
(cas (symbol-value '*foo*) old new))
|
|
</pre></div>
|
|
|
|
<p>First argument of a <code>cas</code> function is the expected old value, and the second
|
|
argument of is the new value. Note that the system provides no automatic
|
|
atomicity for <code>cas</code> functions, nor can it verify that they are atomic: it is up
|
|
to the implementor of a <code>cas</code> function to ensure its atomicity.
|
|
</p>
|
|
<p><code>experimental:</code> Interface subject to change.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Mutex-Support"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Semaphores" accesskey="n" rel="next">Semaphores</a>, Previous: <a href="index.html#Atomic-Operations" accesskey="p" rel="prev">Atomic Operations</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Mutex-Support-1"></span><h3 class="section">13.4 Mutex Support</h3>
|
|
|
|
<p>Mutexes are used for controlling access to a shared resource. One
|
|
thread is allowed to hold the mutex, others which attempt to take it
|
|
will be made to wait until it’s free. Threads are woken in the order
|
|
that they go to sleep.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defpackage :demo (:use "CL" "SB-THREAD" "SB-EXT"))
|
|
|
|
(in-package :demo)
|
|
|
|
(defvar *a-mutex* (make-mutex :name "my lock"))
|
|
|
|
(defun thread-fn ()
|
|
(format t "Thread ~A running ~%" *current-thread*)
|
|
(with-mutex (*a-mutex*)
|
|
(format t "Thread ~A got the lock~%" *current-thread*)
|
|
(sleep (random 5)))
|
|
(format t "Thread ~A dropped lock, dying now~%" *current-thread*))
|
|
|
|
(make-thread #'thread-fn)
|
|
(make-thread #'thread-fn)
|
|
</pre></div>
|
|
|
|
<span id="Structure-sb_002dthread-mutex"></span><dl>
|
|
<dt id="index-mutex">Structure: <strong>mutex</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code>mutex<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Mutex type.
|
|
</p></dd></dl>
|
|
|
|
<span id="Macro-sb_002dthread-with_002dmutex"></span><dl>
|
|
<dt id="index-with_002dmutex">Macro: <strong>with-mutex</strong> <em>[sb-thread] (mutex &key wait-p timeout value) &body body</em></dt>
|
|
<dd><p>Acquire <code>mutex</code> for the dynamic scope of <code>body</code>. If <code>wait-p</code> is true (the default),
|
|
and the <code>mutex</code> is not immediately available, sleep until it is available.
|
|
</p>
|
|
<p>If <code>timeout</code> is given, it specifies a relative timeout, in seconds, on how long
|
|
the system should try to acquire the lock in the contested case.
|
|
</p>
|
|
<p>If the mutex isn’t acquired successfully due to either <code>wait-p</code> or <code>timeout</code>, the
|
|
body is not executed, and <code>with-mutex</code> returns <code>nil</code>.
|
|
</p>
|
|
<p>Otherwise body is executed with the mutex held by current thread, and
|
|
<code>with-mutex</code> returns the values of <code>body</code>.
|
|
</p>
|
|
<p>Historically <code>with-mutex</code> also accepted a <code>value</code> argument, which when provided
|
|
was used as the new owner of the mutex instead of the current thread. This is
|
|
no longer supported: if <code>value</code> is provided, it must be either <code>nil</code> or the
|
|
current thread.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dthread-with_002drecursive_002dlock"></span><dl>
|
|
<dt id="index-with_002drecursive_002dlock">Macro: <strong>with-recursive-lock</strong> <em>[sb-thread] (mutex &key wait-p timeout) &body body</em></dt>
|
|
<dd><p>Acquire <code>mutex</code> for the dynamic scope of <code>body</code>.
|
|
</p>
|
|
<p>If <code>wait-p</code> is true (the default), and the <code>mutex</code> is not immediately available or
|
|
held by the current thread, sleep until it is available.
|
|
</p>
|
|
<p>If <code>timeout</code> is given, it specifies a relative timeout, in seconds, on how long
|
|
the system should try to acquire the lock in the contested case.
|
|
</p>
|
|
<p>If the mutex isn’t acquired successfully due to either <code>wait-p</code> or <code>timeout</code>, the
|
|
body is not executed, and <code>with-recursive-lock</code> returns <code>nil</code>.
|
|
</p>
|
|
<p>Otherwise body is executed with the mutex held by current thread, and
|
|
<code>with-recursive-lock</code> returns the values of <code>body</code>.
|
|
</p>
|
|
<p>Unlike <code>with-mutex</code>, which signals an error on attempt to re-acquire an already
|
|
held mutex, <code>with-recursive-lock</code> allows recursive lock attempts to succeed.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dthread-make_002dmutex"></span><dl>
|
|
<dt id="index-make_002dmutex">Function: <strong>make-mutex</strong> <em>[sb-thread] &key name</em></dt>
|
|
<dd><p>Create a mutex.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-mutex_002dname"></span><dl>
|
|
<dt id="index-mutex_002dname">Function: <strong>mutex-name</strong> <em>[sb-thread] instance</em></dt>
|
|
<dd><p>The name of the mutex. Setfable.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-mutex_002downer"></span><dl>
|
|
<dt id="index-mutex_002downer">Function: <strong>mutex-owner</strong> <em>[sb-thread] mutex</em></dt>
|
|
<dd><p>Current owner of the mutex, <code>nil</code> if the mutex is free. Naturally,
|
|
this is racy by design (another thread may acquire the mutex after
|
|
this function returns), it is intended for informative purposes. For
|
|
testing whether the current thread is holding a mutex see
|
|
<code>holding-mutex-p</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-mutex_002dvalue"></span><dl>
|
|
<dt id="index-mutex_002dvalue">Function: <strong>mutex-value</strong> <em>[sb-thread] mutex</em></dt>
|
|
<dd><p>Current owner of the mutex, <code>nil</code> if the mutex is free. May return a
|
|
stale value, use <code>mutex-owner</code> instead.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-grab_002dmutex"></span><dl>
|
|
<dt id="index-grab_002dmutex">Function: <strong>grab-mutex</strong> <em>[sb-thread] mutex &key waitp timeout</em></dt>
|
|
<dd><p>Acquire <code>mutex</code> for the current thread. If <code>waitp</code> is true (the default) and
|
|
the mutex is not immediately available, sleep until it is available.
|
|
</p>
|
|
<p>If <code>timeout</code> is given, it specifies a relative timeout, in seconds, on how long
|
|
<code>grab-mutex</code> should try to acquire the lock in the contested case.
|
|
</p>
|
|
<p>If <code>grab-mutex</code> returns <code>t</code>, the lock acquisition was successful. In case of <code>waitp</code>
|
|
being <code>nil</code>, or an expired <code>timeout</code>, <code>grab-mutex</code> may also return <code>nil</code> which denotes
|
|
that <code>grab-mutex</code> did -not- acquire the lock.
|
|
</p>
|
|
<p>Notes:
|
|
</p>
|
|
<ul>
|
|
<li> <code>grab-mutex</code> is not interrupt safe. The correct way to call it is:
|
|
|
|
<p>(<code>without-interrupts</code>
|
|
...
|
|
(<code>allow-with-interrupts</code> (<code>grab-mutex</code> ...))
|
|
...)
|
|
</p>
|
|
<p><code>without-interrupts</code> is necessary to avoid an interrupt unwinding the call
|
|
while the mutex is in an inconsistent state while <code>allow-with-interrupts</code>
|
|
allows the call to be interrupted from sleep.
|
|
</p>
|
|
</li><li> (<code>grab-mutex</code> <mutex> :timeout 0.0) differs from
|
|
(<code>grab-mutex</code> <mutex> :waitp nil) in that the former may signal a
|
|
<code>deadline-timeout</code> if the global deadline was due already on entering
|
|
<code>grab-mutex</code>.
|
|
|
|
<p>The exact interplay of <code>grab-mutex</code> and deadlines are reserved to change in
|
|
future versions.
|
|
</p>
|
|
</li><li> It is recommended that you use <code>with-mutex</code> instead of calling <code>grab-mutex</code>
|
|
directly.
|
|
</li></ul>
|
|
</dd></dl>
|
|
<span id="Function-sb_002dthread-release_002dmutex"></span><dl>
|
|
<dt id="index-release_002dmutex">Function: <strong>release-mutex</strong> <em>[sb-thread] mutex &key if-not-owner</em></dt>
|
|
<dd><p>Release <code>mutex</code> by setting it to <code>nil</code>. Wake up threads waiting for
|
|
this mutex.
|
|
</p>
|
|
<p><code>release-mutex</code> is not interrupt safe: interrupts should be disabled
|
|
around calls to it.
|
|
</p>
|
|
<p>If the current thread is not the owner of the mutex then it silently
|
|
returns without doing anything (if <code>if-not-owner</code> is <code>:punt</code>), signals a
|
|
<code>warning</code> (if <code>if-not-owner</code> is <code>:warn</code>), or releases the mutex anyway (if
|
|
<code>if-not-owner</code> is <code>:force</code>).
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Semaphores"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Waitqueue_002fcondition-variables" accesskey="n" rel="next">Waitqueue/condition variables</a>, Previous: <a href="index.html#Mutex-Support" accesskey="p" rel="prev">Mutex Support</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Semaphores-1"></span><h3 class="section">13.5 Semaphores</h3>
|
|
|
|
<p>Semaphores are among other things useful for keeping track of a
|
|
countable resource, e.g. messages in a queue, and sleep when the
|
|
resource is exhausted.
|
|
</p>
|
|
<span id="Structure-sb_002dthread-semaphore"></span><dl>
|
|
<dt id="index-semaphore">Structure: <strong>semaphore</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code>semaphore<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Semaphore type. The fact that a <code>semaphore</code> is a <code>structure-object</code>
|
|
should be considered an implementation detail, and may change in the
|
|
future.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-make_002dsemaphore"></span><dl>
|
|
<dt id="index-make_002dsemaphore">Function: <strong>make-semaphore</strong> <em>[sb-thread] &key name count</em></dt>
|
|
<dd><p>Create a semaphore with the supplied <code>count</code> and <code>name</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-signal_002dsemaphore"></span><dl>
|
|
<dt id="index-signal_002dsemaphore">Function: <strong>signal-semaphore</strong> <em>[sb-thread] semaphore &optional n</em></dt>
|
|
<dd><p>Increment the count of <code>semaphore</code> by <code>n</code>. If there are threads waiting
|
|
on this semaphore, then <code>n</code> of them is woken up.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-wait_002don_002dsemaphore"></span><dl>
|
|
<dt id="index-wait_002don_002dsemaphore">Function: <strong>wait-on-semaphore</strong> <em>[sb-thread] semaphore &key n timeout notification</em></dt>
|
|
<dd><p>Decrement the count of <code>semaphore</code> by <code>n</code> if the count would not be negative.
|
|
</p>
|
|
<p>Else blocks until the semaphore can be decremented. Returns the new count of
|
|
<code>semaphore</code> on success.
|
|
</p>
|
|
<p>If <code>timeout</code> is given, it is the maximum number of seconds to wait. If the count
|
|
cannot be decremented in that time, returns <code>nil</code> without decrementing the
|
|
count.
|
|
</p>
|
|
<p>If <code>notification</code> is given, it must be a <code>semaphore-notification</code> object whose
|
|
<code>semaphore-notification-status</code> is <code>nil</code>. If <code>wait-on-semaphore</code> succeeds and
|
|
decrements the count, the status is set to <code>t</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-try_002dsemaphore"></span><dl>
|
|
<dt id="index-try_002dsemaphore">Function: <strong>try-semaphore</strong> <em>[sb-thread] semaphore &optional n notification</em></dt>
|
|
<dd><p>Try to decrement the count of <code>semaphore</code> by <code>n</code>. If the count were to
|
|
become negative, punt and return <code>nil</code>, otherwise return the new count of
|
|
<code>semaphore</code>.
|
|
</p>
|
|
<p>If <code>notification</code> is given it must be a semaphore notification object
|
|
with <code>semaphore-notification-status</code> of <code>nil</code>. If the count is decremented,
|
|
the status is set to <code>t</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-semaphore_002dcount"></span><dl>
|
|
<dt id="index-semaphore_002dcount">Function: <strong>semaphore-count</strong> <em>[sb-thread] instance</em></dt>
|
|
<dd><p>Returns the current count of the semaphore <code>instance</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-semaphore_002dname"></span><dl>
|
|
<dt id="index-semaphore_002dname">Function: <strong>semaphore-name</strong> <em>[sb-thread] semaphore</em></dt>
|
|
<dd><p>The name of the semaphore <code>instance</code>. Setfable.
|
|
</p></dd></dl>
|
|
|
|
<span id="Structure-sb_002dthread-semaphore_002dnotification"></span><dl>
|
|
<dt id="index-semaphore_002dnotification">Structure: <strong>semaphore-notification</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">semaphore-notification</span><!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Semaphore notification object. Can be passed to <code>wait-on-semaphore</code> and
|
|
<code>try-semaphore</code> as the <code>:notification</code> argument. Consequences are undefined if
|
|
multiple threads are using the same notification object in parallel.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-make_002dsemaphore_002dnotification"></span><dl>
|
|
<dt id="index-make_002dsemaphore_002dnotification">Function: <strong>make-semaphore-notification</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Constructor for <code>semaphore-notification</code> objects. <code>semaphore-notification-status</code>
|
|
is initially <code>nil</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-semaphore_002dnotification_002dstatus"></span><dl>
|
|
<dt id="index-semaphore_002dnotification_002dstatus">Function: <strong>semaphore-notification-status</strong> <em>[sb-thread] semaphore-notification</em></dt>
|
|
<dd><p>Returns <code>t</code> if a <code>wait-on-semaphore</code> or <code>try-semaphore</code> using
|
|
<code>semaphore-notification</code> has succeeded since the notification object was created
|
|
or cleared.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-clear_002dsemaphore_002dnotification"></span><dl>
|
|
<dt id="index-clear_002dsemaphore_002dnotification">Function: <strong>clear-semaphore-notification</strong> <em>[sb-thread] semaphore-notification</em></dt>
|
|
<dd><p>Resets the <code>semaphore-notification</code> object for use with another call to
|
|
<code>wait-on-semaphore</code> or <code>try-semaphore</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Waitqueue_002fcondition-variables"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Barriers" accesskey="n" rel="next">Barriers</a>, Previous: <a href="index.html#Semaphores" accesskey="p" rel="prev">Semaphores</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Waitqueue_002fcondition-variables-1"></span><h3 class="section">13.6 Waitqueue/condition variables</h3>
|
|
|
|
<p>These are based on the POSIX condition variable design, hence the
|
|
annoyingly CL-conflicting name. For use when you want to check a
|
|
condition and sleep until it’s true. For example: you have a shared
|
|
queue, a writer process checking “queue is empty” and one or more
|
|
readers that need to know when “queue is not empty”. It sounds
|
|
simple, but is astonishingly easy to deadlock if another process runs
|
|
when you weren’t expecting it to.
|
|
</p>
|
|
<p>There are three components:
|
|
</p>
|
|
<ul>
|
|
<li> the condition itself (not represented in code)
|
|
|
|
</li><li> the condition variable (a.k.a. waitqueue) which proxies for it
|
|
|
|
</li><li> a lock to hold while testing the condition
|
|
</li></ul>
|
|
|
|
<p>Important stuff to be aware of:
|
|
</p>
|
|
<ul>
|
|
<li> when calling condition-wait, you must hold the mutex. condition-wait
|
|
will drop the mutex while it waits, and obtain it again before
|
|
returning for whatever reason;
|
|
|
|
</li><li> likewise, you must be holding the mutex around calls to
|
|
condition-notify;
|
|
|
|
</li><li> a process may return from condition-wait in several circumstances: it
|
|
is not guaranteed that the underlying condition has become true. You
|
|
must check that the resource is ready for whatever you want to do to
|
|
it.
|
|
|
|
</li></ul>
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">(defvar *buffer-queue* (make-waitqueue))
|
|
(defvar *buffer-lock* (make-mutex :name "buffer lock"))
|
|
|
|
(defvar *buffer* (list nil))
|
|
|
|
(defun reader ()
|
|
(with-mutex (*buffer-lock*)
|
|
(loop
|
|
(condition-wait *buffer-queue* *buffer-lock*)
|
|
(loop
|
|
(unless *buffer* (return))
|
|
(let ((head (car *buffer*)))
|
|
(setf *buffer* (cdr *buffer*))
|
|
(format t "reader ~A woke, read ~A~%"
|
|
*current-thread* head))))))
|
|
|
|
(defun writer ()
|
|
(loop
|
|
(sleep (random 5))
|
|
(with-mutex (*buffer-lock*)
|
|
(let ((el (intern
|
|
(string (code-char
|
|
(+ (char-code #\A) (random 26)))))))
|
|
(setf *buffer* (cons el *buffer*)))
|
|
(condition-notify *buffer-queue*))))
|
|
|
|
(make-thread #'writer)
|
|
(make-thread #'reader)
|
|
(make-thread #'reader)
|
|
</pre></div>
|
|
|
|
<span id="Structure-sb_002dthread-waitqueue"></span><dl>
|
|
<dt id="index-waitqueue">Structure: <strong>waitqueue</strong> <em>[sb-thread]</em></dt>
|
|
<dd><p>Class precedence list: <code>waitqueue<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Waitqueue type.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-make_002dwaitqueue"></span><dl>
|
|
<dt id="index-make_002dwaitqueue">Function: <strong>make-waitqueue</strong> <em>[sb-thread] &key name</em></dt>
|
|
<dd><p>Create a waitqueue.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-waitqueue_002dname"></span><dl>
|
|
<dt id="index-waitqueue_002dname">Function: <strong>waitqueue-name</strong> <em>[sb-thread] instance</em></dt>
|
|
<dd><p>The name of the waitqueue. Setfable.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-condition_002dwait"></span><dl>
|
|
<dt id="index-condition_002dwait">Function: <strong>condition-wait</strong> <em>[sb-thread] queue mutex &key timeout</em></dt>
|
|
<dd><p>Atomically release <code>mutex</code> and start waiting on <code>queue</code> until another thread
|
|
wakes us up using either <code>condition-notify</code> or <code>condition-broadcast</code> on
|
|
<code>queue</code>, at which point we re-acquire <code>mutex</code> and return <code>t</code>.
|
|
</p>
|
|
<p>Spurious wakeups are possible.
|
|
</p>
|
|
<p>If <code>timeout</code> is given, it is the maximum number of seconds to wait,
|
|
including both waiting for the wakeup and the time to re-acquire
|
|
<code>mutex</code>. When neither a wakeup nor a re-acquisition occurs within the
|
|
given time, returns <code>nil</code> without re-acquiring <code>mutex</code>.
|
|
</p>
|
|
<p>If <code>condition-wait</code> unwinds, it may do so with or without <code>mutex</code> being
|
|
held.
|
|
</p>
|
|
<p>Important: Since <code>condition-wait</code> may return without <code>condition-notify</code> or
|
|
<code>condition-broadcast</code> having occurred, the correct way to write code
|
|
that uses <code>condition-wait</code> is to loop around the call, checking the
|
|
associated data:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (defvar *data* nil)
|
|
(defvar *queue* (make-waitqueue))
|
|
(defvar *lock* (make-mutex))
|
|
|
|
;; Consumer
|
|
(defun pop-data (&optional timeout)
|
|
(with-mutex (*lock*)
|
|
(loop until *data*
|
|
do (or (condition-wait *queue* *lock* :timeout timeout)
|
|
;; Lock not held, must unwind without touching *data*.
|
|
(return-from pop-data nil)))
|
|
(pop *data*)))
|
|
|
|
;; Producer
|
|
(defun push-data (data)
|
|
(with-mutex (*lock*)
|
|
(push data *data*)
|
|
(condition-notify *queue*)))
|
|
</pre></div>
|
|
</dd></dl>
|
|
<span id="Function-sb_002dthread-condition_002dnotify"></span><dl>
|
|
<dt id="index-condition_002dnotify">Function: <strong>condition-notify</strong> <em>[sb-thread] queue &optional n</em></dt>
|
|
<dd><p>Notify <code>n</code> threads waiting on <code>queue</code>.
|
|
</p>
|
|
<p><code>important:</code> The same mutex that is used in the corresponding <code>condition-wait</code>
|
|
must be held by this thread during this call.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dthread-condition_002dbroadcast"></span><dl>
|
|
<dt id="index-condition_002dbroadcast">Function: <strong>condition-broadcast</strong> <em>[sb-thread] queue</em></dt>
|
|
<dd><p>Notify all threads waiting on <code>queue</code>.
|
|
</p>
|
|
<p><code>important:</code> The same mutex that is used in the corresponding <code>condition-wait</code>
|
|
must be held by this thread during this call.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Barriers"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Sessions_002fDebugging" accesskey="n" rel="next">Sessions/Debugging</a>, Previous: <a href="index.html#Waitqueue_002fcondition-variables" accesskey="p" rel="prev">Waitqueue/condition variables</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Barriers-1"></span><h3 class="section">13.7 Barriers</h3>
|
|
|
|
<p>These are based on the Linux kernel barrier design, which is in turn
|
|
based on the Alpha CPU memory model. They are presently implemented for
|
|
x86, x86-64, PPC, ARM64, and RISC-V systems, and behave as compiler
|
|
barriers on all other CPUs.
|
|
</p>
|
|
<p>In addition to explicit use of the <code>sb-thread:barrier</code> macro, the
|
|
following functions and macros also serve as <code>:memory</code> barriers:
|
|
</p>
|
|
<ul>
|
|
<li> <code>sb-ext:atomic-decf</code>, <code>sb-ext:atomic-incf</code>, <code>sb-ext:atomic-push</code>,
|
|
and <code>sb-ext:atomic-pop</code>.
|
|
</li><li> <code>sb-ext:compare-and-swap</code>.
|
|
</li><li> <code>sb-thread:grab-mutex</code>, <code>sb-thread:release-mutex</code>,
|
|
<code>sb-thread:with-mutex</code> and <code>sb-thread:with-recursive-lock</code>.
|
|
</li><li> <code>sb-thread:signal-semaphore</code>, <code>sb-thread:try-semaphore</code> and
|
|
<code>sb-thread:wait-on-semaphore</code>.
|
|
</li><li> <code>sb-thread:condition-wait</code>, <code>sb-thread:condition-notify</code> and
|
|
<code>sb-thread:condition-broadcast</code>.
|
|
</li></ul>
|
|
|
|
<span id="Macro-sb_002dthread-barrier"></span><dl>
|
|
<dt id="index-barrier">Macro: <strong>barrier</strong> <em>[sb-thread] (kind) &body forms</em></dt>
|
|
<dd><p>Insert a barrier in the code stream, preventing some sort of
|
|
reordering.
|
|
</p>
|
|
<p><code>kind</code> should be one of:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:compiler</code></em></dt>
|
|
<dd><p>Prevent the compiler from reordering memory access across the
|
|
barrier.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:memory</code></em></dt>
|
|
<dd><p>Prevent the cpu from reordering any memory access across the
|
|
barrier.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:read</code></em></dt>
|
|
<dd><p>Prevent the cpu from reordering any read access across the
|
|
barrier.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:write</code></em></dt>
|
|
<dd><p>Prevent the cpu from reordering any write access across the
|
|
barrier.
|
|
</p>
|
|
</dd>
|
|
<dt><em><code>:data-dependency</code></em></dt>
|
|
<dd><p>Prevent the cpu from reordering dependent memory reads across the
|
|
barrier (requiring reads before the barrier to complete before any
|
|
reads after the barrier that depend on them). This is a weaker
|
|
form of the <code>:read</code> barrier.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p><code>forms</code> is an implicit <code>progn</code>, evaluated before the barrier. <code>barrier</code>
|
|
returns the values of the last form in <code>forms</code>.
|
|
</p>
|
|
<p>The file "memory-barriers.txt" in the Linux kernel documentation is
|
|
highly recommended reading for anyone programming at this level.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Sessions_002fDebugging"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Foreign-threads" accesskey="n" rel="next">Foreign threads</a>, Previous: <a href="index.html#Barriers" accesskey="p" rel="prev">Barriers</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Sessions_002fDebugging-1"></span><h3 class="section">13.8 Sessions/Debugging</h3>
|
|
|
|
<p>If the user has multiple views onto the same Lisp image (for example,
|
|
using multiple terminals, or a windowing system, or network access)
|
|
they are typically set up as multiple <em>sessions</em> such that each
|
|
view has its own collection of foreground/background/stopped threads.
|
|
A thread which wishes to create a new session can use
|
|
<code>sb-thread:with-new-session</code> to remove itself from the current
|
|
session (which it shares with its parent and siblings) and create a
|
|
fresh one.
|
|
# See also <code>sb-thread:make-listener-thread</code>.
|
|
</p>
|
|
<p>Within a single session, threads arbitrate between themselves for the
|
|
user’s attention. A thread may be in one of three notional states:
|
|
foreground, background, or stopped. When a background process
|
|
attempts to print a repl prompt or to enter the debugger, it will stop
|
|
and print a message saying that it has stopped. The user at his
|
|
leisure may switch to that thread to find out what it needs. If a
|
|
background thread enters the debugger, selecting any restart will put
|
|
it back into the background before it resumes. Arbitration for the
|
|
input stream is managed by calls to <code>sb-thread:get-foreground</code>
|
|
(which may block) and <code>sb-thread:release-foreground</code>.
|
|
</p>
|
|
<hr>
|
|
<span id="Foreign-threads"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Implementation-_0028Linux-x86_002fx86_002d64_0029" accesskey="n" rel="next">Implementation (Linux x86/x86-64)</a>, Previous: <a href="index.html#Sessions_002fDebugging" accesskey="p" rel="prev">Sessions/Debugging</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Foreign-threads-1"></span><h3 class="section">13.9 Foreign threads</h3>
|
|
|
|
<p>Direct calls to <code>pthread_create</code> (instead of <code>MAKE-THREAD</code>)
|
|
create threads that SBCL is not aware of, these are called foreign
|
|
threads. Currently, it is not possible to run Lisp code in such
|
|
threads. This means that the Lisp side signal handlers cannot work.
|
|
The best solution is to start foreign threads with signals blocked,
|
|
but since third party libraries may create threads, it is not always
|
|
feasible to do so. As a workaround, upon receiving a signal in a
|
|
foreign thread, SBCL changes the thread’s sigmask to block all signals
|
|
that it wants to handle and resends the signal to the current process
|
|
which should land in a thread that does not block it, that is, a Lisp
|
|
thread.
|
|
</p>
|
|
<p>The resignalling trick cannot work for synchronously triggered signals
|
|
(SIGSEGV and co), take care not to trigger any. Resignalling for
|
|
synchronously triggered signals in foreign threads is subject to
|
|
<code>--lose-on-corruption</code>, see <a href="index.html#Runtime-Options">Runtime Options</a>.
|
|
</p>
|
|
<hr>
|
|
<span id="Implementation-_0028Linux-x86_002fx86_002d64_0029"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Foreign-threads" accesskey="p" rel="prev">Foreign threads</a>, Up: <a href="index.html#Threading" accesskey="u" rel="up">Threading</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Implementation-_0028Linux-x86_002fx86_002d64_0029-1"></span><h3 class="section">13.10 Implementation (Linux x86/x86-64)</h3>
|
|
|
|
<p>Threading is implemented using pthreads and some Linux specific bits
|
|
like futexes.
|
|
</p>
|
|
<p>On x86 the per-thread local bindings for special variables is achieved
|
|
using the %fs segment register to point to a per-thread storage area.
|
|
This may cause interesting results if you link to foreign code that
|
|
expects threading or creates new threads, and the thread library in
|
|
question uses %fs in an incompatible way. On x86-64 the r12 register
|
|
has a similar role.
|
|
</p>
|
|
<p>Queues require the <code>sys_futex()</code> system call to be available:
|
|
this is the reason for the NPTL requirement. We test at runtime that
|
|
this system call exists.
|
|
</p>
|
|
<p>Garbage collection is done with the existing Conservative Generational
|
|
GC. Allocation is done in small (typically 8k) regions: each thread
|
|
has its own region so this involves no stopping. However, when a
|
|
region fills, a lock must be obtained while another is allocated, and
|
|
when a collection is required, all processes are stopped. This is
|
|
achieved by sending them signals, which may make for interesting
|
|
behaviour if they are interrupted in system calls. The streams
|
|
interface is believed to handle the required system call restarting
|
|
correctly, but this may be a consideration when making other blocking
|
|
calls e.g. from foreign library code.
|
|
</p>
|
|
<p>Large amounts of the SBCL library have not been inspected for
|
|
thread-safety. Some of the obviously unsafe areas have large locks
|
|
around them, so compilation and fasl loading, for example, cannot be
|
|
parallelized. Work is ongoing in this area.
|
|
</p>
|
|
<p>A new thread by default is created in the same POSIX process group and
|
|
session as the thread it was created by. This has an impact on
|
|
keyboard interrupt handling: pressing your terminal’s intr key
|
|
(typically <kbd>Control-C</kbd>) will interrupt all processes in the
|
|
foreground process group, including Lisp threads that SBCL considers
|
|
to be notionally ‘background’. This is undesirable, so background
|
|
threads are set to ignore the SIGINT signal.
|
|
</p>
|
|
<p><code>sb-thread:make-listener-thread</code> in addition to creating a new
|
|
Lisp session makes a new POSIX session, so that pressing
|
|
<kbd>Control-C</kbd> in one window will not interrupt another listener -
|
|
this has been found to be embarrassing.
|
|
</p><hr>
|
|
<span id="Timers"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Networking" accesskey="n" rel="next">Networking</a>, Previous: <a href="index.html#Threading" accesskey="p" rel="prev">Threading</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Timers-1"></span><h2 class="chapter">14 Timers</h2>
|
|
|
|
<p>SBCL supports a system-wide event scheduler implemented on top of
|
|
<code>setitimer</code> that also works with threads but does not require a
|
|
separate scheduler thread.
|
|
</p>
|
|
<p>The following example schedules a timer that writes “Hello, world” after
|
|
two seconds.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(schedule-timer (make-timer (lambda ()
|
|
(write-line "Hello, world")
|
|
(force-output)))
|
|
2)
|
|
</pre></div>
|
|
|
|
<p>It should be noted that writing timer functions requires special care,
|
|
as the dynamic environment in which they run is unpredictable: dynamic
|
|
variable bindings, locks held, etc, all depend on whatever code was
|
|
running when the timer fired. The following example should serve as
|
|
a cautionary tale:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defvar *foo* nil)
|
|
|
|
(defun show-foo ()
|
|
(format t "~&foo=~S~%" *foo*)
|
|
(force-output t))
|
|
|
|
(defun demo ()
|
|
(schedule-timer (make-timer #'show-foo) 0.5)
|
|
(schedule-timer (make-timer #'show-foo) 1.5)
|
|
(let ((*foo* t))
|
|
(sleep 1.0))
|
|
(let ((*foo* :surprise!))
|
|
(sleep 2.0)))
|
|
</pre></div>
|
|
|
|
<span id="Timer-Dictionary"></span><h3 class="section">14.1 Timer Dictionary</h3>
|
|
|
|
<span id="Structure-sb_002dext-timer"></span><dl>
|
|
<dt id="index-timer">Structure: <strong>timer</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code>timer<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Timer type. Do not rely on timers being structs as it may change in
|
|
future versions.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-make_002dtimer"></span><dl>
|
|
<dt id="index-make_002dtimer">Function: <strong>make-timer</strong> <em>[sb-ext] function &key name thread</em></dt>
|
|
<dd><p>Create a timer that runs <code>function</code> when triggered.
|
|
</p>
|
|
<p>If a <code>thread</code> is supplied, <code>function</code> is run in that thread. If <code>thread</code> is
|
|
<code>t</code>, a new thread is created for <code>function</code> each time the timer is
|
|
triggered. If <code>thread</code> is <code>nil</code>, <code>function</code> is run in an unspecified thread.
|
|
</p>
|
|
<p>When <code>thread</code> is not <code>t</code>, <code>interrupt-thread</code> is used to run <code>function</code> and the
|
|
ordering guarantees of <code>interrupt-thread</code> apply. In that case, <code>function</code>
|
|
runs with interrupts disabled but <code>with-interrupts</code> is allowed.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-timer_002dname"></span><dl>
|
|
<dt id="index-timer_002dname">Function: <strong>timer-name</strong> <em>[sb-ext] timer</em></dt>
|
|
<dd><p>Return the name of <code>timer</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-timer_002dscheduled_002dp"></span><dl>
|
|
<dt id="index-timer_002dscheduled_002dp">Function: <strong>timer-scheduled-p</strong> <em>[sb-ext] timer &key delta</em></dt>
|
|
<dd><p>See if <code>timer</code> will still need to be triggered after <code>delta</code> seconds
|
|
from now. For timers with a repeat interval it returns true.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-schedule_002dtimer"></span><dl>
|
|
<dt id="index-schedule_002dtimer">Function: <strong>schedule-timer</strong> <em>[sb-ext] timer time &key repeat-interval absolute-p catch-up</em></dt>
|
|
<dd><p>Schedule <code>timer</code> to be triggered at <code>time</code>. If <code>absolute-p</code> then <code>time</code> is
|
|
universal time, but non-integral values are also allowed, else <code>time</code> is
|
|
measured as the number of seconds from the current time.
|
|
</p>
|
|
<p>If <code>repeat-interval</code> is given, <code>timer</code> is automatically rescheduled upon
|
|
expiry.
|
|
</p>
|
|
<p>If <code>repeat-interval</code> is non-NIL, the Boolean <code>catch-up</code> controls whether
|
|
<code>timer</code> will "catch up" by repeatedly calling its function without
|
|
delay in case calls are missed because of a clock discontinuity such
|
|
as a suspend and resume cycle of the computer. The default is <code>nil</code>,
|
|
i.e. do not catch up.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-unschedule_002dtimer"></span><dl>
|
|
<dt id="index-unschedule_002dtimer">Function: <strong>unschedule-timer</strong> <em>[sb-ext] timer</em></dt>
|
|
<dd><p>Cancel <code>timer</code>. Once this function returns it is guaranteed that
|
|
<code>timer</code> shall not be triggered again and there are no unfinished
|
|
triggers.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dext-list_002dall_002dtimers"></span><dl>
|
|
<dt id="index-list_002dall_002dtimers">Function: <strong>list-all-timers</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Return a list of all timers in the system.
|
|
</p></dd></dl>
|
|
<hr>
|
|
<span id="Networking"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Profiling" accesskey="n" rel="next">Profiling</a>, Previous: <a href="index.html#Timers" accesskey="p" rel="prev">Timers</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Networking-1"></span><h2 class="chapter">15 Networking</h2>
|
|
<span id="index-Sockets_002c-Networking"></span>
|
|
|
|
<p>The <code>sb-bsd-sockets</code> module provides a thinly disguised BSD
|
|
socket API for SBCL. Ideas have been stolen from the BSD socket API
|
|
for C and Graham Barr’s IO::Socket classes for Perl.
|
|
</p>
|
|
<p>Sockets are represented as CLOS objects, and the API naming
|
|
conventions attempt to balance between the BSD names and good lisp style.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Sockets-Overview" accesskey="1">Sockets Overview</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#General-Sockets" accesskey="2">General Sockets</a></td><td> </td><td align="left" valign="top">Methods applicable to all sockets
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Socket-Options" accesskey="3">Socket Options</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#INET-Domain-Sockets" accesskey="4">INET Domain Sockets</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Local-_0028Unix_0029-Domain-Sockets" accesskey="5">Local (Unix) Domain Sockets</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Name-Service" accesskey="6">Name Service</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Sockets-Overview"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#General-Sockets" accesskey="n" rel="next">General Sockets</a>, Up: <a href="index.html#Networking" accesskey="u" rel="up">Networking</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Sockets-Overview-1"></span><h3 class="section">15.1 Sockets Overview</h3>
|
|
|
|
<p>Most of the functions are modelled on the BSD socket API. BSD sockets
|
|
are widely supported, portably <em>(“portable” by Unix standards, at least)</em>
|
|
available on a variety of systems, and documented. There are some
|
|
differences in approach where we have taken advantage of some of the
|
|
more useful features of Common Lisp - briefly:
|
|
</p>
|
|
<ul>
|
|
<li> Where the C API would typically return -1 and set <code>errno</code>,
|
|
<code>sb-bsd-sockets</code> signals an error. All the errors are subclasses
|
|
of <code>sb-bsd-sockets:socket-condition</code> and generally correspond one
|
|
for one with possible <code>errno</code> values.
|
|
|
|
</li><li> We use multiple return values in many places where the C API would use
|
|
pass-by-reference values.
|
|
|
|
</li><li> We can often avoid supplying an explicit <em>length</em> argument to
|
|
functions because we already know how long the argument is.
|
|
|
|
</li><li> IP addresses and ports are represented in slightly friendlier fashion
|
|
than "network-endian integers".
|
|
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="General-Sockets"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Socket-Options" accesskey="n" rel="next">Socket Options</a>, Previous: <a href="index.html#Sockets-Overview" accesskey="p" rel="prev">Sockets Overview</a>, Up: <a href="index.html#Networking" accesskey="u" rel="up">Networking</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="General-Sockets-1"></span><h3 class="section">15.2 General Sockets</h3>
|
|
|
|
<span id="Class-sb_002dbsd_002dsockets-socket"></span><dl>
|
|
<dt id="index-socket">Class: <strong>socket</strong> <em>[sb-bsd-sockets]</em></dt>
|
|
<dd><p>Class precedence list: <code>socket<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Slots:
|
|
</p><ul>
|
|
<li> <code>protocol</code> — initarg: <code>:protocol<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-bsd-sockets:socket-protocol</span><!-- /@w --></code>
|
|
|
|
<p>Protocol used by the socket. If a
|
|
keyword, the symbol-name of the keyword will be passed to
|
|
<code>get-protocol-by-name</code> downcased, and the returned value used as
|
|
protocol. Other values are used as-is.
|
|
</p></li><li> <code>type</code> — initarg: <code>:type<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-bsd-sockets:socket-type</span><!-- /@w --></code>
|
|
|
|
<p>Type of the socket: <code>:stream</code> or <code>:datagram</code>.
|
|
</p></li></ul>
|
|
|
|
<p>Common superclass of all sockets, not meant to be
|
|
directly instantiated.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dbind"></span><dl>
|
|
<dt id="index-socket_002dbind">Generic Function: <strong>socket-bind</strong> <em>[sb-bsd-sockets] socket &rest address</em></dt>
|
|
<dd><p>Bind <code>socket</code> to <code>address</code>, which may vary according to socket family.
|
|
For the <code>inet</code> family, pass <code>address</code> and <code>port</code> as two arguments; for <code>file</code>
|
|
address family sockets, pass the filename string. See also bind(2)
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002daccept"></span><dl>
|
|
<dt id="index-socket_002daccept">Generic Function: <strong>socket-accept</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Perform the accept(2) call, returning a newly-created connected
|
|
socket and the peer address as multiple values
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dconnect"></span><dl>
|
|
<dt id="index-socket_002dconnect">Generic Function: <strong>socket-connect</strong> <em>[sb-bsd-sockets] socket &rest address</em></dt>
|
|
<dd><p>Perform the connect(2) call to connect <code>socket</code> to a remote <code>peer</code>.
|
|
No useful return value.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dpeername"></span><dl>
|
|
<dt id="index-socket_002dpeername">Generic Function: <strong>socket-peername</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return SOCKET’s peer; depending on the address family this may
|
|
return multiple values
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dname"></span><dl>
|
|
<dt id="index-socket_002dname">Generic Function: <strong>socket-name</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the address (as vector of bytes) and port that <code>socket</code> is
|
|
bound to, as multiple values.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dreceive"></span><dl>
|
|
<dt id="index-socket_002dreceive">Generic Function: <strong>socket-receive</strong> <em>[sb-bsd-sockets] socket buffer length &key oob peek waitall dontwait element-type</em></dt>
|
|
<dd><p>Read <code>length</code> octets from <code>socket</code> into <code>buffer</code> (or a freshly-consed
|
|
buffer if <code>nil</code>), using recvfrom(2). If <code>length</code> is <code>nil</code>, the length of
|
|
<code>buffer</code> is used, so at least one of these two arguments must be
|
|
non-NIL. If <code>buffer</code> is supplied, it had better be of an element type
|
|
one octet wide. Returns the buffer, its length, and the address of the
|
|
peer that sent it, as multiple values. On datagram sockets, sets
|
|
MSG_TRUNC so that the actual packet length is returned even if the
|
|
buffer was too small.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dsend"></span><dl>
|
|
<dt id="index-socket_002dsend">Generic Function: <strong>socket-send</strong> <em>[sb-bsd-sockets] socket buffer length &key address external-format oob eor dontroute dontwait nosignal confirm more</em></dt>
|
|
<dd><p>Send <code>length</code> octets from <code>buffer</code> into <code>socket</code>, using sendto(2). If
|
|
<code>buffer</code> is a string, it will converted to octets according to
|
|
<code>external-format</code>. If <code>length</code> is <code>nil</code>, the length of the octet buffer is
|
|
used. The format of <code>address</code> depends on the socket type (for example
|
|
for <code>inet</code> domain sockets it would be a list of an <code>ip</code> address and a
|
|
port). If no socket address is provided, send(2) will be called
|
|
instead. Returns the number of octets written.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dlisten"></span><dl>
|
|
<dt id="index-socket_002dlisten">Generic Function: <strong>socket-listen</strong> <em>[sb-bsd-sockets] socket backlog</em></dt>
|
|
<dd><p>Mark <code>socket</code> as willing to accept incoming connections. The
|
|
integer <code>backlog</code> defines the maximum length that the queue of pending
|
|
connections may grow to before new connection attempts are refused.
|
|
See also listen(2)
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dopen_002dp"></span><dl>
|
|
<dt id="index-socket_002dopen_002dp">Generic Function: <strong>socket-open-p</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return true if <code>socket</code> is open; otherwise, return false.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dclose"></span><dl>
|
|
<dt id="index-socket_002dclose">Generic Function: <strong>socket-close</strong> <em>[sb-bsd-sockets] socket &key abort</em></dt>
|
|
<dd><p>Close <code>socket</code>, unless it was already closed.
|
|
</p>
|
|
<p>If <code>socket-make-stream</code> has been called, calls <code>close</code> using <code>abort</code> on that
|
|
stream. Otherwise closes the socket file descriptor using
|
|
close(2).
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dshutdown"></span><dl>
|
|
<dt id="index-socket_002dshutdown">Generic Function: <strong>socket-shutdown</strong> <em>[sb-bsd-sockets] socket &key direction</em></dt>
|
|
<dd><p>Indicate that no communication in <code>direction</code> will be performed on
|
|
<code>socket</code>.
|
|
</p>
|
|
<p><code>direction</code> has to be one of <code>:input</code>, <code>:output</code> or <code>:io</code>.
|
|
</p>
|
|
<p>After a shutdown, no input and/or output of the indicated <code>direction</code>
|
|
can be performed on <code>socket</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-socket_002dmake_002dstream"></span><dl>
|
|
<dt id="index-socket_002dmake_002dstream">Generic Function: <strong>socket-make-stream</strong> <em>[sb-bsd-sockets] socket &key input output element-type external-format buffering timeout auto-close serve-events</em></dt>
|
|
<dd><p>Find or create a <code>stream</code> that can be used for <code>io</code> on <code>socket</code> (which
|
|
must be connected). Specify whether the stream is for <code>input</code>, <code>output</code>,
|
|
or both (it is an error to specify neither).
|
|
</p>
|
|
<p><code>element-type</code> and <code>external-format</code> are as per <code>open</code>.
|
|
</p>
|
|
<p><code>timeout</code> specifies a read timeout for the stream.
|
|
</p></dd></dl>
|
|
<span id="Method-sb_002dbsd_002dsockets-socket_002dmake_002dstream-_0028socket_0029"></span><dl>
|
|
<dt id="index-socket_002dmake_002dstream-1">Method: <strong>socket-make-stream</strong> <em>[sb-bsd-sockets] (socket socket) &key input output (element-type (quote character)) (buffering full) (external-format default) timeout auto-close serve-events</em></dt>
|
|
<dd><p>Default method for <code>socket</code> objects.
|
|
</p>
|
|
<p><code>element-type</code> defaults to <code>character</code>, to construct a bivalent stream,
|
|
capable of both binary and character <code>io</code> use <code>:default</code>.
|
|
</p>
|
|
<p>Acceptable values for <code>buffering</code> are <code>:full</code>, <code>:line</code> and <code>:none</code>, default
|
|
is <code>:full</code>, ie. output is buffered till it is explicitly flushed using
|
|
<code>close</code> or <code>finish-output</code>. (<code>force-output</code> forces some output to be
|
|
flushed: to ensure all buffered output is flused use <code>finish-output</code>.)
|
|
</p>
|
|
<p>Streams have no <code>timeout</code> by default. If one is provided, it is the
|
|
number of seconds the system will at most wait for input to appear on
|
|
the socket stream when trying to read from it.
|
|
</p>
|
|
<p>If <code>auto-close</code> is true, the underlying <code>os</code> socket is automatically
|
|
closed after the stream and the socket have been garbage collected.
|
|
Default is false.
|
|
</p>
|
|
<p>If <code>serve-events</code> is true, blocking <code>io</code> on the socket will dispatch to
|
|
the recursive event loop. Default is false.
|
|
</p>
|
|
<p>The stream for <code>socket</code> will be cached, and a second invocation of this
|
|
method will return the same stream. This may lead to oddities if this
|
|
function is invoked with inconsistent arguments (e.g., one might
|
|
request an input stream and get an output stream in response).
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-socket_002derror"></span><dl>
|
|
<dt id="index-socket_002derror">Function: <strong>socket-error</strong> <em>[sb-bsd-sockets] where &optional errno</em></dt>
|
|
<dd><p>Signal an appropriate error for syscall <code>where</code> and <code>errno</code>.
|
|
</p>
|
|
<p><code>where</code> should be a string naming the failed function.
|
|
</p>
|
|
<p>When supplied, <code>errno</code> should be the <code>unix</code> error number associated to the
|
|
failed call. The default behavior is to use the current value of the
|
|
errno variable.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-non_002dblocking_002dmode"></span><dl>
|
|
<dt id="index-non_002dblocking_002dmode">Generic Function: <strong>non-blocking-mode</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Is <code>socket</code> in non-blocking mode?
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Socket-Options"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#INET-Domain-Sockets" accesskey="n" rel="next">INET Domain Sockets</a>, Previous: <a href="index.html#General-Sockets" accesskey="p" rel="prev">General Sockets</a>, Up: <a href="index.html#Networking" accesskey="u" rel="up">Networking</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Socket-Options-1"></span><h3 class="section">15.3 Socket Options</h3>
|
|
|
|
<p>A subset of socket options are supported, using a fairly general
|
|
framework which should make it simple to add more as required - see
|
|
<samp>SYS:CONTRIB;SB-BSD-SOCKETS:SOCKOPT.LISP</samp> for details. The name
|
|
mapping from C is fairly straightforward: <code>SO_RCVLOWAT</code> becomes
|
|
<code>sockopt-receive-low-water</code> and <code>(setf
|
|
sockopt-receive-low-water)</code>.
|
|
</p>
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002dreuse_002daddress"></span><dl>
|
|
<dt id="index-sockopt_002dreuse_002daddress">Function: <strong>sockopt-reuse-address</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-reuseaddr</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002dkeep_002dalive"></span><dl>
|
|
<dt id="index-sockopt_002dkeep_002dalive">Function: <strong>sockopt-keep-alive</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-keepalive</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002doob_002dinline"></span><dl>
|
|
<dt id="index-sockopt_002doob_002dinline">Function: <strong>sockopt-oob-inline</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-oobinline</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002dbsd_002dcompatible"></span><dl>
|
|
<dt id="index-sockopt_002dbsd_002dcompatible">Function: <strong>sockopt-bsd-compatible</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-bsdcompat</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>. Available only on Linux.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002dpass_002dcredentials"></span><dl>
|
|
<dt id="index-sockopt_002dpass_002dcredentials">Function: <strong>sockopt-pass-credentials</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-passcred</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>. Available only on Linux.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002ddebug"></span><dl>
|
|
<dt id="index-sockopt_002ddebug">Function: <strong>sockopt-debug</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-debug</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002ddont_002droute"></span><dl>
|
|
<dt id="index-sockopt_002ddont_002droute">Function: <strong>sockopt-dont-route</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-dontroute</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002dbroadcast"></span><dl>
|
|
<dt id="index-sockopt_002dbroadcast">Function: <strong>sockopt-broadcast</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>so-broadcast</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-sockopt_002dtcp_002dnodelay"></span><dl>
|
|
<dt id="index-sockopt_002dtcp_002dnodelay">Function: <strong>sockopt-tcp-nodelay</strong> <em>[sb-bsd-sockets] socket</em></dt>
|
|
<dd><p>Return the value of the <code>tcp-nodelay</code> socket option for <code>socket</code>. This can also be
|
|
updated with <code>setf</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="INET-Domain-Sockets"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Local-_0028Unix_0029-Domain-Sockets" accesskey="n" rel="next">Local (Unix) Domain Sockets</a>, Previous: <a href="index.html#Socket-Options" accesskey="p" rel="prev">Socket Options</a>, Up: <a href="index.html#Networking" accesskey="u" rel="up">Networking</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="INET-Domain-Sockets-1"></span><h3 class="section">15.4 INET Domain Sockets</h3>
|
|
|
|
<p>The TCP and UDP sockets that you know and love. Some representation
|
|
issues:
|
|
</p>
|
|
<ul>
|
|
<li> IPv4 Internet addresses are represented by vectors of
|
|
<code>(unsigned-byte 8)</code> - viz. <code>#(127 0 0 1)</code>. Ports are just
|
|
integers: 6010. No conversion between network- and host-order data is
|
|
needed from the user of this package.
|
|
|
|
</li><li> IPv6 Internet addresses are represented by vectors of 16
|
|
<code>(unsigned-byte 8)</code> - viz. <code>#(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
|
1)</code>. Ports are just integers. As for IPv4 addresses, no conversion
|
|
between network- and host-order data is needed from the user of this
|
|
package.
|
|
|
|
</li><li> Socket addresses are represented by the two values for address and port,
|
|
so for example, <code>(socket-connect socket #(192 168 1 1) 80)</code> for
|
|
IPv4 and <code>(socket-connect socket #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
|
80)</code> for IPv6.
|
|
|
|
</li></ul>
|
|
|
|
<span id="Class-sb_002dbsd_002dsockets-inet_002dsocket"></span><dl>
|
|
<dt id="index-inet_002dsocket">Class: <strong>inet-socket</strong> <em>[sb-bsd-sockets]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">inet-socket</span><!-- /@w --></code>, <code>socket<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Class representing <code>tcp</code> and <code>udp</code> over IPv4 sockets.
|
|
</p>
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (make-instance 'sb-bsd-sockets:inet-socket :type :stream :protocol :tcp)
|
|
|
|
(make-instance 'sb-bsd-sockets:inet-socket :type :datagram :protocol :udp)
|
|
</pre></div>
|
|
</dd></dl>
|
|
|
|
<span id="Class-sb_002dbsd_002dsockets-inet6_002dsocket"></span><dl>
|
|
<dt id="index-inet6_002dsocket">Class: <strong>inet6-socket</strong> <em>[sb-bsd-sockets]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">inet6-socket</span><!-- /@w --></code>, <code>socket<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Class representing <code>tcp</code> and <code>udp</code> over IPv6 sockets.
|
|
</p>
|
|
<p>Examples:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (make-instance 'sb-bsd-sockets:inet6-socket :type :stream :protocol :tcp)
|
|
|
|
(make-instance 'sb-bsd-sockets:inet6-socket :type :datagram :protocol :udp)
|
|
</pre></div>
|
|
</dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-make_002dinet_002daddress"></span><dl>
|
|
<dt id="index-make_002dinet_002daddress">Function: <strong>make-inet-address</strong> <em>[sb-bsd-sockets] dotted-quads</em></dt>
|
|
<dd><p>Return a vector of octets given a string <code>dotted-quads</code> in the format
|
|
"127.0.0.1". Signals an error if the string is malformed.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-make_002dinet6_002daddress"></span><dl>
|
|
<dt id="index-make_002dinet6_002daddress">Function: <strong>make-inet6-address</strong> <em>[sb-bsd-sockets] colon-separated-integers</em></dt>
|
|
<dd><p>Return a vector of octets given a string representation of an IPv6
|
|
address <code>colon-separated-integers</code>. Signal an error if the string is
|
|
malformed.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-get_002dprotocol_002dby_002dname"></span><dl>
|
|
<dt id="index-get_002dprotocol_002dby_002dname">Function: <strong>get-protocol-by-name</strong> <em>[sb-bsd-sockets] name</em></dt>
|
|
<dd><p>Given a protocol name, return the protocol number, the protocol name, and
|
|
a list of protocol aliases
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Local-_0028Unix_0029-Domain-Sockets"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Name-Service" accesskey="n" rel="next">Name Service</a>, Previous: <a href="index.html#INET-Domain-Sockets" accesskey="p" rel="prev">INET Domain Sockets</a>, Up: <a href="index.html#Networking" accesskey="u" rel="up">Networking</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Local-_0028Unix_0029-Domain-Sockets-1"></span><h3 class="section">15.5 Local (Unix) Domain Sockets</h3>
|
|
|
|
<p>Local domain (<code>AF_LOCAL</code>) sockets are also known as Unix-domain
|
|
sockets, but were renamed by POSIX presumably on the basis that they
|
|
may be available on other systems too.
|
|
</p>
|
|
<p>A local socket address is a string, which is used to create a node in
|
|
the local filesystem. This means of course that they cannot be used
|
|
across a network.
|
|
</p>
|
|
<span id="Class-sb_002dbsd_002dsockets-local_002dsocket"></span><dl>
|
|
<dt id="index-local_002dsocket">Class: <strong>local-socket</strong> <em>[sb-bsd-sockets]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">local-socket</span><!-- /@w --></code>, <code>socket<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Class representing local domain (AF_LOCAL) sockets,
|
|
also known as unix-domain sockets.
|
|
</p></dd></dl>
|
|
|
|
<p>A local abstract socket address is also a string the scope of which is
|
|
the local machine. However, in contrast to a local socket address, there
|
|
is no corresponding filesystem node.
|
|
</p>
|
|
<span id="Class-sb_002dbsd_002dsockets-local_002dabstract_002dsocket"></span><dl>
|
|
<dt id="index-local_002dabstract_002dsocket">Class: <strong>local-abstract-socket</strong> <em>[sb-bsd-sockets]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">local-abstract-socket</span><!-- /@w --></code>, <code><span class="nolinebreak">local-socket</span><!-- /@w --></code>, <code>socket<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Class representing local domain (AF_LOCAL) sockets with addresses
|
|
in the abstract namespace.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Name-Service"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Local-_0028Unix_0029-Domain-Sockets" accesskey="p" rel="prev">Local (Unix) Domain Sockets</a>, Up: <a href="index.html#Networking" accesskey="u" rel="up">Networking</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Name-Service-1"></span><h3 class="section">15.6 Name Service</h3>
|
|
|
|
<p>Presently name service is implemented by calling out to the
|
|
<code>getaddrinfo(3)</code> and <code>gethostinfo(3)</code>, or to
|
|
<code>gethostbyname(3)</code> <code>gethostbyaddr(3)</code> on platforms where
|
|
the preferred functions are not available. The exact details of
|
|
the name resolving process (for example the choice of whether
|
|
DNS or a hosts file is used for lookup) are platform dependent.
|
|
</p>
|
|
|
|
<span id="Class-sb_002dbsd_002dsockets-host_002dent"></span><dl>
|
|
<dt id="index-host_002dent">Class: <strong>host-ent</strong> <em>[sb-bsd-sockets]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">host-ent</span><!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Slots:
|
|
</p><ul>
|
|
<li> <code>name</code> — initarg: <code>:name<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-bsd-sockets:host-ent-name</span><!-- /@w --></code>
|
|
|
|
<p>The name of the host
|
|
</p></li><li> <code>addresses</code> — initarg: <code>:addresses<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-bsd-sockets:host-ent-addresses</span><!-- /@w --></code>
|
|
|
|
<p>A list of addresses for this host.
|
|
</p></li></ul>
|
|
|
|
<p>This class represents the results of an address lookup.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-get_002dhost_002dby_002dname"></span><dl>
|
|
<dt id="index-get_002dhost_002dby_002dname">Function: <strong>get-host-by-name</strong> <em>[sb-bsd-sockets] node</em></dt>
|
|
<dd><p>Returns a <code>host-ent</code> instance for <code>node</code> or signals a <code>name-service-error</code>.
|
|
</p>
|
|
<p>Another <code>host-ent</code> instance containing zero, one or more IPv6 addresses
|
|
may be returned as a second return value.
|
|
</p>
|
|
<p><code>node</code> may also be an <code>ip</code> address in dotted quad notation or some other
|
|
weird stuff <code>-</code> see getaddrinfo(3) for the details.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dbsd_002dsockets-get_002dhost_002dby_002daddress"></span><dl>
|
|
<dt id="index-get_002dhost_002dby_002daddress">Function: <strong>get-host-by-address</strong> <em>[sb-bsd-sockets] address</em></dt>
|
|
<dd><p>Returns a <code>host-ent</code> instance for <code>address</code>, which should be a vector of
|
|
(integer 0 255) with 4 elements in case of an IPv4 address and 16
|
|
elements in case of an IPv6 address, or signals a <code>name-service-error</code>.
|
|
See gethostbyaddr(3) for details.
|
|
</p></dd></dl>
|
|
|
|
<span id="Generic_002dFunction-sb_002dbsd_002dsockets-host_002dent_002daddress"></span><dl>
|
|
<dt id="index-host_002dent_002daddress">Generic Function: <strong>host-ent-address</strong> <em>[sb-bsd-sockets] host-ent</em></dt>
|
|
<dd><p>Return some valid address for <code>host-ent</code>.
|
|
</p></dd></dl>
|
|
<hr>
|
|
<span id="Profiling"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Contributed-Modules" accesskey="n" rel="next">Contributed Modules</a>, Previous: <a href="index.html#Networking" accesskey="p" rel="prev">Networking</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Profiling-1"></span><h2 class="chapter">16 Profiling</h2>
|
|
<span id="index-Profiling"></span>
|
|
|
|
<p>SBCL includes both a deterministic profiler, that can collect statistics
|
|
on individual functions, and a more “modern” statistical profiler.
|
|
</p>
|
|
<p>Inlined functions do not appear in the results reported by either.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Deterministic-Profiler" accesskey="1">Deterministic Profiler</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Statistical-Profiler" accesskey="2">Statistical Profiler</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Deterministic-Profiler"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Statistical-Profiler" accesskey="n" rel="next">Statistical Profiler</a>, Up: <a href="index.html#Profiling" accesskey="u" rel="up">Profiling</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Deterministic-Profiler-1"></span><h3 class="section">16.1 Deterministic Profiler</h3>
|
|
<span id="index-Profiling_002c-deterministic"></span>
|
|
|
|
<p>The package <code>sb-profile</code> provides a classic, per-function-call
|
|
profiler.
|
|
</p>
|
|
<blockquote>
|
|
<p><b>note:</b> When profiling code executed by multiple threads in parallel, the
|
|
consing attributed to each function is inaccurate.
|
|
</p></blockquote>
|
|
|
|
<span id="Macro-sb_002dprofile-profile"></span><dl>
|
|
<dt id="index-profile">Macro: <strong>profile</strong> <em>[sb-profile] &rest names</em></dt>
|
|
<dd><p><code>profile</code> Name*
|
|
</p>
|
|
<p>If no names are supplied, return the list of profiled functions.
|
|
</p>
|
|
<p>If names are supplied, wrap profiling code around the named functions.
|
|
As in <code>trace</code>, the names are not evaluated. A symbol names a function.
|
|
A string names all the functions named by symbols in the named
|
|
package. If a function is already profiled, then unprofile and
|
|
reprofile (useful to notice function redefinition.) If a name is
|
|
undefined, then we give a warning and ignore it. See also
|
|
<code>unprofile</code>, <code>report</code> and <code>reset</code>.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dprofile-unprofile"></span><dl>
|
|
<dt id="index-unprofile">Macro: <strong>unprofile</strong> <em>[sb-profile] &rest names</em></dt>
|
|
<dd><p>Unwrap any profiling code around the named functions, or if no names
|
|
are given, unprofile all profiled functions. A symbol names
|
|
a function. A string names all the functions named by symbols in the
|
|
named package. <code>names</code> defaults to the list of names of all currently
|
|
profiled functions.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dprofile-report"></span><dl>
|
|
<dt id="index-report">Function: <strong>report</strong> <em>[sb-profile] &key limit print-no-call-list</em></dt>
|
|
<dd><p>Report results from profiling. The results are approximately
|
|
adjusted for profiling overhead. The compensation may be rather
|
|
inaccurate when bignums are involved in runtime calculation, as in a
|
|
very-long-running Lisp process.
|
|
</p>
|
|
<p>If <code>limit</code> is set to an integer, only the top <code>limit</code> results are
|
|
reported. If <code>print-no-call-list</code> is <code>t</code> (the default) then a list of
|
|
uncalled profiled functions are listed.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dprofile-reset"></span><dl>
|
|
<dt id="index-reset">Function: <strong>reset</strong> <em>[sb-profile]</em></dt>
|
|
<dd><p>Reset the counters for all profiled functions.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Statistical-Profiler"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Deterministic-Profiler" accesskey="p" rel="prev">Deterministic Profiler</a>, Up: <a href="index.html#Profiling" accesskey="u" rel="up">Profiling</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Statistical-Profiler-1"></span><h3 class="section">16.2 Statistical Profiler</h3>
|
|
<span id="index-Profiling_002c-statistical"></span>
|
|
|
|
<p>The <code>sb-sprof</code> module, loadable by
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(require :sb-sprof)
|
|
</pre></div>
|
|
<p>provides an alternate profiler which works by taking samples of the
|
|
program execution at regular intervals, instead of instrumenting
|
|
functions like <code>sb-profile:profile</code> does. You might find
|
|
<code>sb-sprof</code> more useful than the deterministic profiler when profiling
|
|
functions in the <code>common-lisp</code>-package, SBCL internals, or code
|
|
where the instrumenting overhead is excessive.
|
|
</p>
|
|
<p>Additionally <code>sb-sprof</code> includes a limited deterministic profiler
|
|
which can be used for reporting the amounts of calls to some functions
|
|
during
|
|
</p>
|
|
<span id="Example-Usage"></span><h4 class="subsection">16.2.1 Example Usage</h4>
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">(in-package :cl-user)
|
|
|
|
(require :sb-sprof)
|
|
|
|
(declaim (optimize speed))
|
|
|
|
(defun cpu-test-inner (a i)
|
|
(logxor a
|
|
(* i 5)
|
|
(+ a i)))
|
|
|
|
(defun cpu-test (n)
|
|
(let ((a 0))
|
|
(dotimes (i (expt 2 n) a)
|
|
(setf a (cpu-test-inner a i)))))
|
|
|
|
;;;; CPU profiling
|
|
|
|
;;; Take up to 1000 samples of running (CPU-TEST 26), and give a flat
|
|
;;; table report at the end. Profiling will end one the body has been
|
|
;;; evaluated once, whether or not 1000 samples have been taken.
|
|
(sb-sprof:with-profiling (:max-samples 1000
|
|
:report :flat
|
|
:loop nil)
|
|
(cpu-test 26))
|
|
|
|
;;; Record call counts for functions defined on symbols in the CL-USER
|
|
;;; package.
|
|
(sb-sprof:profile-call-counts "CL-USER")
|
|
|
|
;;; Take 1000 samples of running (CPU-TEST 24), and give a flat
|
|
;;; table report at the end. The body will be re-evaluated in a loop
|
|
;;; until 1000 samples have been taken. A sample count will be printed
|
|
;;; after each iteration.
|
|
(sb-sprof:with-profiling (:max-samples 1000
|
|
:report :flat
|
|
:loop t
|
|
:show-progress t)
|
|
(cpu-test 24))
|
|
|
|
;;;; Allocation profiling
|
|
|
|
(defun foo (&rest args)
|
|
(mapcar (lambda (x) (float x 1d0)) args))
|
|
|
|
(defun bar (n)
|
|
(declare (fixnum n))
|
|
(apply #'foo (loop repeat n collect n)))
|
|
|
|
(sb-sprof:with-profiling (:max-samples 10000
|
|
:mode :alloc
|
|
:report :flat)
|
|
(bar 1000))
|
|
</pre></div>
|
|
|
|
<span id="Output"></span><h4 class="subsection">16.2.2 Output</h4>
|
|
|
|
<p>The flat report format will show a table of all functions that the
|
|
profiler encountered on the call stack during sampling, ordered by the
|
|
number of samples taken while executing that function.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> Self Total Cumul
|
|
Nr Count % Count % Count % Calls Function
|
|
------------------------------------------------------------------------
|
|
1 69 24.4 97 34.3 69 24.4 67108864 CPU-TEST-INNER
|
|
2 64 22.6 64 22.6 133 47.0 - SB-VM::GENERIC-+
|
|
3 39 13.8 256 90.5 172 60.8 1 CPU-TEST
|
|
4 31 11.0 31 11.0 203 71.7 - SB-KERNEL:TWO-ARG-XOR
|
|
</pre></div>
|
|
|
|
<p>For each function, the table will show three absolute and relative
|
|
sample counts. The Self column shows samples taken while directly
|
|
executing that function. The Total column shows samples taken while
|
|
executing that function or functions called from it (sampled to a
|
|
platform-specific depth). The Cumul column shows the sum of all
|
|
Self columns up to and including that line in the table.
|
|
</p>
|
|
<p>Additionally the Calls column will record the amount of calls that were
|
|
made to the function during the profiling run. This value will only
|
|
be reported for functions that have been explicitly marked for call counting
|
|
with <code>profile-call-counts</code>.
|
|
</p>
|
|
<p>The profiler also hooks into the disassembler such that instructions which
|
|
have been sampled are annotated with their relative frequency of
|
|
sampling. This information is not stored across different sampling
|
|
runs.
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">; 6CF: 702E JO L4 ; 6/242 samples
|
|
; 6D1: D1E3 SHL EBX, 1
|
|
; 6D3: 702A JO L4
|
|
; 6D5: L2: F6C303 TEST BL, 3 ; 2/242 samples
|
|
; 6D8: 756D JNE L8
|
|
; 6DA: 8BC3 MOV EAX, EBX ; 5/242 samples
|
|
; 6DC: L3: 83F900 CMP ECX, 0 ; 4/242 samples
|
|
</pre></div>
|
|
|
|
<span id="Platform-support"></span><h4 class="subsection">16.2.3 Platform support</h4>
|
|
|
|
<p>Allocation profiling is only supported on SBCL builds that use
|
|
the generational garbage collector. Tracking of call stacks at a
|
|
depth of more than two levels is only supported on x86 and x86-64.
|
|
</p>
|
|
<span id="Macros"></span><h4 class="subsection">16.2.4 Macros</h4>
|
|
|
|
<span id="Macro-sb_002dsprof-with_002dprofiling"></span><dl>
|
|
<dt id="index-with_002dprofiling">Macro: <strong>with-profiling</strong> <em>[sb-sprof] (&key sample-interval alloc-interval max-samples reset mode loop max-depth show-progress threads report) &body body</em></dt>
|
|
<dd><p>Evaluate <code>body</code> with statistical profiling turned on. If <code>loop</code> is true,
|
|
loop around the <code>body</code> until a sufficient number of samples has been collected.
|
|
Returns the values from the last evaluation of <code>body</code>.
|
|
</p>
|
|
<p>The following keyword args are recognized:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:sample-interval</code> <n></em></dt>
|
|
<dd><p>Take a sample every <n> seconds. Default is <code>*sample-interval*</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:mode</code> <mode></em></dt>
|
|
<dd><p>If <code>:cpu</code>, run the profiler in <code>cpu</code> profiling mode. If <code>:alloc</code>, run the
|
|
profiler in allocation profiling mode. If <code>:time</code>, run the profiler
|
|
in wallclock profiling mode.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:max-samples</code> <max></em></dt>
|
|
<dd><p>If <code>:loop</code> is <code>nil</code> (the default), collect no more than <max> samples.
|
|
If <code>:loop</code> is <code>t</code>, repeat evaluating body until <max> samples are taken.
|
|
Default is <code>*max-samples*</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:report</code> <type></em></dt>
|
|
<dd><p>If specified, call <code>report</code> with <code>:type</code> <type> at the end.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:reset</code> <bool></em></dt>
|
|
<dd><p>If true, call <code>reset</code> at the beginning.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:threads</code> <list-form></em></dt>
|
|
<dd><p>Form that evaluates to the list threads to profile, or <code>:all</code> to indicate
|
|
that all threads should be profiled. Defaults to all threads.
|
|
</p>
|
|
<p><code>:threads</code> has no effect on call-counting at the moment.
|
|
</p>
|
|
<p>On some platforms (eg. Darwin) the signals used by the profiler are
|
|
not properly delivered to threads in proportion to their <code>cpu</code> usage
|
|
when doing <code>:cpu</code> profiling. If you see empty call graphs, or are obviously
|
|
missing several samples from certain threads, you may be falling afoul
|
|
of this. In this case using <code>:mode</code> <code>:time</code> is likely to work better.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:loop</code> <bool></em></dt>
|
|
<dd><p>If false (the default), evaluate <code>body</code> only once. If true repeatedly
|
|
evaluate <code>body</code>.
|
|
</p></dd>
|
|
</dl>
|
|
|
|
</dd></dl>
|
|
<span id="Macro-sb_002dsprof-with_002dsampling"></span><dl>
|
|
<dt id="index-with_002dsampling">Macro: <strong>with-sampling</strong> <em>[sb-sprof] (&optional on) &body body</em></dt>
|
|
<dd><p>Evaluate body with statistical sampling turned on or off in the current thread.
|
|
</p></dd></dl>
|
|
|
|
<span id="Functions"></span><h4 class="subsection">16.2.5 Functions</h4>
|
|
|
|
<span id="Function-sb_002dsprof-map_002dtraces"></span><dl>
|
|
<dt id="index-map_002dtraces">Function: <strong>map-traces</strong> <em>[sb-sprof] function samples</em></dt>
|
|
<dd><p>Call <code>function</code> on each trace in <code>samples</code>
|
|
</p>
|
|
<p>The signature of <code>function</code> must be compatible with (thread trace).
|
|
</p>
|
|
<p><code>function</code> is called once for each trace where <code>thread</code> is the <code>sb-thread:tread</code>
|
|
instance which was sampled to produce <code>trace</code>, and <code>trace</code> is an opaque object
|
|
to be passed to <code>map-trace-pc-locs</code>.
|
|
</p>
|
|
<p><code>experimental:</code> Interface subject to change.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dsprof-sample_002dpc"></span><dl>
|
|
<dt id="index-sample_002dpc">Function: <strong>sample-pc</strong> <em>[sb-sprof] info pc-or-offset</em></dt>
|
|
<dd><p>Extract and return program counter from <code>info</code> and <code>pc-or-offset</code>.
|
|
</p>
|
|
<p>Can be applied to the arguments passed by <code>map-trace-pc-locs</code> and
|
|
<code>map-all-pc-locs</code>.
|
|
</p>
|
|
<p><code>experimental:</code> Interface subject to change.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dsprof-report"></span><dl>
|
|
<dt id="index-report-1">Function: <strong>report</strong> <em>[sb-sprof] &key type max min-percent call-graph sort-by sort-order stream show-progress</em></dt>
|
|
<dd><p>Report statistical profiling results. The following keyword
|
|
args are recognized:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:type</code> <type></em></dt>
|
|
<dd><p>Specifies the type of report to generate. If <code>:flat</code>, show
|
|
flat report, if <code>:graph</code> show a call graph and a flat report.
|
|
If nil, don’t print out a report.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:stream</code> <stream></em></dt>
|
|
<dd><p>Specify a stream to print the report on. Default is
|
|
<code>*standard-output*</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:max</code> <max></em></dt>
|
|
<dd><p>Don’t show more than <max> entries in the flat report.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:min-percent</code> <min-percent></em></dt>
|
|
<dd><p>Don’t show functions taking less than <min-percent> of the
|
|
total time in the flat report.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:sort-by</code> <column></em></dt>
|
|
<dd><p>If <code>:samples</code>, sort flat report by number of samples taken.
|
|
If <code>:cumulative-samples</code>, sort flat report by cumulative number of samples
|
|
taken (shows how much time each function spent on stack.) Default
|
|
is <code>*report-sort-by*</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:sort-order</code> <order></em></dt>
|
|
<dd><p>If <code>:descending</code>, sort flat report in descending order. If <code>:ascending</code>,
|
|
sort flat report in ascending order. Default is <code>*report-sort-order*</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:show-progress</code> <bool></em></dt>
|
|
<dd><p>If true, print progress messages while generating the call graph.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:call-graph</code> <graph></em></dt>
|
|
<dd><p>Print a report from <graph> instead of the latest profiling
|
|
results.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>Value of this function is a <code>call-graph</code> object representing the
|
|
resulting call-graph, or <code>nil</code> if there are no samples (eg. right after
|
|
calling <code>reset</code>.)
|
|
</p>
|
|
<p>Profiling is stopped before the call graph is generated.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dsprof-reset"></span><dl>
|
|
<dt id="index-reset-1">Function: <strong>reset</strong> <em>[sb-sprof]</em></dt>
|
|
<dd><p>Reset the profiler.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dsprof-start_002dprofiling"></span><dl>
|
|
<dt id="index-start_002dprofiling">Function: <strong>start-profiling</strong> <em>[sb-sprof] &key max-samples mode sample-interval alloc-interval max-depth threads</em></dt>
|
|
<dd><p>Start profiling statistically in the current thread if not already profiling.
|
|
The following keyword args are recognized:
|
|
</p>
|
|
|
|
<dl compact="compact">
|
|
<dt><em><code>:sample-interval</code> <n></em></dt>
|
|
<dd><p>Take a sample every <n> seconds. Default is <code>*sample-interval*</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:mode</code> <mode></em></dt>
|
|
<dd><p>If <code>:cpu</code>, run the profiler in <code>cpu</code> profiling mode. If <code>:alloc</code>, run
|
|
the profiler in allocation profiling mode. If <code>:time</code>, run the profiler
|
|
in wallclock profiling mode.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:max-samples</code> <max></em></dt>
|
|
<dd><p>Maximum number of stack traces to collect. Default is <code>*max-samples*</code>.
|
|
</p>
|
|
|
|
</dd>
|
|
<dt><em><code>:threads</code> <list></em></dt>
|
|
<dd><p>List threads to profile, or <code>:all</code> to indicate that all threads should be
|
|
profiled. Defaults to <code>:all</code>.
|
|
</p>
|
|
<p><code>:threads</code> has no effect on call-counting at the moment.
|
|
</p>
|
|
<p>On some platforms (eg. Darwin) the signals used by the profiler are
|
|
not properly delivered to threads in proportion to their <code>cpu</code> usage
|
|
when doing <code>:cpu</code> profiling. If you see empty call graphs, or are obviously
|
|
missing several samples from certain threads, you may be falling afoul
|
|
of this.
|
|
</p></dd>
|
|
</dl>
|
|
|
|
</dd></dl>
|
|
|
|
<span id="Function-sb_002dsprof-stop_002dprofiling"></span><dl>
|
|
<dt id="index-stop_002dprofiling">Function: <strong>stop-profiling</strong> <em>[sb-sprof]</em></dt>
|
|
<dd><p>Stop profiling if profiling.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dsprof-profile_002dcall_002dcounts"></span><dl>
|
|
<dt id="index-profile_002dcall_002dcounts">Function: <strong>profile-call-counts</strong> <em>[sb-sprof] &rest names</em></dt>
|
|
<dd><p>Mark the functions named by <code>names</code> as being subject to call counting
|
|
during statistical profiling. If a string is used as a name, it will
|
|
be interpreted as a package name. In this case call counting will be
|
|
done for all functions with names like <code>x</code> or (<code>setf</code> <code>x</code>), where <code>x</code> is a symbol
|
|
with the package as its home package.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dsprof-unprofile_002dcall_002dcounts"></span><dl>
|
|
<dt id="index-unprofile_002dcall_002dcounts">Function: <strong>unprofile-call-counts</strong> <em>[sb-sprof]</em></dt>
|
|
<dd><p>Clear all call counting information. Call counting will be done for no
|
|
functions during statistical profiling.
|
|
</p></dd></dl>
|
|
|
|
<span id="Variables"></span><h4 class="subsection">16.2.6 Variables</h4>
|
|
|
|
<span id="Variable-sb_002dsprof-_002amax_002dsamples_002a"></span><dl>
|
|
<dt id="index-_002amax_002dsamples_002a">Variable: <strong>*max-samples*</strong> <em>[sb-sprof]</em></dt>
|
|
<dd><p>Default maximum number of stack traces collected.
|
|
</p></dd></dl>
|
|
|
|
<span id="Variable-sb_002dsprof-_002asample_002dinterval_002a"></span><dl>
|
|
<dt id="index-_002asample_002dinterval_002a">Variable: <strong>*sample-interval*</strong> <em>[sb-sprof]</em></dt>
|
|
<dd><p>Default number of seconds between samples.
|
|
</p></dd></dl>
|
|
|
|
<span id="Credits"></span><h4 class="subsection">16.2.7 Credits</h4>
|
|
|
|
<p><code>sb-sprof</code> is an SBCL port, with enhancements, of Gerd
|
|
Moellmann’s statistical profiler for CMUCL.
|
|
</p><hr>
|
|
<span id="Contributed-Modules"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Deprecation" accesskey="n" rel="next">Deprecation</a>, Previous: <a href="index.html#Profiling" accesskey="p" rel="prev">Profiling</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Contributed-Modules-1"></span><h2 class="chapter">17 Contributed Modules</h2>
|
|
|
|
<p>SBCL comes with a number of modules that are not part of the core
|
|
system. These are loaded via <code>(require :<var>modulename</var>)</code>
|
|
(see <a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a>). This section contains
|
|
documentation (or pointers to documentation) for some of the
|
|
contributed modules.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002daclrepl" accesskey="1">sb-aclrepl</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002dconcurrency" accesskey="2">sb-concurrency</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002dcover" accesskey="3">sb-cover</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002dgrovel" accesskey="4">sb-grovel</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002dmd5" accesskey="5">sb-md5</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002dposix" accesskey="6">sb-posix</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002dqueue" accesskey="7">sb-queue</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002drotate_002dbyte" accesskey="8">sb-rotate-byte</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#sb_002dsimd" accesskey="9">sb-simd</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="sb_002daclrepl"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002dconcurrency" accesskey="n" rel="next">sb-concurrency</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002daclrepl-1"></span><h3 class="section">17.1 sb-aclrepl</h3>
|
|
<span id="index-Read_002dEval_002dPrint-Loop"></span>
|
|
<span id="index-REPL"></span>
|
|
|
|
<p>The <code>sb-aclrepl</code> module offers an Allegro CL-style
|
|
Read-Eval-Print Loop for SBCL, with integrated inspector. Adding a
|
|
debugger interface is planned.
|
|
</p>
|
|
<span id="Usage"></span><h4 class="subsection">17.1.1 Usage</h4>
|
|
|
|
<p>To start <code>sb-aclrepl</code> as your read-eval-print loop, put the form
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(require 'sb-aclrepl)
|
|
</pre></div>
|
|
|
|
<p>in your <samp>~/.sbclrc</samp> initialization file.
|
|
</p>
|
|
<span id="Customization"></span><h4 class="subsection">17.1.2 Customization</h4>
|
|
|
|
<p>The following customization variables are available:
|
|
</p>
|
|
<span id="Variable-sb_002daclrepl-_002acommand_002dchar_002a"></span><dl>
|
|
<dt id="index-_002acommand_002dchar_002a">Variable: <strong>*command-char*</strong> <em>[sb-aclrepl]</em></dt>
|
|
<dd><p>Prefix character for a top-level command
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002daclrepl-_002aprompt_002a"></span><dl>
|
|
<dt id="index-_002aprompt_002a">Variable: <strong>*prompt*</strong> <em>[sb-aclrepl]</em></dt>
|
|
<dd><p>The current prompt string or formatter function.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002daclrepl-_002aexit_002don_002deof_002a"></span><dl>
|
|
<dt id="index-_002aexit_002don_002deof_002a">Variable: <strong>*exit-on-eof*</strong> <em>[sb-aclrepl]</em></dt>
|
|
<dd><p>If <code>t</code>, then exit when the <code>eof</code> character is entered.
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002daclrepl-_002ause_002dshort_002dpackage_002dname_002a"></span><dl>
|
|
<dt id="index-_002ause_002dshort_002dpackage_002dname_002a">Variable: <strong>*use-short-package-name*</strong> <em>[sb-aclrepl]</em></dt>
|
|
<dd><p>when <code>t</code>, use the shortnest package nickname in a prompt
|
|
</p></dd></dl>
|
|
<span id="Variable-sb_002daclrepl-_002amax_002dhistory_002a"></span><dl>
|
|
<dt id="index-_002amax_002dhistory_002a">Variable: <strong>*max-history*</strong> <em>[sb-aclrepl]</em></dt>
|
|
<dd><p>Maximum number of history commands to remember
|
|
</p></dd></dl>
|
|
|
|
<span id="Example-Initialization"></span><h4 class="subsection">17.1.3 Example Initialization</h4>
|
|
|
|
<p>Here’s a longer example of a <samp>~/.sbclrc</samp> file that shows off
|
|
some of the features of <code>sb-aclrepl</code>:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp">(ignore-errors (require 'sb-aclrepl))
|
|
|
|
(when (find-package 'sb-aclrepl)
|
|
(push :aclrepl cl:*features*))
|
|
#+aclrepl
|
|
(progn
|
|
(setq sb-aclrepl:*max-history* 100)
|
|
(setf (sb-aclrepl:alias "asdc")
|
|
#'(lambda (sys) (asdf:operate 'asdf:compile-op sys)))
|
|
(sb-aclrepl:alias "l" (sys) (asdf:operate 'asdf:load-op sys))
|
|
(sb-aclrepl:alias "t" (sys) (asdf:operate 'asdf:test-op sys))
|
|
;; The 1 below means that two characaters ("up") are required
|
|
(sb-aclrepl:alias ("up" 1 "Use package") (package) (use-package package))
|
|
;; The 0 below means only the first letter ("r") is required,
|
|
;; such as ":r base64"
|
|
(sb-aclrepl:alias ("require" 0 "Require module") (sys) (require sys))
|
|
(setq cl:*features* (delete :aclrepl cl:*features*)))
|
|
</pre></div>
|
|
|
|
<p>Questions, comments, or bug reports should be sent to Kevin Rosenberg
|
|
(<a href="mailto:kevin@rosenberg.net">kevin@rosenberg.net</a>).
|
|
</p>
|
|
<span id="Credits-1"></span><h4 class="subsection">17.1.4 Credits</h4>
|
|
|
|
<p>Allegro CL is a registered trademark of Franz Inc.
|
|
</p>
|
|
<hr>
|
|
<span id="sb_002dconcurrency"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002dcover" accesskey="n" rel="next">sb-cover</a>, Previous: <a href="index.html#sb_002daclrepl" accesskey="p" rel="prev">sb-aclrepl</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002dconcurrency-1"></span><h3 class="section">17.2 sb-concurrency</h3>
|
|
<span id="index-Concurrency"></span>
|
|
<span id="index-Sb_002dconcurrency"></span>
|
|
|
|
<p>Additional data structures, synchronization primitives and tools for
|
|
concurrent programming. Similiar to Java’s <code>java.util.concurrent</code>
|
|
package.
|
|
</p>
|
|
<span id="Section-sb_002dconcurrency_003aqueue"></span><span id="Queue"></span><h4 class="subsection">17.2.1 Queue</h4>
|
|
<span id="index-Queue_002c-lock_002dfree"></span>
|
|
|
|
<p><code>sb-concurrency:queue</code> is a lock-free, thread-safe FIFO queue
|
|
datatype.
|
|
<br><br>
|
|
The implementation is based on <cite>An Optimistic Approach to
|
|
Lock-Free FIFO Queues</cite> by Edya Ladan-Mozes and Nir Shavit.
|
|
<br><br>
|
|
Before SBCL 1.0.38, this implementation resided in its own contrib
|
|
(see <a href="index.html#sb_002dqueue">sb-queue</a>) which is still provided for backwards-compatibility
|
|
but which has since been deprecated.
|
|
</p>
|
|
<span id="Structure-sb_002dconcurrency-queue"></span><dl>
|
|
<dt id="index-queue">Structure: <strong>queue</strong> <em>[sb-concurrency]</em></dt>
|
|
<dd><p>Class precedence list: <code>queue<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Lock-free thread safe <code>fifo</code> queue.
|
|
</p>
|
|
<p>Use <code>enqueue</code> to add objects to the queue, and <code>dequeue</code> to remove them.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dconcurrency-dequeue"></span><dl>
|
|
<dt id="index-dequeue">Function: <strong>dequeue</strong> <em>[sb-concurrency] queue</em></dt>
|
|
<dd><p>Retrieves the oldest value in <code>queue</code> and returns it as the primary value,
|
|
and <code>t</code> as secondary value. If the queue is empty, returns <code>nil</code> as both primary
|
|
and secondary value.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-enqueue"></span><dl>
|
|
<dt id="index-enqueue">Function: <strong>enqueue</strong> <em>[sb-concurrency] value queue</em></dt>
|
|
<dd><p>Adds <code>value</code> to the end of <code>queue</code>. Returns <code>value</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-list_002dqueue_002dcontents"></span><dl>
|
|
<dt id="index-list_002dqueue_002dcontents">Function: <strong>list-queue-contents</strong> <em>[sb-concurrency] queue</em></dt>
|
|
<dd><p>Returns the contents of <code>queue</code> as a list without removing them from the
|
|
<code>queue</code>. Mainly useful for manual examination of queue state, as the list may be
|
|
out of date by the time it is returned, and concurrent dequeue operations may
|
|
in the worse case force the queue-traversal to be restarted several times.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-make_002dqueue"></span><dl>
|
|
<dt id="index-make_002dqueue">Function: <strong>make-queue</strong> <em>[sb-concurrency] &key name initial-contents</em></dt>
|
|
<dd><p>Returns a new <code>queue</code> with <code>name</code> and contents of the <code>initial-contents</code>
|
|
sequence enqueued.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-queue_002dcount"></span><dl>
|
|
<dt id="index-queue_002dcount">Function: <strong>queue-count</strong> <em>[sb-concurrency] queue</em></dt>
|
|
<dd><p>Returns the number of objects in <code>queue</code>. Mainly useful for manual
|
|
examination of queue state, and in <code>print-object</code> methods: inefficient as it
|
|
must walk the entire queue.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-queue_002dempty_002dp"></span><dl>
|
|
<dt id="index-queue_002dempty_002dp">Function: <strong>queue-empty-p</strong> <em>[sb-concurrency] queue</em></dt>
|
|
<dd><p>Returns <code>t</code> if <code>queue</code> is empty, <code>nil</code> otherwise.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-queue_002dname"></span><dl>
|
|
<dt id="index-queue_002dname">Function: <strong>queue-name</strong> <em>[sb-concurrency] instance</em></dt>
|
|
<dd><p>Name of a <code>queue</code>. Can be assigned to using <code>setf</code>. Queue names
|
|
can be arbitrary printable objects, and need not be unique.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-queuep"></span><dl>
|
|
<dt id="index-queuep">Function: <strong>queuep</strong> <em>[sb-concurrency] object</em></dt>
|
|
<dd><p>Returns true if argument is a <code>queue</code>, <code>nil</code> otherwise.
|
|
</p></dd></dl>
|
|
|
|
<span id="Mailbox-_0028lock_002dfree_0029"></span><h4 class="subsection">17.2.2 Mailbox (lock-free)</h4>
|
|
<span id="index-Mailbox_002c-lock_002dfree"></span>
|
|
|
|
<p><code>sb-concurrency:mailbox</code> is a lock-free message queue where one
|
|
or multiple ends can send messages to one or multiple receivers. The
|
|
difference to <a href="index.html#Section-sb_002dconcurrency_003aqueue">queues</a> is that the receiving
|
|
end may block until a message arrives.
|
|
<br><br>
|
|
Built on top of the <a href="index.html#Structure-sb_002dconcurrency-queue">queue</a> implementation.
|
|
</p>
|
|
<span id="Structure-sb_002dconcurrency-mailbox"></span><dl>
|
|
<dt id="index-mailbox">Structure: <strong>mailbox</strong> <em>[sb-concurrency]</em></dt>
|
|
<dd><p>Class precedence list: <code>mailbox<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Mailbox aka message queue.
|
|
</p>
|
|
<p><code>send-message</code> adds a message to the mailbox, <code>receive-message</code> waits till
|
|
a message becomes available, whereas <code>receive-message-no-hang</code> is a non-blocking
|
|
variant, and <code>receive-pending-messages</code> empties the entire mailbox in one go.
|
|
</p>
|
|
<p>Messages can be arbitrary objects
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dconcurrency-list_002dmailbox_002dmessages"></span><dl>
|
|
<dt id="index-list_002dmailbox_002dmessages">Function: <strong>list-mailbox-messages</strong> <em>[sb-concurrency] mailbox</em></dt>
|
|
<dd><p>Returns a fresh list containing all the messages in the
|
|
mailbox. Does not remove messages from the mailbox.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-mailbox_002dcount"></span><dl>
|
|
<dt id="index-mailbox_002dcount">Function: <strong>mailbox-count</strong> <em>[sb-concurrency] mailbox</em></dt>
|
|
<dd><p>Returns the number of messages currently in the mailbox.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-mailbox_002dempty_002dp"></span><dl>
|
|
<dt id="index-mailbox_002dempty_002dp">Function: <strong>mailbox-empty-p</strong> <em>[sb-concurrency] mailbox</em></dt>
|
|
<dd><p>Returns true if <code>mailbox</code> is currently empty, <code>nil</code> otherwise.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-mailbox_002dname"></span><dl>
|
|
<dt id="index-mailbox_002dname">Function: <strong>mailbox-name</strong> <em>[sb-concurrency] instance</em></dt>
|
|
<dd><p>Name of a <code>mailbox</code>. SETFable.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-mailboxp"></span><dl>
|
|
<dt id="index-mailboxp">Function: <strong>mailboxp</strong> <em>[sb-concurrency] object</em></dt>
|
|
<dd><p>Returns true if argument is a <code>mailbox</code>, <code>nil</code> otherwise.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-make_002dmailbox"></span><dl>
|
|
<dt id="index-make_002dmailbox">Function: <strong>make-mailbox</strong> <em>[sb-concurrency] &key name initial-contents</em></dt>
|
|
<dd><p>Returns a new <code>mailbox</code> with messages in <code>initial-contents</code> enqueued.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-receive_002dmessage"></span><dl>
|
|
<dt id="index-receive_002dmessage">Function: <strong>receive-message</strong> <em>[sb-concurrency] mailbox &key timeout</em></dt>
|
|
<dd><p>Removes the oldest message from <code>mailbox</code> and returns it as the primary
|
|
value, and a secondary value of <code>t</code>. If <code>mailbox</code> is empty waits until a message
|
|
arrives.
|
|
</p>
|
|
<p>If <code>timeout</code> is provided, and no message arrives within the specified interval,
|
|
returns primary and secondary value of <code>nil</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-receive_002dmessage_002dno_002dhang"></span><dl>
|
|
<dt id="index-receive_002dmessage_002dno_002dhang">Function: <strong>receive-message-no-hang</strong> <em>[sb-concurrency] mailbox</em></dt>
|
|
<dd><p>The non-blocking variant of <code>receive-message</code>. Returns two values,
|
|
the message removed from <code>mailbox</code>, and a flag specifying whether a
|
|
message could be received.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-receive_002dpending_002dmessages"></span><dl>
|
|
<dt id="index-receive_002dpending_002dmessages">Function: <strong>receive-pending-messages</strong> <em>[sb-concurrency] mailbox &optional n</em></dt>
|
|
<dd><p>Removes and returns all (or at most <code>n</code>) currently pending messages
|
|
from <code>mailbox</code>, or returns <code>nil</code> if no messages are pending.
|
|
</p>
|
|
<p>Note: Concurrent threads may be snarfing messages during the run of
|
|
this function, so even though <code>x</code>,<code>y</code> appear right next to each other in
|
|
the result, does not necessarily mean that <code>y</code> was the message sent
|
|
right after <code>x</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-send_002dmessage"></span><dl>
|
|
<dt id="index-send_002dmessage">Function: <strong>send-message</strong> <em>[sb-concurrency] mailbox message</em></dt>
|
|
<dd><p>Adds a <code>message</code> to <code>mailbox</code>. Message can be any object.
|
|
</p></dd></dl>
|
|
|
|
<span id="Section-sb_002dconcurrency_003agate"></span><span id="Gates"></span><h4 class="subsection">17.2.3 Gates</h4>
|
|
<span id="index-Gate"></span>
|
|
|
|
<p><code>sb-concurrency:gate</code> is a synchronization object suitable for when
|
|
multiple threads must wait for a single event before proceeding.
|
|
</p>
|
|
<span id="Structure-sb_002dconcurrency-gate"></span><dl>
|
|
<dt id="index-gate">Structure: <strong>gate</strong> <em>[sb-concurrency]</em></dt>
|
|
<dd><p>Class precedence list: <code>gate<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p><code>gate</code> type. Gates are synchronization constructs suitable for making
|
|
multiple threads wait for single event before proceeding.
|
|
</p>
|
|
<p>Use <code>wait-on-gate</code> to wait for a gate to open, <code>open-gate</code> to open one,
|
|
and <code>close-gate</code> to close an open gate. <code>gate-open-p</code> can be used to test
|
|
the state of a gate without blocking.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dconcurrency-close_002dgate"></span><dl>
|
|
<dt id="index-close_002dgate">Function: <strong>close-gate</strong> <em>[sb-concurrency] gate</em></dt>
|
|
<dd><p>Closes <code>gate</code>. Returns <code>t</code> if the gate was previously open, and <code>nil</code>
|
|
if the gate was already closed.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-gate_002dname"></span><dl>
|
|
<dt id="index-gate_002dname">Function: <strong>gate-name</strong> <em>[sb-concurrency] instance</em></dt>
|
|
<dd><p>Name of a <code>gate</code>. SETFable.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-gate_002dopen_002dp"></span><dl>
|
|
<dt id="index-gate_002dopen_002dp">Function: <strong>gate-open-p</strong> <em>[sb-concurrency] gate</em></dt>
|
|
<dd><p>Returns true if <code>gate</code> is open.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-gatep"></span><dl>
|
|
<dt id="index-gatep">Function: <strong>gatep</strong> <em>[sb-concurrency] object</em></dt>
|
|
<dd><p>Returns true if the argument is a <code>gate</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-make_002dgate"></span><dl>
|
|
<dt id="index-make_002dgate">Function: <strong>make-gate</strong> <em>[sb-concurrency] &key name open</em></dt>
|
|
<dd><p>Makes a new gate. Gate will be initially open if <code>open</code> is true, and closed if <code>open</code>
|
|
is <code>nil</code> (the default.) <code>name</code>, if provided, is the name of the gate, used when printing
|
|
the gate.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-open_002dgate"></span><dl>
|
|
<dt id="index-open_002dgate">Function: <strong>open-gate</strong> <em>[sb-concurrency] gate</em></dt>
|
|
<dd><p>Opens <code>gate</code>. Returns <code>t</code> if the gate was previously closed, and <code>nil</code>
|
|
if the gate was already open.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-wait_002don_002dgate"></span><dl>
|
|
<dt id="index-wait_002don_002dgate">Function: <strong>wait-on-gate</strong> <em>[sb-concurrency] gate &key timeout</em></dt>
|
|
<dd><p>Waits for <code>gate</code> to open, or <code>timeout</code> seconds to pass. Returns <code>t</code>
|
|
if the gate was opened in time, and <code>nil</code> otherwise.
|
|
</p></dd></dl>
|
|
|
|
<span id="Section-sb_002dconcurrency_003afrlock"></span><span id="Frlocks_002c-aka-Fast-Read-Locks"></span><h4 class="subsection">17.2.4 Frlocks, aka Fast Read Locks</h4>
|
|
<span id="index-Frlock"></span>
|
|
<span id="index-Fast-Read-Lock"></span>
|
|
|
|
<span id="Structure-sb_002dconcurrency-frlock"></span><dl>
|
|
<dt id="index-frlock">Structure: <strong>frlock</strong> <em>[sb-concurrency]</em></dt>
|
|
<dd><p>Class precedence list: <code>frlock<!-- /@w --></code>, <code><span class="nolinebreak">structure-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>FRlock, aka Fast Read Lock.
|
|
</p>
|
|
<p>Fast Read Locks allow multiple readers and one potential writer to operate in
|
|
parallel while providing for consistency for readers and mutual exclusion for
|
|
writers.
|
|
</p>
|
|
<p>Readers gain entry to protected regions without waiting, but need to retry if
|
|
a writer operated inside the region while they were reading. This makes frlocks
|
|
very efficient when readers are much more common than writers.
|
|
</p>
|
|
<p>FRlocks are <code>not</code> suitable when it is not safe at all for readers and writers to
|
|
operate on the same data in parallel: they provide consistency, not exclusion
|
|
between readers and writers. Hence using an frlock to eg. protect an <code>sbcl</code>
|
|
hash-table is unsafe. If multiple readers operating in parallel with a writer
|
|
would be safe but inconsistent without a lock, frlocks are suitable.
|
|
</p>
|
|
<p>The recommended interface to use is <code>frlock-read</code> and <code>frlock-write</code>, but those
|
|
needing it can also use a lower-level interface.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> ;; Values returned by FOO are always consistent so that
|
|
;; the third value is the sum of the two first ones.
|
|
(let ((a 0)
|
|
(b 0)
|
|
(c 0)
|
|
(lk (make-frlock)))
|
|
(defun foo ()
|
|
(frlock-read (lk) a b c))
|
|
(defun bar (x y)
|
|
(frlock-write (lk)
|
|
(setf a x
|
|
b y
|
|
c (+ x y)))))
|
|
</pre></div>
|
|
</dd></dl>
|
|
|
|
<span id="Macro-sb_002dconcurrency-frlock_002dread"></span><dl>
|
|
<dt id="index-frlock_002dread">Macro: <strong>frlock-read</strong> <em>[sb-concurrency] (frlock) &body value-forms</em></dt>
|
|
<dd><p>Evaluates <code>value-forms</code> under <code>frlock</code> till it obtains a consistent
|
|
set, and returns that as multiple values.
|
|
</p></dd></dl>
|
|
<span id="Macro-sb_002dconcurrency-frlock_002dwrite"></span><dl>
|
|
<dt id="index-frlock_002dwrite">Macro: <strong>frlock-write</strong> <em>[sb-concurrency] (frlock &key wait-p timeout) &body body</em></dt>
|
|
<dd><p>Executes <code>body</code> while holding <code>frlock</code> for writing.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dconcurrency-make_002dfrlock"></span><dl>
|
|
<dt id="index-make_002dfrlock">Function: <strong>make-frlock</strong> <em>[sb-concurrency] &key name</em></dt>
|
|
<dd><p>Returns a new <code>frlock</code> with <code>name</code>.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-frlock_002dname"></span><dl>
|
|
<dt id="index-frlock_002dname">Function: <strong>frlock-name</strong> <em>[sb-concurrency] instance</em></dt>
|
|
<dd><p>Name of an <code>frlock</code>. SETFable.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dconcurrency-frlock_002dread_002dbegin"></span><dl>
|
|
<dt id="index-frlock_002dread_002dbegin">Function: <strong>frlock-read-begin</strong> <em>[sb-concurrency] frlock</em></dt>
|
|
<dd><p>Start a read sequence on <code>frlock</code>. Returns a read-token and an epoch to be
|
|
validated later.
|
|
</p>
|
|
<p>Using <code>frlock-read</code> instead is recommended.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-frlock_002dread_002dend"></span><dl>
|
|
<dt id="index-frlock_002dread_002dend">Function: <strong>frlock-read-end</strong> <em>[sb-concurrency] frlock</em></dt>
|
|
<dd><p>Ends a read sequence on <code>frlock</code>. Returns a token and an epoch. If the token
|
|
and epoch are <code>eql</code> to the read-token and epoch returned by <code>frlock-read-begin</code>,
|
|
the values read under the <code>frlock</code> are consistent and can be used: if the values
|
|
differ, the values are inconsistent and the read must be restated.
|
|
</p>
|
|
<p>Using <code>frlock-read</code> instead is recommended.
|
|
</p>
|
|
<p>Example:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (multiple-value-bind (t0 e0) (frlock-read-begin *fr*)
|
|
(let ((a (get-a))
|
|
(b (get-b)))
|
|
(multiple-value-bind (t1 e1) (frlock-read-end *fr*)
|
|
(if (and (eql t0 t1) (eql e0 e1))
|
|
(list :a a :b b)
|
|
:aborted))))
|
|
</pre></div>
|
|
</dd></dl>
|
|
<span id="Function-sb_002dconcurrency-grab_002dfrlock_002dwrite_002dlock"></span><dl>
|
|
<dt id="index-grab_002dfrlock_002dwrite_002dlock">Function: <strong>grab-frlock-write-lock</strong> <em>[sb-concurrency] frlock &key wait-p timeout</em></dt>
|
|
<dd><p>Acquires <code>frlock</code> for writing, invalidating existing and future read-tokens
|
|
for the duration. Returns <code>t</code> on success, and <code>nil</code> if the lock wasn’t acquired
|
|
due to eg. a timeout. Using <code>frlock-write</code> instead is recommended.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dconcurrency-release_002dfrlock_002dwrite_002dlock"></span><dl>
|
|
<dt id="index-release_002dfrlock_002dwrite_002dlock">Function: <strong>release-frlock-write-lock</strong> <em>[sb-concurrency] frlock</em></dt>
|
|
<dd><p>Releases <code>frlock</code> after writing, allowing valid read-tokens to be acquired again.
|
|
Signals an error if the current thread doesn’t hold <code>frlock</code> for writing. Using <code>frlock-write</code>
|
|
instead is recommended.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="sb_002dcover"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002dgrovel" accesskey="n" rel="next">sb-grovel</a>, Previous: <a href="index.html#sb_002dconcurrency" accesskey="p" rel="prev">sb-concurrency</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002dcover-1"></span><h3 class="section">17.3 sb-cover</h3>
|
|
<span id="index-Code-Coverage"></span>
|
|
|
|
<p>The <code>sb-cover</code> module provides a code coverage tool for SBCL. The
|
|
tool has support for expression coverage, and for some branch coverage.
|
|
Coverage reports are only generated for code compiled using
|
|
<code>compile-file</code> with the value of the
|
|
<code>sb-cover:store-coverage-data</code> optimization quality set to 3.
|
|
</p>
|
|
<p>As of SBCL 1.0.6 <code>sb-cover</code> is still experimental, and the
|
|
interfaces documented here might change in later versions.
|
|
</p>
|
|
<span id="Example-Usage-1"></span><h4 class="subsection">17.3.1 Example Usage</h4>
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">;;; Load SB-COVER
|
|
(require :sb-cover)
|
|
|
|
;;; Turn on generation of code coverage instrumentation in the compiler
|
|
(declaim (optimize sb-cover:store-coverage-data))
|
|
|
|
;;; Load some code, ensuring that it's recompiled with the new optimization
|
|
;;; policy.
|
|
(asdf:oos 'asdf:load-op :cl-ppcre-test :force t)
|
|
|
|
;;; Run the test suite.
|
|
(cl-ppcre-test:test)
|
|
|
|
;;; Produce a coverage report
|
|
(sb-cover:report "/tmp/report/")
|
|
|
|
;;; Turn off instrumentation
|
|
(declaim (optimize (sb-cover:store-coverage-data 0)))
|
|
</pre></div>
|
|
|
|
|
|
<span id="Functions-1"></span><h4 class="subsection">17.3.2 Functions</h4>
|
|
|
|
<span id="Function-sb_002dcover-report"></span><dl>
|
|
<dt id="index-report-2">Function: <strong>report</strong> <em>[sb-cover] directory &key form-mode if-matches external-format</em></dt>
|
|
<dd><p>Print a code coverage report of all instrumented files into <code>directory</code>.
|
|
If <code>directory</code> does not exist, it will be created. The main report will be
|
|
printed to the file cover-index.html. The external format of the source
|
|
files can be specified with the <code>external-format</code> parameter.
|
|
</p>
|
|
<p>If the keyword argument <code>form-mode</code> has the value <code>:car</code>, the annotations in
|
|
the coverage report will be placed on the CARs of any cons-forms, while if
|
|
it has the value <code>:whole</code> the whole form will be annotated (the default).
|
|
The former mode shows explicitly which forms were instrumented, while the
|
|
latter mode is generally easier to read.
|
|
</p>
|
|
<p>The keyword argument <code>if-matches</code> should be a designator for a function
|
|
of one argument, called for the namestring of each file with code
|
|
coverage info. If it returns true, the file’s info is included in the
|
|
report, otherwise ignored. The default value is <code>cl:identity</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dcover-reset_002dcoverage"></span><dl>
|
|
<dt id="index-reset_002dcoverage">Function: <strong>reset-coverage</strong> <em>[sb-cover] &optional object</em></dt>
|
|
<dd><p>Reset all coverage data back to the ‘Not executed‘ state.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dcover-clear_002dcoverage"></span><dl>
|
|
<dt id="index-clear_002dcoverage">Function: <strong>clear-coverage</strong> <em>[sb-cover]</em></dt>
|
|
<dd><p>Clear all files from the coverage database. The files will be re-entered
|
|
into the database when the <code>fasl</code> files (produced by compiling
|
|
<code>store-coverage-data</code> optimization policy set to 3) are loaded again into the
|
|
image.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dcover-save_002dcoverage"></span><dl>
|
|
<dt id="index-save_002dcoverage">Function: <strong>save-coverage</strong> <em>[sb-cover]</em></dt>
|
|
<dd><p>Returns an opaque representation of the current code coverage state.
|
|
The only operation that may be done on the state is passing it to
|
|
<code>restore-coverage</code>. The representation is guaranteed to be readably printable.
|
|
A representation that has been printed and read back will work identically
|
|
in <code>restore-coverage</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dcover-save_002dcoverage_002din_002dfile"></span><dl>
|
|
<dt id="index-save_002dcoverage_002din_002dfile">Function: <strong>save-coverage-in-file</strong> <em>[sb-cover] pathname</em></dt>
|
|
<dd><p>Call <code>save-coverage</code> and write the results of that operation into the
|
|
file designated by <code>pathname</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dcover-restore_002dcoverage"></span><dl>
|
|
<dt id="index-restore_002dcoverage">Function: <strong>restore-coverage</strong> <em>[sb-cover] coverage-state</em></dt>
|
|
<dd><p>Restore the code coverage data back to an earlier state produced by
|
|
<code>save-coverage</code>.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dcover-restore_002dcoverage_002dfrom_002dfile"></span><dl>
|
|
<dt id="index-restore_002dcoverage_002dfrom_002dfile">Function: <strong>restore-coverage-from-file</strong> <em>[sb-cover] pathname</em></dt>
|
|
<dd><p><code>read</code> the contents of the file designated by <code>pathname</code> and pass the
|
|
result to <code>restore-coverage</code>.
|
|
</p></dd></dl>
|
|
|
|
|
|
<hr>
|
|
<span id="sb_002dgrovel"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002dmd5" accesskey="n" rel="next">sb-md5</a>, Previous: <a href="index.html#sb_002dcover" accesskey="p" rel="prev">sb-cover</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002dgrovel-1"></span><h3 class="section">17.4 sb-grovel</h3>
|
|
<span id="index-Foreign-Function-Interface_002c-generation"></span>
|
|
|
|
<p>The <code>sb-grovel</code> module helps in generation of foreign function
|
|
interfaces. It aids in extracting constants’ values from the C
|
|
compiler and in generating SB-ALIEN structure and union types,
|
|
see <a href="index.html#Defining-Foreign-Types">Defining Foreign Types</a>.
|
|
</p>
|
|
<p>The ASDF(<a href="http://www.cliki.net/ASDF">http://www.cliki.net/ASDF</a>) component type
|
|
GROVEL-CONSTANTS-FILE has its PERFORM
|
|
operation defined to write out a C source file, compile it, and run
|
|
it. The output from this program is Lisp, which is then itself
|
|
compiled and loaded.
|
|
</p>
|
|
<p>sb-grovel is used in a few contributed modules, and it is currently
|
|
compatible only to SBCL. However, if you want to use it, here are a
|
|
few directions.
|
|
</p>
|
|
<span id="Using-sb_002dgrovel-in-your-own-ASDF-system"></span><h4 class="subsection">17.4.1 Using sb-grovel in your own ASDF system</h4>
|
|
|
|
<ol>
|
|
<li> Create a Lisp package for the foreign constants/functions to go into.
|
|
|
|
</li><li> Make your system depend on the ’sb-grovel system.
|
|
|
|
</li><li> Create a grovel-constants data file - for an example, see
|
|
example-constants.lisp in the contrib/sb-grovel/ directory in the SBCL
|
|
source distribution.
|
|
|
|
</li><li> Add it as a component in your system. e.g.
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">(eval-when (:compile-toplevel :load-toplevel :execute)
|
|
(require :sb-grovel))
|
|
|
|
(defpackage :example-package.system
|
|
(:use :cl :asdf :sb-grovel :sb-alien))
|
|
|
|
(in-package :example-package.system)
|
|
|
|
(defsystem example-system
|
|
:depends-on (sb-grovel)
|
|
:components
|
|
((:module "sbcl"
|
|
:components
|
|
((:file "defpackage")
|
|
(grovel-constants-file "example-constants"
|
|
:package :example-package)))))
|
|
</pre></div>
|
|
|
|
<p>Make sure to specify the package you chose in step 1
|
|
</p>
|
|
</li><li> Build stuff.
|
|
|
|
</li></ol>
|
|
|
|
<span id="Contents-of-a-grovel_002dconstants_002dfile"></span><h4 class="subsection">17.4.2 Contents of a grovel-constants-file</h4>
|
|
|
|
<p>The grovel-constants-file, typically named <code>constants.lisp</code>,
|
|
comprises lisp expressions describing the foreign things that you want
|
|
to grovel for. A <code>constants.lisp</code> file contains two sections:
|
|
</p>
|
|
<ul>
|
|
<li> a list of headers to include in the C program, for example:
|
|
<div class="lisp">
|
|
<pre class="lisp">("sys/types.h" "sys/socket.h" "sys/stat.h" "unistd.h" "sys/un.h"
|
|
"netinet/in.h" "netinet/in_systm.h" "netinet/ip.h" "net/if.h"
|
|
"netdb.h" "errno.h" "netinet/tcp.h" "fcntl.h" "signal.h" )
|
|
</pre></div>
|
|
|
|
</li><li> A list of sb-grovel clauses describing the things you want to grovel
|
|
from the C compiler, for example:
|
|
<div class="lisp">
|
|
<pre class="lisp">((:integer af-local
|
|
#+(or sunos solaris) "AF_UNIX"
|
|
#-(or sunos solaris) "AF_LOCAL"
|
|
"Local to host (pipes and file-domain).")
|
|
(:structure stat ("struct stat"
|
|
(integer dev "dev_t" "st_dev")
|
|
(integer atime "time_t" "st_atime")))
|
|
(:function getpid ("getpid" int )))
|
|
</pre></div>
|
|
</li></ul>
|
|
|
|
<p>There are two types of things that sb-grovel can sensibly extract from
|
|
the C compiler: constant integers and structure layouts. It is also
|
|
possible to define foreign functions in the constants.lisp file, but
|
|
these definitions don’t use any information from the C program; they
|
|
expand directly to <code>sb-alien:define-alien-routine</code>
|
|
(see <a href="index.html#The-define_002dalien_002droutine-Macro">The define-alien-routine Macro</a>) forms.
|
|
</p>
|
|
<p>Here’s how to use the grovel clauses:
|
|
</p>
|
|
<ul>
|
|
<li> <code>:integer</code> - constant expressions in C. Used in this form:
|
|
<div class="lisp">
|
|
<pre class="lisp"> (:integer lisp-variable-name "C expression" &optional doc export)
|
|
</pre></div>
|
|
|
|
<p><code>"C expression"</code> will be typically be the name of a constant. But
|
|
other forms are possible.
|
|
</p>
|
|
</li><li> <code>:enum</code>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (:enum lisp-type-name ((lisp-enumerated-name c-enumerated-name) ...)))
|
|
</pre></div>
|
|
|
|
<p>An <code>sb-alien:enum</code> type with name <code>lisp-type-name</code> will be defined.
|
|
The symbols are the <code>lisp-enumerated-name</code>s, and the values
|
|
are grovelled from the <code>c-enumerated-name</code>s.
|
|
</p>
|
|
</li><li> <code>:structure</code> - alien structure definitions look like this:
|
|
<div class="lisp">
|
|
<pre class="lisp"> (:structure lisp-struct-name ("struct c_structure"
|
|
(type-designator lisp-element-name
|
|
"c_element_type" "c_element_name"
|
|
:distrust-length nil)
|
|
; ...
|
|
))
|
|
</pre></div>
|
|
|
|
<p><code>type-designator</code> is a reference to a type whose size (and type
|
|
constraints) will be groveled for. sb-grovel accepts a form of type
|
|
designator that doesn’t quite conform to either lisp nor sb-alien’s
|
|
type specifiers. Here’s a list of type designators that sb-grovel
|
|
currently accepts:
|
|
</p><ul>
|
|
<li> <code>integer</code> - a C integral type; sb-grovel will infer the exact
|
|
type from size information extracted from the C program. All common C
|
|
integer types can be grovelled for with this type designator, but it
|
|
is not possible to grovel for bit fields yet.
|
|
|
|
</li><li> <code>(unsigned n)</code> - an unsigned integer variable that is <code>n</code>
|
|
bytes long. No size information from the C program will be used.
|
|
</li><li> <code>(signed n)</code> - an signed integer variable that is <code>n</code> bytes
|
|
long. No size information from the C program will be used.
|
|
|
|
</li><li> <code>c-string</code> - an array of <code>char</code> in the structure. sb-grovel
|
|
will use the array’s length from the C program, unless you pass it the
|
|
<code>:distrust-length</code> keyword argument with non-<code>nil</code> value
|
|
(this might be required for structures such as solaris’s <code>struct
|
|
dirent</code>).
|
|
|
|
</li><li> <code>c-string-pointer</code> - a pointer to a C string, corresponding to
|
|
the <code>sb-alien:c-string</code> type (see <a href="index.html#Foreign-Type-Specifiers">Foreign Type Specifiers</a>).
|
|
</li><li> <code>(array alien-type)</code> - An array of the previously-declared alien
|
|
type. The array’s size will be determined from the output of the C
|
|
program and the alien type’s size.
|
|
</li><li> <code>(array alien-type n)</code> - An array of the previously-declared alien
|
|
type. The array’s size will be assumed as being <code>n</code>.
|
|
</li></ul>
|
|
|
|
|
|
<p>Note that <code>c-string</code> and <code>c-string-pointer</code> do not have the
|
|
same meaning. If you declare that an element is of type
|
|
<code>c-string</code>, it will be treated as if the string is a part of the
|
|
structure, whereas if you declare that the element is of type
|
|
<code>c-string-pointer</code>, a <em>pointer to a string</em> will be the
|
|
structure member.
|
|
</p>
|
|
</li><li> <code>:function</code> - alien function definitions are similar to
|
|
<code>define-alien-routine</code> definitions, because they expand to such
|
|
forms when the lisp program is loaded. See <a href="index.html#Foreign-Function-Calls">Foreign Function Calls</a>.
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">(:function lisp-function-name ("alien_function_name" alien-return-type
|
|
(argument alien-type)
|
|
(argument2 alien-type)))
|
|
</pre></div>
|
|
</li></ul>
|
|
|
|
|
|
<span id="Programming-with-sb_002dgrovel_0027s-structure-types"></span><h4 class="subsection">17.4.3 Programming with sb-grovel’s structure types</h4>
|
|
|
|
<p>Let us assume that you have a grovelled structure definition:
|
|
</p><div class="lisp">
|
|
<pre class="lisp"> (:structure mystruct ("struct my_structure"
|
|
(integer myint "int" "st_int")
|
|
(c-string mystring "char[]" "st_str")))
|
|
</pre></div>
|
|
|
|
<p>What can you do with it? Here’s a short interface document:
|
|
</p>
|
|
<ul>
|
|
<li> Creating and destroying objects:
|
|
<ul>
|
|
<li> Function <code>(allocate-mystruct)</code> - allocates an object of type <code>mystruct</code>and
|
|
returns a system area pointer to it.
|
|
</li><li> Function <code>(free-mystruct var)</code> - frees the alien object pointed to by
|
|
<var>var</var>.
|
|
</li><li> Macro <code>(with-mystruct var ((member init) [...]) &body body)</code> -
|
|
allocates an object of type <code>mystruct</code> that is valid in
|
|
<var>body</var>. If <var>body</var> terminates or control unwinds out of
|
|
<var>body</var>, the object pointed to by <var>var</var> will be deallocated.
|
|
</li></ul>
|
|
|
|
</li><li> Accessing structure members:
|
|
<ul>
|
|
<li> <code>(mystruct-myint var)</code> and <code>(mystruct-mystring var)</code> return
|
|
the value of the respective fields in <code>mystruct</code>.
|
|
</li><li> <code>(setf (mystruct-myint var) new-val)</code> and
|
|
<code>(setf (mystruct-mystring var) new-val)</code> sets the value of the respective
|
|
structure member to the value of <var>new-val</var>. Notice that in
|
|
<code>(setf (mystruct-mystring var) new-val)</code>’s case, new-val is a lisp
|
|
string.
|
|
</li></ul>
|
|
</li></ul>
|
|
|
|
<span id="Traps-and-Pitfalls"></span><h4 class="subsubsection">17.4.3.1 Traps and Pitfalls</h4>
|
|
<p>Basically, you can treat functions and data structure definitions that
|
|
sb-grovel spits out as if they were alien routines and types. This has
|
|
a few implications that might not be immediately obvious (especially
|
|
if you have programmed in a previous version of sb-grovel that didn’t
|
|
use alien types):
|
|
</p>
|
|
<ul>
|
|
<li> You must take care of grovel-allocated structures yourself. They are
|
|
alien types, so the garbage collector will not collect them when you
|
|
drop the last reference.
|
|
|
|
</li><li> If you use the <code>with-mystruct</code> macro, be sure that no references
|
|
to the variable thus allocated leaks out. It will be deallocated when
|
|
the block exits.
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="sb_002dmd5"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002dposix" accesskey="n" rel="next">sb-posix</a>, Previous: <a href="index.html#sb_002dgrovel" accesskey="p" rel="prev">sb-grovel</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002dmd5-1"></span><h3 class="section">17.5 sb-md5</h3>
|
|
<span id="index-Hashing_002c-cryptographic"></span>
|
|
|
|
<p>The <code>sb-md5</code> module implements the RFC1321 MD5 Message Digest
|
|
Algorithm. [FIXME cite]
|
|
</p>
|
|
<span id="Function-sb_002dmd5-md5sum_002dfile"></span><dl>
|
|
<dt id="index-md5sum_002dfile">Function: <strong>md5sum-file</strong> <em>[sb-md5] pathname</em></dt>
|
|
<dd><p>Calculate the MD5 message-digest of the file specified by ‘pathname’.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dmd5-md5sum_002dsequence"></span><dl>
|
|
<dt id="index-md5sum_002dsequence">Function: <strong>md5sum-sequence</strong> <em>[sb-md5] sequence &key start end</em></dt>
|
|
<dd><p>Calculate the MD5 message-digest of data in ‘sequence’, which should
|
|
be a 1d simple-array with element type (unsigned-byte 8). On <code>cmu</code> <code>cl</code>
|
|
and <code>sbcl</code> non-simple and non-1d arrays with this element-type are also
|
|
supported.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dmd5-md5sum_002dstream"></span><dl>
|
|
<dt id="index-md5sum_002dstream">Function: <strong>md5sum-stream</strong> <em>[sb-md5] stream</em></dt>
|
|
<dd><p>Calculate an MD5 message-digest of the contents of ‘stream’. Its
|
|
element-type has to be (unsigned-byte 8). Use on character streams is
|
|
<code>deprecated</code>, as this will not work correctly on implementations with
|
|
‘char-code-limit’ > 256 and ignores character coding issues.
|
|
</p></dd></dl>
|
|
|
|
<span id="Function-sb_002dmd5-md5sum_002dstring"></span><dl>
|
|
<dt id="index-md5sum_002dstring">Function: <strong>md5sum-string</strong> <em>[sb-md5] string &key external-format start end</em></dt>
|
|
<dd><p>Calculate the MD5 message-digest of the binary representation of
|
|
‘string’ (as octets) in the external format specified by
|
|
‘external-format’. The boundaries ‘start’ and ‘end’ refer to character
|
|
positions in the string, not to octets in the resulting binary
|
|
representation. The permissible external format specifiers are
|
|
determined by the underlying implementation.
|
|
</p></dd></dl>
|
|
|
|
<span id="Credits-2"></span><h4 class="subsection">17.5.1 Credits</h4>
|
|
|
|
<p>The implementation for CMUCL was largely done by Pierre Mai, with help
|
|
from members of the <code>cmucl-help</code> mailing list. Since CMUCL and
|
|
SBCL are similar in many respects, it was not too difficult to extend
|
|
the low-level implementation optimizations for CMUCL to SBCL.
|
|
Following this, SBCL’s compiler was extended to implement efficient
|
|
compilation of modular arithmetic (see <a href="index.html#Modular-arithmetic">Modular arithmetic</a>), which
|
|
enabled the implementation to be expressed in portable arithmetical
|
|
terms, apart from the use of <code>rotate-byte</code> for bitwise rotation.
|
|
<span id="index-rotate_002dbyte-_005bsb_002drotate_002dbyte_005d"></span>
|
|
</p>
|
|
|
|
<hr>
|
|
<span id="sb_002dposix"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002dqueue" accesskey="n" rel="next">sb-queue</a>, Previous: <a href="index.html#sb_002dmd5" accesskey="p" rel="prev">sb-md5</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002dposix-1"></span><h3 class="section">17.6 sb-posix</h3>
|
|
<span id="index-Operating-System-Interface"></span>
|
|
<span id="index-System-Calls"></span>
|
|
<span id="index-Posix"></span>
|
|
|
|
<p>Sb-posix is the supported interface for calling out to the operating
|
|
system.<a id="DOCF10" href="index.html#FOOT10"><sup>10</sup></a>
|
|
</p>
|
|
<p>The scope of this interface is “operating system calls on a typical
|
|
Unixlike platform”. This is section 2 of the Unix manual, plus section
|
|
3 calls that are (a) typically found in libc, but (b) not part of the C
|
|
standard. For example, we intend to provide support for
|
|
<code>opendir()</code> and <code>readdir()</code>, but not for <code>printf()</code>.
|
|
That said, if your favourite system call is not included yet, you are
|
|
encouraged to submit a patch to the SBCL mailing list.
|
|
</p>
|
|
<p>Some facilities are omitted where they offer absolutely no additional
|
|
use over some portable function, or would be actively dangerous to the
|
|
consistency of Lisp. Not all functions are available on all
|
|
platforms.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Lisp-names-for-C-names" accesskey="1">Lisp names for C names</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Types" accesskey="2">Types</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Function-Parameters" accesskey="3">Function Parameters</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Function-Return-Values" accesskey="4">Function Return Values</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Lisp-objects-and-C-structures" accesskey="5">Lisp objects and C structures</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Functions-with-idiosyncratic-bindings" accesskey="6">Functions with idiosyncratic bindings</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
|
|
<hr>
|
|
<span id="Lisp-names-for-C-names"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Types" accesskey="n" rel="next">Types</a>, Up: <a href="index.html#sb_002dposix" accesskey="u" rel="up">sb-posix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Lisp-names-for-C-names-1"></span><h4 class="subsection">17.6.1 Lisp names for C names</h4>
|
|
|
|
<p>All symbols are in the <code>SB-POSIX</code> package. This package contains a
|
|
Lisp function for each supported Unix system call or function, a
|
|
variable or constant for each supported Unix constant, an object type
|
|
for each supported Unix structure type, and a slot name for each
|
|
supported Unix structure member. A symbol name is derived from the C
|
|
binding’s name, by (a) uppercasing, then (b) removing leading
|
|
underscores (<code>#\_</code>) then replacing remaining underscore characters
|
|
with the hyphen (<code>#\-</code>). The requirement to uppercase is so that in
|
|
a standard upcasing reader the user may write <code>sb-posix:creat</code>
|
|
instead of <code>sb-posix:|creat|</code> as would otherise be required.
|
|
</p>
|
|
<p>No other changes to “Lispify” symbol names are made, so <code>creat()</code>
|
|
becomes <code>CREAT</code>, not <code>CREATE</code>.
|
|
</p>
|
|
<p>The user is encouraged not to <code>(USE-PACKAGE :SB-POSIX)</code> but instead
|
|
to use the <code>SB-POSIX:</code> prefix on all references, as some of the
|
|
symbols symbols contained in the SB-POSIX package have the same name as
|
|
CL symbols (<code>OPEN</code>, <code>CLOSE</code>, <code>SIGNAL</code> etc).
|
|
</p>
|
|
<hr>
|
|
<span id="Types"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Function-Parameters" accesskey="n" rel="next">Function Parameters</a>, Previous: <a href="index.html#Lisp-names-for-C-names" accesskey="p" rel="prev">Lisp names for C names</a>, Up: <a href="index.html#sb_002dposix" accesskey="u" rel="up">sb-posix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Types-1"></span><h4 class="subsection">17.6.2 Types</h4>
|
|
|
|
<p>Generally, marshalling between Lisp and C data types is done using
|
|
SBCL’s FFI. See <a href="index.html#Foreign-Function-Interface">Foreign Function Interface</a>.
|
|
</p>
|
|
<p>Some functions accept objects such as filenames or file descriptors. In
|
|
the C binding to POSIX these are represented as strings and small
|
|
integers respectively. For the Lisp programmer’s convenience we
|
|
introduce designators such that CL pathnames or open streams can be
|
|
passed to these functions. For example, <code>rename</code> accepts both
|
|
pathnames and strings as its arguments.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#File_002ddescriptors" accesskey="1">File-descriptors</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Filenames" accesskey="2">Filenames</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="File_002ddescriptors"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Filenames" accesskey="n" rel="next">Filenames</a>, Up: <a href="index.html#Types" accesskey="u" rel="up">Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="File_002ddescriptors-1"></span><h4 class="subsubsection">17.6.2.1 File-descriptors</h4>
|
|
|
|
<span id="Type-sb_002dposix-file_002ddescriptor"></span><dl>
|
|
<dt id="index-file_002ddescriptor-1">Type: <strong>file-descriptor</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>A <code>fixnum</code> designating a native file descriptor.
|
|
</p>
|
|
<p><code>sb-sys:make-fd-stream</code> can be used to construct a <code>file-stream</code> associated with a
|
|
native file descriptor.
|
|
</p>
|
|
<p>Note that mixing I/O operations on a <code>file-stream</code> with operations directly on its
|
|
descriptor may produce unexpected results if the stream is buffered.
|
|
</p></dd></dl>
|
|
<span id="Type-sb_002dposix-file_002ddescriptor_002ddesignator"></span><dl>
|
|
<dt id="index-file_002ddescriptor_002ddesignator">Type: <strong>file-descriptor-designator</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Designator for a <code>file-descriptor:</code> either a fixnum designating itself, or
|
|
a <code>file-stream</code> designating the underlying file-descriptor.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dposix-file_002ddescriptor"></span><dl>
|
|
<dt id="index-file_002ddescriptor">Function: <strong>file-descriptor</strong> <em>[sb-posix] file-descriptor</em></dt>
|
|
<dd><p>Converts <code>file-descriptor-designator</code> into a <code>file-descriptor</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Filenames"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#File_002ddescriptors" accesskey="p" rel="prev">File-descriptors</a>, Up: <a href="index.html#Types" accesskey="u" rel="up">Types</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Filenames-1"></span><h4 class="subsubsection">17.6.2.2 Filenames</h4>
|
|
|
|
<span id="Type-sb_002dposix-filename"></span><dl>
|
|
<dt id="index-filename-1">Type: <strong>filename</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>A <code>string</code> designating a filename in native namestring syntax.
|
|
</p>
|
|
<p>Note that native namestring syntax is distinct from Lisp namestring syntax:
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (pathname "/foo*/bar")
|
|
</pre></div>
|
|
|
|
<p>is a wild pathname with a pattern-matching directory component.
|
|
<code>sb-ext:parse-native-namestring</code> may be used to construct Lisp pathnames that
|
|
denote <code>posix</code> filenames as understood by system calls, and
|
|
<code>sb-ext:native-namestring</code> can be used to coerce them into strings in the native
|
|
namestring syntax.
|
|
</p>
|
|
<p>Note also that <code>posix</code> filename syntax does not distinguish the names of files
|
|
from the names of directories: in order to parse the name of a directory in
|
|
<code>posix</code> filename syntax into a pathname <code>my-defaults</code> for which
|
|
</p>
|
|
<div class="lisp">
|
|
<pre class="lisp"> (merge-pathnames (make-pathname :name "FOO" :case :common)
|
|
my-defaults)
|
|
</pre></div>
|
|
|
|
<p>returns a pathname that denotes a file in the directory, supply a true
|
|
<code>:as-directory</code> argument to <code>sb-ext:parse-native-namestring</code>. Likewise, to supply
|
|
the name of a directory to a <code>posix</code> function in non-directory syntax, supply a
|
|
true <code>:as-file</code> argument to <code>sb-ext:native-namestring</code>.
|
|
</p></dd></dl>
|
|
<span id="Type-sb_002dposix-filename_002ddesignator"></span><dl>
|
|
<dt id="index-filename_002ddesignator">Type: <strong>filename-designator</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Designator for a <code>filename:</code> a <code>string</code> designating itself, or a
|
|
designator for a <code>pathname</code> designating the corresponding native namestring.
|
|
</p></dd></dl>
|
|
<span id="Function-sb_002dposix-filename"></span><dl>
|
|
<dt id="index-filename">Function: <strong>filename</strong> <em>[sb-posix] filename</em></dt>
|
|
<dd><p>Converts <code>filename-designator</code> into a <code>filename</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Function-Parameters"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Function-Return-Values" accesskey="n" rel="next">Function Return Values</a>, Previous: <a href="index.html#Types" accesskey="p" rel="prev">Types</a>, Up: <a href="index.html#sb_002dposix" accesskey="u" rel="up">sb-posix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Function-Parameters-1"></span><h4 class="subsection">17.6.3 Function Parameters</h4>
|
|
|
|
<p>The calling convention is modelled after that of CMUCL’s <code>UNIX</code>
|
|
package: in particular, it’s like the C interface except that:
|
|
</p>
|
|
<ol type="a" start="1">
|
|
<li> Length arguments are omitted or optional where the sensible value
|
|
is obvious. For example, <code>read</code> would be defined this way:
|
|
|
|
<div class="lisp">
|
|
<pre class="lisp">(read fd buffer &optional (length (length buffer))) => bytes-read
|
|
</pre></div>
|
|
|
|
</li><li> Where C simulates “out” parameters using pointers (for instance, in
|
|
<code>pipe()</code> or <code>socketpair()</code>) these may be optional or omitted
|
|
in the Lisp interface: if not provided, appropriate objects will be
|
|
allocated and returned (using multiple return values if necessary).
|
|
|
|
</li><li> Some functions accept objects such as filenames or file descriptors.
|
|
Wherever these are specified as such in the C bindings, the Lisp
|
|
interface accepts designators for them as specified in the ’Types’
|
|
section above.
|
|
|
|
</li><li> A few functions have been included in sb-posix that do not correspond
|
|
exactly with their C counterparts. These are described in
|
|
See <a href="index.html#Functions-with-idiosyncratic-bindings">Functions with idiosyncratic bindings</a>.
|
|
|
|
</li></ol>
|
|
|
|
<hr>
|
|
<span id="Function-Return-Values"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Lisp-objects-and-C-structures" accesskey="n" rel="next">Lisp objects and C structures</a>, Previous: <a href="index.html#Function-Parameters" accesskey="p" rel="prev">Function Parameters</a>, Up: <a href="index.html#sb_002dposix" accesskey="u" rel="up">sb-posix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Function-Return-Values-1"></span><h4 class="subsection">17.6.4 Function Return Values</h4>
|
|
|
|
<p>The return value is usually the same as for the C binding, except in
|
|
error cases: where the C function is defined as returning some sentinel
|
|
value and setting <code>errno</code> on error, we instead signal an error of
|
|
type <code>SYSCALL-ERROR</code>. The actual error value (<code>errno</code>) is
|
|
stored in this condition and can be accessed with <code>SYSCALL-ERRNO</code>.
|
|
</p>
|
|
<p>We do not automatically translate the returned value into “Lispy”
|
|
objects – for example, <code>SB-POSIX:OPEN</code> returns a small integer,
|
|
not a stream. Exception: boolean-returning functions (or, more
|
|
commonly, macros) do not return a C integer, but instead a Lisp
|
|
boolean.
|
|
</p>
|
|
<hr>
|
|
<span id="Lisp-objects-and-C-structures"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Functions-with-idiosyncratic-bindings" accesskey="n" rel="next">Functions with idiosyncratic bindings</a>, Previous: <a href="index.html#Function-Return-Values" accesskey="p" rel="prev">Function Return Values</a>, Up: <a href="index.html#sb_002dposix" accesskey="u" rel="up">sb-posix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Lisp-objects-and-C-structures-1"></span><h4 class="subsection">17.6.5 Lisp objects and C structures</h4>
|
|
|
|
<p>Sb-posix provides various Lisp object types to stand in for C
|
|
structures in the POSIX library. Lisp bindings to C functions that
|
|
accept, manipulate, or return C structures accept, manipulate, or
|
|
return instances of these Lisp types instead of instances of alien
|
|
types.
|
|
</p>
|
|
<p>The names of the Lisp types are chosen according to the general rules
|
|
described above. For example Lisp objects of type <code>STAT</code> stand
|
|
in for C structures of type <code>struct stat</code>.
|
|
</p>
|
|
<p>Accessors are provided for each standard field in the structure. These
|
|
are named <code><var>structure-name</var>-<var>field-name</var></code> where the two
|
|
components are chosen according to the general name conversion rules,
|
|
with the exception that in cases where all fields in a given structure
|
|
have a common prefix, that prefix is omitted. For example,
|
|
<code>stat.st_dev</code> in C becomes <code>STAT-DEV</code> in Lisp.
|
|
</p>
|
|
|
|
|
|
<p>Because sb-posix might not support all semi-standard or
|
|
implementation-dependent members of all structure types on your system
|
|
(patches welcome), here is an enumeration of all supported Lisp
|
|
objects corresponding to supported POSIX structures, and the supported
|
|
slots for those structures.
|
|
</p>
|
|
<ul>
|
|
<li> flock
|
|
<span id="Class-sb_002dposix-flock"></span><dl>
|
|
<dt id="index-flock">Class: <strong>flock</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Class precedence list: <code>flock<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Slots:
|
|
</p><ul>
|
|
<li> <code>type</code> — initarg: <code>:type<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:flock-type</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:flock-type)</span><!-- /@w --></code>
|
|
|
|
<p>Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
|
|
</p></li><li> <code>whence</code> — initarg: <code>:whence<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:flock-whence</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:flock-whence)</span><!-- /@w --></code>
|
|
|
|
<p>Flag for starting offset.
|
|
</p></li><li> <code>start</code> — initarg: <code>:start<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:flock-start</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:flock-start)</span><!-- /@w --></code>
|
|
|
|
<p>Relative offset in bytes.
|
|
</p></li><li> <code>len</code> — initarg: <code>:len<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:flock-len</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:flock-len)</span><!-- /@w --></code>
|
|
|
|
<p>Size; if 0 then until <code>eof</code>.
|
|
</p></li><li> <code>pid</code> — reader: <code><span class="nolinebreak">sb-posix:flock-pid</span><!-- /@w --></code>
|
|
|
|
<p>Process <code>id</code> of the process holding the lock; returned with F_GETLK.
|
|
</p></li></ul>
|
|
|
|
<p>Class representing locks used in fcntl(2).
|
|
</p></dd></dl>
|
|
|
|
</li><li> passwd
|
|
<span id="Class-sb_002dposix-passwd"></span><dl>
|
|
<dt id="index-passwd">Class: <strong>passwd</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Class precedence list: <code>passwd<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Slots:
|
|
</p><ul>
|
|
<li> <code>name</code> — initarg: <code>:name<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:passwd-name</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:passwd-name)</span><!-- /@w --></code>
|
|
|
|
<p>User’s login name.
|
|
</p></li><li> <code>passwd</code> — initarg: <code>:passwd<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:passwd-passwd</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:passwd-passwd)</span><!-- /@w --></code>
|
|
|
|
<p>The account’s encrypted password.
|
|
</p></li><li> <code>uid</code> — initarg: <code>:uid<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:passwd-uid</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:passwd-uid)</span><!-- /@w --></code>
|
|
|
|
<p>Numerical user <code>id</code>.
|
|
</p></li><li> <code>gid</code> — initarg: <code>:gid<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:passwd-gid</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:passwd-gid)</span><!-- /@w --></code>
|
|
|
|
<p>Numerical group <code>id</code>.
|
|
</p></li><li> <code>gecos</code> — initarg: <code>:gecos<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:passwd-gecos</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:passwd-gecos)</span><!-- /@w --></code>
|
|
|
|
<p>User’s name or comment field.
|
|
</p></li><li> <code>dir</code> — initarg: <code>:dir<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:passwd-dir</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:passwd-dir)</span><!-- /@w --></code>
|
|
|
|
<p>Initial working directory.
|
|
</p></li><li> <code>shell</code> — initarg: <code>:shell<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:passwd-shell</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:passwd-shell)</span><!-- /@w --></code>
|
|
|
|
<p>Program to use as shell.
|
|
</p></li></ul>
|
|
|
|
<p>Instances of this class represent entries in the system’s user database.
|
|
</p></dd></dl>
|
|
|
|
</li><li> stat
|
|
<span id="Class-sb_002dposix-stat"></span><dl>
|
|
<dt id="index-stat">Class: <strong>stat</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Class precedence list: <code>stat<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Slots:
|
|
</p><ul>
|
|
<li> <code>mode</code> — initarg: <code>:mode<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-mode</span><!-- /@w --></code>
|
|
|
|
<p>Mode of file.
|
|
</p></li><li> <code>ino</code> — initarg: <code>:ino<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-ino</span><!-- /@w --></code>
|
|
|
|
<p>File serial number.
|
|
</p></li><li> <code>dev</code> — initarg: <code>:dev<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-dev</span><!-- /@w --></code>
|
|
|
|
<p>Device <code>id</code> of device containing file.
|
|
</p></li><li> <code>nlink</code> — initarg: <code>:nlink<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-nlink</span><!-- /@w --></code>
|
|
|
|
<p>Number of hard links to the file.
|
|
</p></li><li> <code>uid</code> — initarg: <code>:uid<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-uid</span><!-- /@w --></code>
|
|
|
|
<p>User <code>id</code> of file.
|
|
</p></li><li> <code>gid</code> — initarg: <code>:gid<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-gid</span><!-- /@w --></code>
|
|
|
|
<p>Group <code>id</code> of file.
|
|
</p></li><li> <code>size</code> — initarg: <code>:size<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-size</span><!-- /@w --></code>
|
|
|
|
<p>For regular files, the file size in
|
|
bytes. For symbolic links, the length
|
|
in bytes of the filename contained in
|
|
the symbolic link.
|
|
</p></li><li> <code>rdev</code> — initarg: <code>:rdev<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-rdev</span><!-- /@w --></code>
|
|
|
|
<p>For devices the device number.
|
|
</p></li><li> <code>atime</code> — initarg: <code>:atime<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-atime</span><!-- /@w --></code>
|
|
|
|
<p>Time of last access.
|
|
</p></li><li> <code>mtime</code> — initarg: <code>:mtime<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-mtime</span><!-- /@w --></code>
|
|
|
|
<p>Time of last data modification.
|
|
</p></li><li> <code>ctime</code> — initarg: <code>:ctime<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:stat-ctime</span><!-- /@w --></code>
|
|
|
|
<p>Time of last status change.
|
|
</p></li></ul>
|
|
|
|
<p>Instances of this class represent <code>posix</code> file metadata.
|
|
</p></dd></dl>
|
|
|
|
</li><li> termios
|
|
<span id="Class-sb_002dposix-termios"></span><dl>
|
|
<dt id="index-termios">Class: <strong>termios</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Class precedence list: <code>termios<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Slots:
|
|
</p><ul>
|
|
<li> <code>iflag</code> — initarg: <code>:iflag<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:termios-iflag</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:termios-iflag)</span><!-- /@w --></code>
|
|
|
|
<p>Input modes.
|
|
</p></li><li> <code>oflag</code> — initarg: <code>:oflag<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:termios-oflag</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:termios-oflag)</span><!-- /@w --></code>
|
|
|
|
<p>Output modes.
|
|
</p></li><li> <code>cflag</code> — initarg: <code>:cflag<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:termios-cflag</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:termios-cflag)</span><!-- /@w --></code>
|
|
|
|
<p>Control modes.
|
|
</p></li><li> <code>lflag</code> — initarg: <code>:lflag<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:termios-lflag</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:termios-lflag)</span><!-- /@w --></code>
|
|
|
|
<p>Local modes.
|
|
</p></li><li> <code>cc</code> — initarg: <code>:cc<!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:termios-cc</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:termios-cc)</span><!-- /@w --></code>
|
|
|
|
<p>Control characters.
|
|
</p></li></ul>
|
|
|
|
<p>Instances of this class represent I/O characteristics of the terminal.
|
|
</p></dd></dl>
|
|
|
|
</li><li> timeval
|
|
<span id="Class-sb_002dposix-timeval"></span><dl>
|
|
<dt id="index-timeval">Class: <strong>timeval</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Class precedence list: <code>timeval<!-- /@w --></code>, <code><span class="nolinebreak">standard-object</span><!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Slots:
|
|
</p><ul>
|
|
<li> <code>sec</code> — initarg: <code><span class="nolinebreak">:tv-sec</span><!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:timeval-sec</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:timeval-sec)</span><!-- /@w --></code>
|
|
|
|
<p>Seconds.
|
|
</p></li><li> <code>usec</code> — initarg: <code><span class="nolinebreak">:tv-usec</span><!-- /@w --></code>; reader: <code><span class="nolinebreak">sb-posix:timeval-usec</span><!-- /@w --></code>; writer: <code>(setf <span class="nolinebreak">sb-posix:timeval-usec)</span><!-- /@w --></code>
|
|
|
|
<p>Microseconds.
|
|
</p></li></ul>
|
|
|
|
<p>Instances of this class represent time values.
|
|
</p></dd></dl>
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="Functions-with-idiosyncratic-bindings"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Lisp-objects-and-C-structures" accesskey="p" rel="prev">Lisp objects and C structures</a>, Up: <a href="index.html#sb_002dposix" accesskey="u" rel="up">sb-posix</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Functions-with-idiosyncratic-bindings-1"></span><h4 class="subsection">17.6.6 Functions with idiosyncratic bindings</h4>
|
|
|
|
<p>A few functions in sb-posix don’t correspond directly to their C
|
|
counterparts.
|
|
</p>
|
|
<ul>
|
|
<li> getcwd
|
|
<span id="Function-sb_002dposix-getcwd"></span><dl>
|
|
<dt id="index-getcwd">Function: <strong>getcwd</strong> <em>[sb-posix]</em></dt>
|
|
<dd><p>Returns the process’s current working directory as a string.
|
|
</p></dd></dl>
|
|
</li><li> readlink
|
|
<span id="Function-sb_002dposix-readlink"></span><dl>
|
|
<dt id="index-readlink">Function: <strong>readlink</strong> <em>[sb-posix] pathspec</em></dt>
|
|
<dd><p>Returns the resolved target of a symbolic link as a string.
|
|
</p></dd></dl>
|
|
</li><li> syslog
|
|
<span id="Function-sb_002dposix-syslog"></span><dl>
|
|
<dt id="index-syslog">Function: <strong>syslog</strong> <em>[sb-posix] priority format &rest args</em></dt>
|
|
<dd><p>Send a message to the syslog facility, with severity level
|
|
<code>priority</code>. The message will be formatted as by <code>cl:format</code> (rather
|
|
than C’s printf) with format string <code>format</code> and arguments <code>args</code>.
|
|
</p></dd></dl>
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="sb_002dqueue"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002drotate_002dbyte" accesskey="n" rel="next">sb-rotate-byte</a>, Previous: <a href="index.html#sb_002dposix" accesskey="p" rel="prev">sb-posix</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002dqueue-1"></span><h3 class="section">17.7 sb-queue</h3>
|
|
<span id="index-Queue_002c-FIFO"></span>
|
|
|
|
<p>Since SBCL 1.0.38, the <code>sb-queue</code> module has been merged into the
|
|
<code>sb-concurrency</code> module (see <a href="index.html#sb_002dconcurrency">sb-concurrency</a>.)
|
|
</p>
|
|
<hr>
|
|
<span id="sb_002drotate_002dbyte"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#sb_002dsimd" accesskey="n" rel="next">sb-simd</a>, Previous: <a href="index.html#sb_002dqueue" accesskey="p" rel="prev">sb-queue</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002drotate_002dbyte-1"></span><h3 class="section">17.8 sb-rotate-byte</h3>
|
|
<span id="index-Modular-arithmetic-1"></span>
|
|
<span id="index-Arithmetic_002c-modular-1"></span>
|
|
<span id="index-Arithmetic_002c-hardware-1"></span>
|
|
|
|
<p>The <code>sb-rotate-byte</code> module offers an interface to bitwise
|
|
rotation, with an efficient implementation for operations which can be
|
|
performed directly using the platform’s arithmetic routines. It
|
|
implements the specification at
|
|
<a href="http://www.cliki.net/ROTATE-BYTE">http://www.cliki.net/ROTATE-BYTE</a>.
|
|
</p>
|
|
<p>Bitwise rotation is a component of various cryptographic or hashing
|
|
algorithms: MD5, SHA-1, etc.; often these algorithms are specified on
|
|
32-bit rings. [FIXME cite cite cite].
|
|
</p>
|
|
<span id="Function-sb_002drotate_002dbyte-rotate_002dbyte"></span><dl>
|
|
<dt id="index-rotate_002dbyte">Function: <strong>rotate-byte</strong> <em>[sb-rotate-byte] count bytespec integer</em></dt>
|
|
<dd><p>Rotates a field of bits within <code>integer</code>; specifically, returns an
|
|
integer that contains the bits of <code>integer</code> rotated <code>count</code> times
|
|
leftwards within the byte specified by <code>bytespec</code>, and elsewhere
|
|
contains the bits of <code>integer</code>.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="sb_002dsimd"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#sb_002drotate_002dbyte" accesskey="p" rel="prev">sb-rotate-byte</a>, Up: <a href="index.html#Contributed-Modules" accesskey="u" rel="up">Contributed Modules</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="sb_002dsimd-1"></span><h3 class="section">17.9 sb-simd</h3>
|
|
<span id="index-SIMD"></span>
|
|
|
|
<p>The <code>sb-simd</code> module provides a convenient interface for SIMD
|
|
programming in SBCL. It provides one package per SIMD instruction set,
|
|
plus functions and macros for querying whether an instruction set is
|
|
available and what functions and data types it exports.
|
|
</p>
|
|
<span id="Data-Types"></span><h4 class="subsection">17.9.1 Data Types</h4>
|
|
|
|
<p>The central data type in <code>sb-simd</code> is the SIMD pack. A SIMD pack
|
|
is very similar to a specialized vector, except that its length must be
|
|
a particular power of two that depends on its element type and the
|
|
underlying hardware. The set of element types that are supported for
|
|
SIMD packs is similar to that of SBCL’s specialized array element types,
|
|
except that there is currently no support for SIMD packs of complex
|
|
numbers or characters.
|
|
</p>
|
|
<p>The supported scalar types are <code>f32</code>, <code>f64</code>, <code>sN</code>, and
|
|
<code>uN</code>, where <code>N</code> is either 8, 16, 32, or 64. These scalar
|
|
types are abbreviations for the Common Lisp types <code>single-float</code>,
|
|
<code>double-float</code>, <code>signed-byte</code>, and <code>unsigned-byte</code>,
|
|
respectively. For each scalar data type <code>X</code>, there exists one or
|
|
more SIMD data type <code>X.Y</code> with <code>Y</code> elements. For example, in
|
|
AVX there are two supported SIMD data types with element type
|
|
<code>f64</code>, namely <code>f64.2</code> (128 bit) and <code>f64.4</code> (256 bit).
|
|
</p>
|
|
<p>SIMD packs are regular Common Lisp objects that have a type, a class,
|
|
and can be passed as function arguments. The price for this is that
|
|
SIMD packs have both a boxed and an unboxed representation. The unboxed
|
|
representation of a SIMD pack has zero overhead and fits into a CPU
|
|
register, but can only be used within a function and when the compiler
|
|
can statically determine the SIMD pack’s type. Otherwise, the SIMD pack
|
|
is boxed, i.e., spilled to the heap together with its type information.
|
|
In practice, boxing of SIMD packs can usually be avoided via inlining,
|
|
or by loading and storing them to specialized arrays instead of passing
|
|
them around as function arguments.
|
|
</p>
|
|
<span id="Casts"></span><h4 class="subsection">17.9.2 Casts</h4>
|
|
|
|
<p>For each scalar data type <code>X</code>, there is a function named <code>X</code>
|
|
that is equivalent to <code>(lambda (v) (coerce v 'X))</code>. For each SIMD
|
|
data type <code>X.Y</code>, there is a function named <code>X.Y</code> that ensures
|
|
that its argument is of type <code>X.Y</code>, or, if the argument is a number,
|
|
calls the cast function of <code>X</code> and broadcasts the result.
|
|
</p>
|
|
<p>All functions provided by <code>sb-simd</code> (apart from the casts
|
|
themselves) implicitly cast each argument to its expected type. So to
|
|
add the number five to each single float in a SIMD pack <code>x</code> of type
|
|
<code>f32.8</code>, it is sufficient to write <code>(f32.8+ x 5)</code>. We don’t
|
|
mention this implicit conversion explicitly in the following sections,
|
|
so if any function description states that an argument must be of type
|
|
<code>X.Y</code>, the argument can actually be of any type that is a suitable
|
|
argument of the cast function named <code>X.Y</code>.
|
|
</p>
|
|
<span id="Constructors"></span><h4 class="subsection">17.9.3 Constructors</h4>
|
|
|
|
<p>For each SIMD data type <code>X.Y</code>, there is a constructor named
|
|
<code>make-X.Y</code> that takes <code>Y</code> arguments of type <code>X</code> and
|
|
returns a SIMD pack whose elements are the supplied values.
|
|
</p>
|
|
<span id="Unpackers"></span><h4 class="subsection">17.9.4 Unpackers</h4>
|
|
|
|
<p>For each SIMD data type <code>X.Y</code>, there is a function named
|
|
<code>X.Y-values</code> that returns, as <code>Y</code> multiple values, the
|
|
elements of the supplied SIMD pack of type <code>X.Y</code>.
|
|
</p>
|
|
<span id="Reinterpret-Casts"></span><h4 class="subsection">17.9.5 Reinterpret Casts</h4>
|
|
|
|
<p>For each SIMD data type <code>X.Y</code>, there is a function named
|
|
<code>X.Y!</code> that takes any SIMD pack or scalar datum and interprets its
|
|
bits as a SIMD pack of type <code>X.Y</code>. If the supplied datum has more
|
|
bits than the resulting value, the excess bits are discarded. If the
|
|
supplied datum has less bits than the resulting value, the missing bits are
|
|
assumed to be zero.
|
|
</p>
|
|
<span id="Associatives"></span><h4 class="subsection">17.9.6 Associatives</h4>
|
|
|
|
<p>For each associative binary function, e.g., <code>two-arg-X.Y-OP</code>, there
|
|
is a function <code>X.Y-OP</code> that takes any number of arguments and
|
|
combines them with this binary function in a tree-like fashion. If the
|
|
binary function has an identity element, it is possible to call the
|
|
function with zero arguments, in which case the identity element is
|
|
returned. If there is no identity element, the function must receive at
|
|
least one argument.
|
|
</p>
|
|
<p>Examples of associative functions are <code>f32.8+</code>, for summing any
|
|
number of 256 bit packs of single floats, and <code>u8.32-max</code>, for
|
|
computing the element-wise maximum of one or more 256 bit packs of 8 bit
|
|
integers.
|
|
</p>
|
|
<span id="Reducers"></span><h4 class="subsection">17.9.7 Reducers</h4>
|
|
|
|
<p>For binary functions <code>two-arg-X.Y-OP</code> that are not associative, but
|
|
that have a neutral element, there are functions <code>X.Y-OP</code> that take
|
|
any positive number of arguments and return the reduction of all
|
|
arguments with the binary function. In the special case of a single
|
|
supplied argument, the binary function is invoked on the neutral element
|
|
and that argument. Reducers have been introduced to generate Lisp-style
|
|
subtraction and division functions.
|
|
</p>
|
|
<p>Examples of reducers are <code>f32.8/</code>, for successively dividing a pack
|
|
of 32 bit single floats by all further supplied packs of 32 bit single
|
|
floats, or <code>u32.8-</code> for subtracting any number of supplied packs of
|
|
32 bit unsigned integers from the first supplied one, except in the case
|
|
of a single argument, where <code>u32.8-</code> simply negates all values in
|
|
the pack.
|
|
</p>
|
|
<span id="Rounding"></span><h4 class="subsection">17.9.8 Rounding</h4>
|
|
|
|
<p>For each floating-point SIMD data type <code>X.Y</code> there are several
|
|
functions that round the values of a supplied SIMD pack to nearby
|
|
floating-point values whose fractional digits are all zero. Those
|
|
functions are <code>X.Y-round</code>, <code>X.Y-floor</code>, <code>X.Y-ceiling</code>,
|
|
and <code>X.Y-truncate</code>, and they have the same semantics as the one
|
|
argument versions of <code>cl:round</code>, <code>cl:floor</code>,
|
|
<code>cl:ceiling</code>, and <code>cl:truncate</code>, respectively.
|
|
</p>
|
|
<span id="Comparisons"></span><h4 class="subsection">17.9.9 Comparisons</h4>
|
|
|
|
<p>For each SIMD data type <code>X.Y</code>, there exist conversion functions
|
|
<code>X.Y<</code>, <code>X.Y<=</code>, <code>X.Y></code>, <code>X.Y>=</code>, and
|
|
<code>X.Y=</code> that check whether the supplied arguments are strictly
|
|
monotonically increasing, monotonically increasing, strictly monotonically
|
|
decreasing, monotonically decreasing, equal, or nowhere equal,
|
|
respectively. In contrast to the Common Lisp functions <code><</code>,
|
|
<code><=</code>, <code>></code>, <code>>=</code>, <code>=</code>, and <code>/=</code> the SIMD
|
|
comparison functions don’t return a generalized boolean, but a SIMD pack of
|
|
unsigned integers with <code>Y</code> elements. The bits of each unsigned
|
|
integer are either all one, if the values of the arguments at that position
|
|
satisfy the test, or all zero, if they don’t. We call a SIMD packs of such
|
|
unsigned integers a mask.
|
|
</p>
|
|
<span id="Conditionals"></span><h4 class="subsection">17.9.10 Conditionals</h4>
|
|
|
|
<p>The SIMD paradigm is inherently incompatible with fine-grained control
|
|
flow. A piece of code containing an <code>if</code> special form cannot be
|
|
vectorized in a straightforward way, because doing so would require as
|
|
many instruction pointers and processor states as there are values in
|
|
the desired SIMD data type. Instead, most SIMD instruction sets provide
|
|
an operator for selecting values from one of two supplied SIMD packs
|
|
based on a mask. The mask is a SIMD pack with as many elements as the
|
|
other two arguments, but whose elements are unsigned integers whose bits
|
|
must be either all zeros or all ones. This selection mechanism can be
|
|
used to emulate the effect of an <code>if</code> special form, at the price
|
|
that both operands have to be computed each time.
|
|
</p>
|
|
<p>In <code>sb-simd</code>, all conditional operations and comparisons emit
|
|
suitable mask fields, and there is a <code>X.Y-if</code> function for each
|
|
SIMD data type with element type <code>X</code> and number of elements
|
|
<code>Y</code> whose first arguments must be a suitable mask, whose second and
|
|
third argument must be objects that can be converted to the SIMD data
|
|
type <code>X.Y</code>, and that returns a value of type <code>X.Y</code> where each
|
|
element is from the second operand if the corresponding mask bits are
|
|
set, and from the third operand if the corresponding mask bits are not
|
|
set.
|
|
</p>
|
|
<span id="Loads-and-Stores"></span><h4 class="subsection">17.9.11 Loads and Stores</h4>
|
|
|
|
<p>In practice, a SIMD pack <code>X.Y</code> is usually not constructed by
|
|
calling its constructor, but by loading <code>Y</code> consecutive elements
|
|
from a specialized array with element type <code>X</code>. The functions for
|
|
doing so are called <code>X.Y-aref</code> and <code>X.Y-row-major-aref</code>, and
|
|
have similar semantics as Common Lisp’s <code>aref</code> and
|
|
<code>row-major-aref</code>. In addition to that, some instruction sets
|
|
provide the functions <code>X.Y-non-temporal-aref</code> and
|
|
<code>X.Y-non-temporal-row-major-aref</code>, for accessing a memory location
|
|
without loading the referenced values into the CPU’s cache.
|
|
</p>
|
|
<p>For each function <code>X.Y-foo</code> for loading SIMD packs from an array,
|
|
there also exists a corresponding function <code>(setf X.Y-foo)</code> for
|
|
storing a SIMD pack in the specified memory location. An exception to
|
|
this rule is that some instruction sets (e.g., SSE) only provide
|
|
functions for non-temporal stores, but not for the corresponding
|
|
non-temporal loads.
|
|
</p>
|
|
<p>One difficulty when treating the data of a Common Lisp array as a SIMD
|
|
pack is that some hardware instructions require a particular alignment
|
|
of the address being referenced. Luckily, most architectures provide
|
|
instructions for unaligned loads and stores that are, at least on modern
|
|
CPUs, not slower than their aligned equivalents. So by default we
|
|
translate all array references as unaligned loads and stores. An
|
|
exception are the instructions for non-temporal loads and stores, that
|
|
always require a certain alignment. We do not handle this case
|
|
specially, so without special handling by the user, non-temporal loads
|
|
and stores will only work on certain array indices that depend on the
|
|
actual placement of that array in memory.
|
|
</p>
|
|
<span id="Specialized-Scalar-Operations"></span><h4 class="subsection">17.9.12 Specialized Scalar Operations</h4>
|
|
|
|
<p>Finally, for each SIMD function <code>X.Y-OP</code> that applies a certain
|
|
operation <code>OP</code> element-wise to the <code>Y</code> elements of type
|
|
<code>X</code>, there exists also a functions <code>X-OP</code> for applying that
|
|
operation only to a single element. For example, the SIMD function
|
|
<code>f64.4+</code> has a corresponding function <code>f64+</code> that differs from
|
|
<code>cl:+</code> in that it only accepts arguments of type double float, and
|
|
that it adds its supplied arguments in a fixed order that is the same as
|
|
the one used by <code>f64.4</code>.
|
|
</p>
|
|
<p>There are good reasons for exporting scalar functions from a SIMD
|
|
library, too. The most obvious one is that they obey the same naming
|
|
convention and hence make it easier to locate the correct functions.
|
|
Another benefit is that the semantics of each scalar operation is
|
|
precisely the same as that of the corresponding SIMD function, so they
|
|
can be used to write reference implementations for testing. A final
|
|
reason is that these scalar functions can be used to simplify the life
|
|
of tools for automatic vectorization.
|
|
</p>
|
|
<span id="Instruction-Set-Dispatch"></span><h4 class="subsection">17.9.13 Instruction Set Dispatch</h4>
|
|
|
|
<p>One challenge that is unique to image-based programming systems such as
|
|
Lisp is that a program can run on one machine, be dumped as an image,
|
|
and then resumed on another machine. While nobody expects this feature
|
|
to work across machines with different architectures, it is quite likely
|
|
that the machine where the image is dumped and the one where execution
|
|
is resumed provide different instruction set extensions.
|
|
</p>
|
|
<p>As a practical example, consider a game developer that develops software
|
|
on an x86-64 machine with all SIMD extensions up to AVX2, but then dumps
|
|
it as an image and ships it to a customer whose machine only supports
|
|
SIMD extensions up to SSE2. Ideally, the image should contain multiple
|
|
optimized versions of all crucial functions, and dynamically select the
|
|
most appropriate version based on the instruction set extensions that
|
|
are actually available.
|
|
</p>
|
|
<p>This kind of run time instruction set dispatch is explicitly supported
|
|
by means of the <code>instruction-set-case</code> macro. The code resulting
|
|
from an invocation of this macro compiles to an efficient jump table
|
|
whose index is recomputed on each startup of the Lisp image.
|
|
</p><hr>
|
|
<span id="Deprecation"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Concept-Index" accesskey="n" rel="next">Concept Index</a>, Previous: <a href="index.html#Contributed-Modules" accesskey="p" rel="prev">Contributed Modules</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Deprecation-1"></span><h2 class="chapter">18 Deprecation</h2>
|
|
|
|
<p>In order to support evolution of interfaces in SBCL as well as in user
|
|
code, SBCL allows declaring functions, variables and types as
|
|
deprecated. Users of deprecated things are notified by means of warnings
|
|
while the deprecated thing in question is still available.
|
|
</p>
|
|
<p>This chapter documents the interfaces for being notified when using
|
|
deprecated thing and declaring things as deprecated, the deprecation
|
|
process used for SBCL interfaces, and lists legacy interfaces in various
|
|
stages of deprecation.
|
|
</p>
|
|
<p><em>Deprecation</em> in this context should not be confused with those
|
|
things the ANSI Common Lisp standard calls <em>deprecated</em>: the
|
|
entirety of ANSI CL is supported by SBCL, and none of those interfaces
|
|
are subject to censure.
|
|
</p>
|
|
<table class="menu" border="0" cellspacing="0">
|
|
<tr><td align="left" valign="top">• <a href="index.html#Why-Deprecate_003f" accesskey="1">Why Deprecate?</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#The-Deprecation-Pipeline" accesskey="2">The Deprecation Pipeline</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Deprecation-Conditions" accesskey="3">Deprecation Conditions</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Introspecting-Deprecation-Information" accesskey="4">Introspecting Deprecation Information</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Deprecation-Declaration" accesskey="5">Deprecation Declaration</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Deprecation-Examples" accesskey="6">Deprecation Examples</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
<tr><td align="left" valign="top">• <a href="index.html#Deprecated-Interfaces-in-SBCL" accesskey="7">Deprecated Interfaces in SBCL</a></td><td> </td><td align="left" valign="top">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
<span id="Why-Deprecate_003f"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#The-Deprecation-Pipeline" accesskey="n" rel="next">The Deprecation Pipeline</a>, Up: <a href="index.html#Deprecation" accesskey="u" rel="up">Deprecation</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Why-Deprecate_003f-1"></span><h3 class="section">18.1 Why Deprecate?</h3>
|
|
<span id="index-Why-Deprecate_003f"></span>
|
|
|
|
<p>While generally speaking we try to keep SBCL changes as backwards
|
|
compatible as feasible, there are situations when existing interfaces
|
|
are deprecated:
|
|
</p>
|
|
<ul>
|
|
<li> <strong>Broken Interfaces</strong>
|
|
|
|
<p>Sometimes it turns out that an interface is sufficiently misdesigned
|
|
that fixing it would be worse than deprecating it and replacing it
|
|
with another.
|
|
</p>
|
|
<p>This is typically the case when fixing the interface would change its
|
|
semantics in ways that could break user code subtly: in such cases we
|
|
may end up considering the obvious breakage caused by deprecation to
|
|
be preferable.
|
|
</p>
|
|
<p>Another example are functions or macros whose current signature makes
|
|
them hard or impossible to extend in the future: backwards compatible
|
|
extensions would either make the interface intolerably hairy, or are
|
|
sometimes outright impossible.
|
|
</p>
|
|
</li><li> <strong>Internal Interfaces</strong>
|
|
|
|
<p>SBCL has several internal interfaces that were never meant to be used
|
|
in user code – or at least never meant to be used in user code
|
|
unwilling to track changes to SBCL internals.
|
|
</p>
|
|
<p>Ideally we’d like to be free to refactor our own internals as we
|
|
please, without even going through the hassle of deprecating things.
|
|
Sometimes, however, it turns out that our internal interfaces have
|
|
several external users who aren’t using them advisedly, but due to
|
|
misunderstandings regarding their status or stability.
|
|
</p>
|
|
<p>Consider a deprecated internal interface a reminder for SBCL
|
|
maintainers not to delete the thing just yet, even though it is seems
|
|
unused – because it has external users.
|
|
</p>
|
|
<p>When internal interfaces are deprecated we try our best to provide
|
|
supported alternatives.
|
|
</p>
|
|
</li><li> <strong>Aesthetics & Ease of Maintenance</strong>
|
|
|
|
<p>Sometimes an interface isn’t broken or internal, but just inconsistent
|
|
somehow.
|
|
</p>
|
|
<p>This mostly happens only with historical interfaces inherited from
|
|
CMUCL which often haven’t been officially supported in SBCL before, or
|
|
with new extensions to SBCL that haven’t been around for very long in
|
|
the first place.
|
|
</p>
|
|
<p>The alternative would be to keep the suboptimal version around
|
|
forever, possibly alongside an improved version. Sometimes we may do
|
|
just that, but because every line of code comes with a maintenance
|
|
cost, sometimes we opt to deprecate the suboptimal version instead:
|
|
SBCL doesn’t have infinite developer resources.
|
|
</p>
|
|
<p>We also believe that sometimes cleaning out legacy interfaces helps
|
|
keep the whole system more comprehensible to users, and makes
|
|
introspective tools such as
|
|
<span id="index-apropos-_005bcl_005d"></span>
|
|
<code>apropos</code> more useful.
|
|
</p>
|
|
</li></ul>
|
|
|
|
<hr>
|
|
<span id="The-Deprecation-Pipeline"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Deprecation-Conditions" accesskey="n" rel="next">Deprecation Conditions</a>, Previous: <a href="index.html#Why-Deprecate_003f" accesskey="p" rel="prev">Why Deprecate?</a>, Up: <a href="index.html#Deprecation" accesskey="u" rel="up">Deprecation</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="The-Deprecation-Pipeline-1"></span><h3 class="section">18.2 The Deprecation Pipeline</h3>
|
|
<span id="index-The-Deprecation-Pipeline"></span>
|
|
|
|
<p>SBCL uses a <em>deprecation pipeline</em> with multiple stages: as time
|
|
goes by, deprecated things move from earlier stages of deprecation to
|
|
later stages before finally being removed. The intention is making users
|
|
aware of necessary changes early but allowing a migration to new
|
|
interfaces at a reasonable pace.
|
|
</p>
|
|
<p>Deprecation proceeds in three stages, each lasting approximately a
|
|
year. In some cases it might move slower or faster, but one year per
|
|
stage is what we aim at in general. During each stage warnings (and
|
|
errors) of increasing severity are signaled, which note that the
|
|
interface is deprecated, and point users towards any replacements when
|
|
applicable.
|
|
</p>
|
|
<ol>
|
|
<li> <strong>Early Deprecation</strong>
|
|
|
|
<p>During early deprecation the interface is kept in working
|
|
condition. However, when a thing in this deprecation stage is used, an
|
|
<span id="index-early_002ddeprecation_002dwarning-_005bsb_002dext_005d"></span>
|
|
<code>sb-ext:early-deprecation-warning</code>, which is a
|
|
<span id="index-style_002dwarning-_005bcl_005d-1"></span>
|
|
<code>style-warning</code>, is signaled at
|
|
compile-time.
|
|
</p>
|
|
<p>The internals may change at this stage: typically because the interface
|
|
is re-implemented on top of its successor. While we try to keep things
|
|
as backwards-compatible as feasible (taking maintenance costs into account),
|
|
sometimes semantics change slightly.
|
|
</p>
|
|
<p>For example, when the spinlock API was deprecated, spinlock objects ceased
|
|
to exist, and the whole spinlock API became a synonym for the mutex
|
|
API – so code using the spinlock API continued working, but silently
|
|
switched to mutexes instead. However, if someone relied on
|
|
</p>
|
|
<p><code>(typep lock 'spinlock)</code>
|
|
</p>
|
|
<p>returning <code>NIL</code> for a mutexes, trouble could ensue.
|
|
</p>
|
|
</li><li> <strong>Late Deprecation</strong>
|
|
|
|
<p>During late deprecation the interface remains as it was during early
|
|
deprecation, but the compile-time warning is upgraded: when a thing in
|
|
this deprecation stage is used, a
|
|
<span id="index-late_002ddeprecation_002dwarning-_005bsb_002dext_005d"></span>
|
|
<code>sb-ext:late-deprecation-warning</code>,
|
|
which is a full
|
|
<span id="index-warning-_005bcl_005d-1"></span>
|
|
<code>warning</code>, is signaled at compile-time.
|
|
</p>
|
|
</li><li> <strong>Final Deprecation</strong>
|
|
|
|
<p>During final deprecation the symbols still exist. However, when a thing
|
|
in this deprecation stage is used, a
|
|
<span id="index-final_002ddeprecation_002dwarning-_005bsb_002dext_005d"></span>
|
|
<code>sb-ext:final-deprecation-warning</code>,
|
|
which is a full
|
|
<span id="index-warning-_005bcl_005d-2"></span>
|
|
<code>warning</code>, is signaled at compile-time and an
|
|
<span id="index-error-_005bcl_005d-1"></span>
|
|
<code>error</code> is signaled at run-time.
|
|
</p>
|
|
</li><li> <strong>After Final Deprecation</strong>
|
|
|
|
<p>The interface is deleted entirely.
|
|
</p>
|
|
</li></ol>
|
|
|
|
<hr>
|
|
<span id="Deprecation-Conditions"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Introspecting-Deprecation-Information" accesskey="n" rel="next">Introspecting Deprecation Information</a>, Previous: <a href="index.html#The-Deprecation-Pipeline" accesskey="p" rel="prev">The Deprecation Pipeline</a>, Up: <a href="index.html#Deprecation" accesskey="u" rel="up">Deprecation</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Deprecation-Conditions-1"></span><h3 class="section">18.3 Deprecation Conditions</h3>
|
|
<span id="index-Deprecation-Conditions"></span>
|
|
|
|
<span id="index-deprecation_002dcondition-_005bsb_002dext_005d"></span>
|
|
<p><code>sb-ext:deprecation-condition</code> is the superclass of all
|
|
deprecation-related warning and error conditions. All common slots and
|
|
readers are defined in this condition class.
|
|
</p>
|
|
<span id="Condition-sb_002dext-deprecation_002dcondition"></span><dl>
|
|
<dt id="index-deprecation_002dcondition">Condition: <strong>deprecation-condition</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">deprecation-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>Superclass for deprecation-related error and warning
|
|
conditions.
|
|
</p></dd></dl>
|
|
|
|
<span id="Condition-sb_002dext-early_002ddeprecation_002dwarning"></span><dl>
|
|
<dt id="index-early_002ddeprecation_002dwarning">Condition: <strong>early-deprecation-warning</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">early-deprecation-warning</span><!-- /@w --></code>, <code><span class="nolinebreak">style-warning</span><!-- /@w --></code>, <code>warning<!-- /@w --></code>, <code><span class="nolinebreak">deprecation-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>This warning is signaled when the use of a variable,
|
|
function, type, etc. in <code>:early</code> deprecation is detected at
|
|
compile-time. The use will work at run-time with no warning or
|
|
error.
|
|
</p></dd></dl>
|
|
|
|
<span id="Condition-sb_002dext-late_002ddeprecation_002dwarning"></span><dl>
|
|
<dt id="index-late_002ddeprecation_002dwarning">Condition: <strong>late-deprecation-warning</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">late-deprecation-warning</span><!-- /@w --></code>, <code>warning<!-- /@w --></code>, <code><span class="nolinebreak">deprecation-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>This warning is signaled when the use of a variable,
|
|
function, type, etc. in <code>:late</code> deprecation is detected at
|
|
compile-time. The use will work at run-time with no warning or
|
|
error.
|
|
</p></dd></dl>
|
|
|
|
<span id="Condition-sb_002dext-final_002ddeprecation_002dwarning"></span><dl>
|
|
<dt id="index-final_002ddeprecation_002dwarning">Condition: <strong>final-deprecation-warning</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">final-deprecation-warning</span><!-- /@w --></code>, <code>warning<!-- /@w --></code>, <code><span class="nolinebreak">deprecation-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>This warning is signaled when the use of a variable,
|
|
function, type, etc. in <code>:final</code> deprecation is detected at
|
|
compile-time. An error will be signaled at run-time.
|
|
</p></dd></dl>
|
|
|
|
<span id="Condition-sb_002dext-deprecation_002derror"></span><dl>
|
|
<dt id="index-deprecation_002derror">Condition: <strong>deprecation-error</strong> <em>[sb-ext]</em></dt>
|
|
<dd><p>Class precedence list: <code><span class="nolinebreak">deprecation-error</span><!-- /@w --></code>, <code>error<!-- /@w --></code>, <code><span class="nolinebreak">serious-condition</span><!-- /@w --></code>, <code><span class="nolinebreak">deprecation-condition</span><!-- /@w --></code>, <code>condition<!-- /@w --></code>, <code>t<!-- /@w --></code>
|
|
</p>
|
|
<p>This error is signaled at run-time when an attempt is made to use
|
|
a thing that is in <code>:final</code> deprecation, i.e. call a function or access
|
|
a variable.
|
|
</p></dd></dl>
|
|
|
|
<hr>
|
|
<span id="Introspecting-Deprecation-Information"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Deprecation-Declaration" accesskey="n" rel="next">Deprecation Declaration</a>, Previous: <a href="index.html#Deprecation-Conditions" accesskey="p" rel="prev">Deprecation Conditions</a>, Up: <a href="index.html#Deprecation" accesskey="u" rel="up">Deprecation</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Introspecting-Deprecation-Information-1"></span><h3 class="section">18.4 Introspecting Deprecation Information</h3>
|
|
<span id="index-Introspecting-Deprecation-Information"></span>
|
|
|
|
<p>The deprecation status of functions and variables can be inspected
|
|
using the <code>sb-cltl2:function-information</code> and
|
|
<code>sb-cltl2:variable-information</code> functions provided by the
|
|
<code>sb-cltl2</code> contributed module.
|
|
</p>
|
|
<hr>
|
|
<span id="Deprecation-Declaration"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Deprecation-Examples" accesskey="n" rel="next">Deprecation Examples</a>, Previous: <a href="index.html#Introspecting-Deprecation-Information" accesskey="p" rel="prev">Introspecting Deprecation Information</a>, Up: <a href="index.html#Deprecation" accesskey="u" rel="up">Deprecation</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Deprecation-Declaration-1"></span><h3 class="section">18.5 Deprecation Declaration</h3>
|
|
<span id="index-Deprecation-Declaration"></span>
|
|
<span id="index-deprecated-_005bsb_002dext_005d"></span>
|
|
|
|
<p>The <code>sb-ext:deprecated</code> declaration can be used to declare objects
|
|
in various namespaces<a id="DOCF11" href="index.html#FOOT11"><sup>11</sup></a> as deprecated.
|
|
</p>
|
|
<dl>
|
|
<dt id="index-deprecated">Declaration: <strong>deprecated</strong> <em>[sb-ext]</em></dt>
|
|
<dd>
|
|
<p>Syntax:
|
|
</p><div class="example">
|
|
<pre class="example"><code>sb-ext:deprecated</code> stage since {object-clause}*
|
|
|
|
stage ::= {:early | :late | :final}
|
|
|
|
since ::= {<var>version</var> | (<var>software</var> <var>version</var>)}
|
|
|
|
object-clause ::= (namespace <var>name</var> [:replacement <var>replacement</var>])
|
|
|
|
namespace ::= {cl:variable | cl:function | cl:type}
|
|
</pre></div>
|
|
|
|
<p>were <var>name</var> is the name of the deprecated thing,
|
|
<var>version</var> and <var>software</var> are strings describing the version in
|
|
which the thing has been deprecated and <var>replacement</var> is a name or a
|
|
list of names designating things that should be used instead of the
|
|
deprecated thing.
|
|
</p>
|
|
<p>Currently the following namespaces are supported:
|
|
</p>
|
|
<dl compact="compact">
|
|
<dt><code>cl:function</code></dt>
|
|
<dd><p>Declare functions, compiler-macros or macros as deprecated.
|
|
</p>
|
|
<blockquote>
|
|
<p><b>note:</b> When declaring a function to be in <code>:final</code> deprecation, there
|
|
should be no actual definition of the function as the declaration emits
|
|
a stub function that signals a
|
|
<span id="index-deprecation_002derror-_005bsb_002dext_005d"></span>
|
|
<code>sb-ext:deprecation-error</code> at run-time when called.
|
|
</p></blockquote>
|
|
|
|
</dd>
|
|
<dt><code>cl:variable</code></dt>
|
|
<dd><p>Declare special and global variables, constants and symbol-macros as
|
|
deprecated.
|
|
</p>
|
|
<blockquote>
|
|
<p><b>note:</b> When declaring a variable to be in <code>:final</code> deprecation, there
|
|
should be no actual definition of the variable as the declaration emits
|
|
a symbol-macro that signals a
|
|
<span id="index-deprecation_002derror-_005bsb_002dext_005d-1"></span>
|
|
<code>sb-ext:deprecation-error</code> at run-time when accessed.
|
|
</p></blockquote>
|
|
|
|
</dd>
|
|
<dt><code>cl:type</code></dt>
|
|
<dd><p>Declare named types (i.e. defined via <code>deftype</code>), standard classes,
|
|
structure classes and condition classes as deprecated.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
</dd></dl>
|
|
|
|
<hr>
|
|
<span id="Deprecation-Examples"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Deprecated-Interfaces-in-SBCL" accesskey="n" rel="next">Deprecated Interfaces in SBCL</a>, Previous: <a href="index.html#Deprecation-Declaration" accesskey="p" rel="prev">Deprecation Declaration</a>, Up: <a href="index.html#Deprecation" accesskey="u" rel="up">Deprecation</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Deprecation-Examples-1"></span><h3 class="section">18.6 Deprecation Examples</h3>
|
|
<span id="index-Deprecation-Examples"></span>
|
|
|
|
<p>Marking functions as deprecated:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(defun foo ())
|
|
(defun bar ())
|
|
(declaim (deprecated :early ("my-system" "1.2.3")
|
|
(function foo :replacement bar)))
|
|
|
|
;; Remember: do not define the actual function or variable in case of
|
|
;; :final deprecation:
|
|
(declaim (deprecated :final ("my-system" "1.2.3")
|
|
(function fez :replacement whoop)))
|
|
</pre></div>
|
|
|
|
<p>Attempting to use the deprecated functions:
|
|
</p><div class="lisp">
|
|
<pre class="lisp">(defun baz ()
|
|
(foo))
|
|
| STYLE-WARNING: The function CL-USER::FOO has been deprecated...
|
|
=> BAZ
|
|
(baz)
|
|
=> NIL ; no error
|
|
|
|
(defun danger ()
|
|
(fez))
|
|
| WARNING: The function CL-USER::FEZ has been deprecated...
|
|
=> DANGER
|
|
(danger)
|
|
|- ERROR: The function CL-USER::FEZ has been deprecated...
|
|
</pre></div>
|
|
|
|
<hr>
|
|
<span id="Deprecated-Interfaces-in-SBCL"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Deprecation-Examples" accesskey="p" rel="prev">Deprecation Examples</a>, Up: <a href="index.html#Deprecation" accesskey="u" rel="up">Deprecation</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Deprecated-Interfaces-in-SBCL-1"></span><h3 class="section">18.7 Deprecated Interfaces in SBCL</h3>
|
|
|
|
<p>This sections lists legacy interfaces in various stages of deprecation.
|
|
</p>
|
|
<span id="List-of-Deprecated-Interfaces"></span><h4 class="subsection">18.7.1 List of Deprecated Interfaces</h4>
|
|
|
|
<span id="Early-Deprecation"></span><h4 class="subsubsection">18.7.1.1 Early Deprecation</h4>
|
|
|
|
<span id="index-early_002ddeprecation_002dwarning-_005bsb_002dext_005d-1"></span>
|
|
|
|
<ul>
|
|
<li> <strong>SOCKINT::WIN32-*</strong>
|
|
|
|
<p>Deprecated in favor of the corresponding prefix-less functions
|
|
(e.g. <code>sockint::bind</code> replaces <code>sockint::win32-bind</code>) as of
|
|
1.2.10 in March 2015. Expected to move into late deprecation in August
|
|
2015.
|
|
</p>
|
|
<br>
|
|
</li><li> <strong>SB-UNIX:UNIX-EXIT</strong>
|
|
|
|
<p>Deprecated as of 1.0.56.55 in May 2012. Expected to move into late
|
|
deprecation in May 2013.
|
|
</p>
|
|
<p>When the SBCL process termination was refactored as part of changes that
|
|
led to <code>sb-ext:quit</code> being deprecated, <code>sb-unix:unix-exit</code>
|
|
ceased to be used internally. Since <code>SB-UNIX</code> is an internal package
|
|
not intended for user code to use, and since we’re slowly in the process
|
|
of refactoring things to be less Unix-oriented, <code>sb-unix:unix-exit</code>
|
|
was initially deleted as it was no longer used. Unfortunately it became
|
|
apparent that it was used by several external users, so it was re-instated
|
|
in deprecated form.
|
|
</p>
|
|
<p>While the cost of keeping <code>sb-unix:unix-exit</code> indefinitely is
|
|
trivial, the ability to refactor our internals is important, so its
|
|
deprecation was taken as an opportunity to highlight that
|
|
<code>SB-UNIX</code> is an internal package and <code>SB-POSIX</code> should be
|
|
used by user-programs instead – or alternatively calling the foreign
|
|
function directly if the desired interface doesn’t for some reason
|
|
exist in <code>SB-POSIX</code>.
|
|
</p>
|
|
<p><strong>Remedy</strong>
|
|
</p>
|
|
<p>For code needing to work with legacy SBCLs, use e.g. <code>system-exit</code>
|
|
as show above in remedies for <code>sb-ext:quit</code>. In modern SBCLs
|
|
simply call either <code>sb-posix:exit</code> or <code>sb-ext:exit</code> with
|
|
appropriate arguments.
|
|
</p>
|
|
<br>
|
|
</li><li> <strong>SB-C::MERGE-TAIL-CALLS Compiler Policy</strong>
|
|
|
|
<p>Deprecated as of 1.0.53.74 in November 2011. Expected to move into
|
|
late deprecation in November 2012.
|
|
</p>
|
|
<p>This compiler policy was never functional: SBCL has always merged tail
|
|
calls when it could, regardless of this policy setting. (It was also
|
|
never officially supported, but several code-bases have historically
|
|
used it.)
|
|
</p>
|
|
<p><strong>Remedy</strong>
|
|
</p>
|
|
<p>Simply remove the policy declarations. They were never necessary: SBCL
|
|
always merged tail-calls when possible. To disable tail merging,
|
|
structure the code to avoid the tail position instead.
|
|
</p>
|
|
<br>
|
|
</li><li> <strong>Spinlock API</strong>
|
|
|
|
<p>Deprecated as of 1.0.53.11 in August 2011. Expected to move into late
|
|
deprecation in August 2012.
|
|
</p>
|
|
<p>Spinlocks were an internal interface, but had a number of external users
|
|
and were hence deprecated instead of being simply deleted.
|
|
</p>
|
|
<p>Affected symbols: <code>sb-thread::spinlock</code>,
|
|
<code>sb-thread::make-spinlock</code>, <code>sb-thread::with-spinlock</code>,
|
|
<code>sb-thread::with-recursive-spinlock</code>,
|
|
<code>sb-thread::get-spinlock</code>, <code>sb-thread::release-spinlock</code>,
|
|
<code>sb-thread::spinlock-value</code>, and <code>sb-thread::spinlock-name</code>.
|
|
</p>
|
|
<p><strong>Remedy</strong>
|
|
</p>
|
|
<p>Use the mutex API instead, or implement spinlocks suiting your needs
|
|
on top of <code>sb-ext:compare-and-swap</code>,
|
|
<code>sb-ext:spin-loop-hint</code>, etc.
|
|
</p>
|
|
</li><li> <strong>SOCKINT::HANDLE->FD</strong>, <strong>SOCKINT::FD->HANDLE</strong>
|
|
|
|
<p>Internally deprecated in 2012. Declared deprecated as of 1.2.10 in March
|
|
2015. Expected to move into final deprecation in August 2015.
|
|
</p>
|
|
</li></ul>
|
|
|
|
<span id="Late-Deprecation"></span><h4 class="subsubsection">18.7.1.2 Late Deprecation</h4>
|
|
|
|
<span id="index-late_002ddeprecation_002dwarning-_005bsb_002dext_005d-1"></span>
|
|
|
|
<ul>
|
|
<li> <strong>SB-THREAD:JOIN-THREAD-ERROR-THREAD and SB-THREAD:INTERRUPT-THREAD-ERROR-THREAD</strong>
|
|
|
|
<p>Deprecated in favor of <code>sb-thread:thread-error-thread</code> as of
|
|
1.0.29.17 in June 2009. Expected to move into final deprecation in
|
|
June 2012.
|
|
</p>
|
|
<p><strong>Remedy</strong>
|
|
</p>
|
|
<p>For code that needs to support legacy SBCLs, use e.g.:
|
|
</p>
|
|
<br>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun get-thread-error-thread (condition)
|
|
#+#.(cl:if (cl:find-symbol "THREAD-ERROR-THREAD" :sb-thread)
|
|
'(and) '(or))
|
|
(sb-thread:thread-error-thread condition)
|
|
#-#.(cl:if (cl:find-symbol "THREAD-ERROR-THREAD" :sb-thread)
|
|
'(and) '(or))
|
|
(etypecase condition
|
|
(sb-thread:join-thread-error
|
|
(sb-thread:join-thread-error-thread condition))
|
|
(sb-thread:interrupt-thread-error
|
|
(sb-thread:interrupt-thread-error-thread condition))))
|
|
</pre></div>
|
|
<br>
|
|
|
|
<br>
|
|
</li><li> <strong>SB-INTROSPECT:FUNCTION-ARGLIST</strong>
|
|
|
|
<p>Deprecated in favor of <code>sb-introspect:function-lambda-list</code> as of
|
|
1.0.24.5 in January 2009. Expected to move into final deprecation in
|
|
January 2012.
|
|
</p>
|
|
<p>Renamed for consistency and aesthetics. Functions have lambda-lists,
|
|
not arglists.
|
|
</p>
|
|
<p><strong>Remedy</strong>
|
|
</p>
|
|
<p>For code that needs to support legacy SBCLs, use e.g.:
|
|
</p>
|
|
<br>
|
|
<div class="lisp">
|
|
<pre class="lisp">(defun get-function-lambda-list (function)
|
|
#+#.(cl:if (cl:find-symbol "FUNCTION-LAMBDA-LIST" :sb-introspect)
|
|
'(and) '(or))
|
|
(sb-introspect:function-lambda-list function)
|
|
#-#.(cl:if (cl:find-symbol "FUNCTION-LAMBDA-LIST" :sb-introspect)
|
|
'(and) '(or))
|
|
(sb-introspect:function-arglist function))
|
|
</pre></div>
|
|
<br>
|
|
|
|
<br>
|
|
</li><li> <strong>Stack Allocation Policies</strong>
|
|
|
|
<p>Deprecated in favor of <code>sb-ext:*stack-allocate-dynamic-extent*</code>
|
|
as of 1.0.19.7 in August 2008, and are expected to be removed in
|
|
August 2012.
|
|
</p>
|
|
<p>Affected symbols: <code>sb-c::stack-allocate-dynamic-extent</code>,
|
|
<code>sb-c::stack-allocate-vector</code>, and
|
|
<code>sb-c::stack-allocate-value-cells</code>.
|
|
</p>
|
|
<p>These compiler policies were never officially supported, and turned
|
|
out the be a flawed design.
|
|
</p>
|
|
<p><strong>Remedy</strong>
|
|
</p>
|
|
<p>For code that needs stack-allocation in legacy SBCLs, conditionalize
|
|
using:
|
|
</p>
|
|
<br>
|
|
<div class="lisp">
|
|
<pre class="lisp">#-#.(cl:if (cl:find-symbol "*STACK-ALLOCATE-DYNAMIC-EXTENT*" :sb-ext)
|
|
'(and) '(or))
|
|
(declare (optimize sb-c::stack-allocate-dynamic-extent))
|
|
</pre></div>
|
|
<br>
|
|
|
|
<p>However, unless stack allocation is essential, we recommend simply
|
|
removing these declarations. Refer to documentation on
|
|
<code>sb-ext:*stack-allocate-dynamic*</code> for details on stack allocation
|
|
control in modern SBCLs.
|
|
</p>
|
|
<br>
|
|
</li><li> <strong>SB-SYS:OUTPUT-RAW-BYTES</strong>
|
|
|
|
<p>Deprecated as of 1.0.8.16 in June 2007. Expected to move into final
|
|
deprecation in June 2012.
|
|
</p>
|
|
<p>Internal interface with some external users. Never officially
|
|
supported, deemed unnecessary in presence of <code>write-sequence</code> and
|
|
bivalent streams.
|
|
</p>
|
|
<p><strong>Remedy</strong>
|
|
</p>
|
|
<p>Use streams with element-type <code>(unsigned-byte 8)</code>
|
|
or <code>:default</code> – the latter allowing both binary and
|
|
character IO – in conjunction with <code>write-sequence</code>.
|
|
</p>
|
|
</li></ul>
|
|
|
|
<span id="Final-Deprecation"></span><h4 class="subsubsection">18.7.1.3 Final Deprecation</h4>
|
|
|
|
<span id="index-final_002ddeprecation_002dwarning-_005bsb_002dext_005d-1"></span>
|
|
|
|
<p>No interfaces are currently in final deprecation.
|
|
</p>
|
|
<span id="Historical-Interfaces"></span><h4 class="subsection">18.7.2 Historical Interfaces</h4>
|
|
|
|
<p>The following is a partial list of interfaces present in historical
|
|
versions of SBCL, which have since then been deleted.
|
|
</p>
|
|
<ul>
|
|
<li> <strong>SB-KERNEL:INSTANCE-LAMBDA</strong>
|
|
|
|
<p>Historically needed for CLOS code. Deprecated as of 0.9.3.32 in August
|
|
2005. Deleted as of 1.0.47.8 in April 2011. Plain <code>lambda</code> can be
|
|
used where <code>sb-kernel:instance-lambda</code> used to be needed.
|
|
</p>
|
|
<br>
|
|
</li><li> <strong>SB-ALIEN:DEF-ALIEN-ROUTINE, SB-ALIEN:DEF-ALIEN-VARIABLE, SB-ALIEN:DEF-ALIEN-TYPE</strong>
|
|
|
|
<p>Inherited from CMUCL, naming convention not consistent with preferred
|
|
SBCL style. Deprecated as of 0.pre7.90 in December 2001. Deleted as of
|
|
1.0.9.17 in September 2007. Replaced by
|
|
<code>sb-alien:define-alien-routine</code>,
|
|
<code>sb-alien:define-alien-variable</code>, and
|
|
<code>sb-alien:define-alien-type</code>.
|
|
</p>
|
|
</li></ul>
|
|
<hr>
|
|
<span id="Concept-Index"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Function-Index" accesskey="n" rel="next">Function Index</a>, Previous: <a href="index.html#Deprecation" accesskey="p" rel="prev">Deprecation</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Concept-Index-1"></span><h2 class="appendix">Appendix A Concept Index</h2>
|
|
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Concept-Index_cp_letter-A"><b>A</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-B"><b>B</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-C"><b>C</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-D"><b>D</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-E"><b>E</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-F"><b>F</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-G"><b>G</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-H"><b>H</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-I"><b>I</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-L"><b>L</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-M"><b>M</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-N"><b>N</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-O"><b>O</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-P"><b>P</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-Q"><b>Q</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-R"><b>R</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-S"><b>S</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-T"><b>T</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-U"><b>U</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-V"><b>V</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-W"><b>W</b></a>
|
|
|
|
</td></tr></table>
|
|
<table class="index-cp" border="0">
|
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-A">A</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Actual-Source">Actual Source</a>:</td><td> </td><td valign="top"><a href="index.html#The-Parts-of-a-Compiler-Diagnostic">The Parts of a Compiler Diagnostic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Actual-Source-1">Actual Source</a>:</td><td> </td><td valign="top"><a href="index.html#The-Original-and-Actual-Source">The Original and Actual Source</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Arithmetic_002c-hardware">Arithmetic, hardware</a>:</td><td> </td><td valign="top"><a href="index.html#Modular-arithmetic">Modular arithmetic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Arithmetic_002c-hardware-1">Arithmetic, hardware</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002drotate_002dbyte">sb-rotate-byte</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Arithmetic_002c-modular">Arithmetic, modular</a>:</td><td> </td><td valign="top"><a href="index.html#Modular-arithmetic">Modular arithmetic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Arithmetic_002c-modular-1">Arithmetic, modular</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002drotate_002dbyte">sb-rotate-byte</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Asynchronous-Timeout">Asynchronous Timeout</a>:</td><td> </td><td valign="top"><a href="index.html#Asynchronous-Timeouts">Asynchronous Timeouts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Availability-of-debug-variables">Availability of debug variables</a>:</td><td> </td><td valign="top"><a href="index.html#Variable-Value-Availability">Variable Value Availability</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-B">B</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Block-compilation_002c-debugger-implications">Block compilation, debugger implications</a>:</td><td> </td><td valign="top"><a href="index.html#Entry-Point-Details">Entry Point Details</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Block_002c-basic">Block, basic</a>:</td><td> </td><td valign="top"><a href="index.html#Source-Location-Availability">Source Location Availability</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Block_002c-start-location">Block, start location</a>:</td><td> </td><td valign="top"><a href="index.html#Source-Location-Availability">Source Location Availability</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-C">C</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Character-Coding-Conditions">Character Coding Conditions</a>:</td><td> </td><td valign="top"><a href="index.html#Character-Coding-Conditions">Character Coding Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Character-Names">Character Names</a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Cleanup_002c-stack-frame-kind">Cleanup, stack frame kind</a>:</td><td> </td><td valign="top"><a href="index.html#Entry-Point-Details">Entry Point Details</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Code-Coverage">Code Coverage</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Compatibility-with-other-Lisps">Compatibility with other Lisps</a>:</td><td> </td><td valign="top"><a href="index.html#Getting-Existing-Programs-to-Run">Getting Existing Programs to Run</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Compile-time-type-errors">Compile time type errors</a>:</td><td> </td><td valign="top"><a href="index.html#Type-Errors-at-Compile-Time">Type Errors at Compile Time</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Compiler-Diagnostic-Severity">Compiler Diagnostic Severity</a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Compiler-messages">Compiler messages</a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Messages">Diagnostic Messages</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Concurrency">Concurrency</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Converting-between-Strings-and-Octet-Vectors">Converting between Strings and Octet Vectors</a>:</td><td> </td><td valign="top"><a href="index.html#Converting-between-Strings-and-Octet-Vectors">Converting between Strings and Octet Vectors</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-D">D</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Deadline">Deadline</a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Debug-optimization-quality">Debug optimization quality</a>:</td><td> </td><td valign="top"><a href="index.html#Variable-Value-Availability">Variable Value Availability</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Debug-optimization-quality-1">Debug optimization quality</a>:</td><td> </td><td valign="top"><a href="index.html#Source-Location-Availability">Source Location Availability</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Debug-optimization-quality-2">Debug optimization quality</a>:</td><td> </td><td valign="top"><a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Debug-variables">Debug variables</a>:</td><td> </td><td valign="top"><a href="index.html#Variable-Access">Variable Access</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Debugger">Debugger</a>:</td><td> </td><td valign="top"><a href="index.html#Debugger">Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-debugger_002c-disabling">debugger, disabling</a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-debugger_002c-enabling">debugger, enabling</a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Decimal-Syntax-for-Rationals">Decimal Syntax for Rationals</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-declaration_002c-dynamic_002dextent">declaration, <code>dynamic-extent</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Declaration_002c-freeze_002dtype">Declaration, <code>freeze-type</code></a>:</td><td> </td><td valign="top"><a href="index.html#Efficiency-Hacks">Efficiency Hacks</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Declarations">Declarations</a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Deprecation-Conditions">Deprecation Conditions</a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Conditions">Deprecation Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Deprecation-Declaration">Deprecation Declaration</a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Declaration">Deprecation Declaration</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Deprecation-Examples">Deprecation Examples</a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Examples">Deprecation Examples</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-disabling-debugger">disabling debugger</a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-disabling-ldb">disabling ldb</a>:</td><td> </td><td valign="top"><a href="index.html#Runtime-Options">Runtime Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-disabling-ldb-1">disabling ldb</a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-dynamic_002dextent-declaration"><code>dynamic-extent</code> declaration</a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-E">E</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Efficiency">Efficiency</a>:</td><td> </td><td valign="top"><a href="index.html#Efficiency">Efficiency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Entry-points_002c-external">Entry points, external</a>:</td><td> </td><td valign="top"><a href="index.html#Entry-Point-Details">Entry Point Details</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Errors_002c-run_002dtime">Errors, run-time</a>:</td><td> </td><td valign="top"><a href="index.html#Unknown-Locations-and-Interrupts">Unknown Locations and Interrupts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Existing-programs_002c-to-run">Existing programs, to run</a>:</td><td> </td><td valign="top"><a href="index.html#Getting-Existing-Programs-to-Run">Getting Existing Programs to Run</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Extended-Package-Prefix-Syntax">Extended Package Prefix Syntax</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-External-entry-points">External entry points</a>:</td><td> </td><td valign="top"><a href="index.html#Entry-Point-Details">Entry Point Details</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-External-Format-Designators">External Format Designators</a>:</td><td> </td><td valign="top"><a href="index.html#External-Format-Designators">External Format Designators</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-External-formats">External formats</a>:</td><td> </td><td valign="top"><a href="index.html#Foreign-Type-Specifiers">Foreign Type Specifiers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-External_002c-stack-frame-kind">External, stack frame kind</a>:</td><td> </td><td valign="top"><a href="index.html#Entry-Point-Details">Entry Point Details</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-F">F</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Fast-Read-Lock">Fast Read Lock</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Finalization">Finalization</a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Foreign-Function-Interface_002c-generation">Foreign Function Interface, generation</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dgrovel">sb-grovel</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-freeze_002dtype-declaration"><code>freeze-type</code> declaration</a>:</td><td> </td><td valign="top"><a href="index.html#Efficiency-Hacks">Efficiency Hacks</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Frlock">Frlock</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Function_002c-tracing">Function, tracing</a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-G">G</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Garbage-collection">Garbage collection</a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Garbage-Collection_002c-conservative">Garbage Collection, conservative</a>:</td><td> </td><td valign="top"><a href="index.html#History-and-Implementation-of-SBCL">History and Implementation of SBCL</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Garbage-Collection_002c-generational">Garbage Collection, generational</a>:</td><td> </td><td valign="top"><a href="index.html#History-and-Implementation-of-SBCL">History and Implementation of SBCL</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Gate">Gate</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-H">H</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Hash-tables">Hash tables</a>:</td><td> </td><td valign="top"><a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Hashing_002c-cryptographic">Hashing, cryptographic</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dmd5">sb-md5</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-I">I</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Inline-expansion">Inline expansion</a>:</td><td> </td><td valign="top"><a href="index.html#Open-Coding-and-Inline-Expansion">Open Coding and Inline Expansion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Inline-expansion-1">Inline expansion</a>:</td><td> </td><td valign="top"><a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Interning-Symbols">Interning Symbols</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Interpreter">Interpreter</a>:</td><td> </td><td valign="top"><a href="index.html#Interpreter">Interpreter</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Interrupts">Interrupts</a>:</td><td> </td><td valign="top"><a href="index.html#Unknown-Locations-and-Interrupts">Unknown Locations and Interrupts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Introspecting-Deprecation-Information">Introspecting Deprecation Information</a>:</td><td> </td><td valign="top"><a href="index.html#Introspecting-Deprecation-Information">Introspecting Deprecation Information</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-L">L</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ldb">ldb</a>:</td><td> </td><td valign="top"><a href="index.html#Reporting-Bugs">Reporting Bugs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ldb-1">ldb</a>:</td><td> </td><td valign="top"><a href="index.html#Runtime-Options">Runtime Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ldb-2">ldb</a>:</td><td> </td><td valign="top"><a href="index.html#Runtime-Options">Runtime Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ldb_002c-disabling">ldb, disabling</a>:</td><td> </td><td valign="top"><a href="index.html#Runtime-Options">Runtime Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ldb_002c-disabling-1">ldb, disabling</a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ldb_002c-enabling">ldb, enabling</a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Locations_002c-unknown">Locations, unknown</a>:</td><td> </td><td valign="top"><a href="index.html#Unknown-Locations-and-Interrupts">Unknown Locations and Interrupts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Logical-pathnames">Logical pathnames</a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-Pathnames">Lisp Pathnames</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-M">M</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Macroexpansion">Macroexpansion</a>:</td><td> </td><td valign="top"><a href="index.html#The-Processing-Path">The Processing Path</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Macroexpansion_002c-errors-during">Macroexpansion, errors during</a>:</td><td> </td><td valign="top"><a href="index.html#Errors-During-Macroexpansion">Errors During Macroexpansion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Mailbox_002c-lock_002dfree">Mailbox, lock-free</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Messages_002c-Compiler">Messages, Compiler</a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Messages">Diagnostic Messages</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Modular-arithmetic">Modular arithmetic</a>:</td><td> </td><td valign="top"><a href="index.html#Modular-arithmetic">Modular arithmetic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Modular-arithmetic-1">Modular arithmetic</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002drotate_002dbyte">sb-rotate-byte</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-N">N</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Name_002c-of-character">Name, of character</a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-NFKC">NFKC</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Nicknames_002c-Package_002dlocal">Nicknames, Package-local</a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Normalization_002c-String">Normalization, String</a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Normalization_002c-Symbol-Name">Normalization, Symbol Name</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-O">O</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Open_002dcoding">Open-coding</a>:</td><td> </td><td valign="top"><a href="index.html#Open-Coding-and-Inline-Expansion">Open Coding and Inline Expansion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Operating-System-Interface">Operating System Interface</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dposix">sb-posix</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-optimization-quality_002c-safety">optimization quality, <code>safety</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Optimize-declaration">Optimize declaration</a>:</td><td> </td><td valign="top"><a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Optional_002c-stack-frame-kind">Optional, stack frame kind</a>:</td><td> </td><td valign="top"><a href="index.html#Entry-Point-Details">Entry Point Details</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Original-Source">Original Source</a>:</td><td> </td><td valign="top"><a href="index.html#The-Parts-of-a-Compiler-Diagnostic">The Parts of a Compiler Diagnostic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Original-Source-1">Original Source</a>:</td><td> </td><td valign="top"><a href="index.html#The-Original-and-Actual-Source">The Original and Actual Source</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-P">P</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Package-Locks">Package Locks</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Package-Prefix-Syntax_002c-extended">Package Prefix Syntax, extended</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Package_002dLocal-Nicknames">Package-Local Nicknames</a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Packages_002c-locked">Packages, locked</a>:</td><td> </td><td valign="top"><a href="index.html#Package-Locks">Package Locks</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Pathnames">Pathnames</a>:</td><td> </td><td valign="top"><a href="index.html#Pathnames">Pathnames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Pathnames_002c-logical">Pathnames, logical</a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-Pathnames">Lisp Pathnames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Policy_002c-debugger">Policy, debugger</a>:</td><td> </td><td valign="top"><a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Posix">Posix</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dposix">sb-posix</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Precise-type-checking">Precise type checking</a>:</td><td> </td><td valign="top"><a href="index.html#Precise-Type-Checking">Precise Type Checking</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Processing-Path">Processing Path</a>:</td><td> </td><td valign="top"><a href="index.html#The-Parts-of-a-Compiler-Diagnostic">The Parts of a Compiler Diagnostic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Processing-Path-1">Processing Path</a>:</td><td> </td><td valign="top"><a href="index.html#The-Processing-Path">The Processing Path</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Profiling">Profiling</a>:</td><td> </td><td valign="top"><a href="index.html#Profiling">Profiling</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Profiling_002c-deterministic">Profiling, deterministic</a>:</td><td> </td><td valign="top"><a href="index.html#Deterministic-Profiler">Deterministic Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Profiling_002c-statistical">Profiling, statistical</a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-Q">Q</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Queue_002c-FIFO">Queue, FIFO</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dqueue">sb-queue</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Queue_002c-lock_002dfree">Queue, lock-free</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-R">R</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Random-Number-Generation">Random Number Generation</a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Rational_002c-decimal-syntax-for">Rational, decimal syntax for</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Read-errors_002c-compiler">Read errors, compiler</a>:</td><td> </td><td valign="top"><a href="index.html#Read-Errors">Read Errors</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Read_002dEval_002dPrint-Loop">Read-Eval-Print Loop</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002daclrepl">sb-aclrepl</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Reader-Extensions">Reader Extensions</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Recursion_002c-tail">Recursion, tail</a>:</td><td> </td><td valign="top"><a href="index.html#Debug-Tail-Recursion">Debug Tail Recursion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-REPL">REPL</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002daclrepl">sb-aclrepl</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-S">S</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Safety-optimization-quality">Safety optimization quality</a>:</td><td> </td><td valign="top"><a href="index.html#Declarations-as-Assertions">Declarations as Assertions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Safety-optimization-quality-1">Safety optimization quality</a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-safety-optimization-quality"><code>safety</code> optimization quality</a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Sb_002dconcurrency">Sb-concurrency</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Semi_002dinline-expansion">Semi-inline expansion</a>:</td><td> </td><td valign="top"><a href="index.html#Debugger-Policy-Control">Debugger Policy Control</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Severity-of-compiler-messages">Severity of compiler messages</a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-SIMD">SIMD</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dsimd">sb-simd</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Single-Stepping">Single Stepping</a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Slot-access">Slot access</a>:</td><td> </td><td valign="top"><a href="index.html#Slot-access">Slot access</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Sockets_002c-Networking">Sockets, Networking</a>:</td><td> </td><td valign="top"><a href="index.html#Networking">Networking</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Source-location-printing_002c-debugger">Source location printing, debugger</a>:</td><td> </td><td valign="top"><a href="index.html#Source-Location-Printing">Source Location Printing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Source_002dto_002dsource-transformation">Source-to-source transformation</a>:</td><td> </td><td valign="top"><a href="index.html#The-Processing-Path">The Processing Path</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Stack-frames">Stack frames</a>:</td><td> </td><td valign="top"><a href="index.html#Stack-Frames">Stack Frames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Static-functions">Static functions</a>:</td><td> </td><td valign="top"><a href="index.html#Open-Coding-and-Inline-Expansion">Open Coding and Inline Expansion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Stepper">Stepper</a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Stream-External-formats">Stream External formats</a>:</td><td> </td><td valign="top"><a href="index.html#Stream-External-Formats">Stream External Formats</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Supported-External-Formats">Supported External Formats</a>:</td><td> </td><td valign="top"><a href="index.html#Supported-External-Formats">Supported External Formats</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Symbol-Name-Normalization">Symbol Name Normalization</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Symbols_002c-interning">Symbols, interning</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Synchronous-Timeout">Synchronous Timeout</a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-System-Calls">System Calls</a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dposix">sb-posix</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-T">T</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Tail-recursion">Tail recursion</a>:</td><td> </td><td valign="top"><a href="index.html#Debug-Tail-Recursion">Debug Tail Recursion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-The-Default-External-Format">The Default External Format</a>:</td><td> </td><td valign="top"><a href="index.html#The-Default-External-Format">The Default External Format</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-The-Deprecation-Pipeline">The Deprecation Pipeline</a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Timeout">Timeout</a>:</td><td> </td><td valign="top"><a href="index.html#Timeout-Parameters">Timeout Parameters</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Timeout-1">Timeout</a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Timeout-2">Timeout</a>:</td><td> </td><td valign="top"><a href="index.html#Asynchronous-Timeouts">Asynchronous Timeouts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Tracing">Tracing</a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Type-checking_002c-at-compile-time">Type checking, at compile time</a>:</td><td> </td><td valign="top"><a href="index.html#Type-Errors-at-Compile-Time">Type Errors at Compile Time</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Type-checking_002c-precise">Type checking, precise</a>:</td><td> </td><td valign="top"><a href="index.html#Precise-Type-Checking">Precise Type Checking</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Types_002c-portability">Types, portability</a>:</td><td> </td><td valign="top"><a href="index.html#Getting-Existing-Programs-to-Run">Getting Existing Programs to Run</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-U">U</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Unicode">Unicode</a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Unicode-1">Unicode</a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Unknown-code-locations">Unknown code locations</a>:</td><td> </td><td valign="top"><a href="index.html#Unknown-Locations-and-Interrupts">Unknown Locations and Interrupts</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-V">V</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Validity-of-debug-variables">Validity of debug variables</a>:</td><td> </td><td valign="top"><a href="index.html#Variable-Value-Availability">Variable Value Availability</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Variables_002c-debugger-access">Variables, debugger access</a>:</td><td> </td><td valign="top"><a href="index.html#Variable-Access">Variable Access</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Concept-Index_cp_letter-W">W</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Weak-pointers">Weak pointers</a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-Why-Deprecate_003f">Why Deprecate?</a>:</td><td> </td><td valign="top"><a href="index.html#Why-Deprecate_003f">Why Deprecate?</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
</table>
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Concept-Index_cp_letter-A"><b>A</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-B"><b>B</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-C"><b>C</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-D"><b>D</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-E"><b>E</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-F"><b>F</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-G"><b>G</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-H"><b>H</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-I"><b>I</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-L"><b>L</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-M"><b>M</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-N"><b>N</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-O"><b>O</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-P"><b>P</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-Q"><b>Q</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-R"><b>R</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-S"><b>S</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-T"><b>T</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-U"><b>U</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-V"><b>V</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Concept-Index_cp_letter-W"><b>W</b></a>
|
|
|
|
</td></tr></table>
|
|
|
|
<hr>
|
|
<span id="Function-Index"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Variable-Index" accesskey="n" rel="next">Variable Index</a>, Previous: <a href="index.html#Concept-Index" accesskey="p" rel="prev">Concept Index</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Function-Index-1"></span><h2 class="appendix">Appendix B Function Index</h2>
|
|
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Function-Index_fn_symbol-1"><b>(</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_symbol-2"><b>?</b></a>
|
|
|
|
<br>
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-A"><b>A</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-B"><b>B</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-C"><b>C</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-D"><b>D</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-E"><b>E</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-F"><b>F</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-G"><b>G</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-H"><b>H</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-I"><b>I</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-J"><b>J</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-L"><b>L</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-M"><b>M</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-N"><b>N</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-O"><b>O</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-P"><b>P</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-Q"><b>Q</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-R"><b>R</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-S"><b>S</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-T"><b>T</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-U"><b>U</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-V"><b>V</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-W"><b>W</b></a>
|
|
|
|
</td></tr></table>
|
|
<table class="index-fn" border="0">
|
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_symbol-1">(</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_0028setf"><code>(setf</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_0028setf-1"><code>(setf</code></a>:</td><td> </td><td valign="top"><a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_0028setf-logical_002dpathname_002dtranslations-_005bcl_005d_0029"><code>(setf logical-pathname-translations [cl])</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-Pathnames">Lisp Pathnames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_0028setf-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d_0029"><code>(setf slot-value-using-class [sb-mop])</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_0028setf-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d_0029-1"><code>(setf slot-value-using-class [sb-mop])</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_symbol-2">?</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_003f"><code>?</code></a>:</td><td> </td><td valign="top"><a href="index.html#Information-Commands">Information Commands</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-A">A</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-abort"><code>abort</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exiting-Commands">Exiting Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-abort_002dthread"><code>abort-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-add_002dimplementation_002dpackage"><code>add-implementation-package</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-add_002dpackage_002dlocal_002dnickname"><code>add-package-local-nickname</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-addr"><code>addr</code></a>:</td><td> </td><td valign="top"><a href="index.html#Coercing-Foreign-Values">Coercing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-adjust_002dsequence"><code>adjust-sequence</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-adjust_002dsequence-_005bsb_002dsequence_005d"><code>adjust-sequence [sb-sequence]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-age"><code>age</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-alien_002dcallable_002dfunction"><code>alien-callable-function</code></a>:</td><td> </td><td valign="top"><a href="index.html#Calling-Lisp-From-C">Calling Lisp From C</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-alien_002dfuncall"><code>alien-funcall</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-alien_002dfuncall-Primitive">The alien-funcall Primitive</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-alien_002dsap"><code>alien-sap</code></a>:</td><td> </td><td valign="top"><a href="index.html#Coercing-Foreign-Values">Coercing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-alphabetic_002dp"><code>alphabetic-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-always_002dbound"><code>always-bound</code></a>:</td><td> </td><td valign="top"><a href="index.html#Global-and-Always_002dBound-variables">Global and Always-Bound variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-apropos-_005bcl_005d"><code>apropos [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Why-Deprecate_003f">Why Deprecate?</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-array_002dstorage_002dvector"><code>array-storage-vector</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Extensions">Miscellaneous Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-assert_002dversion_002d_003e_003d"><code>assert-version->=</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Extensions">Miscellaneous Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-atomic_002ddecf"><code>atomic-decf</code></a>:</td><td> </td><td valign="top"><a href="index.html#Atomic-Operations">Atomic Operations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-atomic_002dincf"><code>atomic-incf</code></a>:</td><td> </td><td valign="top"><a href="index.html#Atomic-Operations">Atomic Operations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-atomic_002dpop"><code>atomic-pop</code></a>:</td><td> </td><td valign="top"><a href="index.html#Atomic-Operations">Atomic Operations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-atomic_002dpush"><code>atomic-push</code></a>:</td><td> </td><td valign="top"><a href="index.html#Atomic-Operations">Atomic Operations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-atomic_002dupdate"><code>atomic-update</code></a>:</td><td> </td><td valign="top"><a href="index.html#Atomic-Operations">Atomic Operations</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-B">B</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-backtrace"><code>backtrace</code></a>:</td><td> </td><td valign="top"><a href="index.html#Information-Commands">Information Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-barrier"><code>barrier</code></a>:</td><td> </td><td valign="top"><a href="index.html#Barriers">Barriers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-bidi_002dclass"><code>bidi-class</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-bidi_002dmirroring_002dglyph"><code>bidi-mirroring-glyph</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-both_002dcase_002dp-_005bcl_005d"><code>both-case-p [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-bottom"><code>bottom</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stack-Motion">Stack Motion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-bytes_002dconsed_002dbetween_002dgcs"><code>bytes-consed-between-gcs</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-C">C</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-cancel_002dfinalization"><code>cancel-finalization</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-cas"><code>cas</code></a>:</td><td> </td><td valign="top"><a href="index.html#Atomic-Operations">Atomic Operations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-case_002dignorable_002dp"><code>case-ignorable-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-cased_002dp"><code>cased-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-casefold"><code>casefold</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-cast"><code>cast</code></a>:</td><td> </td><td valign="top"><a href="index.html#Coercing-Foreign-Values">Coercing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-change_002dclass-_005bcl_005d"><code>change-class [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-char_002dblock"><code>char-block</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-char_002ddowncase-_005bcl_005d"><code>char-downcase [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-char_002dname-_005bcl_005d"><code>char-name [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-class_002dname-_005bcl_005d"><code>class-name [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-class_002dof-_005bcl_005d"><code>class-of [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-class_002dprototype-_005bsb_002dmop_005d"><code>class-prototype [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-clear_002dcoverage"><code>clear-coverage</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-clear_002dsemaphore_002dnotification"><code>clear-semaphore-notification</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-close"><code>close</code></a>:</td><td> </td><td valign="top"><a href="index.html#Methods-common-to-all-streams">Methods common to all streams</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-close_002dgate"><code>close-gate</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-coerce-_005bcl_005d"><code>coerce [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-combining_002dclass"><code>combining-class</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-compare_002dand_002dswap"><code>compare-and-swap</code></a>:</td><td> </td><td valign="top"><a href="index.html#Atomic-Operations">Atomic Operations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-compute_002deffective_002dmethod-_005bsb_002dmop_005d"><code>compute-effective-method [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-concatenate"><code>concatenate</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-condition_002dbroadcast"><code>condition-broadcast</code></a>:</td><td> </td><td valign="top"><a href="index.html#Waitqueue_002fcondition-variables">Waitqueue/condition variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-condition_002dnotify"><code>condition-notify</code></a>:</td><td> </td><td valign="top"><a href="index.html#Waitqueue_002fcondition-variables">Waitqueue/condition variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-condition_002dwait"><code>condition-wait</code></a>:</td><td> </td><td valign="top"><a href="index.html#Waitqueue_002fcondition-variables">Waitqueue/condition variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-confusable_002dp"><code>confusable-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-cons-_005bcl_005d"><code>cons [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-continue"><code>continue</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exiting-Commands">Exiting Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-copy-function"><code><code>copy function</code></code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-copy_002dseq-_005bcl_005d"><code>copy-seq [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-D">D</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-decimal_002dvalue"><code>decimal-value</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-declare-_005bcl_005d"><code>declare [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-default_002dignorable_002dp"><code>default-ignorable-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defclass-_005bcl_005d"><code>defclass [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defclass-_005bcl_005d-1"><code>defclass [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defclass-_005bcl_005d-2"><code>defclass [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defconstant-_005bcl_005d"><code>defconstant [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Defining-Constants">Defining Constants</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defglobal"><code>defglobal</code></a>:</td><td> </td><td valign="top"><a href="index.html#Global-and-Always_002dBound-variables">Global and Always-Bound variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-define_002dalien_002dcallable"><code>define-alien-callable</code></a>:</td><td> </td><td valign="top"><a href="index.html#Calling-Lisp-From-C">Calling Lisp From C</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-define_002dalien_002droutine"><code>define-alien-routine</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-define_002dalien_002droutine-Macro">The define-alien-routine Macro</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-define_002dalien_002dvariable"><code>define-alien-variable</code></a>:</td><td> </td><td valign="top"><a href="index.html#External-Foreign-Variables">External Foreign Variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-define_002dhash_002dtable_002dtest"><code>define-hash-table-test</code></a>:</td><td> </td><td valign="top"><a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defmethod-_005bcl_005d"><code>defmethod [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defpackage"><code>defpackage</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defpackage-1"><code>defpackage</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defpackage-_005bcl_005d"><code>defpackage [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defpackage-_005bcl_005d-1"><code>defpackage [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Implementation-Packages">Implementation Packages</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-defstruct-_005bcl_005d"><code>defstruct [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-delete_002ddirectory"><code>delete-directory</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Extensions">Miscellaneous Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deprecated"><code>deprecated</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Declaration">Deprecation Declaration</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deprecated-_005bsb_002dext_005d"><code>deprecated [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Declaration">Deprecation Declaration</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-dequeue"><code>dequeue</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deref"><code>deref</code></a>:</td><td> </td><td valign="top"><a href="index.html#Accessing-Foreign-Values">Accessing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-describe"><code>describe</code></a>:</td><td> </td><td valign="top"><a href="index.html#Information-Commands">Information Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-describe_002dcompiler_002dpolicy"><code>describe-compiler-policy</code></a>:</td><td> </td><td valign="top"><a href="index.html#Compiler-Policy">Compiler Policy</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-digit_002dvalue"><code>digit-value</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-disable_002ddebugger"><code>disable-debugger</code></a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-disable_002dpackage_002dlocks"><code>disable-package-locks</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-disable_002dpackage_002dlocks-_005bsb_002dext_005d"><code>disable-package-locks [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-dolist-_005bcl_005d"><code>dolist [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-dosequence"><code>dosequence</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-down"><code>down</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stack-Motion">Stack Motion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-dynamic_002dspace_002dsize"><code>dynamic-space-size</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-E">E</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-east_002dasian_002dwidth"><code>east-asian-width</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ed"><code>ed</code></a>:</td><td> </td><td valign="top"><a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-element-function"><code><code>element function</code></code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-elt"><code>elt</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-emptyp"><code>emptyp</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-enable_002ddebugger"><code>enable-debugger</code></a>:</td><td> </td><td valign="top"><a href="index.html#Enabling-and-Disabling-the-Debugger">Enabling and Disabling the Debugger</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-enable_002dpackage_002dlocks"><code>enable-package-locks</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-enable_002dpackage_002dlocks-_005bsb_002dext_005d"><code>enable-package-locks [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-endp-function"><code><code>endp function</code></code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-enqueue"><code>enqueue</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ensure_002dclass-_005bsb_002dmop_005d"><code>ensure-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ensure_002dclass-_005bsb_002dmop_005d-1"><code>ensure-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ensure_002dclass_002dusing_002dclass-_005bsb_002dmop_005d"><code>ensure-class-using-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ensure_002dclass_002dusing_002dclass-_005bsb_002dmop_005d-1"><code>ensure-class-using-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ensure_002dgeneric_002dfunction-_005bcl_005d"><code>ensure-generic-function [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-error"><code>error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Information-Commands">Information Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-eval-_005bcl_005d"><code>eval [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Interpreter">Interpreter</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-exit"><code>exit</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exit">Exit</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-expt-_005bcl_005d"><code>expt [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-extern_002dalien"><code>extern-alien</code></a>:</td><td> </td><td valign="top"><a href="index.html#External-Foreign-Variables">External Foreign Variables</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-F">F</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-file_002ddescriptor"><code>file-descriptor</code></a>:</td><td> </td><td valign="top"><a href="index.html#File_002ddescriptors">File-descriptors</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-filename"><code>filename</code></a>:</td><td> </td><td valign="top"><a href="index.html#Filenames">Filenames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-finalize"><code>finalize</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-finalize_002dinheritance-_005bsb_002dmop_005d"><code>finalize-inheritance [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-find-_005bcl_005d"><code>find [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-find_002dclass-_005bcl_005d"><code>find-class [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-find_002dclass-_005bcl_005d-1"><code>find-class [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-find_002dmethod-_005bcl_005d"><code>find-method [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-find_002dpackage-_005bcl_005d"><code>find-package [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-find_002dsymbol-_005bcl_005d"><code>find-symbol [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-flet-_005bcl_005d"><code>flet [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-flet-_005bcl_005d-1"><code>flet [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-float_002ddenormalized_002dp-_005bsb_002dext_005d"><code>float-denormalized-p [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stale-Extensions">Stale Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-frame"><code>frame</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stack-Motion">Stack Motion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-free_002dalien"><code>free-alien</code></a>:</td><td> </td><td valign="top"><a href="index.html#Foreign-Dynamic-Allocation">Foreign Dynamic Allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-frlock_002dname"><code>frlock-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-frlock_002dread"><code>frlock-read</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-frlock_002dread_002dbegin"><code>frlock-read-begin</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-frlock_002dread_002dend"><code>frlock-read-end</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-frlock_002dwrite"><code>frlock-write</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-funcallable_002dstandard_002dinstance_002daccess-_005bsb_002dmop_005d"><code>funcallable-standard-instance-access [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-G">G</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-gate_002dname"><code>gate-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-gate_002dopen_002dp"><code>gate-open-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-gatep"><code>gatep</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-gc"><code>gc</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-gc_002dlogfile"><code>gc-logfile</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-general_002dcategory"><code>general-category</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generation_002daverage_002dage"><code>generation-average-age</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generation_002dbytes_002dallocated"><code>generation-bytes-allocated</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generation_002dbytes_002dconsed_002dbetween_002dgcs"><code>generation-bytes-consed-between-gcs</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generation_002dminimum_002dage_002dbefore_002dgc"><code>generation-minimum-age-before-gc</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generation_002dnumber_002dof_002dgcs"><code>generation-number-of-gcs</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generation_002dnumber_002dof_002dgcs_002dbefore_002dpromotion"><code>generation-number-of-gcs-before-promotion</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generic_002dfunction_002ddeclarations-_005bsb_002dmop_005d"><code>generic-function-declarations [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-get_002dbytes_002dconsed"><code>get-bytes-consed</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-get_002derrno"><code>get-errno</code></a>:</td><td> </td><td valign="top"><a href="index.html#External-Foreign-Variables">External Foreign Variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-get_002dhost_002dby_002daddress"><code>get-host-by-address</code></a>:</td><td> </td><td valign="top"><a href="index.html#Name-Service">Name Service</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-get_002dhost_002dby_002dname"><code>get-host-by-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#Name-Service">Name Service</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-get_002dprotocol_002dby_002dname"><code>get-protocol-by-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#INET-Domain-Sockets">INET Domain Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-get_002dtime_002dof_002dday"><code>get-time-of-day</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Extensions">Miscellaneous Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-getcwd"><code>getcwd</code></a>:</td><td> </td><td valign="top"><a href="index.html#Functions-with-idiosyncratic-bindings">Functions with idiosyncratic bindings</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-global"><code>global</code></a>:</td><td> </td><td valign="top"><a href="index.html#Global-and-Always_002dBound-variables">Global and Always-Bound variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-grab_002dfrlock_002dwrite_002dlock"><code>grab-frlock-write-lock</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-grab_002dmutex"><code>grab-mutex</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-grapheme_002dbreak_002dclass"><code>grapheme-break-class</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-graphemes"><code>graphemes</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-H">H</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-hangul_002dsyllable_002dtype"><code>hangul-syllable-type</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-hash_002dtable_002dsynchronized_002dp"><code>hash-table-synchronized-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-hash_002dtable_002dweakness"><code>hash-table-weakness</code></a>:</td><td> </td><td valign="top"><a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-help"><code>help</code></a>:</td><td> </td><td valign="top"><a href="index.html#Information-Commands">Information Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-hex_002ddigit_002dp"><code>hex-digit-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-host_002dent_002daddress"><code>host-ent-address</code></a>:</td><td> </td><td valign="top"><a href="index.html#Name-Service">Name Service</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-I">I</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-ideographic_002dp"><code>ideographic-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-index-function"><code><code>index function</code></code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-inspect-_005bcl_005d"><code>inspect [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Tools-To-Help-Developers">Tools To Help Developers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-int_002dsap"><code>int-sap</code></a>:</td><td> </td><td valign="top"><a href="index.html#Accessing-Foreign-Values">Accessing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-intern-_005bcl_005d"><code>intern [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-intern-_005bcl_005d-1"><code>intern [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-intern_002deql_002dspecializer-_005bsb_002dmop_005d"><code>intern-eql-specializer [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-interrupt_002dthread"><code>interrupt-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-iterator_002dcopy"><code>iterator-copy</code></a>:</td><td> </td><td valign="top"><a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-iterator_002delement"><code>iterator-element</code></a>:</td><td> </td><td valign="top"><a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-iterator_002dendp"><code>iterator-endp</code></a>:</td><td> </td><td valign="top"><a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-iterator_002dindex"><code>iterator-index</code></a>:</td><td> </td><td valign="top"><a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-iterator_002dstep"><code>iterator-step</code></a>:</td><td> </td><td valign="top"><a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-J">J</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-join_002dthread"><code>join-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-join_002dthread-_005bsb_002dthread_005d"><code>join-thread [sb-thread]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timeout-Parameters">Timeout Parameters</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-L">L</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-labels-_005bcl_005d"><code>labels [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-labels-_005bcl_005d-1"><code>labels [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-length"><code>length</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-let-_005bcl_005d"><code>let [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Efficiency-Issues">Miscellaneous Efficiency Issues</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-let-_005bcl_005d-1"><code>let [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-let_002a-_005bcl_005d"><code>let* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Efficiency-Issues">Miscellaneous Efficiency Issues</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-let_002a-_005bcl_005d-1"><code>let* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-line_002dbreak_002dclass"><code>line-break-class</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-lines"><code>lines</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list-_005bcl_005d"><code>list [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list_002a-_005bcl_005d"><code>list* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list_002dall_002dthreads"><code>list-all-threads</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list_002dall_002dtimers"><code>list-all-timers</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timers">Timers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list_002dlocals"><code>list-locals</code></a>:</td><td> </td><td valign="top"><a href="index.html#Variable-Access">Variable Access</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list_002dmailbox_002dmessages"><code>list-mailbox-messages</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list_002dqueue_002dcontents"><code>list-queue-contents</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-load_002dshared_002dobject"><code>load-shared-object</code></a>:</td><td> </td><td valign="top"><a href="index.html#Loading-Shared-Object-Files">Loading Shared Object Files</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-lock_002dpackage"><code>lock-package</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-logand-_005bcl_005d"><code>logand [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Modular-arithmetic">Modular arithmetic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-logical_002dpathname_002dtranslations-_005bcl_005d"><code>logical-pathname-translations [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-Pathnames">Lisp Pathnames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-lowercase"><code>lowercase</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-lowercase_002dp"><code>lowercase-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-M">M</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-macrolet-_005bcl_005d"><code>macrolet [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mailbox_002dcount"><code>mailbox-count</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mailbox_002dempty_002dp"><code>mailbox-empty-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mailbox_002dname"><code>mailbox-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mailboxp"><code>mailboxp</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-main_002dthread"><code>main-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-main_002dthread_002dp"><code>main-thread-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dalien"><code>make-alien</code></a>:</td><td> </td><td valign="top"><a href="index.html#Foreign-Dynamic-Allocation">Foreign Dynamic Allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dalien_002dstring"><code>make-alien-string</code></a>:</td><td> </td><td valign="top"><a href="index.html#Foreign-Dynamic-Allocation">Foreign Dynamic Allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002darray-_005bcl_005d"><code>make-array [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dfrlock"><code>make-frlock</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dgate"><code>make-gate</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dhash_002dtable"><code>make-hash-table</code></a>:</td><td> </td><td valign="top"><a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dinet_002daddress"><code>make-inet-address</code></a>:</td><td> </td><td valign="top"><a href="index.html#INET-Domain-Sockets">INET Domain Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dinet6_002daddress"><code>make-inet6-address</code></a>:</td><td> </td><td valign="top"><a href="index.html#INET-Domain-Sockets">INET Domain Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dinstance-_005bcl_005d"><code>make-instance [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dmailbox"><code>make-mailbox</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dmethod_002dlambda-_005bsb_002dmop_005d"><code>make-method-lambda [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dmethod_002dspecializers_002dform-_005bsb_002dpcl_005d"><code>make-method-specializers-form [sb-pcl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dmutex"><code>make-mutex</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dqueue"><code>make-queue</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002drandom_002dstate-_005bcl_005d"><code>make-random-state [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsemaphore"><code>make-semaphore</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsemaphore_002dnotification"><code>make-semaphore-notification</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsequence_002diterator"><code>make-sequence-iterator</code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsequence_002diterator-_005bsb_002dsequence_005d"><code>make-sequence-iterator [sb-sequence]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsequence_002diterator-_005bsb_002dsequence_005d-1"><code>make-sequence-iterator [sb-sequence]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsequence_002dlike"><code>make-sequence-like</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsequence_002dlike-_005bsb_002dsequence_005d"><code>make-sequence-like [sb-sequence]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsimple_002dsequence_002diterator"><code>make-simple-sequence-iterator</code></a>:</td><td> </td><td valign="top"><a href="index.html#Simple-Iterator-Protocol">Simple Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dsimple_002dsequence_002diterator-_005bsb_002dsequence_005d"><code>make-simple-sequence-iterator [sb-sequence]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dthread"><code>make-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dtimer"><code>make-timer</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timers">Timers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dwaitqueue"><code>make-waitqueue</code></a>:</td><td> </td><td valign="top"><a href="index.html#Waitqueue_002fcondition-variables">Waitqueue/condition variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-make_002dweak_002dpointer"><code>make-weak-pointer</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-map"><code>map</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-map_002dtraces"><code>map-traces</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-math_002dp"><code>math-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-md5sum_002dfile"><code>md5sum-file</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dmd5">sb-md5</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-md5sum_002dsequence"><code>md5sum-sequence</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dmd5">sb-md5</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-md5sum_002dstream"><code>md5sum-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dmd5">sb-md5</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-md5sum_002dstring"><code>md5sum-string</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dmd5">sb-md5</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-merge"><code>merge</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mirrored_002dp"><code>mirrored-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-muffle_002dconditions"><code>muffle-conditions</code></a>:</td><td> </td><td valign="top"><a href="index.html#Controlling-Verbosity">Controlling Verbosity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mutex_002dname"><code>mutex-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mutex_002downer"><code>mutex-owner</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mutex_002dvalue"><code>mutex-value</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-N">N</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-name_002dchar-_005bcl_005d"><code>name-char [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-name_002dconflict_002dsymbols-_005bsb_002dext_005d"><code>name-conflict-symbols [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Resolution-of-Name-Conflicts">Resolution of Name Conflicts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-native_002dnamestring"><code>native-namestring</code></a>:</td><td> </td><td valign="top"><a href="index.html#Native-Filenames">Native Filenames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-native_002dpathname"><code>native-pathname</code></a>:</td><td> </td><td valign="top"><a href="index.html#Native-Filenames">Native Filenames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-next"><code>next</code></a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-non_002dblocking_002dmode"><code>non-blocking-mode</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-normalize_002dstring"><code>normalize-string</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-normalized_002dp"><code>normalized-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-numeric_002dvalue"><code>numeric-value</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-O">O</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-octets_002dto_002dstring"><code>octets-to-string</code></a>:</td><td> </td><td valign="top"><a href="index.html#Converting-between-Strings-and-Octet-Vectors">Converting between Strings and Octet Vectors</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-open-_005bcl_005d"><code>open [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#External-Format-Designators">External Format Designators</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-open-_005bcl_005d-1"><code>open [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stream-External-Formats">Stream External Formats</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-open_002dgate"><code>open-gate</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-out"><code>out</code></a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-P">P</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dimplemented_002dby_002dlist"><code>package-implemented-by-list</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dimplements_002dlist"><code>package-implements-list</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlocal_002dnicknames"><code>package-local-nicknames</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlocally_002dnicknamed_002dby_002dlist"><code>package-locally-nicknamed-by-list</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlocked_002derror_002dsymbol"><code>package-locked-error-symbol</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlocked_002dp"><code>package-locked-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-parse_002dnative_002dnamestring"><code>parse-native-namestring</code></a>:</td><td> </td><td valign="top"><a href="index.html#Native-Filenames">Native Filenames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-parse_002dspecializer_002dusing_002dclass-_005bsb_002dpcl_005d"><code>parse-specializer-using-class [sb-pcl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-posix_002dgetenv"><code>posix-getenv</code></a>:</td><td> </td><td valign="top"><a href="index.html#Querying-the-process-environment">Querying the process environment</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-print"><code>print</code></a>:</td><td> </td><td valign="top"><a href="index.html#Information-Commands">Information Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dalive_002dp"><code>process-alive-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dclose"><code>process-close</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dcore_002ddumped"><code>process-core-dumped</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002derror"><code>process-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dexit_002dcode"><code>process-exit-code</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dinput"><code>process-input</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dkill"><code>process-kill</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002doutput"><code>process-output</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dp"><code>process-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dstatus"><code>process-status</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-process_002dwait"><code>process-wait</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-profile"><code>profile</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deterministic-Profiler">Deterministic Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-profile_002dcall_002dcounts"><code>profile-call-counts</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-prog2-_005bcl_005d"><code>prog2 [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exceptions-to-ANSI-Conformance">Exceptions to ANSI Conformance</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-proplist_002dp"><code>proplist-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-purify-_005bsb_002dext_005d"><code>purify [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Efficiency-Hacks">Efficiency Hacks</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-Q">Q</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-queue_002dcount"><code>queue-count</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-queue_002dempty_002dp"><code>queue-empty-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-queue_002dname"><code>queue-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-queuep"><code>queuep</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-R">R</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-random-_005bcl_005d"><code>random [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-random-_005bcl_005d-1"><code>random [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-read-_005bcl_005d"><code>read [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-read_002dfrom_002dstring-_005bcl_005d"><code>read-from-string [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-read_002dline-_005bcl_005d"><code>read-line [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-readlink"><code>readlink</code></a>:</td><td> </td><td valign="top"><a href="index.html#Functions-with-idiosyncratic-bindings">Functions with idiosyncratic bindings</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-readtable_002dnormalization"><code>readtable-normalization</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-receive_002dmessage"><code>receive-message</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-receive_002dmessage_002dno_002dhang"><code>receive-message-no-hang</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-receive_002dpending_002dmessages"><code>receive-pending-messages</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-release_002dfrlock_002dwrite_002dlock"><code>release-frlock-write-lock</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-release_002dmutex"><code>release-mutex</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-remove_002dimplementation_002dpackage"><code>remove-implementation-package</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-remove_002dpackage_002dlocal_002dnickname"><code>remove-package-local-nickname</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-report"><code>report</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deterministic-Profiler">Deterministic Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-report-1"><code>report</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-report-2"><code>report</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-require"><code>require</code></a>:</td><td> </td><td valign="top"><a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-reset"><code>reset</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deterministic-Profiler">Deterministic Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-reset-1"><code>reset</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-reset_002dcoverage"><code>reset-coverage</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-restart"><code>restart</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exiting-Commands">Exiting Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-restart_002dframe"><code>restart-frame</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exiting-Commands">Exiting Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-restore_002dcoverage"><code>restore-coverage</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-restore_002dcoverage_002dfrom_002dfile"><code>restore-coverage-from-file</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-restrict_002dcompiler_002dpolicy"><code>restrict-compiler-policy</code></a>:</td><td> </td><td valign="top"><a href="index.html#Compiler-Policy">Compiler Policy</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-return"><code>return</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exiting-Commands">Exiting Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-return_002dfrom_002dthread"><code>return-from-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-rotate_002dbyte"><code>rotate-byte</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002drotate_002dbyte">sb-rotate-byte</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-rotate_002dbyte-_005bsb_002drotate_002dbyte_005d"><code>rotate-byte [sb-rotate-byte]</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dmd5">sb-md5</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-run_002dprogram"><code>run-program</code></a>:</td><td> </td><td valign="top"><a href="index.html#Running-external-programs">Running external programs</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-run_002dprogram-_005bsb_002dext_005d"><code>run-program [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-S">S</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sample_002dpc"><code>sample-pc</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sap_002dalien"><code>sap-alien</code></a>:</td><td> </td><td valign="top"><a href="index.html#Coercing-Foreign-Values">Coercing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sap_002dref_002d32"><code>sap-ref-32</code></a>:</td><td> </td><td valign="top"><a href="index.html#Accessing-Foreign-Values">Accessing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sap_003d"><code>sap=</code></a>:</td><td> </td><td valign="top"><a href="index.html#Accessing-Foreign-Values">Accessing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-satisfies-_005bcl_005d"><code>satisfies [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Handling-of-Types">Handling of Types</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-save_002dcoverage"><code>save-coverage</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-save_002dcoverage_002din_002dfile"><code>save-coverage-in-file</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dcover">sb-cover</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-save_002dlisp_002dand_002ddie"><code>save-lisp-and-die</code></a>:</td><td> </td><td valign="top"><a href="index.html#Saving-a-Core-Image">Saving a Core Image</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-schedule_002dtimer"><code>schedule-timer</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timers">Timers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-script"><code>script</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-search_002droots"><code>search-roots</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-seed_002drandom_002dstate"><code>seed-random-state</code></a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-semaphore_002dcount"><code>semaphore-count</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-semaphore_002dname"><code>semaphore-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-semaphore_002dnotification_002dstatus"><code>semaphore-notification-status</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-send_002dmessage"><code>send-message</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sentence_002dbreak_002dclass"><code>sentence-break-class</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sentences"><code>sentences</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-set_002dsbcl_002dsource_002dlocation"><code>set-sbcl-source-location</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-Pathnames">Lisp Pathnames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-setf-element-function"><code><code>setf element function</code></code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-setf-_005bcl_005d"><code>setf [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Efficiency-Issues">Miscellaneous Efficiency Issues</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-setq-_005bcl_005d"><code>setq [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Miscellaneous-Efficiency-Issues">Miscellaneous Efficiency Issues</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-signal_002dsemaphore"><code>signal-semaphore</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sleep-_005bcl_005d"><code>sleep [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timeouts-and-Deadlines">Timeouts and Deadlines</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sleep-_005bcl_005d-1"><code>sleep [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-slot"><code>slot</code></a>:</td><td> </td><td valign="top"><a href="index.html#Accessing-Foreign-Values">Accessing Foreign Values</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-slot_002dboundp_002dusing_002dclass-_005bsb_002dmop_005d"><code>slot-boundp-using-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-slot_002dboundp_002dusing_002dclass-_005bsb_002dmop_005d-1"><code>slot-boundp-using-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-slot_002ddefinition_002dallocation-_005bsb_002dmop_005d"><code>slot-definition-allocation [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-slot_002ddefinition_002dname-_005bsb_002dmop_005d"><code>slot-definition-name [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d"><code>slot-value-using-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-slot_002dvalue_002dusing_002dclass-_005bsb_002dmop_005d-1"><code>slot-value-using-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002daccept"><code>socket-accept</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dbind"><code>socket-bind</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dclose"><code>socket-close</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dconnect"><code>socket-connect</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002derror"><code>socket-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dlisten"><code>socket-listen</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dmake_002dstream"><code>socket-make-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dmake_002dstream-1"><code>socket-make-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dname"><code>socket-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dopen_002dp"><code>socket-open-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dpeername"><code>socket-peername</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dreceive"><code>socket-receive</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dsend"><code>socket-send</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket_002dshutdown"><code>socket-shutdown</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002dbroadcast"><code>sockopt-broadcast</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002dbsd_002dcompatible"><code>sockopt-bsd-compatible</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002ddebug"><code>sockopt-debug</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002ddont_002droute"><code>sockopt-dont-route</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002dkeep_002dalive"><code>sockopt-keep-alive</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002doob_002dinline"><code>sockopt-oob-inline</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002dpass_002dcredentials"><code>sockopt-pass-credentials</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002dreuse_002daddress"><code>sockopt-reuse-address</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sockopt_002dtcp_002dnodelay"><code>sockopt-tcp-nodelay</code></a>:</td><td> </td><td valign="top"><a href="index.html#Socket-Options">Socket Options</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-soft_002ddotted_002dp"><code>soft-dotted-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-source"><code>source</code></a>:</td><td> </td><td valign="top"><a href="index.html#Source-Location-Printing">Source Location Printing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-standard_002dinstance_002daccess-_005bsb_002dmop_005d"><code>standard-instance-access [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-start"><code>start</code></a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-start_002dprofiling"><code>start-profiling</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-step"><code>step</code></a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-step-1"><code>step</code></a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-step-function"><code><code>step function</code></code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stop"><code>stop</code></a>:</td><td> </td><td valign="top"><a href="index.html#Single-Stepping">Single Stepping</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stop_002dprofiling"><code>stop-profiling</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dadvance_002dto_002dcolumn"><code>stream-advance-to-column</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dclear_002dinput"><code>stream-clear-input</code></a>:</td><td> </td><td valign="top"><a href="index.html#Input-stream-methods">Input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dclear_002doutput"><code>stream-clear-output</code></a>:</td><td> </td><td valign="top"><a href="index.html#Output-stream-methods">Output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002delement_002dtype"><code>stream-element-type</code></a>:</td><td> </td><td valign="top"><a href="index.html#Methods-common-to-all-streams">Methods common to all streams</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dexternal_002dformat-_005bcl_005d"><code>stream-external-format [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stream-External-Formats">Stream External Formats</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dfile_002dposition"><code>stream-file-position</code></a>:</td><td> </td><td valign="top"><a href="index.html#Methods-common-to-all-streams">Methods common to all streams</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dfinish_002doutput"><code>stream-finish-output</code></a>:</td><td> </td><td valign="top"><a href="index.html#Output-stream-methods">Output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dforce_002doutput"><code>stream-force-output</code></a>:</td><td> </td><td valign="top"><a href="index.html#Output-stream-methods">Output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dfresh_002dline"><code>stream-fresh-line</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dline_002dcolumn"><code>stream-line-column</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dline_002dlength"><code>stream-line-length</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dlisten"><code>stream-listen</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-input-stream-methods">Character input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dpeek_002dchar"><code>stream-peek-char</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-input-stream-methods">Character input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dread_002dbyte"><code>stream-read-byte</code></a>:</td><td> </td><td valign="top"><a href="index.html#Binary-stream-methods">Binary stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dread_002dchar"><code>stream-read-char</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-input-stream-methods">Character input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dread_002dchar_002dno_002dhang"><code>stream-read-char-no-hang</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-input-stream-methods">Character input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dread_002dline"><code>stream-read-line</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-input-stream-methods">Character input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dread_002dsequence"><code>stream-read-sequence</code></a>:</td><td> </td><td valign="top"><a href="index.html#Input-stream-methods">Input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dstart_002dline_002dp"><code>stream-start-line-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dterpri"><code>stream-terpri</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dunread_002dchar"><code>stream-unread-char</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-input-stream-methods">Character input stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dwrite_002dbyte"><code>stream-write-byte</code></a>:</td><td> </td><td valign="top"><a href="index.html#Binary-stream-methods">Binary stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dwrite_002dchar"><code>stream-write-char</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dwrite_002dsequence"><code>stream-write-sequence</code></a>:</td><td> </td><td valign="top"><a href="index.html#Output-stream-methods">Output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stream_002dwrite_002dstring"><code>stream-write-string</code></a>:</td><td> </td><td valign="top"><a href="index.html#Character-output-stream-methods">Character output stream methods</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-string_002dto_002doctets"><code>string-to-octets</code></a>:</td><td> </td><td valign="top"><a href="index.html#Converting-between-Strings-and-Octet-Vectors">Converting between Strings and Octet Vectors</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-string_002dupcase-_005bcl_005d"><code>string-upcase [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-subseq-_005bcl_005d"><code>subseq [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-subseq-_005bcl_005d-1"><code>subseq [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-subseq-_005bcl_005d-2"><code>subseq [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-subtypep-_005bcl_005d"><code>subtypep [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-symbol_002dmacrolet-_005bcl_005d"><code>symbol-macrolet [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-symbol_002dvalue_002din_002dthread"><code>symbol-value-in-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-syslog"><code>syslog</code></a>:</td><td> </td><td valign="top"><a href="index.html#Functions-with-idiosyncratic-bindings">Functions with idiosyncratic bindings</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-T">T</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-terminate_002dthread"><code>terminate-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-thread_002dalive_002dp"><code>thread-alive-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-thread_002derror_002dthread"><code>thread-error-thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-thread_002dname"><code>thread-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-thread_002dyield"><code>thread-yield</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-timer_002dname"><code>timer-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timers">Timers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-timer_002dscheduled_002dp"><code>timer-scheduled-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timers">Timers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-titlecase"><code>titlecase</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-top"><code>top</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stack-Motion">Stack Motion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-toplevel"><code>toplevel</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exiting-Commands">Exiting Commands</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-trace"><code>trace</code></a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-trace-_005bcl_005d"><code>trace [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Tools-To-Help-Developers">Tools To Help Developers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-truly_002dthe"><code>truly-the</code></a>:</td><td> </td><td valign="top"><a href="index.html#Efficiency-Hacks">Efficiency Hacks</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-try_002dsemaphore"><code>try-semaphore</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-typep-_005bcl_005d"><code>typep [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-U">U</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unicode_002d1_002dname"><code>unicode-1-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unicode_002dequal"><code>unicode-equal</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unicode_003c"><code>unicode<</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unicode_003c_003d"><code>unicode<=</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unicode_003d"><code>unicode=</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unicode_003e"><code>unicode></code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unicode_003e_003d"><code>unicode>=</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unload_002dshared_002dobject"><code>unload-shared-object</code></a>:</td><td> </td><td valign="top"><a href="index.html#Loading-Shared-Object-Files">Loading Shared Object Files</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unlock_002dpackage"><code>unlock-package</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unmuffle_002dconditions"><code>unmuffle-conditions</code></a>:</td><td> </td><td valign="top"><a href="index.html#Controlling-Verbosity">Controlling Verbosity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unparse_002dspecializer_002dusing_002dclass-_005bsb_002dpcl_005d"><code>unparse-specializer-using-class [sb-pcl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unprofile"><code>unprofile</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deterministic-Profiler">Deterministic Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unprofile_002dcall_002dcounts"><code>unprofile-call-counts</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-unschedule_002dtimer"><code>unschedule-timer</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timers">Timers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-untrace"><code>untrace</code></a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-up"><code>up</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stack-Motion">Stack Motion</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-uppercase"><code>uppercase</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-uppercase_002dp"><code>uppercase-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-V">V</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-validate_002dsuperclass-_005bsb_002dmop_005d"><code>validate-superclass [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-validate_002dsuperclass-_005bsb_002dmop_005d-1"><code>validate-superclass [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-var"><code>var</code></a>:</td><td> </td><td valign="top"><a href="index.html#Variable-Access">Variable Access</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-vector-_005bcl_005d"><code>vector [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Function-Index_fn_letter-W">W</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-wait_002dfor"><code>wait-for</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timeout-Parameters">Timeout Parameters</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-wait_002don_002dgate"><code>wait-on-gate</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-wait_002don_002dsemaphore"><code>wait-on-semaphore</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-waitqueue_002dname"><code>waitqueue-name</code></a>:</td><td> </td><td valign="top"><a href="index.html#Waitqueue_002fcondition-variables">Waitqueue/condition variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-weak_002dpointer_002dvalue"><code>weak-pointer-value</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-whitespace_002dp"><code>whitespace-p</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dalien"><code>with-alien</code></a>:</td><td> </td><td valign="top"><a href="index.html#Local-Foreign-Variables">Local Foreign Variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dcompilation_002dunit"><code>with-compilation-unit</code></a>:</td><td> </td><td valign="top"><a href="index.html#Compiler-Policy">Compiler Policy</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dcompilation_002dunit-_005bcl_005d"><code>with-compilation-unit [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Parts-of-a-Compiler-Diagnostic">The Parts of a Compiler Diagnostic</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002ddeadline"><code>with-deadline</code></a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dlocked_002dhash_002dtable"><code>with-locked-hash-table</code></a>:</td><td> </td><td valign="top"><a href="index.html#Hash-Table-Extensions">Hash Table Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dmutex"><code>with-mutex</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dopen_002dfile-_005bcl_005d"><code>with-open-file [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#External-Format-Designators">External Format Designators</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dopen_002dfile-_005bcl_005d-1"><code>with-open-file [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Stream-External-Formats">Stream External Formats</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dprofiling"><code>with-profiling</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002drecursive_002dlock"><code>with-recursive-lock</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dsampling"><code>with-sampling</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dsequence_002diterator"><code>with-sequence-iterator</code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dsequence_002diterator_002dfunctions"><code>with-sequence-iterator-functions</code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dtimeout"><code>with-timeout</code></a>:</td><td> </td><td valign="top"><a href="index.html#Asynchronous-Timeouts">Asynchronous Timeouts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-with_002dunlocked_002dpackages"><code>with-unlocked-packages</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-without_002dpackage_002dlocks"><code>without-package-locks</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-word_002dbreak_002dclass"><code>word-break-class</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-words"><code>words</code></a>:</td><td> </td><td valign="top"><a href="index.html#Unicode-Support">Unicode Support</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
</table>
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Function-Index_fn_symbol-1"><b>(</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_symbol-2"><b>?</b></a>
|
|
|
|
<br>
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-A"><b>A</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-B"><b>B</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-C"><b>C</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-D"><b>D</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-E"><b>E</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-F"><b>F</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-G"><b>G</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-H"><b>H</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-I"><b>I</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-J"><b>J</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-L"><b>L</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-M"><b>M</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-N"><b>N</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-O"><b>O</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-P"><b>P</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-Q"><b>Q</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-R"><b>R</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-S"><b>S</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-T"><b>T</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-U"><b>U</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-V"><b>V</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Function-Index_fn_letter-W"><b>W</b></a>
|
|
|
|
</td></tr></table>
|
|
|
|
<hr>
|
|
<span id="Variable-Index"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Type-Index" accesskey="n" rel="next">Type Index</a>, Previous: <a href="index.html#Function-Index" accesskey="p" rel="prev">Function Index</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Variable-Index-1"></span><h2 class="appendix">Appendix C Variable Index</h2>
|
|
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Variable-Index_vr_symbol-1"><b>*</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Variable-Index_vr_symbol-2"><b>+</b></a>
|
|
</td></tr></table>
|
|
<table class="index-vr" border="0">
|
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Variable-Index_vr_symbol-1">*</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aafter_002dgc_002dhooks_002a"><code>*after-gc-hooks*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002acommand_002dchar_002a"><code>*command-char*</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002daclrepl">sb-aclrepl</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002acompiler_002dprint_002dvariable_002dalist_002a"><code>*compiler-print-variable-alist*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Controlling-Verbosity">Controlling Verbosity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002acore_002dpathname_002a"><code>*core-pathname*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Saving-a-Core-Image">Saving a Core Image</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002acurrent_002dthread_002a"><code>*current-thread*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002adebug_002dprint_002dvariable_002dalist_002a"><code>*debug-print-variable-alist*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Debugger-Command-Loop">Debugger Command Loop</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aed_002dfunctions_002a"><code>*ed-functions*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aevaluator_002dmode_002a"><code>*evaluator-mode*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Interpreter">Interpreter</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aevaluator_002dmode_002a-_005bsb_002dext_005d"><code>*evaluator-mode* [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Interpreter">Interpreter</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aexit_002dhooks_002a"><code>*exit-hooks*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Initialization-and-Exit-Hooks">Initialization and Exit Hooks</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aexit_002don_002deof_002a"><code>*exit-on-eof*</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002daclrepl">sb-aclrepl</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002afeatures_002a-_005bcl_005d"><code>*features* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002agc_002drun_002dtime_002a"><code>*gc-run-time*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Garbage-Collection">Garbage Collection</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002ainit_002dhooks_002a"><code>*init-hooks*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Initialization-and-Exit-Hooks">Initialization and Exit Hooks</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002ainvoke_002ddebugger_002dhook_002a"><code>*invoke-debugger-hook*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Debugger-Invocation">Debugger Invocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002amax_002dhistory_002a"><code>*max-history*</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002daclrepl">sb-aclrepl</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002amax_002dsamples_002a"><code>*max-samples*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002amax_002dtrace_002dindentation_002a"><code>*max-trace-indentation*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002amodule_002dprovider_002dfunctions_002a"><code>*module-provider-functions*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002amuffled_002dwarnings_002a"><code>*muffled-warnings*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Customization-Hooks-for-Users">Customization Hooks for Users</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aon_002dpackage_002dvariance_002a"><code>*on-package-variance*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Variance">Package Variance</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002apackage_002a-_005bcl_005d"><code>*package* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002apackage_002a-_005bcl_005d-1"><code>*package* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002apackage_002a-_005bcl_005d-2"><code>*package* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package_002dLocal-Nicknames">Package-Local Nicknames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002apackage_002a-_005bcl_005d-3"><code>*package* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Implementation-Packages">Implementation Packages</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aposix_002dargv_002a-_005bsb_002dext_005d"><code>*posix-argv* [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Shebang-Scripts">Shebang Scripts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aposix_002dargv_002a-_005bsb_002dext_005d-1"><code>*posix-argv* [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Command_002dline-arguments">Command-line arguments</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aprompt_002a"><code>*prompt*</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002daclrepl">sb-aclrepl</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002arandom_002dstate_002a-_005bcl_005d"><code>*random-state* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aread_002ddefault_002dfloat_002dformat_002a-_005bcl_005d"><code>*read-default-float-format* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002aread_002ddefault_002dfloat_002dformat_002a-_005bcl_005d-1"><code>*read-default-float-format* [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002asample_002dinterval_002a"><code>*sample-interval*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Statistical-Profiler">Statistical Profiler</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002asave_002dhooks_002a"><code>*save-hooks*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Saving-a-Core-Image">Saving a Core Image</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002astack_002dallocate_002ddynamic_002dextent_002a"><code>*stack-allocate-dynamic-extent*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Dynamic_002dextent-allocation">Dynamic-extent allocation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002asysinit_002dpathname_002dfunction_002a"><code>*sysinit-pathname-function*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Saving-a-Core-Image">Saving a Core Image</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002atrace_002dencapsulate_002ddefault_002a"><code>*trace-encapsulate-default*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002atrace_002dindentation_002dstep_002a"><code>*trace-indentation-step*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002atrace_002dreport_002ddefault_002a"><code>*trace-report-default*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Function-Tracing">Function Tracing</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002ause_002dshort_002dpackage_002dname_002a"><code>*use-short-package-name*</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002daclrepl">sb-aclrepl</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002auserinit_002dpathname_002dfunction_002a"><code>*userinit-pathname-function*</code></a>:</td><td> </td><td valign="top"><a href="index.html#Saving-a-Core-Image">Saving a Core Image</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Variable-Index_vr_symbol-2">+</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-_002bslot_002dunbound_002b-_005bsb_002dpcl_005d"><code>+slot-unbound+ [sb-pcl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
</table>
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Variable-Index_vr_symbol-1"><b>*</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Variable-Index_vr_symbol-2"><b>+</b></a>
|
|
</td></tr></table>
|
|
|
|
<hr>
|
|
<span id="Type-Index"></span><div class="header">
|
|
<p>
|
|
Next: <a href="index.html#Colophon" accesskey="n" rel="next">Colophon</a>, Previous: <a href="index.html#Variable-Index" accesskey="p" rel="prev">Variable Index</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Type-Index-1"></span><h2 class="appendix">Appendix D Type Index</h2>
|
|
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Type-Index_tp_letter-B"><b>B</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-C"><b>C</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-D"><b>D</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-E"><b>E</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-F"><b>F</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-G"><b>G</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-H"><b>H</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-I"><b>I</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-J"><b>J</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-L"><b>L</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-M"><b>M</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-N"><b>N</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-P"><b>P</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-Q"><b>Q</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-R"><b>R</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-S"><b>S</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-T"><b>T</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-V"><b>V</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-W"><b>W</b></a>
|
|
|
|
</td></tr></table>
|
|
<table class="index-tp" border="0">
|
|
<tr><td></td><th align="left">Index Entry</th><td> </td><th align="left"> Section</th></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-B">B</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-built_002din_002dclass-_005bcl_005d"><code>built-in-class [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-C">C</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-character-_005bcl_005d"><code>character [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exceptions-to-ANSI-Conformance">Exceptions to ANSI Conformance</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-code_002ddeletion_002dnote"><code>code-deletion-note</code></a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-code_002ddeletion_002dnote-_005bsb_002dext_005d"><code>code-deletion-note [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-compiler_002dnote"><code>compiler-note</code></a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-compiler_002dnote-_005bsb_002dext_005d"><code>compiler-note [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-D">D</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deadline_002dtimeout"><code>deadline-timeout</code></a>:</td><td> </td><td valign="top"><a href="index.html#Synchronous-Timeouts-_0028Deadlines_0029">Synchronous Timeouts (Deadlines)</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deprecation_002dcondition"><code>deprecation-condition</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Conditions">Deprecation Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deprecation_002dcondition-_005bsb_002dext_005d"><code>deprecation-condition [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Conditions">Deprecation Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deprecation_002derror"><code>deprecation-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Conditions">Deprecation Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deprecation_002derror-_005bsb_002dext_005d"><code>deprecation-error [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Declaration">Deprecation Declaration</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-deprecation_002derror-_005bsb_002dext_005d-1"><code>deprecation-error [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Declaration">Deprecation Declaration</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-E">E</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-early_002ddeprecation_002dwarning"><code>early-deprecation-warning</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Conditions">Deprecation Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-early_002ddeprecation_002dwarning-_005bsb_002dext_005d"><code>early-deprecation-warning [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-early_002ddeprecation_002dwarning-_005bsb_002dext_005d-1"><code>early-deprecation-warning [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecated-Interfaces-in-SBCL">Deprecated Interfaces in SBCL</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-error-_005bcl_005d"><code>error [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-error-_005bcl_005d-1"><code>error [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-F">F</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-file_002ddescriptor-1"><code>file-descriptor</code></a>:</td><td> </td><td valign="top"><a href="index.html#File_002ddescriptors">File-descriptors</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-file_002ddescriptor_002ddesignator"><code>file-descriptor-designator</code></a>:</td><td> </td><td valign="top"><a href="index.html#File_002ddescriptors">File-descriptors</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-filename-1"><code>filename</code></a>:</td><td> </td><td valign="top"><a href="index.html#Filenames">Filenames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-filename_002ddesignator"><code>filename-designator</code></a>:</td><td> </td><td valign="top"><a href="index.html#Filenames">Filenames</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-final_002ddeprecation_002dwarning"><code>final-deprecation-warning</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Conditions">Deprecation Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-final_002ddeprecation_002dwarning-_005bsb_002dext_005d"><code>final-deprecation-warning [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-final_002ddeprecation_002dwarning-_005bsb_002dext_005d-1"><code>final-deprecation-warning [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecated-Interfaces-in-SBCL">Deprecated Interfaces in SBCL</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-float-_005bcl_005d"><code>float [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-float-_005bcl_005d-1"><code>float [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Random-Number-Generation">Random Number Generation</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-flock"><code>flock</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-objects-and-C-structures">Lisp objects and C structures</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-frlock"><code>frlock</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-funcallable_002dstandard_002dclass-_005bsb_002dmop_005d"><code>funcallable-standard-class [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-funcallable_002dstandard_002dobject-_005bsb_002dmop_005d"><code>funcallable-standard-object [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-funcallable_002dstandard_002dobject-_005bsb_002dmop_005d-1"><code>funcallable-standard-object [sb-mop]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-function-_005bcl_005d"><code>function [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-function-_005bcl_005d-1"><code>function [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dbinary_002dinput_002dstream"><code>fundamental-binary-input-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dbinary_002doutput_002dstream"><code>fundamental-binary-output-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dbinary_002dstream"><code>fundamental-binary-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dcharacter_002dinput_002dstream"><code>fundamental-character-input-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dcharacter_002doutput_002dstream"><code>fundamental-character-output-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dcharacter_002dstream"><code>fundamental-character-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dinput_002dstream"><code>fundamental-input-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002doutput_002dstream"><code>fundamental-output-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-fundamental_002dstream"><code>fundamental-stream</code></a>:</td><td> </td><td valign="top"><a href="index.html#Gray-Streams-classes">Gray Streams classes</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-G">G</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-gate"><code>gate</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-generic_002dfunction-_005bcl_005d"><code>generic-function [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-H">H</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-host_002dent"><code>host-ent</code></a>:</td><td> </td><td valign="top"><a href="index.html#Name-Service">Name Service</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-I">I</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-inet_002dsocket"><code>inet-socket</code></a>:</td><td> </td><td valign="top"><a href="index.html#INET-Domain-Sockets">INET Domain Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-inet6_002dsocket"><code>inet6-socket</code></a>:</td><td> </td><td valign="top"><a href="index.html#INET-Domain-Sockets">INET Domain Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-interrupt_002dthread_002derror"><code>interrupt-thread-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-J">J</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-join_002dthread_002derror"><code>join-thread-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-join_002dthread_002derror-_005bsb_002dthread_005d"><code>join-thread-error [sb-thread]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timeout-Parameters">Timeout Parameters</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-L">L</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-late_002ddeprecation_002dwarning"><code>late-deprecation-warning</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecation-Conditions">Deprecation Conditions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-late_002ddeprecation_002dwarning-_005bsb_002dext_005d"><code>late-deprecation-warning [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-late_002ddeprecation_002dwarning-_005bsb_002dext_005d-1"><code>late-deprecation-warning [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Deprecated-Interfaces-in-SBCL">Deprecated Interfaces in SBCL</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-list-_005bcl_005d-1"><code>list [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-local_002dabstract_002dsocket"><code>local-abstract-socket</code></a>:</td><td> </td><td valign="top"><a href="index.html#Local-_0028Unix_0029-Domain-Sockets">Local (Unix) Domain Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-local_002dsocket"><code>local-socket</code></a>:</td><td> </td><td valign="top"><a href="index.html#Local-_0028Unix_0029-Domain-Sockets">Local (Unix) Domain Sockets</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-M">M</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mailbox"><code>mailbox</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-mutex"><code>mutex</code></a>:</td><td> </td><td valign="top"><a href="index.html#Mutex-Support">Mutex Support</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-N">N</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-name_002dconflict-_005bsb_002dext_005d"><code>name-conflict [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Resolution-of-Name-Conflicts">Resolution of Name Conflicts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-nil-_005bcl_005d"><code>nil [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exceptions-to-ANSI-Conformance">Exceptions to ANSI Conformance</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-P">P</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002derror-_005bcl_005d"><code>package-error [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlock_002dviolation"><code>package-lock-violation</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlock_002dviolation-_005bsb_002dext_005d"><code>package-lock-violation [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlocked_002derror"><code>package-locked-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-package_002dlocked_002derror-_005bsb_002dext_005d"><code>package-locked-error [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-passwd"><code>passwd</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-objects-and-C-structures">Lisp objects and C structures</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-protocol_002dunimplemented"><code>protocol-unimplemented</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-Q">Q</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-queue"><code>queue</code></a>:</td><td> </td><td valign="top"><a href="index.html#sb_002dconcurrency">sb-concurrency</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-R">R</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-rational-_005bcl_005d"><code>rational [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-rational-_005bcl_005d-1"><code>rational [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Reader-Extensions">Reader Extensions</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-S">S</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-semaphore"><code>semaphore</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-semaphore_002dnotification"><code>semaphore-notification</code></a>:</td><td> </td><td valign="top"><a href="index.html#Semaphores">Semaphores</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sequence-_005bcl_005d"><code>sequence [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sequence-_005bcl_005d-1"><code>sequence [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sequence-_005bcl_005d-2"><code>sequence [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-sequence-_005bcl_005d-3"><code>sequence [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Iterator-Protocol">Iterator Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-socket"><code>socket</code></a>:</td><td> </td><td valign="top"><a href="index.html#General-Sockets">General Sockets</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-standard_002dclass-_005bcl_005d"><code>standard-class [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-standard_002dgeneric_002dfunction-_005bcl_005d"><code>standard-generic-function [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-standard_002dobject-_005bcl_005d"><code>standard-object [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-standard_002dobject-_005bcl_005d-1"><code>standard-object [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-stat"><code>stat</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-objects-and-C-structures">Lisp objects and C structures</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-string-_005bcl_005d"><code>string [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Exceptions-to-ANSI-Conformance">Exceptions to ANSI Conformance</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-structure_002dclass-_005bcl_005d"><code>structure-class [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-style_002dwarning-_005bcl_005d"><code>style-warning [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-style_002dwarning-_005bcl_005d-1"><code>style-warning [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-symbol_002dpackage_002dlocked_002derror"><code>symbol-package-locked-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Dictionary">Package Lock Dictionary</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-symbol_002dpackage_002dlocked_002derror-_005bsb_002dext_005d"><code>symbol-package-locked-error [sb-ext]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Package-Lock-Violations">Package Lock Violations</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-T">T</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-t-_005bcl_005d"><code>t [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Metaobject-Protocol">Metaobject Protocol</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-termios"><code>termios</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-objects-and-C-structures">Lisp objects and C structures</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-thread"><code>thread</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-thread_002derror"><code>thread-error</code></a>:</td><td> </td><td valign="top"><a href="index.html#Threading-basics">Threading basics</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-timeout"><code>timeout</code></a>:</td><td> </td><td valign="top"><a href="index.html#Asynchronous-Timeouts">Asynchronous Timeouts</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-timer"><code>timer</code></a>:</td><td> </td><td valign="top"><a href="index.html#Timers">Timers</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-timeval"><code>timeval</code></a>:</td><td> </td><td valign="top"><a href="index.html#Lisp-objects-and-C-structures">Lisp objects and C structures</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-V">V</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-vector-_005bcl_005d-1"><code>vector [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Extensible-Sequences">Extensible Sequences</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
<tr><th id="Type-Index_tp_letter-W">W</th><td></td><td></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-waitqueue"><code>waitqueue</code></a>:</td><td> </td><td valign="top"><a href="index.html#Waitqueue_002fcondition-variables">Waitqueue/condition variables</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-warning-_005bcl_005d"><code>warning [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#Diagnostic-Severity">Diagnostic Severity</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-warning-_005bcl_005d-1"><code>warning [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td></td><td valign="top"><a href="index.html#index-warning-_005bcl_005d-2"><code>warning [cl]</code></a>:</td><td> </td><td valign="top"><a href="index.html#The-Deprecation-Pipeline">The Deprecation Pipeline</a></td></tr>
|
|
<tr><td colspan="4"> <hr></td></tr>
|
|
</table>
|
|
<table><tr><th valign="top">Jump to: </th><td><a class="summary-letter" href="index.html#Type-Index_tp_letter-B"><b>B</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-C"><b>C</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-D"><b>D</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-E"><b>E</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-F"><b>F</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-G"><b>G</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-H"><b>H</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-I"><b>I</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-J"><b>J</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-L"><b>L</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-M"><b>M</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-N"><b>N</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-P"><b>P</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-Q"><b>Q</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-R"><b>R</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-S"><b>S</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-T"><b>T</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-V"><b>V</b></a>
|
|
|
|
<a class="summary-letter" href="index.html#Type-Index_tp_letter-W"><b>W</b></a>
|
|
|
|
</td></tr></table>
|
|
|
|
<hr>
|
|
<span id="Colophon"></span><div class="header">
|
|
<p>
|
|
Previous: <a href="index.html#Type-Index" accesskey="p" rel="prev">Type Index</a>, Up: <a href="index.html#Top" accesskey="u" rel="up">Top</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
|
|
</div>
|
|
<span id="Colophon-1"></span><h2 class="unnumbered">Colophon</h2>
|
|
|
|
<p>This manual is maintained in Texinfo, and automatically translated
|
|
into other forms (e.g. HTML or pdf). If you’re <em>reading</em> this
|
|
manual in one of these non-Texinfo translated forms, that’s fine, but
|
|
if you want to <em>modify</em> this manual, you are strongly advised to
|
|
seek out a Texinfo version and modify that instead of modifying a
|
|
translated version. Even better might be to seek out <em>the</em>
|
|
Texinfo version (maintained at the time of this writing as part of the
|
|
SBCL project at <a href="http://sbcl.sourceforge.net/">http://sbcl.sourceforge.net/</a>) and submit a
|
|
patch.
|
|
</p>
|
|
<div class="footnote">
|
|
<hr>
|
|
<h4 class="footnotes-heading">Footnotes</h4>
|
|
|
|
<h5><a id="FOOT1" href="index.html#DOCF1">(1)</a></h3>
|
|
<p>Historically, the ILISP package at
|
|
<a href="http://ilisp.cons.org/">http://ilisp.cons.org/</a> provided similar functionality, but it
|
|
does not support modern SBCL versions.</p>
|
|
<h5><a id="FOOT2" href="index.html#DOCF2">(2)</a></h3>
|
|
<p>Actually, this declaration is unnecessary in
|
|
SBCL, since it already knows that <code>position</code> returns a
|
|
non-negative <code>fixnum</code> or <code>nil</code>.</p>
|
|
<h5><a id="FOOT3" href="index.html#DOCF3">(3)</a></h3>
|
|
<p>A deprecated
|
|
extension <code>sb-ext:inhibit-warnings</code> is still supported, but
|
|
liable to go away at any time.</p>
|
|
<h5><a id="FOOT4" href="index.html#DOCF4">(4)</a></h3>
|
|
<p>Since the location of an interrupt or hardware
|
|
error will always be an unknown location, non-argument variable values
|
|
will never be available in the interrupted frame. See <a href="index.html#Unknown-Locations-and-Interrupts">Unknown Locations and Interrupts</a>.</p>
|
|
<h5><a id="FOOT5" href="index.html#DOCF5">(5)</a></h3>
|
|
<p>The variable bindings are actually created
|
|
using the Lisp <code>symbol-macrolet</code> special form.</p>
|
|
<h5><a id="FOOT6" href="index.html#DOCF6">(6)</a></h3>
|
|
<p>A motivation, rationale and additional examples for the design
|
|
of this extension can be found in the paper <cite>Rhodes, Christophe
|
|
(2007): User-extensible sequences in Common Lisp</cite> available for download
|
|
at
|
|
<a href="http://www.doc.gold.ac.uk/~mas01cr/papers/ilc2007/sequences-20070301.pdf">http://www.doc.gold.ac.uk/~mas01cr/papers/ilc2007/sequences-20070301.pdf</a>.</p>
|
|
<h5><a id="FOOT7" href="index.html#DOCF7">(7)</a></h3>
|
|
<p>In SBCL versions prior to 1.0.13, <code>sb-ext:run-program</code>
|
|
searched for executables in a manner somewhat incompatible with other
|
|
languages. As of this version, SBCL uses the system library routine
|
|
<code>execvp(3)</code>, and no longer contains the function,
|
|
<code>find-executable-in-search-path</code>, which implemented the old
|
|
search. Users who need this function may find it
|
|
in <samp>run-program.lisp</samp> versions 1.67 and earlier in SBCL’s CVS
|
|
repository here
|
|
<a href="http://sbcl.cvs.sourceforge.net/sbcl/sbcl/src/code/run-program.lisp?view=log">http://sbcl.cvs.sourceforge.net/sbcl/sbcl/src/code/run-program.lisp?view=log</a>. However,
|
|
we caution such users that this search routine finds executables that
|
|
system library routines do not.</p>
|
|
<h5><a id="FOOT8" href="index.html#DOCF8">(8)</a></h3>
|
|
<p>Please
|
|
note that the codepoint U+1F5CF (PAGE) introduced in Unicode 7.0 is
|
|
named <code>UNICODE_PAGE</code>, since the name “Page” is required to be
|
|
assigned to form-feed (U+0C) by the ANSI standard.</p>
|
|
<h5><a id="FOOT9" href="index.html#DOCF9">(9)</a></h3>
|
|
<p>See chapter 7 "Testing widely used RNGs" in
|
|
<cite>TestU01: A C Library for Empirical Testing of Random Number
|
|
Generators</cite> by Pierre L’Ecuyer and Richard Simard, ACM Transactions on
|
|
Mathematical Software, Vol. 33, article 22, 2007.</p>
|
|
<h5><a id="FOOT10" href="index.html#DOCF10">(10)</a></h3>
|
|
<p>The functionality contained in the package
|
|
<code>SB-UNIX</code> is for SBCL internal use only; its contents are likely to
|
|
change from version to version.</p>
|
|
<h5><a id="FOOT11" href="index.html#DOCF11">(11)</a></h3>
|
|
<p>See “namespace” entry in the glossary
|
|
of the Common Lisp Hyperspec.</p>
|
|
</div>
|
|
<hr>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|