CMU Users Manual

Rob ert A MacLachlan Editor

July

CMUCS

Scho ol of

Carnegie Mellon University

Pittsburgh PA

Sup ersedes Technical Rep orts CMUCS and CMUCS

Abstract

CMU Common Lisp is an implementation of that Common Lisp is currently supp orted on MIPSpro cessor

DECstations Sparcbased workstations from Sun and the IBM RT PC and other p orts are planned All

architectures are supp orted under MachaBerkeley binary compatible op erating system The Sparc is

also supp orted under SunOS The largest single part of this do cument describ es the Python and the

programming styles and techniques that the compiler encourages The rest of the do cument describ es extensions

and the implementation dep endentchoices made in developing this implementation of Common Lisp Wehave

added several extensions including a source level debugger an interface to Unix system calls a foreign function

call interface supp ort for interpro cess communication and remote pro cedure call and other features that provide

agoodenvironment for developing Lisp co de

This research was sp onsored by The Defense Advanced Research Pro jects Agency Information Science and Technology

Oce under the title Research on Parallel Computing ARPA Order No issued byDARPACMO under Contract

MDAC

The views and conclusions contained in this do cument are those of the author and should not b e interpreted as

represen ting the ocial p olicies either expressed or implied of the US government

Keywords lisp Common Lisp manual compiler implementation programming

environment

Contents

Introduction

Supp ort

Lo cal Distribution of CMU Common Lisp

Net Distribution of CMU Common Lisp

Source Availability

Command Line Options

Credits

Design Choices and Extensions

Data Typ es

Symb ols

Integers

Floats

Characters

Array Initialization

Default Interrupts for Lisp

Packages

The Editor

Garbage Collection

Describ e

The Insp ector

The Graphical Interface

The TTY Insp ector

Load

The Reader

Running Programs from Lisp

Pro cess Accessors

Saving a Core Image

Pathnames

Unix Pathnames

Wildcard Pathnames

Logical Pathnames

Search Lists

Predened SearchLists

SearchList Op erations

Search List Example

Filesystem Op erations

Wildcard Matching

File Name Completion

Miscellaneous Filesystem Op erations

Time Parsing and Formatting

Lisp i

CONTENTS ii

The Debugger

Debugger Intro duction

The Command Lo op

StackFrames

Stack Motion

How Arguments are Printed

Function Names

FunnyFrames

Debug Tail Recursion

Unknown Lo cations and Interrupts

Variable Access

Variable Value Availability

Note On Lexical Variable Access

Source Lo cation Printing

How the Source is Found

Source Lo cation Availability

Compiler Policy Control

Exiting Commands

Information Commands

Breakp oint Commands

Breakp oint Example

Function Tracing

Encapsulation Functions

Sp ecials

The Compiler

Compiler Intro duction

Calling the Compiler

Compilation Units

Undened Warnings

Interpreting Error Messages

The Parts of the Error Message

The Original and Actual Source

The Pro cessing Path

Error Severity

Errors During Macro expansion

Read Errors

Error Message Parameterization

Typ es in Python

Compile Time Typ e Errors

Precise Typ e Checking

Weakened Typ e Checking

Getting Existing Programs to Run

Compiler Policy

The Optimize Declaration

The OptimizeInterface Declaration

Op en Co ding and Inline Expansion

Advanced Compiler Use and Eciency Hints

Advanced Compiler Intro duction

Typ es

Optimization

Function Call

Represen tation of Ob jects

Writing Ecient Code

More Ab out Typ es in Python

CONTENTS iii

More Typ es Meaningful

Canonicalization

Member Typ es

Union Typ es

The EmptyTyp e

Function Typ es

The Values Declaration

Structure Typ es

The Freeze yp e Declaration

Typ e Restrictions

Typ e Style Recommendations

Typ e Inference

Variable Typ e Inference

Lo cal Function Typ e Inference

Global Function Typ e Inference

Op eration Sp ecic Typ e Inference

Dynamic Typ e Inference

Typ e Check Optimization

Source Optimization

Let Optimization

ConstantFolding

Unused Expression Elimination

Control Optimization

Unreachable Co de Deletion

Multiple Values Optimization

Source to Source Transformation

Style Recommendations

Tail Recursion

Tail Recursion Exceptions

Lo cal Call

SelfRecursive Calls

Let Calls

Closures

Lo cal Tail Recursion

Return Values

Blo ck Compilation

Blo ck Compilation Semantics

Blo ck Compilation Declarations

Compiler Arguments

Practical Diculties

Context Declarations

Context Declaration Example

Inline Expansion

Inline Expansion Recording

SemiInline Expansion

The Mayb eInline Declaration

Byte Co ded Compilation

Ob ject Represen tation

Think Before You Use a List

Structure Representation

Arrays

Vectors

BitVectors

Hashtables

Numb ers

CONTENTS iv

Descriptors

NonDescriptor Representations

Variables

Generic Arithmetic

Fixnums

Word Integers

Floating Point Eciency

Sp ecialized Arrays

Sp ecialized Structure Slots

Interactions With Lo cal Call

Represen tation of Characters

General Eciency Hints

Compile Your Co de

Avoid Unnecessary Consing

Complex ArgumentSyntax

Mapping and Iteration

Trace Files and Disassembly

Eciency Notes

Typ e Uncertainty

Eciency Notes and Typ e Checking

Represen tation Eciency Notes

Verb osityControl

Proling

Prole Interface

Proling Techniques

Nested or Recursive Calls

Clock resolution

Proling overhead

Additional Timing Utilities

A Note on Timing

Benchmarking Techniques

UNIX Interface

Reading the Command Line

Useful Variables

Lisp Equivalents for C Routines

Typ e Translations

System Area Pointers

Unix System Calls

File Descriptor Streams

Making Sense of Mach Return Co des

Unix Interrupts

Changing Interrupt Handlers

Examples of Signal Handlers

Event Dispatching with SERVEEVENT

Ob ject Sets

The SERVEEVENT Function

Using SERVEEVENT with Unix File Descriptors

Using SERVEEVENT with the CLX Interface to X

Without Ob ject Sets

With Ob ject Sets

A SERVEEVENT Example

Without Ob ject Sets Example

With Ob ject Sets Example

CONTENTS v

Alien Ob jects

Intro duction to Aliens

Alien Typ es

Dening Alien Typ es

Alien Typ es and Lisp Typ es

Alien Typ e Sp eciers

The CCall Package

Alien Op erations

Alien Access Op erations

Alien Coercion Op erations

Alien Dynamic Allo cation

Alien Variables

Lo cal Alien Variables

External Alien Variables

Alien Data Structure Example

Loading Unix Ob ject Files

Alien Function Calls

The alienfuncall Primitive

The defalienroutine Macro

defalienroutine Example

Calling Lisp from C

StepbyStep Alien Example

Interprocess Communication under LISP

The REMOTE Package

Connecting Servers and Clients

Remote Evaluations

Remote Ob jects

Host Addresses

The WIRE Package

Untagged Data

Tagged Data

Making Your Own Wires

OutOfBand Data

Debugger Programmers Interface

DI Exceptional Conditions

Debugconditions

Debugerrors

Debugvariables

Frames

Debugfunctions

Debugblo cks

Breakp oints

Co delo cations

Debugsources

Source Translation Utilities

Function Index

Variable Index

Typ e Index

Concept Index

Chapter

Intro duction

CMU Common Lisp is a publicdomain implementation of Common Lisp develop ed in the Computer Science

Department of Carnegie Mellon University CMU Common Lisp is currently supp orted on MIPSpro cessor

DECstations Sparcbased workstations from Sun and the IBM RT PC and other p orts are planned Currently

it runs under CMUs Mach op erating system OSF or SunOS This do cument describ es the implementation

based on the Python compiler Previous versions of CMU Common Lisp ran on the IBM RT PC and when known

as on the Perq workstation See man cmucl manmancmucl for other general information

CMU Common Lisp sources and executables are freely available via anonymousFTPthissoftware is as is

and has no warrantyofany kind CMU and the authors assume no resp onsibility for the consequences of any

use of this See docreleasenotestxt for a description of the state of the release you have

Supp ort

The CMU Common Lisp pro jects goal is to develop a high quality public domain system so wewantyour bug

rep orts bug xes and enhancements However sta limitations prevent us from providing extensive supp ort

to p eople outside of CMU We are lo oking for university and industrial aliates to help us with p orting and

maintenance for hardware and software that is not widely used at CMU

This manual contains only implementationsp ecic information ab out CMU Common Lisp Users will also

need a separate manual describing the Common Lisp standard Common Lisp was initially dened in Common

Lisp The Languageby Guy L Steele Jr Common Lisp is now undergoing standardization by the XJ

committee of ANSI The XJ sp ec is not y et completed but a numb er of clarications and modication have

b een approved Weintend that CMU Common Lisp will eventually adhere to the XJ sp ec and wehave

already implemented many of the changes approved by XJ

Until the XJ standard is completed the second edition of Common Lisp The Language is probably the

b est available manual for the language and for our implementation of it This b o ok has no ocial role in the

standardization pro cess but it do es include many of the changes adopted since the rst edition was completed

In addition to the language itself this do cument describ es a numb er of useful library modules that run in

CMU Common Lisp an like text editor is included as an integral part of the CMU Common

Lisp environment Two do cuments describ e Hemlock the Hemlock Users Manual and the Hemlock Command

Implementors Manual

Lo cal Distribution of CMU Common Lisp

At CMU you can get Common Lisp by running modmisc

usrcsetcmodmisc csmisccmucl

This establishes usrmisccmucl as a symb olic link to the release area In your login add CMU CL

to your path

setpath i usrmisccmucl

CHAPTER INTRODUCTION

Then run lisp Note that the rst time you run Lisp it will take AFS several minutes to copy the image into

its lo cal cache Subsequen t starts will b e much faster

Or you can run directly out of the AFS release area whichmay b e necessary on SunOS machines Put this

in your login shell script

setenv CMUCLLIB afscsmisccmuclsysbetalib

setpath i afscsmisccmuclsysbeta

After setting your path man cmucl will giveanintro duction to CMU CL and man lisp will describ e

command line options For SunOS installation notes see the README le in the SunOS release area

See usrmisccmucldoc for release notes and do cumentation Hardcopy do cumentation is available in

the do cument ro om Do cumentation supplements maybeavailable for recent additions see the README le

Send bug rep orts and questions to cmuclbugscscmuedu If you send a bug rep ort to gripeorhelp

they will just forward it to this mailing list

Net Distribution of CMU Common Lisp

Externally CMU Common Lisp is only available via anonymous FTPWe dont have the manpower to make

tap es These are our distribution machines

lisprtslispcscmuedu

lisprtslispcscmuedu

Log in with the user anonymous and usernamehost as password ie your EMAIL address When you

log in the curren t directory should b e set to the CMU Common Lisp release area If y ou haveany trouble with

FTP access please send mail to slispcscmuedu

The release area holds compressed tar les with names of the form

versionmachine ostarZ

FTP compressed tar archives in binary mode To extract cd to the directory that is to b e the ro ot of the tree

then typ e

uncompress filetarZ tar xf

The resulting tree is ab out megabytes For installation directions see the section site initialization in

README le at the ro ot of the tree

If poor network connections make it dicult to transfer a meg le the release is also available split into

ve parts with the sux to To extract from multiple les use

cat filetarZ uncompress tar xf

The release area also contains source distributions and other binary distributions A listing of the current

contents of the release area is in FILES Ma jor release announcements will b e made to complanglisp until

there is enough volume to warrantacomplanglispcmu

Source Availability

Lisp and do cumentation sources are available via anonymous FTP ftp to any CMU CS machine All CMU

written co de is public domain but CMU CL also makes use of two imported packages PCL and CLX Although

these packages are copyrighted they may b e freely distributed without any licensing agreement or fee See the

README le in the binary distribution for uptodate source p ointers

The release area contains a source distribution which is an image of all the lisp source les used to build

a particular system version

v ersionsourcetarZ meg

All of our les including the release area are actually in the AFS le system On the release machines the

FTP servers home is the release directory afscscmueduprojectrelease The actual working

source areas are in other sub directories of clisp and you can directly cd to those directories if you knowthe

name Due to the wayanonymous FTP access control is done it is important to cd to the source directory with a single command and then do a get op eration

CHAPTER INTRODUCTION

Command Line Options

The command line syntax and environment is describ ed in the lisp man page in the manman directory of

the distribution See also cmucl Currently Lisp accepts the following switches

core requires an argument that should b e the name of a core le Rather than using the default core le

usrmisclispliblispcore the sp ecied core le is loaded

edit sp ecies to enter Hemlock A le to edit may b e sp ecied by placing the name of the le b etween the

program name usually lisp and the rst switch

eval accepts one argumentwhich should b e a Lisp form to evaluate during the start up sequence The value

of the form will not b e printed unless it is wrapp ed in a form that do es output

hinit accepts an argument that should b e the name of the hemlock init le to load the rst time the function

ed is invoked The default is to load hemlockinitobjecttyp e or if that do es not exist hemlock

initlisp from the users home directory If the le is not in the users home directory the full path

must b e sp ecied

init accepts an argument that should b e the name of an init le to load during the normal start up sequence

The default is to load initob jecttyp e or if that do es not exist initlisp from the users home

directory If the le is not in the users home directory the full path must b e sp ecied

noinit accepts no arguments and sp ecies that an init le should not b e loaded during the normal start up

sequence Also this switch suppresses the loading of a hemlock init le when Hemlockisstartedupwith

the edit switch

load accepts an argumentwhich should b e the name of a le to load into Lisp b efore entering Lisps readeval

print loop

slave sp ecies that Lisp should start up as a sla ve Lisp and try to connect to an editor Lisp The

name of the editor to connect to must b e sp ecied to nd the editors name use the Hemlock

Accept Slave Connections command The name for the editor Lisp is of the form

machinename so cket

where machinename is the internet host name for the machine and so cket is the decimal number of the

so cket to connect to

For more details on the use of the edit and slave switches see the Hemlock Users Manual

Arguments to the ab ove switches can b e sp ecied in one of twoways switchvalue or switchspace value

For example to start up the saved core le mylispcore use either of the following two commands

lisp coremylispcore

lisp core mylispcore

Credits

Since many p eople have contributed to the development of CMU Common Lisp The currently active

memb ers are

David Axmark

Miles Bader

Ted Dunning

Scott Fahlman fearless leader

Mike Garland

Paul Gleichauf

Sean Hallgren

Simon Leinen

William Lott

Robert A Maclachlan Tim Moore

CHAPTER INTRODUCTION

Many p eople are voluntarily working on improving CMU Common Lisp means a fulltime CMU employee

and means a parttime student employee A partial listing of signicant past contributors follows

Rick Busdiecker

Bill Chiles

Chris Hoover

John Kolojejchick

Todd Kaufmann

Dave McDonald

Skef Wholey

This researc h was sp onsored by the Defense Advanced Researc h Pro jects Agency Information Science and

Technology Oce under the title Research on Parallel Computing issued byDARPACMO under Contract

MDAC ARPA Order No

The views and conclusions contained in this do cument are those of the authors and should not b e interpreted

as represen ting the ocial p olicies either expressed or implied of the Defense Advanced Research Pro jects

Agency or the US government

Chapter

Design Choices and Extensions

Several design choices in Common Lisp are left to the individual implementation and some essen tial parts of

the programming environment are left undened This chapter discusses the most important design choices and

extensions

Data Typ es

Symb ols

As in Common Lisp The Language all symb ols and package names are printed in lower case as a user is likely

to typ e them Internally they are normally stored upp er case only

Integers

The fixnum typ e is equivalenttosignedbyte Integers outside this range are represen ted as a bignum or

aword integer see section page Almost all integers that app ear in programs can b e represen ted as

a fixnumsointeger numb er consing is rare

Floats

CMU Common Lisp supp orts two oating p oint formats singlefloat and doublefloat These are im

plemented with IEEE single and double oat arithmetic resp ectively shortfloat is a synonym for single

floatandlongfloat is a synonym for doublefloat The initial value of readdefaultfloatformat

is singlefloat

Both singlefloat and doublefloat are represen ted with a p ointer descriptor so oat op erations can cause

numb er consing Numb er consing is greatly reduced if programs are written to allow the use of nondescriptor

represen tations see section page

IEEE Special Values

CMU Common Lisp supp orts the IEEE innity and NaN sp ecial values These nonnumeric values will only b e

generated when trapping is disabled for some oating p oint exception see section page so users of

the default conguration need not concern themselves with sp ecial values

extensionsshortfloatpositiveinfinity Constant

extensionsshortfloatnegativeinfinity Constant

extensionssinglefloatpositiveinfinity Constant

extensionssinglefloatnegativeinfinity Constant

extensionsdoublefloatpositiveinfinity Constant

extensionsdoublefloatnegativeinfinity Constant

CHAPTER DESIGN CHOICES AND EXTENSIONS

extensionslongfloatpositiveinfinity Constant

extensionslongfloatnegativeinfinity Constant

The values of these constants are the IEEE p ositive and negativeinnity ob jects for each oat format

extensionsfloatinfinityp x Function

This function returns true if x is an IEEE oat innity of either sign x must b e a oat

extensionsfloatnanp x Function

extensionsfloattrappingnanp x Function

floatnanp returns true if x is an IEEE NaN Not A Numb er ob ject floattrappingnanp returns

true only if x is a trapping NaN With either function x must b e a oat

NegativeZero

The IEEE oat format provides for distinct p ositive and negative zeros To test the sign on zero or anyother

oat use the Common Lisp floatsign function Negative zero prints as f or d

Denormalized Floats

CMU Common Lisp supp orts IEEE denormalized oats Denormalized oats provide a mechanism for grad

ual underow The Common Lisp floatprecision function returns the actual precision of a denormalized

oat which will b e less than floatdigits Note that in order to generate or even prin t denormalized

oats trapping must b e disabled for the underow exception see section page The Common Lisp

leastpositiveformatfloat constants are denormalized

extensionsfloatnormalizedp x Function

This function returns true if x is a denormalized oat x must b e a oat

Floating Point Exceptions

The IEEE oating p oint standard denes several exceptions that o ccur when the result of a oating p oint

op eration is unclear or undesirable Exceptions can b e ignored in which case some default action is taken such

as returning a sp ecial value When trapping is enabled for an exception a error is signalled whenever that

exception o ccurs These are the p ossible oating p oint exceptions

underflow This exception o ccurs when the result of an op eration is to o small to b e represen ted as a normal

ized oat in its format If trapping is enabled the floatingpointunderflow condition is signalled

Otherwise the op eration results in a denormalized oat or zero

overflow This exception o ccurs when the result of an op eration is to o large to b e represen ted as a oat in

its format If trapping is enabled the floatingpointoverflow exception is signalled Otherwise the

op eration results in the appropriate innity

inexact This exception o ccurs when the result of a oating p oint op eration is not exact ie the result

was rounded If trapping is enabled the extensionsfloatingpointinexact condition is signalled

Otherwise the rounded result is returned

invalid This exception o ccurs when the result of an op eration is illdened such as If trapping

is enabled the extensionsfloatingpointinvalid condition is signalled Otherwise a quiet NaN is

returned

dividebyzero This exception o ccurs when a oat is divided by zero If trapping is enabled the divide

byzero condition is signalled Otherwise the appropriate innity is returned

CHAPTER DESIGN CHOICES AND EXTENSIONS

Floating Point Rounding Mo de

IEEE oating p oint sp ecies four p ossible rounding modes

nearest In this mode the inexact results are rounded to the nearer of the two p ossible result values If the

neither p ossibility is nearer then the even alternativeischosen This form of rounding is also called round

to even and is the form of rounding sp ecied for the Common Lisp round function

positiveinfinity This mode rounds inexact results to the p ossible value closer to p ositive innityThisis

analogous to the Common Lisp ceiling function

negativeinfinity This mode rounds inexact results to the p ossible value closer to negative innityThisis

analogous to the Common Lisp floor function

zero This mode rounds inexact results to the p ossible value closer to zero This is analogous to the Common

Lisp truncate function

Warning Although the rounding mode can b e changed with setfloatingpointmodes use of anyvalue

other than the default nearest can cause unusual b ehavior since it will aect rounding done by Common

Lisp system co de as well as rounding in user co de In particular the unary round function will stop doing

roundtonearest on oats and instead do the selected form of rounding

Accessing the Floating PointModes

These functions can b e used to modify or read the oating p oint modes

extensionssetfloatingpointmodes key traps roundingmode Function

fastmode accruedexceptions

currentexceptions

extensionsgetfloatingpointmode Function s

The keyword arguments to setfloatingpointmodes set various modes controlling how oating p oint

arithmetic is done

traps A list of the exception conditions that should cause traps Possible exceptions are underflow

overflow inexact invalid and dividebyzero Initially all traps except inexact are enabled

See section page

roundingmode The rounding mode to use when the result is not exact Possible values are nearest

positiveinfinity negativeinfinity and zero Initially the rounding mode is nearestSee

the warning in section ab out use of other rounding modes

currentexceptions accruedexceptions Lists of exception keywords used to set the exception ags The

curren texceptions are the exceptions for the previous op eration so setting it is not very useful The

accruedexceptions are a cumulative record of the exceptions that o ccurred since the last time these ags

were cleared Sp ecifying will clear any accrued exceptions

fastmode Set the hardwares fast mode ag if any When set IEEE conformance or debuggabilitymaybe

impaired Some machines maynothave this feature in which case the value is always nil No currently

supp orted machines have a fast mode

Ifakeyword argument is not supplied then the asso ciated state is not changed

getfloatingpointmo des returns a list represen ting the state of the oating p ointmodes The list is in

the same format as the keyword arguments to setfloatingpointmodesso apply could b e used with set

floatingpointmodes to restore the modes in eect at the time of the call to getfloatingpointmodes

CHAPTER DESIGN CHOICES AND EXTENSIONS

Characters

CMU Common Lisp implements characters according to Common Lisp the Language I I The main dierence

from the rst version is that character bits and fonthave b een eliminated and the names of the typ es have b een

changed basecharacter is the new equivalentoftheoldstringchar In this implementation all characters

are base characters there are no extended characters Character co des range b etween and using the

ASCI I enco ding

Array Initialization

If no initialvalue is sp ecied arrays are initialized to zero

Default Interrupts for Lisp

CMU Common Lisp has several interrupt handlers dened when it starts up as follows

SIGINT c causes Lisp to enter a break lo op This puts you into the debugger which allows you to lo ok at the

curren t state of the computation If you pro ceed from the break loop the computation will pro ceed from

where it was interrupted

SIGQUIT causes Lisp to do a throw to the toplevel This causes the curren t computation to b e ab orted and

control returned to the toplevel readevalprintloop

SIGTSTP z causes Lisp to susp end execution and return to the Unix shell If control is returned to Lisp the

computation will pro ceed from where it was interrupted

SIGILL SIGBUS SIGSEGV and SIGFPE cause Lisp to signal an error

For keyb oard interrupt signals the standard interrupt c haracter is in parentheses Your loginmay set up

dierent interrupt characters When a signal is generated there may b e some delay b efore it is pro cessed since

Lisp cannot b e interrupted safely in an arbitrary place The computation will continue until a safe p ointis

reached and then the interrupt will b e pro cessed See section page to dene your own signal handlers

Packages

When CMU Common Lisp is rst started up the default package is the user package The user package uses

the commonlisp extensionsandpcl packages The symb ols exp orted from these three packages can b e

referenced without package qualiers This section describ es packages whichhave exp orted interfaces that may

concern users The numerous internal packages which implement parts of the system are not describ ed here

Package nicknames are in parenthesis after the full name

alien ccall Exp ort the features of the Alien foreign data structure facility see section page

pcl This package contains PCL Portable CommonLoops which is a p ortable implementation of CLOS the

Common Lisp Ob ject System This implements most but not all of the features in the CLOS chapter

of Common Lisp The Language

debug The debug package contains the commandline oriented debugger It exp orts utilityv arious functions and

switches

debuginternals The debuginternals package exp orts the primitives used to write debuggers See section

page

extensions ext The extensions packages exp orts local extensions to Common Lisp that are do cumented in

this manual Examples include the savelisp function and time parsing

hemlock ed The hemlock package contains all the co de to implement Hemlock commands The hemlock

package currently exp orts no symb ols

CHAPTER DESIGN CHOICES AND EXTENSIONS

hemlockinternals hi The hemlockinternals package contains co de that implements low level primitives

and exp orts those symb ols used to write Hemlock commands

keyword The keyword package contains keywords eg start All symb ols in the keyword package are

exp orted and evaluate to themselves ie the value of the symb ol is the symbol itself

profile The profile package exp orts a simple runtime proling facility see section page

commonlisp cl lisp The commonlisp package exp orts all the symb ols dened by Common Lisp the Lan

guage and only those symb ols Strictly p ortable Lisp co de will dep end only on the symb ols exp orted from

the lisp package

unix mach These packages exp ort interfaces to generic BSD Unix and Mach see section page

system sys The system package contains functions and information necessary for system interfacing This

package is used by the lisp package and exp orts several symb ols that are necessary to interface to system

co de

commonlispuser user cluser The commonlispuser package is the default package and is where a users

co de and data is placed unless otherwise sp ecied This package exp orts no sym b ols

xlib The xlib package contains the Common Lisp X interface CLX to the X proto col This is mostly Lisp

co de with a couple of functions that are dened in C to connect to the server

wire The wire package exp orts a remote pro cedure call facility see section page

The Editor

The ed function invokes the Hemlock editor whichisdescribedinHemlock Users Manual and Hemlock Command

Implementors Manual Most users at CMU prefer to use Hemlocks slaveCommon Lisp mechanism which

provides an interactive buer for the readevalprint lo op and editor commands for evaluating and compiling

text from a buer into the slave Common Lisp Since the editor runs in the Common Lisp using slaves keeps

users from trashing their editor by developing in the same Common Lisp with Hemlock

Garbage Collection

CMU Common Lisp uses a stopandcopy garbage collector that compacts the items in dynamic space every time

it runs Most users cause the system to garbage collect GC frequently long b efore space is exhausted With

or megabytes of memory causing GCs more frequently on less garbage allows the system to GC without

much if any paging

The following functions invoke the garbage collector or control whether automatic garbage collection is in

eect

extensionsgc Function

This function runs the garbage collector If extgcverbose is nonnil then it invokes extgcnotify

before b efore GCing and extgcnotifyafter afterwards

extensionsgcoff Function

This function inhibits automatic garbage collection After calling it the system will not GC unless you call

extgc or extgcon

extensionsgcon Function

This function reinstates automatic garbage collection If the system would have GCed while automatic GC

was inhibited then this will call extgc

The following variables control the b ehavior of the garbage collector

CHAPTER DESIGN CHOICES AND EXTENSIONS

extensionsbytesconsedbetweengcs Variable

CMU Common Lisp automatically GCs whenever the amount of memory allocated to dynamic ob jects

exceeds the value of an internal variable After each GC the system sets this internal variable to the amount

of dynamic space in use at that p ointplusthevalue of the variable extbytesconsedbetweengcsThe

default value is

extensionsgcverbose Variable

This variable controls whether extgc invokes the functions in extgcnotifybefore and extgc

notifyafterIfgcverbose is nil extgc forego es printing any messages The default value is T

extensionsgcnotifybefore Variable

This variables value is a function that should notify the user that the system is ab out to GC It takes one

argument the amount of dynamic space in use b efore the GC measured in bytes The default value of this

variable is a function that prints a message similar to the following

GC threshold exceeded with bytes in use Commencing GC

extensionsgcnotifyafter Variable

This variables value is a function that should notify the user when a GC nishes The function must take

three arguments the amount of dynamic spaced retained by the GC the amoun t of dynamic space freed and

the new threshold which is the minimum amount of space in use b efore the next GC will o ccur All values are

byte quantities The default value of this variable is a function that prints a message similar to the following

GC completed with bytes retained and bytes freed

GC will next o ccur when at least bytes are in use

Note that a garbage collection will not happ en at exactly the new threshold printed by the default extgc

notifyafter function The system p erio dically checks whether this threshold has b een exceeded and only

then do es a garbage collection

extensionsgcinhibithook Variable

This variables value is either a function of one argumentornil When the system has triggered an automatic

GC if this variable is a function then the system calls the function with the amount of dynamic space currently

in use measured in bytes If the function returns nil then the GC o ccurs otherwise the system inhibits

automatic GC as if you had called extgcoff The writer of this ho ok is resp onsible for knowing when

automatic GC has b een turned o and for calling or providing a way to call extgcon The default value of

this variable is nil

extensionsbeforegchooks Variable

extensionsaftergchooks Variable

These variables values are lists of functions to call b efore or after any GC o ccurs The system provides these

purely for sideeect and the functions take no arguments

Describe

In addition to the basic function describ ed b elow there are a numb er of switches and other things that can b e

used to control describes b ehavior

Function describe ob ject optional stream

The describe function prints useful information ab out ob ject on stream which defaults to standard

outputFor any ob ject describe will printoutthetyp e Then it prints other information based on the typ e

of ob ject The typ es which are presently handled are

CHAPTER DESIGN CHOICES AND EXTENSIONS

hashtable describe prints the number of entries currently in the hash table and the numb er of buckets

curren tly allocated

function describe prints a list of the functions name if any and its formal parameters If the name has

function do cumentation then it will b e printed If the function is compiled then the le where it is dened

will b e printed as well

fixnum describe prints whether the integer is prime or not

symbol The symbols value prop erties and do cumentation are printed If the symb ol has a function denition

then the function is describ ed

If there is anything interesting to b e said ab out some component of the ob ject describ e will invoke itself recur

sively to describ e that ob ject The level of recursion is indicated by indenting output

extensionsdescribelevel Variable

The maximum level of recursive description allowed Initially two

extensionsdescribeindentation Variable

The numb er of spaces to indent for each level of recursive description initially three

extensionsdescribeprintlevel Variable

extensionsdescribeprintlength Variable

The values of printlevel and printlength during description Initially twoandve

The Insp ector

CMU Comm has b oth a graphical insp ector that uses X windows and a simple terminalbased insp ector

inspect optional ob ject Function

Inspect calls the insp ector on the optional argument ob jectIfob ject is unsupplied inspect immediately

returns nil Otherwise the b ehavior of insp ect dep ends on whether Lisp is running under X When inspect is

eventually exited it returns some selected Lisp ob ject

The Graphical Interface

CMU Common Lisp has an interface to which is functionally similar to CLM but works b etter in CMU

CL See

docmotiftoolkitdoc

docmotifinternalsdoc

This motif interface has b een used to write the insp ector and graphical debugger There is also a Lisp control

panel with a simple le management facility aprop os and insp ector dialogs and controls for setting global

options See the interface and toolkit packages

interfacelispcontrolpanel Function

This function creates a control panel for the Lisp pro cess

interfaceinterfacestyle Variable

When the graphical interface is loaded this variable controls whether it is used by inspect and the error

system If the value is graphics the default and the DISPLAY environmentvariable is dened the graphical

insp ector and debugger will b e invoked by inspect or when an error is signalled Possible values are graphics

and tty If the value is graphics but there is no X displaythenwe quietly use the TTY interface

CHAPTER DESIGN CHOICES AND EXTENSIONS

The TTY Insp ector

If X is unavailable a terminal insp ector is invoked The TTY insp ector is a crude interface to describe which

allows ob jects to b e traversed and maintains a history This insp ector prints information ab out and ob ject and a

numb ered list of the components of the ob ject The commandline based interface is a normal readevalprint

lo op but an integer n descends into the nth component of the current ob ject and symb ols with these sp ecial

names are interpreted as commands

U Move back to the enclosing ob ject As you descend into the components of an ob ject a stack of all the ob jects

previously seen is kept This command p ops you up one level of this stack

Q E Return the current ob ject from inspect

R Recompute ob ject display and print again Useful if the ob ject mayhave changed

D Display again without recomputing

H Showhelpmessage

Load

load lename key verbose print ifdoesnotexist Function

ifsourcenewer contents

As in standard Common Lisp this function loads a le containing source or ob ject co de into the running Lisp

Several CMU extensions have b een made to load to conveniently supp ort a variety of program le organizations

lename may b e a wildcard pathname such as lisp in which case all matching les are loaded

If lename has a pathnametype or extension then that exact le is loaded If the le has no extension

then this tells load to use a heuristic to load the right le The loadsourcetypes and loadobject

types variables b elow are used to determine the default source and ob ject le typ es If only the source or the

ob ject le exists but not b oth then that le is quietly loaded Similarly if b oth the source and ob ject le exist

and the ob ject le is newer than the source le then the ob ject le is loaded The value of the ifsourcenewer

argument is used to determine what action to take when b oth the source and ob ject les exist but the ob ject

le is out of date

loadob ject The ob ject le is loaded even though the source le is newer

loadsource The source le is loaded instead of the older ob ject le

compile The source le is compiled and then the new ob ject le is loaded

query Theuserisasked a yes or no question to determine whether the source or ob ject le is loaded

This argument defaults to the value of extloadifsourcenewer initially loadobject

The contents argument can b e used to override the heuristic based on the le extension that normally

determines whether to load the le as a source le or an ob ject le If nonnull this argumentmust b e either

source or binarywhich forces loading in source and binary mode resp ectivelyYou really shouldnt ever

need to use this argument

extensionsloadsourcetypes Variable

extensionsloadobjecttypes Variable

These variables are lists of p ossible pathnametype values for source and ob ject les to b e passed to load

These variables are only used when the le passed to load has no typ e in this case the p ossible source and

ob ject typ es are used to default the typ e in order to determine the names of the source and ob ject les

extensionsloadifsourcenewer Variable

This variable determines the default value of the ifsourcenewer argumenttoload Its initial value is

loadobject

CHAPTER DESIGN CHOICES AND EXTENSIONS

The Reader

extensionsignoreextracloseparentheses Variable

If this variable is t the default then the reader merely prints a warning when an extra close parenthesis is

detected instead of signalling an error

Running Programs from Lisp

It is p ossible to run programs from Lisp by using the following function

extensionsrunprogram program args key env wait pty input Function

ifinputdoesnotexist

output

Runprogram runs program in a child pro cess Program should b e a pathname or string naming the program

Args should b e a list of strings which this passes to program as normal Unix parameters For no arguments

sp ecify args as nil The value returned is either a pro cess structure or nil The pro cess interface follows the

description of runprogramIfrunprogram fails to fork the child pro cess it returns nil

Except for sharing le descriptors as explained in keyword argument descriptions runprogram closes all le

descriptors in the child pro cess b efore running the program When you are done using a pro cess call process

close to reclaim system resources You only need to do this when you supply stream for one of input

outputor errororyou supply pty nonnilYou can call processclose regardless of whether you must

to reclaim resources without p enaltyifyou feel safer

runprogram accepts the following keyword arguments

env This is an alist mapping keywords and simplestrings The default is extenvironmentlistIfenv

is sp ecied runprogram uses the value given and do es not combine the environment passed to Lisp with

the one sp ecied

wait If nonnil the default wait until the child pro cess terminates If nilcontinue running Lisp while the

child pro cess runs

pty This should b e one of t nil or a stream If sp ecied nonnil the subpro cess executes under a Unix

PTY If sp ecied as a stream the system collects all output to this pty and writes it to this stream If

sp ecied as tthe processpty slot contains a stream from whichyou can read the programs output and

to whichyou can write input for the program The default is nil

input This sp ecies how the program gets its input If sp ecied as a string it is the name of a le that contains

input for the child pro cess runprogram op ens the le as standard input If sp ecied as nil the default

then standard input is the le devnull If sp ecied as t the program uses the current standard input

This may cause some confusion if wait is nil since two pro cesses may use the terminal at the same time

If sp ecied as stream then the processinput slot contains an output stream Anything written to this

stream go es to the program as input Input may also b e an input stream that already contains all the

input for the pro cess In this case runprogram reads all the input from this stream b efore returning so

this cannot b e used to in teract with the pro cess

ifinputdoesnotexist This sp ecies what to do if the input le do es not exist The following values are

valid nil the default causes runprogram to return nil without doing anything create creates the

named le and error signals an error

output This sp ecies what happ ens with the programs output If sp ecied as a pathname it is the name of

a le that contains output the program writes to its standard output If sp ecied as nil the default all

output go es to devnull If sp ecied as t the program writes to the Lisp pro cesss standard output

This may cause confusion if wait is nil since two pro cesses may write to the terminal at the same time

If sp ecied as stream then the processoutput slot contains an input stream from whichyou can read the programs output

CHAPTER DESIGN CHOICES AND EXTENSIONS

ifoutputexists This sp ecies what to do if the output le already exists The following values are valid

nil causes runprogram to return nil without doing anything error the default signals an error

supersede overwrites the curren t le and append app ends all output to the le

error This is similar to output except the le b ecomes the programs standard error Additionally error

can b e output in which case the programs error output is routed to the same place sp ecied for output

If sp ecied as streamthe processerror contains a stream similar to the processoutput slot when

sp ecifying the output argument

iferrorexists This sp ecies what to do if the error output le already exists It accepts the same values

as ifoutputexists

statushook This sp ecies a function to call whenever the pro cess changes status This is esp ecially useful

when sp ecifying wait as nil The function takes the pro cess as a required argument

beforeexecve This sp ecies a function to run in the child pro cess b efore it b ecomes the program to run This

is useful for actions such as authenticating the child pro cess without modifying the parent Lisp pro cess

Pro cess Accessors

The following functions interface the pro cess returned by runprogram

extensionsprocessp thing Function

This function returns t if thing is a pro cess Otherwise it returns nil

extensionsprocesspid pro cess Function

This function returns the pro cess ID an integer for the pro cess

extensionsprocessstatus pro cess Function

This function returns the curren t status of pro cesswhich is one of running stopped exitedor

signaled

extensionsprocessexitcode pro cess Function

This function returns either the exit co de for pro cessifitisexited or the termination signal pro cess if it

is signaled The result is undened for pro cesses that are still alive

extensionsprocesscoredumped pro cess Function

This function returns t if someone used a Unix signal to terminate the pro cess and caused it to dump a Unix

core image

extensionsprocesspty pro cess Function

This function returns either the twoway stream connected to pro cess s Unix PTY connection or nil if there

is none

extensionsprocessinput pro cess Function

extensionsprocessoutput pro cess Function

extensionsprocesserror pro cess Function

If the corresp onding stream was created these functions return the input output or error le descriptor nil is returned if there is no stream

CHAPTER DESIGN CHOICES AND EXTENSIONS

extensionsprocessstatushook pro cess Function

This function returns the curren t function to call whenever pro cess s status changes This function takes the

pro cess as a required argument processstatushook is setfable

extensionsprocessplist pro cess Function

This function returns annotations supplied by users and it is setfable This is available solely for users to

asso ciate information with pro cess without having to build alists or hash tables of pro cess structures

extensionsprocesswait pro cess optional checkforstopp ed Function

This function waits for pro cess to nish If checkforstopped is nonnil this also returns when pro cess stops

extensionsprocesskill pro cess signal optional whom Function

This function sends the Unix signal to pro cess Signal should b e the numb er of the signal or a keyword with

the Unix name for example sigsegv Whom should b e one of the following

pid This is the default and it indicates sending the signal to pro cess only

processgroup This indicates sending the signal to pro cess s group

ptyprocessgroup This indicates sending the signal to the pro cess group curren tly in the foreground on the

Unix PTY connected to pro cess This last option is useful if the running program is a shell and you wish

to signal the program running under the shell not the shell itself If processpty of pro cess is nilusing

this option is an error

extensionsprocessalivep pro cess Function

This function returns t if pro cess s status is either running or stopped

extensionsprocessclose pro cess Function

This function closes all the streams asso ciated with pro cessWhenyou are done using a pro cess call this to

reclaim system resources

Saving a Core Image

A mechanism has b een provided to save a running Lisp core image and to later restore it This is convenientif

you dont want to load several les into a Lisp when you rst start it up The main problem is the large size of

each saved Lisp image typically at least megabytes

extensionssavelisp le key purify rootstructures initfunction Function

loadinitfile printherald siteinit

processcommandline

The savelisp function saves the state of the currently running Lisp core image in le The keyword

arguments have the following meaning

purify If nonNIL the default the core image is puried b efore it is saved This means moving accessible Lisp

ob jects from dynamic space into readonly and static space This reduces the amountofwork the garbage

collector must do when the resulting core image is b eing run Also if more than one Lisp is running on

the same machine this maximizes the amount of memory that can b e shared b etw een the two pro cesses

Ob jects in readonly and static space can never b e reclaimed even if all p ointers to them are dropp ed

rootstructures This should b e a list of the main entry p oints for the resulting core image The purication

pro cess tries to localize symb ols functions etc in the core image so that paging p erformance is improved

The default value is NIL which means that Lisp ob jects will still b e localized but probably not as optimally

as they could b e This argument has no meaning if purify is NIL

CHAPTER DESIGN CHOICES AND EXTENSIONS

initfunction This is the function that starts running when the created core le is resumed The default

function simply invokes the top level readevalprint lo op If the function returns the lisp will exit

loadinitfile If nonNIL then load an init le either the one sp ecied on the command line or

initfasltyp e or if initfasltyp e do es not exist initlisp from the users home directory

If the init le is found it is loaded into the resumed core le b efore the readevalprint lo op is entered

siteinit If nonNIL the name of the site init le to quietly load The default is librarysiteinitNo

error is signalled if the le do es not exist

printherald If nonNIL the default then print out the standard Lisp herald when starting

processcommandline If nonNIL the default pro cesses the command line switches and p erforms the ap

propriate actions

To resume a saved le typ e

lisp core file

Pathnames

In Common Lisp quite a few asp ects of pathname semantics are left to the implementation

Unix Pathnames

Unix pathnames are always parsed with a unixhost ob ject as the host and nil as the device The last two

dots in the namestring mark the typ e and version however if the rst character is a dot it is considered

part of the name If the last character is a dot then the pathname has the emptystring as its typ e The typ e

defaults to nil and the version defaults to newest

defun parse x

values pathnamename x pathnametype x pathnameversion x

parse foo foo NIL NEWEST

parse foobar foo bar NEWEST

parse foo foo NIL NEWEST

parse foobar foo bar NEWEST

parse NEWEST

parse foo foo NEWEST

parse foobar foo bar

parse foobarbaz foobar baz NEWEST

The directory of pathnames b eginning with a slash or a searchlist see section page is starts

absolute others start with relative The directory is parsed as up there is no namestring for back

pathnamedirectory usrfoobarbaz ABSOLUTE usr foo

pathnamedirectory foobarbaz RELATIVE UP foo

Wildcard Pathnames

Wildcards are supp orted in Unix pathnames If is sp ecied for a part of a pathname that is parsed as

wild can b e used as a directory name to indicate wildinferiors Filesystem op erations treat wild

inferiors the same as wild but pathname pattern matching eg for logical pathname translation see section

page matches anynumb er of directory parts with see see section page

emb edded in a pathname part matches anynumber of characters Similarlymatches exactly one

character and abmatches the characters aorb These pathname parts are parsed as pattern ob jects

Backslash can b e used as an escap e character in namestring parsing to prevent the next character from b eing

treated as a wildcard Note that if typ ed in a string constant the backslash must b e doubled since the string

reader also uses backslash as a quote pathnamename foobar foobar

CHAPTER DESIGN CHOICES AND EXTENSIONS

Logical Pathnames

If a namestring b egins with the name of a dened logical pathname host followed by a colon then it will b e parsed

as a logical pathname Both and wildcards are implemented loadlogicalpathnamedefaults on

name lo oks for a logical host denition le in librarynametranslations Note that library designates

the search list see section page initialized to the CMU CommonLisplib directorynotalogical

pathname The format of the le is a single list of twolists of the from and to patterns

footext usrramfootxt

foolisp usrramfool

Search Lists

Search lists are an extension to Common Lisp pathnames They serve a function somewhat similar to Common

Lisp logical pathnames but work more likeUnixPATH variables Search lists are used for two purp oses

They provide a convenient shorthand for commonly used directory names and

They allow the abstract directory structure indep endent sp ecication of le lo cations in program path

name constants similar to logical pathnames

Each search list has an asso ciated list of directories represen ted as pathnames with no name or typ e component

The namestring for any relative pathname may b e prexed with slist indicating that the pathname is relative

to the search list slist instead of to the current working directory Once qualied with a search list the pathname

is no longer considered to b e relative

When a search list qualied pathname is passed to a lesystem op eration suchasopen load or truename

each directory in the search list is successiv ely used as the ro ot of the pathname until the le is located When

a le is written to a searc h list directorytheleisalways written to the rst directory in the list

Predened SearchLists

These searchlists are initialized from the Unix environment or when Lisp was built

default The curren t directory at startup

home The users home directory

library The CMU Common Lisp lib directory CMUCLLIB environmentvariable

path The Unix command path PATH environmentvariable

target The ro ot of the tree where CMU Common Lisp was compiled

It can b e useful to redene these searchlists for example library can b e augmented to allow logical pathname

translations to b e lo cated and target can b e redened to p oint to where CMU Common Lisp system sources

are locally installed

SearchList Op erations

These op erations dene and access searchlist denitions A searc hlist name maybeparsedinto a pathname

b efore the searchlist is actually dened but the searchlist must b e dened b efore it can actually b e used in a

lesystem op eration

extensionssearchlist name Function

This function returns the list of directories asso ciated with the search list nameIfname is not a dened

searc h list then an error is signalled When set with setf the list of directories is changed to the new value If

the new value is just a namestring or pathname then it is interpreted as a oneelement list Note that unlike

Unix pathnames search list names are caseinsensitive

CHAPTER DESIGN CHOICES AND EXTENSIONS

extensionssearchlistdefinedp name Function

extensionsclearsearchlist name Function

searchlistdefinedp returns t if name is a dened search list name nil otherwise clearsearchlist

make the searc h list name undened

extensionsenumeratesearchlist var pathname result fform g Macro

This macro provides an interface to search list resolution The b o dy forms are executed with var b ound to

each successiv e p ossible expansion for nameIfname do es not contain a searc hlist then the b o dy is executed

exactly once Everything is wrapp ed in a blo cknamednilso return can b e used to terminate earlyTheresult

form default nilisevaluated to determine the result of the iteration

Search List Example

The search list code can b e dened as follows

setf extsearchlist code usrlispcode

It is now p ossible to use code as an abbreviation for the directory usrlispcode in all le op erations For

example you can now sp ecify codeevallisp to refer to the le usrlispcode evallisp

To obtain the value of a searchlist name use the function searchlist as follows

extsearchlist name

Where name is the name of a search list as describ ed ab ove For example calling extsearchlist on code

as follows

extsearchlist code

returns the list usrlispcode

Filesystem Op erations

CMU Common Lisp provides a numb er of extensions and optional features b eyond those require by Common

Lisp

Wildcard Matching

Unix lesystem op erations such as open will accept wildcard pathnames that match a single le of course

directory allows anynumb er of matches Filesystem op erations treat wildinferiors the same as wild

directory wildnamekey all checkforsubdirs Function

followlinks

The keyword arguments to this Common Lisp function are a CMU extension The arguments all default to

thave the following functions

all Include les b eginning with dot suchaslogin similar to ls a

checkforsubdirs Test whether les are directories similar to ls F

followlinks Call truename on each le which expands out all symb olic links Note that this option can

easily result in pathnames b eing returned whichhave a dierent directory from the one in the wildname

argument

Function extensionsprintdirectory wildname optionalstream key all verbose

returnlist

Print a directory of wildname listing to stream default standardoutput all and verbose both

default to nil and corresp ond to the aandl options of ls Normally this function returns nil but if

returnlist is true a list of the matched pathnames are returned

CHAPTER DESIGN CHOICES AND EXTENSIONS

File Name Completion

extensionscompletefile pathname key defaults ignoretypes Function

Attempt to complete a le name to the longest unambiguous prex If supplied directory from defaults

is used as the working directory when doing completion ignoretypes is a list of strings of the pathname

typ es aka extensions that should b e disregarded as p ossible matches binary le names etc

extensionsambiguousfiles pathname optionaldefaults Function

Return a list of pathnames for all the p ossible completions of pathname with resp ect to defaults

Miscellaneous Filesystem Op erations

extensionsdefaultdirectory Function

Return the current working directory as a pathname If set with setf set the working directory

extensionsfilewritable name Function

This function accepts a pathname and returns t if the curren t pro cess can write it and nil otherwise

extensionsunixnamestring pathname optionalforinput Function

This function converts pathname into a string that can b e used with UNIX system calls Searchlists and

wildcards are expanded forinput controls the treatment of searchlists when true the default and the le

exists anywhere on the searchlist then that absolute pathname is returned otherwise the rst elementofthe

searc hlist is used as the directory

Time Parsing and Formatting

Functions are provided to allow parsing strings containing time information and printing time in various formats

are available

extensionsparsetime timestring key erroronmismatch defaultseconds Function

defaultminutes defaulthours

defaultday

parsetime accepts a string containing a time eg Jan and returns the universal time if it is

successful If it is unsuccessful and the keyword argument erroronmismatch is nonnil it signals an error

Otherwise it returns nil The other keyword arguments have the following meaning

defaultseconds sp ecies the default value for the seconds value if one is not provided by timestringThe

default value is

defaultminutes sp ecies the default value for the minutes value if one is not provided by timestringThe

default value is

defaulthours sp ecies the default value for the hours value if one is not provided by timestring The default

value is

defaultday sp ecies the default value for the dayvalue if one is not provided by timestring The default

value is the current day

defaultmonth sp ecies the default value for the month value if one is not provided by timestring The default

value is the current month

defaultyear sp ecies the default value for the year value if one is not provided b y timestring The default

value is the current year

CHAPTER DESIGN CHOICES AND EXTENSIONS

defaultzone sp ecies the default value for the time zone value if one is not provided by timestringThe

default value is the curren t time zone

defaultweekday sp ecies the default value for the dayoftheweek if one is not provided by timestringThe

default value is the curren t day of the week

Any of the ab ovekeywords can b e given the value current which means to use the curren t value as determined

by a call to the op erating system

extensionsformatuniversaltime dest universaltime key timezone Function

style datefirst

printseconds

extensionsformatdecodedtime dest seconds minutes hours daymonth year key Function

formatuniversaltime formats the time sp ecied by universaltime formatdecodedtime formats the

time sp ecied by seconds minutes hours day month and year Dest is any destination accepted by the format

function The keyword argumen ts have the following meaning

timezone is an integer sp ecifying the hours west of Greenwich Timezone defaults to the curren t time zone

style sp ecies the style to use in formatting the time The legal values are

short sp ecies to use a numeric date

long sp ecies to format months and weekdays as words instead of numbers

abbreviated is similar to long except the words are abbreviated

government is similar to abbreviated except the date is of the form daymonth year instead of month

dayyear

datefirst if nonnil default will place the date rst Otherwise the time is placed rst

printseconds if nonnil default will format the seconds as part of the time Otherwise the seconds will

b e omitted

printmeridian if nonnil default will format AM or PM as part of the time Otherwise the AM

or PM will b e omitted

printtimezone if nonnil default will format the time zone as part of the time Otherwise the time zone

will b e omitted

printseconds if nonnil default will format the seconds as part of the time Otherwise the seconds will

b e omitted

printweekday if nonnil default will format the weekday as part of date Otherwise the weekday will b e

omitted

Lisp Library

The CMU Common Lisp pro ject maintains a collection of useful or interesting programs written by users of our

system The library is in libcontrib Two les there that users should read are

CATALOGTXT This le contains a page for eachentry in the libraryItcontains information such as the

author p ortability or dep endency issues how to load the entry etc

READMETXT This le describ es the librarys organization and all the p ossible pieces of information an

entrys catalog description could contain

Hemlock has a command Library Entry that displays a list of the curren t library entries in an editor buer

There are mode sp ecic commands that display catalog descriptions and load entries This is a simple and

convenient waytobrowse the library

Chapter

The Debugger

By Rob ert MacLachlan

Debugger Intro duction

The CMU Common Lisp debugger is unique in its level of supp ort for sourcelevel debugging of compiled co de

Although some other debuggers allow access of variables by name this seems to b e the rst Common Lisp

debugger that

Tells you when a variable do esnt haveavalue b ecause it hasnt b een initialized yet or has already b een

deallo cated or

Can display the precise source location corresp onding to a co de location in the debugged program

These features allow the debugging of compiled co de to b e made almost indistinguishable from interpreted co de

debugging

The debugger is an interactive command lo op that allows a user to examine the function call stack The

debugger is invoked when

A seriouscondition is signalled and it is not handled or

error is called and the condition it signals is not handled or

The debugger is explicitly invoked with the Common Lisp break or debug functions

Note thereare two debugger interfaces in CMU CL the TTY debugger describedbelow and the Motif

debugger Since the dierence is only in the user interface much of this chapter also applies to the Motif

version SeeSeesection page for a very brief discussion of the graphical interface

When you enter the TTY debugger it lo oks something like this

Error in function CAR

Wrong type argument should have been of type LIST

Restarts

Return to TopLevel

Debug type H for help

CAR

The rst group of lines describ e what the error was that put us in the debugger In this case car was called

on After Restarts isalistofallthewa ys that we can restart execution after this error In this case the

only option is to return to toplevel After printing its banner the debugger prints the current frame and the

debugger prompt

CHAPTER THE DEBUGGER

The Command Lo op

The debugger is an interactive readevalprintloopmuch like the normal toplevel but some symb ols are inter

preted as debugger commands instead of b eing evaluated A debugger command starts with the symb ol name

of the command p ossibly followed by some arguments on the same line Some commands prompt for additional

input Debugger commands can b e abbreviated byanyunambiguous prex help can b e typ ed as h he etc

For convenience some commands haveambiguous oneletter abbreviations f for frame

The package is not signicant in debugger commands any symb ol with the name of a debugger command

will work If you wanttoshow the value of a variable that happ ens also to b e the name of a debugger command

you can use the listlocals command or the debugvar function or you can wrap the variable in a progn to

hide it from the command loop

The debugger prompt is frame where frame is the numb er of the current frame Frames are numb ered

starting from zero at the top most recen t call increasing down to the b ottom The curren t frame is the frame

that commands refer to The current frame also provides the lexical environment for evaluation of noncommand

forms

The debugger evaluates forms in the lexical environment of the functions b eing debugged The debugger

can only access variables You cant go or returnfrom into a function and you cant call lo cal functions

Sp ecial variable references are evaluated with their current value the innermost binding around the debugger

invo cation you dont get the value that the sp ecial had in the curren t frame See section page for

more information on debugger variable access

StackFrames

A stack frame is the runtime represen tation of a call to a function the frame stores the state that a function

needs to rememb er what it is doing Frames have

Variables see section page which are the values b eing op erated on and

Arguments to the call which are really just particularly interesting variables and

A current location see section page which is the place in the program where the function was

running when it stopp ed to call another function or b ecause of an interrupt or error

Stack Motion

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

up Move up to the next higher frame More recen t function calls are considered to b e higher on the stack

down Movedown to the next lower frame

top Move to the highest frame

bottom Move to the lowest frame

frame n Move to the frame with the sp ecied numb er Prompts for the numb er if not supplied

How Arguments are Printed

A frame is printed to lo ok like a function call but with the actual argumentvalues in the argument p ositions

So the frame for this call in the source

myfun a

would look like this MYFUN A

CHAPTER THE DEBUGGER

All keyword and optional arguments are displayed with their actual values if the corresp onding argumentwas

not supplied the value will b e the default So this call

subseq foo

would look like this

SUBSEQ foo

And this call

stringupcase test case

would look like this

STRINGUPCASE test case START END NIL

The arguments to a function call are displayed by accessing the argumentvariables Although those variables

are initialized to the actual argumentvalues they can b e set inside the function in this case the new value will

b e displayed

rest arguments are handled somewhat dierentlyThevalue of the rest argumentvariable is displayed as

the spreadout arguments to the call so

format t A is a A This test

would look like this

FORMAT T A is a A This TEST

Rest arguments cause an exception to the normal displayofkeyword arguments in functions that haveboth

rest and key arguments In this case the keyword argumentvariables are not displayed at all the rest arg

is displayed instead So for these functions only the keywords actually supplied will b e shown and the values

displayed will b e the argumentvalues not values of the p ossibly modied variables

If the variable for an argument is never referenced by the function it will b e deleted The variable value is

then unavailable so the debugger prints unusedarg instead of the value Similarly ifforanyofanumber

of reasons describ ed in more detail in section the value of the variable is unavailable or not known to b e

available then unavailablearg will b e printed instead of the argumentvalue

Printing of argumentvalues is controlled by debugprintlevel and debugprintlength page

Function Names

If a function is dened by defun labelsor flet then the debugger will print the actual function name after

the op en parenthesis like

STRINGUPCASE test case START END NIL

SETF AREF a for

Otherwise the function name is a string and will b e printed in quotes

DEFUN MYFUN BAR

DEFMACRO DO DO I I I NIL

SETQ GCNOTIFYBEFORE

This string name is derived from the defmumble form that encloses or expanded into the lamb da or the

outermost enclosing form if there is no defmumble

CHAPTER THE DEBUGGER

FunnyFrames

Sometimes the evaluator intro duces new functions that are used to implement a user function but are not directly

sp ecied in the source The main place this is done is for checking argumenttyp e and syntax Usually these

functions do their thing and then go awayandthus are not seen on the stack in the debugger But when you

get some sort of error during lamb dalist pro cessing you end up in the debugger on one of these funny frames

These funny frames are agged byprinting keyword after the parentheses For example this call

car a b

will look like this

CAR A EXTERNAL

And this call

stringupcase test case end

would look like this

DEFUN STRINGUPCASE test case OPTIONAL

As you can see these frames haveonlyavague resemblance to the original call Fortunately the error

message displayed when you enter the debugger will usually tell you what problem is in these cases to o many

arguments and odd keyword arguments Also if you go down the stack to the frame for the calling function

you can display the original source see section page

With recursive or block compiled functions see section page an EXTERNAL frame may app ear

b efore the frame represen ting the rst call to the recursive function or entry to the compiled blo ck This is a

consequence of the way the compiler do es block compilation there is nothing o dd with your program You will

also see CLEANUP frames during the execution of unwindprotect cleanup co de Note that inline expansion and

op enco ding aect what frames are presen t in the debugger see sections and

Debug Tail Recursion

Both the compiler and the interpreter are prop erly tail recursive If a function call is in a tailrecursive

p osition the stack frame will b e deallocated at the time of the call rather than after the call returns Consider

this backtrace

BAR

FOO

Because of tail recursion it is not necessarily the case that FOO directly called BARItmay b e that FOO called

some other function FOO which then called BAR tailrecursively as in this example

defun foo

foo

defun foo

bar

defun bar

Usually the elimination of tailrecursive frames makes debugging more pleasant since theses frames are mostly

uninformative If there is any doubt ab out how one function called another it can usually b e eliminated by

nding the source location in the calling frame section

For a more thorough discussion of tail recursion see section page

CHAPTER THE DEBUGGER

Unknown Lo cations and Interrupts

The debugger op erates using sp ecial debugging information attached to the compiled co de This debug infor

mation tells the debugger what it needs to know ab out the locations in the co de where the debugger can b e

invoked If the debugger somehow encounters a location not describ ed in the debug information then it is said

to b e unknown If the co de location for a frame is unknown then some variables may b e inaccessible and the

source location cannot b e precisely displayed

There are three reasons why a co de lo cation could b e unknown

There is inadequate debug information due to the value of the debug optimization quality See section

page

The debugger was entered b ecause of an interrupt such as C

A hardware error suchasbus error o ccurred in co de that was compiled unsafely due to the value of

the safety optimization quality See section page

In the last two cases the values of argumentvariables are accessible but may b e incorrect See section

page for more details on when variable values are accessible

It is p ossible for an interrupt to happ en when a function call or return is in progress The debugger may

then ame out with some obscure error or insist that the b ottom of the stack has b een reached when the real

problem is that the current stack frame cant b e located If this happ ens return from the interrupt and try

again

When running interpreted co de all lo cations should b e known However an interrupt might catch some

subfunction of the interpreter at an unknown location In this case you should b e able to go up the stacka

frame or two and reach an interpreted frame which can b e debugged

Variable Access

There are three ways to access the curren t frames lo cal variables in the debugger The simplest is to typ e the

v ariables name into the debuggers readevalprint lo op The debugger will evaluate the variable reference as

though it had app eared inside that frame

The debugger doesnt really understand lexical scoping it has just one namespace for all the variables in

a function If a symb ol is the name of multiple variables in the same function then the reference app ears

ambiguous even though lexical scoping sp ecies whichvalue is visible at anygiven source location If the scop es

of the twovariables are not nested then the debugger can resolve the ambiguityby observing that only one

variable is accessible

When there are ambiguous variables the evaluator assigns eachoneasmallinteger identier The debugvar

function and the listlocals command use this identier to distinguish b etween ambiguous variables

listlocals prex

This command prints the name and value of all variables in the curren t frame whose name has the sp ecied

prex prex may b e a string or a symb ol If no prex is given then all available variables are printed If

avariable has a p otentially ambiguous name then the name is printed with a identier sux where

identier is the small integer used to make the name unique

debugvar name optional identier Function

This function returns the value of the variable in the current frame with the sp ecied name If supplied

identier determines whichvalue to return when there are ambiguous v ariables

When name is a symb ol it is interpreted as the symb ol name of the variable ie the package is signicant

If name is an uninterned symb ol gensym then return the value of the uninterned variable with the same name

If name is a string debugvar interprets it as the prex of a variable name and must unambiguously complete

to the name of a valid variable

This function is useful mainly for accessing the value of uninterned or ambiguous variables since most

variables can b e evaluated directly

CHAPTER THE DEBUGGER

Variable Value Availability

The value of a variable may b e unavailable to the debugger in p ortions of the program where Common Lisp says

that the variable is dened 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 displayanincorrectvalue for a variable Rather than

displaying incorrect values the debugger tells you the value is unavailable

The one exception is this if you interrupt eg with C or if there is an unexp ected hardware error such

as bus error which should only happ en in unsafe co de then the values displayed for arguments to the

interrupted frame might b e incorrect This exception applies only to the interrupted frame any frame farther

down the stack will b e ne

The value of a variable maybeunavailable for these reasons

The value of the debug optimization qualitymayhave omitted debug information needed to determine

whether the variable is available Unless a variable is an argument its value will only b e available when

debug is at least

The compiler did lifetime analysis and determined that the value was no longer needed even though its

scop e had not b een exited Lifetime analysis is inhibited when the debug optimization qualityis

The v ariables name is an uninterned symb ol gensym Tosave space the compiler only dumps debug

information ab out uninterned variables when the debug optimization qualityis

The frames lo cation is unknown see section page b ecause the debugger was entered due to an

interrupt or unexp ected hardware error Under these conditions the values of arguments will b e available

but might b e incorrect This is the exception ab ove

The variable was optimized out of existence Variables with no reads are always optimized awayeven

in the interpreter The degree to which the compiler deletes variables will dep end on the value of the

compilespeed optimization quality but most sourcelevel optimizations are done under all compilation

p olicies

Since it is esp ecially useful to b e able to get the arguments to a function argumentvariables are treated

sp ecially when the speed optimization quality is less than and the debug quality is at least With this

compilation p olicythevalues of argumentvariables are almost always available everywhere in the function even

at unknown lo cations For nonargumentvariables debug must b e at least for values to b e available and even

then values are only available at known lo cations

Note On Lexical Variable Access

When the debugger command lo op establishes v ariable bindings for available variables these variable bindings



have lexical scop e and dynamic extent You can close over them but such closures cant b e used as upward

funargs

You can also set local variables using setq but if the variable was closed over in the original source and

never set then setting the variable in the debugger maynotchange the value in all the functions the variable is

dened in Another risk of setting variables is that you may assign a value of a typ e that the compiler proved

the variable could never take on This may result in bad things happ ening

Source Lo cation Printing

One of CMU Common Lisps unique capabilities is source level debugging of compiled co de These commands

display the source lo cation for the current frame

source context

This command displays the le that the current frames function was dened from if it was dened from a

le and then the source form resp onsible for generating the co de that the curren t frame was executing If

context is sp ecied then it is an integer sp ecifying the numb er of enclosing levels of list structure to print

Since the lo cation of an interrupt or hardware error will always b e an unknown lo cation see section page nonargument

variable values will never b e available in the interrupted frame



The variable bindings are actually created using the Common Lisp symbolmacrolet sp ecial form

CHAPTER THE DEBUGGER

vsource context

This command is identical to source except that it uses the global values of printlevel and print

length instead of the debugger printing control variables debugprintlevel and debugprint

length

The source form for a lo cation in the co de is the innermost list presen t in the original source that encloses

the form resp onsible for generating that co de If the actual source form is not a list then some enclosing list

will b e printed For example if the source form was a reference to the variable somerandomspecial then

the innermost enclosing evaluated form will b e printed Here are some p ossible enclosing forms

let a somerandomspecial

somerandomspecial

If the co de at a location was generated from the expansion of a macro or a sourcelevel compiler opti

mization then the form in the original source that expanded into that co de will b e printed Supp ose the le

usrmemystufflisplooked like this

defmacro mymac

myfun

defun foo

mymac

If foo has called myfun and is waiting for it to return then the source command would print

File usrmemystufflisp

MYMAC

Note that the macro use was printed not the actual function call form myfun

If enclosing source is printed by giving an argumenttosource or vsource then the actual source form is

marked by wrapping it in a list whose rst elementisHERE In the previous example source would

print

File usrmemystufflisp

DEFUN FOO

HERE

MYMAC

How the Source is Found

If the co de was dened from Common Lisp by compile or eval then the source can always b e reliably located

If the co de was dened from a fasl le created by compilefile then the debugger gets the source forms it

prints by reading them from the original source le This is a p otential problem since the source le mighthave

moved or changed since the time it was compiled

The source le is op ened using the truename of the source le pathname originally given to the compiler

This is an absolute pathname with all logical names and symb olic links expanded If the le cant b e lo cated

using this name then the debugger gives up and signals an error

If the source le can b e found but has b een modied since the time it was compiled the debugger prints

this warning

File has been modified since compilation

lename Using form offset instead of character position

CHAPTER THE DEBUGGER

where lename is the name of the source le It then pro ceeds using a robust but not fo olproof heuristic for

lo cating the source This heuristic works if

No toplevel forms b efore the toplevel form containing the source have b een added or deleted and

The toplevel form containing the source has not b een modied much More preciselynoneofthelist

forms b eginning b efore the source form have b een added or deleted

If the heuristic do esnt work the displayed source will b e wrong but will probably b e near the actual source

If the shap e of the toplevel form in the source le is to o dierent from the original form then an error will

b e signalled When the heuristic is used the the source location commands are noticeably slowed

Source lo cation printing can also b e confused if after the source was compiled a readmacro you used in the

co de was redened to expand into something dierent or if a readmacro ever returns the same eq list twice If

you dont dene read macros and dont use in p erverted ways you dont need to worry ab out this

Source Lo cation Availability

Source lo cation information is only available when the debug optimization quality is at least If source lo cation

information is unavailable the source commands will give an error message

If source lo cation information is available but the source location is unknown b ecause of an interrupt or

unexp ected hardware error see section page then the command will print

Unknown location using block start

and then pro ceed to print the source lo cation for the start of the basic blo ck enclosing the co de location Its a

bit complicated to explain exactly what a basic blo ck is but here are some prop erties of the blo ck start location

The block start location may b e the same as the true location

The block start location will never b e later in the the programs owofcontrol than the true lo cation

No conditional control structures such as if cond or will intervene b etween the blo ck start and the

true lo cation but note that some conditionals presen t in the original source could b e optimized away

Function calls do not end basic blo cks

The head of a loop will b e the start of a block

The programming language concept of block structure and the Common Lisp block sp ecial form are

totally unrelated to the compilers basic blo ck

In other words the true lo cation lies b etween the printed location and the next conditional but watch out

b ecause the compiler mayhavechanged the program on you

Compiler Policy Control

The compilation p olicy sp ecied by optimize declarations aects the b ehavior seen in the debugger The

debug quality directly aects the debugger bycontrolling the amount of debugger information dumped Other

optimization qualities have indirect but observable eects due to changes in the way compilation is done

Unlike the other optimization qualities which are compared in relativevalue to evaluate tradeos the debug

optimization quality is directly translated to a level of debug information This absolute interpretation allows

the user to count on a particular amount of debug information b eing available even when the values of the other

qualities are changed during compilation These are the levels of debug information that corresp ond to the values

of the debug quality

Only the function name and enough information to allow the stac ktobeparsed

Any level greater than gives level plus all argumentvariables Values will only b e accessible if the

argumentvariable is never set and speed is not CMU Common Lisp allows anyrealvalue for opti

mization qualities It may b e useful to sp ecify to get backtrace argumentdisplay without argument

do cumentation

CHAPTER THE DEBUGGER

Level provides argument do cumentation printed arglists and derived argumentresult typ e information

This makes describe more informative and allows the compiler to do compiletime argumentcount and

typ e checking for any calls compiled at runtime

Level plus all interned local variables source lo cation information and lifetime information that tells the

debugger when arguments are available even when speed is or the argument is set This is the default

Level plus all uninterned variables In addition lifetime analysis is disabled even when speed is ensuring

that all variable values are available at anyknown location within the scop e of the binding This has a

sp eed p enalty in addition to the obvious space p enalty

As you can see if the speed qualityis debugger p erformance is degraded This eect comes from the

elimination of argumentvariable sp ecialcasing see section page Some degree of sp eeddebuggability

tradeo is unavoidable but the eect is not to o drastic when debug is at least

In addition to inline and notinline declarations the relativevaluesofthe speed and space qualities also

change whether functions are inline expanded see section page If a function is inline expanded then

there will b e no frame to represen t the call and the arguments will b e treated likeany other lo cal v ariable

Functions mayalsobesemiinlineinwhich case there is a frame to represen t the call but the call is to an

optimized local version of the function not to the original function

Exiting Commands

These commands get you out of the debugger

quit Throw to top level

restart n

Invokes the nth restart case as displayed bytheerror command If n is not sp ecied the available restart

cases are rep orted

go Calls continue on the condition given to debug If there is no restart case named continue then an error is

signaled

abort Calls abort on the condition given to debug This is useful for p opping debug command lo op levels or

ab orting to top level as the case maybe

Information Commands

Most of these commands print information ab out the curren t frame or function but a few show general infor

mation

help Displays a synopsis of debugger commands

describe Calls describe on the current function displays number of local variables and indicates whether the

function is compiled or interpreted

print Displays the current function call as it would b e displayed bymoving to this frame

vprint or pp verb osity

Displa ys the current function call using printlevel and printlength instead of debugprint

level and debugprintlength verb osity is a small integer default that controls other dimensions

of verb osity

error Prints the condition given to invokedebugger and the active pro ceed cases

backtrace n

Displays all the frames from the current to the b ottom Only shows n frames if sp ecied The printing is

controlled by debugprintlevel and debugprintlength

CHAPTER THE DEBUGGER

Breakp oint Commands

CMU Common Lisp supp orts setting of breakp oints inside compiled functions and stepping of compiled co de

Breakp oints can only b e set at at known lo cations see section page so these commands are largely

useless unless the debug optimize quality is at least see section page These commands manipulate

breakp oints

breakpoint lo cation foption value g

Set a breakp oint in some function location maybeaninteger co de location numb er as displayed by list

locationsora keyword The keyword can b e used to indicate setting a breakp oint at the function start

start s or function end end e The breakpoint command has condition break print and

function options whichwork similarly to the trace options

listlocations or ll function

List all the co de locations in the current frames function or in function if it is supplied The display

format is the co de lo cation numb er a colon and then the source form for that lo cation

N

If consecutive lo cations have the same source then a numeric range like will b e printed For example

a default function call has a known lo cation b oth immediately b efore and after the call whichwould result

in two co de locations with the same source The listed function b ecomes the new default function for

breakp oin t setting via the breakpoint command

listbreakpoints or lb

List all currently active breakp oints with their breakp ointnumber

deletebreakpoint or db number

Delete a breakp oint sp ecied by its breakp ointnumb er If no numb er is sp ecied delete all breakp oints

step

Step to the next p ossible breakp oint lo cation in the current function This always steps over function calls

instead of stepping into them

Breakp oint Example

Consider this denition of the factorial function

defun n

if zerop n

n n

This debugger session demonstrates the use of breakp oints

commonlispuser break Invoke debugger

Break

Restarts

CONTINUE Return from BREAK

ABORT Return to TopLevel

Debug type H for help

INTERACTIVEEVAL BREAK

ll

LAMBDA N BLOCK IF ZEROP N

CHAPTER THE DEBUGGER

N N

N

N

N N

LAMBDA N BLOCK IF

br

N N

in

Added

q

commonlispuser Call the function

Breakpoint hit

Restarts

CONTINUE Return from BREAK

ABORT Return to TopLevel

Debug type H for help

We are now in first call arg before the multiply

Source N N

st

Step

We have finished evaluation of n

Source N

st

Breakpoint hit

Restarts

CONTINUE Return from BREAK

ABORT Return to TopLevel

Debug type H for help

We hit the breakpoint in the recursive call

Source N N

Function Tracing

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 breakp oints on function entry or exit

trace foption globalvalue g fname foption value g g Macro

trace is a debugging to ol that prints information when sp ecied functions are called In its simplest form

trace name name

trace causes a printout on traceoutput each time that one of the named functions is entered or returns

the names are not evaluated Trace output is indented according to the numb er of p ending traced calls and

CHAPTER THE DEBUGGER

this trace depth is printed at the b eginning of each line of output Printing verb osity of arguments and return

values is controlled by debugprintlevel and debugprintlength

If no names or options are are given trace returns the list of all currently traced functions traced

functionlist

Trace options can cause the normal printout to b e suppressed or cause extra information to b e printed

Each option is a pair of an option keyword and a value form Options maybeintersp ersed with function names

Options only aect tracing of the function whose name they app ear immediately after Global options are

sp ecied b efore the rst name and aect all functions traced byagiven use of trace If an already traced

function is traced again any new options replace the old options The following options are dened

condition form conditionafter form conditionall form

If condition is sp ecied then trace do es nothing unless form evaluates to true at the time of the call

conditionafter is similar but suppresses the initial printout and is tested when the function returns

conditionall tries b oth b efore and after

wherein names

If sp ecied names is a function name or list of names trace do es nothing unless a call to one of those

functions encloses the call to this function ie it would app ear in a backtrace Anonymous functions

have string names like DEFUN FOO

break form breakafter form breakall form

If sp ecied and form evaluates to true then the debugger is inv oked at the start of the function at the

end of the function or b oth according to the resp ective option

print form printafter form printall form

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 b oth according to the resp ective option Multiple print options cause multiple

values to b e printed

function functionform

This is a not really an option but rather another way of sp ecifying what function to trace The function

form is evaluated immediately and the resulting function is traced

encapsulate fdefault t nil g

In CMU Common Lisp tracing can b e done either by temporarily redening the function name encap

sulation or using breakp oints When breakp oints are used the function ob ject itself is destructiv ely

modied to cause the tracing action The advantage of using breakp oints is that tracing works even when

the function is anonymously called via funcall

When encapsulate is true tracing is done via encapsulation default is the default and means

to use encapsulation for interpreted functions and funcallable instances breakp oints otherwise When

encapsulation is used forms are not evaluated in the functions lexical environment but debugarg can

still b e used

condition break and print forms are evaluated in the lexical environment of the called function

debugvar and debugarg can b e used The after and all forms are evaluated in the null environment

Macro untrace rest functionnames

This macro turns o tracing for the sp ecied functions and removes their names from tracedfunction

listIfnofunctionnames are given then all curren tly traced functions are untraced

extensionstracedfunctionlist Variable

A list of function names maintained and used by trace untraceand untraceall This list should contain

the names of all functions currently b eing traced

extensionsmaxtraceindentation Variable

The maximum numb er of spaces which should b e used to indent trace printout This variable is initially set to

CHAPTER THE DEBUGGER

Encapsulation Functions

The encapsulation functions provide a mechanism for intercepting the arguments and results of a function

encapsulate changes the function denition of a symbol and saves it so that it can b e restored later The new

denition normally calls the original denition The Common Lisp fdefinition function always returns the

original denition stripping o any encapsulation

The original denition of the symb ol can b e restored at any time bytheunencapsulate function

encapsulate and unencapsulate allow a symbol to be multiply encapsulated in such a way that dierent

encapsulations can b e completely transparent to each other

Each encapsulation has a typ e whichmay b e an arbitrary lisp ob ject If a symb ol has several encapsulations

of dierent typ es then any one of them can b e removed without aecting more recen t ones A symbol mayhave

more than one encapsulation of the same typ e but only the most recen t one can b e undone

extensionsencapsulate symbol typ e b o dy Function

Saves the current denition of symbol and replaces it with a function which returns the result of evaluating

the form body Typ e is an arbitrary lisp ob ject whichisthetyp e of encapsulation

When the new function is called the following variables are b ound for the evaluation of body

extensionsargumentlist A list of the arguments to the function

extensionsbasicdefinition The unencapsulated denition of the function

The unencapsulated denition may b e called with the original arguments by including the form

apply extensionsbasicdefinition extensionsargumentlist

encapsulate always returns symbol

extensionsunencapsulate symbol typ e Function

Undo es symbols most recen t encapsulation of typ e typ e Typ e is compared with eq Encapsulations of other

typ es are left in place

extensionsencapsulatedp symbol typ e Function

Returns t if symbol has an encapsulation of typ e typ e Returns nil otherwise Typ e is compared with eq

Sp ecials

These are the sp ecial variables that control the debugger action

extensionsdebugprintlevel Variable

extensionsdebugprintlength Variable

printlevel and printlength are b ound to these values during the execution of some debug com

mands When evaluating arbitrary expressions in the debugger the normal values of printlevel and print

length are in eect These variables are initially set to and resp ectively

Chapter

The Compiler

Compiler Intro duction

This chapter contains information ab out the compiler that every CMU Common Lisp user should b e familiar

with Chapter go es into greater depth describing ways to use more advanced features

The CMU Common Lisp compiler also known as Python has many features that are seldom or never

supp orted byconventional Common Lisp

Source level debugging of compiled co de see chapter

Typ e error compiler warnings for typ e errors detectable at compile time

Compiler error messages that provide a go o d indication of where the error app eared in the source

Full runtime checking of all p otential typ e errors with optimization of typ e checks to minimize the cost

Schemelike features such as prop er tail recursion and extensive sourcelevel optimization

Advanced tuning and optimization features such as comprehensiveeciencynotesow analysis and

untagged numb er represen tations see chapter

Calling the Compiler

Functions may b e compiled using compile compilefileor compilefromstream

compile name optional denition Function

This function compiles the function whose name is nameIfname is nil the compiled function ob ject is

returned If denition is supplied it should b e a lamb da expression that is to b e compiled and then placed in

the function cell of name As p er the prop osed XJ cleanup compileargumentproblems denition may

also b e an interpreted function

The return values are as p er the prop osed XJ cleanup compilerdiagnostics The rst value is the

function name or function ob ject The second value is nil if no compiler diagnostics were issued and t otherwise

The third value is nil if no compiler diagnostics other than style warnings were issued A nonnil value indicates

that there were serious compiler diagnostics issued or that other conditions of typ e error or warning but

not stylewarningwere signalled during compilation

compilefile inputpathname key outputfile errorfile tracefile Function

erroroutput verbose print progress

load blockcompile entrypoints

bytecompile

The CMU Common Lisp compilefile is extended through the addition of several new keywords and an

additional interpretation of inputpathname

CHAPTER THE COMPILER

inputpathname If this argument is a list of input les rather than a single input pathname then all the source

les are compiled into a single ob ject le In this case the name of the rst le is used to determine the

default output le names This is esp ecially useful in combination with blockcompile

outputle This argument sp ecies the name of the output le t gives the default name nil suppresses the

output le

errorle A listing of all the error output is directed to this le If there are no errors then no error le is

pro duced and any existing error le is deleted t gives name err the default and nil suppresses

the output le

erroroutput If t the default then error output is sent to erroroutput If a stream then output is sent to

that stream instead If nil then error output is suppressed Note that this error output is in addition to

but the same as the output placed in the errorle

verb ose If t the default then the compiler prints to error output at the start and end of compilation of each

le See compileverbose page

print If t the default then the compiler prints to error output when each function is compiled See compile

print page

progress If t default nil then the compiler prints to error output progress information ab out the phases of

compilation of each function This is a CMU extension that is useful mainly in large block compilations

See compileprogress page

tracele If true several of the intermediate represen tations including annotated assembly co de are dumped

out to this le t gives name traceTrace output is o by default See section page

load If true load the resulting output le

blo ckcompile Controls the compiletime resolution of function calls By default only selfrecursive calls are

resolved unless an extblockstart declaration app ears in the source le See section page

entryp oints If nonnull then this is a list of the names of all functions in the le that should have global

denitions installed b ecause they are referenced in other les See section page

bytecompile If true compiling to a compact interpreted byte co de is enabled Possible values are t nil and

maybe the default See bytecompiledefault page and See section page

The return values are as p er the prop osed XJ cleanup compilerdiagnostics The rst value from

compilefile is the truename of the output le or nil if the le could not b e created The interpretation of

the second and third values is describ ed ab ove for compile

compileverbose Variable

compileprint Variable

compileprogress Variable

These variables determine the default values for the verbose print and progress arguments to compile

file

extensionscompilefromstream inputstream key errorstream Function

tracestream

blockcompile entrypoints

bytecompile

This function is similar to compilefile but it takes all its arguments as streams It reads Common Lisp

co de from inputstream until end of le is reached compiling into the curren t environment This function returns

the same twovalues as the last tw ovalues of compile No output les are pro duced

CHAPTER THE COMPILER

Compilation Units

CMU Common Lisp supp orts the withcompilationunit macro added to the language by the prop osed XJ

withcompilationunit compiler cleanup This provides a mechanism for eliminating spurious undened warn

ings when there are forward references across les and also provides a standard way to access compiler extensions

withcompilationunit fkey value g fformg Macro

This macro evaluates the forms in an environment that causes warnings for undened variables functions

and typ es to b e delayed until all the forms have b een evaluated Eachkeyword value is an evaluated form These

keyword options are recognized

override If uses of withcompilationunit are dynamically nested the outermost use will take precedence

suppressing printing of undened warnings by inner uses However when the override option is true this

shadowing is inhibited an inner use will print summary warnings for the compilations within the inner

scop e

optimize This is a CMU extension that sp ecies of the global compilation p olicy for the dynamic extentof

the b o dy The argument should evaluate to an optimize declare form lik e

optimize speed safety

See section page

optimizeinterface Similar to optimize but sp ecies the compilation p olicy for function interfaces argu

ment countandtyp e checking for the dynamic extent of the b o dy See section page

contextdeclarations This is a CMU extension that patternmatches on function names automatically splic

ing in any appropriate declarations at the head of the function denition See section page

Undened Warnings

Warnings ab out undened variables functions and typ es are delayed until the end of the current compilation unit

The compiler entry functions compile etc implicitly use withcompilationunit so undened warnings will

b e printed at the end of the compilation unless there is an enclosing withcompilationunit In order the gain

the b enet of this mechanism you should wrap a single withcompilationunit around the calls to compile

file ie

withcompilationunit

compilefile file

compilefile file

Unlike for functions and typ es undened warnings for variables are not suppressed when a denition eg

defvar app ears after the reference but in the same compilation unit This is b ecause doing sp ecial declarations

out of order just do esnt work although early references will b e compiled as sp ecial bindings will b e done

lexically

Undened warnings are printed with full source context see section page which tremendously

simplies the problem of nding undened references that resulted from macroexpansion After printing detailed

information ab out the undened uses of each name withcompilationunit also prints summary listings of

the names of all the undened functions typ es and variables

undefinedwarninglimit Variable

This variable controls the numb er of undened warnings for each distinct name that are printed with full

source context when the compilation unit ends If there are more undened references than this then they are

condensed into a single warning

Warning count more uses of undefined function name

When the value is then the undened warnings are not broken down by name at all only the summary listing

of undened names is printed

CHAPTER THE COMPILER

Interpreting Error Messages

One of Pythons unique features is the level of source lo cation information it provides in error messages The

error messages contain a lot of detail in a terse format to they may b e confusing at rst Error messages will b e

illustrated using this example program

defmacro zoq x

roq ploq x

defun foo y

declare symbol y

zoq y

The main problem with this program is that it is trying to add to a symb ol Note also that the functions roq

and ploq arent dened anywhere

The Parts of the Error Message

The compiler will pro duce this warning

File usrmestufflisp

In DEFUN FOO

ZOQ Y

ROQ PLOQ

Y

Warning Result is a SYMBOL not a NUMBER

In this example we see each of the six p ossible parts of a compiler error message

File usrmestufflisp This is the le that the compiler read the relevant co de from The le name is

displayed b ecause it may not b e immediately obvious when there is an error during compilation of a large

system esp ecially when withcompilationunit is used to delay undened warnings

In DEFUN FOO This is the denition or toplevel form resp onsible for the error It is obtained by taking the rst

two elements of the enclosing form whose rst elementisasymb ol b eginning with DEF If there is no

enclosing def mumble then the outermost form is used If there are multiple def mumbles then they are

all printed from the out in separated by s In this example the problem was in the defun for foo

ZOQ Y This is the original source form resp onsible for the error Original source means that the form directly

app eared in the original input to the compiler ie in the lamb da passed to compile or the toplevel form

read from the source le In this example the expansion of the zoq macro was resp onsible for the error

ROQ PLOQ This is the pro cessing path that the compiler used to pro duce the errorful co de The pro cessing

path is a represen tation of the evaluated forms enclosing the actual source that the compiler encountered

when pro cessing the original source The path is the rst elementofeach form or the form itself if the

form is not a list These forms result from the expansion of macros or sourcetosource transformation done

by the compiler In this example the enclosing evaluated forms are the calls to roq ploq and These

calls resulted from the expansion of the zoq macro

Y This is the actual source resp onsible for the error If the actual source app ears 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 b een the last form of the pro cessing path In this example the problem is with

the evaluation of the reference to the variable y

Warning Result is a SYMBOL not a NUMBER This is the explanation the problem In this example the prob

lem is that y evaluates to a symbol but is in a context where a numb er is required the argumentto

CHAPTER THE COMPILER

Note that each part of the error message is distinctively marked

File and In mark the le and denition resp ectively

The original source is an indented form with no prex

Each line of the pro cessing path is prexed with

The actual source form is indented like the original source but is marked by a preceding line This is

like the macroexpands to notation used in Common Lisp The Language

The explanation is prexed with the error severity see section page either Error Warning

or Note

Each part of the error message is more sp ecic than the preceding one If consecutive error messages are for

nearby locations then the front part of the error messages would b e the same In this case the compiler omits

as much of the second message as in common with the rst For example

File usrmestufflisp

In DEFUN FOO

ZOQ Y

ROQ

PLOQ Y

Warning Undefined function PLOQ

ROQ PLOQ Y

Warning Undefined function ROQ

In this example the le denition 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

rst message followed by

Last message occurs rep eats times

where rep eats is the numb er of times the message was given

If the source was not from a le then no le line is printed If the actual source is the same as the original

source then the pro cessing path and actual source will b e omitted If no forms intervene b etween the original

source and the actual source then the pro cessing path will also b e omitted

The Original and Actual Source

The original source displayed will almost alwa ys b e a list If the actual source for an error message is a symbol

the original source will b e the immediately enclosing evaluated list form So even if the oending symbol does

app ear in the original source the compiler will print the enclosing list and then print the symb ol as the actual

source as though the symbol were intro duced by a macro

When the actual source is displayed and is not a symb ol it will always b e co de that resulted from the

expansion of a macro or a sourcetosource compiler optimization This is co de that did not app ear in the

original source program it was intro duced by the compiler

Keep in mind that when the compiler displays a source form in an error message it always displays the most

sp ecic innermost resp onsible form For example compiling this function

defun bar x

let a

declare fixnum a

setq a foo x a

CHAPTER THE COMPILER

Gives this error message

In DEFUN BAR

LET A DECLARE FIXNUM A SETQ A FOO X A

Warning The binding of A is not a FIXNUM

NIL

This error message is not saying theres a problem somewhere in this let itissaying that there is a problem

with the let itself In this example the problem is that as nil initial value is not a fixnum

The Pro cessing Path

The pro cessing path is mainly useful for debugging macros so if you dont write macros you can ignore the

pro cessing path Consider this example

defun foo n

dotimes i n undefined

Compiling results in this error message

In DEFUN FOO

DOTIMES I N UNDEFINED

DO BLOCK LET TAGBODY RETURNFROM

PROGN UNDEFINED

Warning Undefined variable UNDEFINED

Note that do app ears in the pro cessing path This is b ecause dotimes expands into

do i i g n

i g undefined

declare type unsignedbyte i

The rest of the pro cessing path results from the expansion of do

block nil

let i g n

declare type unsignedbyte i

tagbody go g

g psetq i i

g unless i g go g

returnfrom nil progn undefined

In this example the compiler descended into the block let tagbody and returnfrom to reach the progn

printed as the actual source This is a place where the actual source app ears in explanation rule was applied

The innermost actual source form was the symbol undefined itself but that also app eared in the explanation

so the compiler backed out one level

Error Severity

There are three levels of compiler error severity

Error This severity is used when the compiler encounters a problem serious enough to prevent normal pro cessing

of a form Instead of compiling the form the compiler compiles a call to error Errors are used mainly

for signalling syntax errors If an error happ ens during macroexpansion the compiler will handle it The

compiler also handles and attempts to pro ceed from read errors

Warning Warnings are used when the compiler can prove that something bad will happ en if a p ortion of the

program is executed but the compiler can pro ceed by compiling co de that signals an error at runtime if the problem has not b een xed

CHAPTER THE COMPILER

Violation of typ e declarations or

Function calls that have the wrong numb er of arguments or malformed keyword argument lists or

Referencing a variable declared ignore or unrecognized declaration sp eciers

In the language of the Common Lisp standard these are situations where the compiler can determine

that a situation with undened consequences or that would cause an error to b e signalled would result at

runtime

Note Notes are used when there is something that seems a bit o dd but that might reasonably app ear in correct

programs

Note that the compiler does not fully conform to the prop osed XJ compilerdiagnostics cleanup Errors

warnings and notes mostly corresp ond to errors warnings and stylewarnings but many things that the cleanup

considers to b e stylewarnings are printed as warnings rather than notes Also warnings stylewarnings and

most errors arent really signalled using the condition system

Errors During Macro expansion

The compiler handles errors that happ en during macroexpansion turning them into compiler errors If you want

to debug the error to debug a macro you can set breakonsignals to errorFor example this denition

defun foo e l

do current l cdr current

atom current nil

when eq car current e return current

gives this error

In DEFUN FOO

DO CURRENT L NIL WHEN EQ E RETURN CURRENT

Error during macroexpansion

Error in function LISPDODOBODY

DO step variable is not a symbol ATOM CURRENT

Read Errors

The compiler also handles errors while reading the source For example

Error Read error at

foo

Error in function LISPCOMMAMACRO

Comma not inside a backquote

The at refers to the character p osition in the source le at which the error was signalled which is generally

immediately after the erroneous text The next line foo is the line in the source that contains the

error le p osition The indicates the error p osition within that line in this example immediately after the

oending comma

When in Hemlockorany other EMACSlike editor you can go to a character p osition with

M Cu p osition Cf

Note that if the source is from a Hemlock buer then the p osition is relative to the start of the compiled region

or defun not the le or buer start

After printing a read error message the compiler attempts to recover from the error bybacking up to the

start of the enclosing toplevel form and reading again with readsuppress true If the compiler can recover

from the error then it substitutes a call to cerror for the unreadable form and pro ceeds to compile the rest of

the le normally

If there is a read error when the le p osition is at the end of the le ie an unexp ected EOF error then

the error message lo oks like this

CHAPTER THE COMPILER

Error Read error in form starting at

defun test

Error in function LISPFLUSHWHITESPACE

EOF while reading Stream for file usrmetestlisp

In this case starting at indicates the character p osition at which the compiler started reading ie the

p osition b efore the start of the form that was missing the closing delimiter The line defun test is rst

line after the starting p osition that the compiler thinks mightcontain the unmatched op en delimiter

Error Message Parameterization

There is some control over the verb osity of error messages See also undefinedwarninglimit page

efficiencynotelimit and efficiencynotecostthreshold page

enclosingsourcecutoff Variable

This variable sp ecies the numb er of enclosing actual source forms that are printed in full rather than in the

abbreviated pro cessing path format Increasing the value from its default of allows you to see more of the guts

of the macroexpanded source which is useful when debugging macros

errorprintlength Variable

errorprintlevel Variable

These variables are the printlevel and print length used in printing error messages The default values are

and Ifnull the global values of printlevel and printlength are used

extensionsdefsourcecontext name lambdalist fform g Macro

This macro denes how to extract an abbreviated source context from the name d form when it app ears in

the compiler input lamb dalist is a defmacro style lamb dalist used to parse the arguments The body should

return a list of subforms that can b e printed on ab out one line There are predened methods for defstruct

defmethodetc If no method is dened then the rst two subforms are returned Note that this facility

implicitly determines the string name asso ciated with anonymous functions

Typ es in Python

A big dierence b etween Python and all other Common Lisp compilers is the approachtotyp e checking and

amount of knowledge ab out typ es

Python treats typ e declarations much dierently that other Lisp compilers do Python doesnt blindly

b elievetyp e declarations it considers them assertions ab out the program that should b e checked

Python also has a tremendously greater knowledge of the Common Lisp typ e system than other compilers

Supp ort is incomplete only for the not and and satisfies typ es

See also sections and

Compile Time Typ e Errors

If the compiler can prove at compile time that some p ortion of the program cannot b e executed without a typ e

error then it will giveawarning at compile time It is p ossible that the oending co de would never actually b e

executed at runtime due to some higher level consistency constraintunknown to the compiler so a typ e warning

do esnt always indicate an incorrect program For example consider this co de fragment

CHAPTER THE COMPILER

defun raz foo

let x case foo

this

that

theother

declare fixnum x

foo x

Compilation pro duces this warning

In DEFUN RAZ

CASE FOO THIS THAT THEOTHER

LET COND IF COND IF COND IF

COND

Warning This is not a FIXNUM

NIL

In this case the warning is telling you that if foo isnt anyofthis that or theother then x will b e

initialized to nil which the fixnum declaration makes illegal The warning will go awayifecase is used instead

of caseorif theother is changed to t

This sort of spurious typ e warning happ ens moderately often in the expansion of complex macros and in

inline functions In such cases there may b e dead co de that is impossible to correctly execute The compiler

cant always prove this co de is dead could never b e executed so it compiles the erroneous co de which will

always signal an error if it is executed and gives a warning

extensionsrequiredargument Function

This function can b e used as the default value for keyword arguments that must always b e supplied Since it

is known by the compiler to never return it will avoid any compiletime typ e warnings that would result from

a default value inconsistent with the declared typ e When this function is called it signals an error indicating

that a required keyword argumentwas not supplied This function is also useful for defstruct slot defaults

corresp onding to required arguments See section page

Although this function is a CMU extension it is relatively harmless to use it in otherwise p ortable co de since

you can easily dene it yourself

defun requiredargument

error A required keyword argument was not supplied

Typ e warnings are inhibited when the extensionsinhibitwarnings optimization qualityis see section

page This can b e used in a local declaration to inhibit typ e warnings in a co de fragmentthathas

spurious warnings

Precise Typ e Checking

With the default compilation p olicy all typ e assertions are precisely checked Precise checking means that the

check is done as though typep had b een called with the exact typ e sp ecier that app eared in the declaration

Python uses p olicy to determine whether to trust typ e assertions see section page Typ e assertions

from declarations are indistinguishable from the typ e assertions on arguments to builtin functions In Python

adding typ e declarations makes co de safer

If a variable is declared to b e integer then its value must always always b e an integer b etween

and Ifmultiple typ e declarations apply to a single variable then all the declarations must b e correct it is

as though all the typ es were intersected pro ducing a single and typ e sp ecier

Argumenttyp e declarations are automatically enforced If you declare the typ e of a function argument a

typ e check will b e done when that function is called In a function call the called function do es the argument

There are a few circumstances where a typ e declaration is discarded rather than b eing used as typ e assertion This do esnt

aect safetymuch since such discarded declarations are also not b elieved to b e true by the compiler

CHAPTER THE COMPILER

typ e checking which means that a more restrictive typ e assertion in the calling function eg from themay

b e lost

The typ es of structure slots are also checked The value of a structure slot must always b e of the typ e indicated



in any type slot option Because of precise typ e checking the arguments to slot accessors are checked to b e

the correct typ e of structure

In traditional Common Lisp compilers not all typ e assertions are checked and typ e checks are not precise

Traditional compilers blindly trust explicit typ e declarations but maycheck the argumenttyp e assertions for

builtin functions Typ e checking is not precise since the argumenttyp e checks will b e for the most general typ e

legal for that argument In many systems typ e declarations suppress what little typ e checking is b eing done

so adding typ e declarations makes co de unsafe This is a problem since it discourages writing typ e declarations

during initial co ding In addition to b eing more error prone adding typ e declarations during tuning also loses

all the b enets of debugging with checked typ e assertions

To gain maximum b enet from Pythons typ e checking you should always declare the typ es of function

arguments and structure slots as precisely as p ossible This often involves the use of or member and other

liststyle typ e sp eciers Paradoxicallyeven though adding typ e declarations intro duces typ e checks it usually

reduces the overall amountoftyp e chec king This is esp ecially true for structure slot typ e declarations

Python uses the safety optimization quality rather than presence or absence of declarations to cho ose one

of three levels of runtime typ e error checking see section page See section page for more

information ab out typ es in Python

Weakened Typ e Checking

When the value for the speed optimization quality is greater than safetyandsafety is not then typ e

checking is weakened to reduce the sp eed and space p enalty In structureintensive co de this can double the

sp eed yet still catch most typ e errors Weakened typ e checks provide a level of safety similar to that of safe

co de in other Common Lisp compilers

Atyp e check is weakened bychanging the check to b e for some convenient sup ertyp e of the asserted typ e For

example integer is changed to fixnum simplevector to simplevector and structure typ es

are changed to structure A complex check like

or node hunk member foo bar baz

will b e omitted entirely ie the check is weakened to If a precise check can b e done for no extra cost then

no weakening is done

Although weakened typ e checking is similar to typ e checking done by other compilers it is sometimes safer

ened checks are done in the same places is precise checks so all the preceding and sometimes less safe Weak

discussion ab out where checking is done still applies Weakened checking is sometimes somewhat unsafe b ecause

although the check is weakened the precise typ e is still input into typ e inference In some contexts this will

result in typ e inferences not justied bytheweakened check and hence deletion of some typ e checks that would

b e done by conventional compilers

For example if this co de was compiled with weakened checks

defstruct foo

a nil type simplestring

defstruct bar

a nil type singlefloat

defun myfun x

declare type bar x

bara x

and myfun was passed a foothennotyp e error would b e signalled and wewould try to multiply a simple

vector as though it were a oat with unpredictable results This is b ecause the check for bar was weakened

to structureyet when compiling the call to bara the compiler thinks it knows it has a bar



The initial value need not b e of this typ e as long as the corresp onding argument to the constructorisalways supplied but this

will cause a compiletimetyp e warning unless requiredargument is used

CHAPTER THE COMPILER

Note that normally even weakened typ e checks rep ort the precise typ e in error messages For example if

myfuns bar check is weakened to structure and the argumentisnil then the error will b e

Typeerror in MYFUN

NIL is not of type BAR

However there is some sp eed and space cost for signalling a precise error so the weakened typ e is rep orted if

the speed optimization qualityis or debug qualityislessthan

Typeerror in MYFUN

NIL is not of type STRUCTURE

See section page for further discussion of the optimize declaration

Getting Existing Programs to Run

Since Python do es much more comprehensivetyp e checking than other Lisp compilers Python will detect typ e

errors in many programs that have b een debugged using other compilers These errors are mostly incorrect

declarations although compiletimetyp e errors can nd actual bugs if parts of the program have never b een

tested

Some incorrect declarations can only b e detected by runtime typ e checking It is very important to initially

compile programs with full typ e checks and then test this version After the checking version has b een tested

then you can consider weakening or eliminating typ e checks This applies even to previously debugged

programs Python do es much more typ e inference than other Common Lisp compilers so b elieving an incorrect

declaration do es much more damage

The most common problem is with variables whose initial value do esnt match the typ e declaration Incorrect

initial values will always b e agged by a compiletime typ e error and they are simple to x once located Consider

this co de fragment

prog foo

declare fixnum foo

setq foo

Here the variable foo is given an initial value of nil but is declared to b e a fixnumEven if it is never read

the initial value of a variable must match the declared typ e There are twoways to x this problem Change

the declaration

prog foo

declare type or fixnum null foo

setq foo

or change the initial value

prog foo

declare fixnum foo

setq foo

It is generally preferable to change to a legal initial value rather than to weaken the declaration but sometimes

it is simpler to weaken the declaration than to try to make an initial value of the appropriate typ e

Another declaration problem o ccasionally encountered is incorrect declarations on defmacro arguments This

probably usually happ ens when a function is converted into a macro Consider this macro

defmacro my x

declare fixnum x the fixnum x

CHAPTER THE COMPILER

Although legal and welldened Common Lisp this meaning of this denition is almost certainly not what the

writer intended For example this call is illegal

my

The call is illegal b ecause the argument to the macro is whichisalist not a fixnum Because of

macro semantics it is hardly ever useful to declare the typ es of macro arguments If you really want to assert

something ab out the typ e of the result of evaluating a macro argument then put a the in the expansion

defmacro my x

the fixnum the fixnum x

In this case it would b e stylistically preferable to change this macro back to a function and declare it inline

Macros have no eciency advantage over inline functions when using Python See section page

Some more subtle problems are caused by incorrect declarations that cant b e detected at compile time

Consider this co de

do pos position a string start pos

null pos

declare fixnum pos

Although pos is almost always a fixnumitis nil at the end of the loop If this example is compiled with full

typ e checks the default then running it will signal a typ e error at the end of the lo op If compiled without

typ e checks the program will go into an innite lo op or p erhaps position will complain b ecause nil isnt

a sensible start WhyBecause if y ou compile without typ e checks the compiler just quietly b elieves the typ e

declaration Since pos is always a fixnum it is never nilso null pos is never true and the lo op exit test is

optimized away Such errors are sometimes agged by unreachable co de notes see section page but

it is still importan t to initially compile any system with full typ e checks even if the system works ne when

compiled using other compilers



In this case the x is to weaken the typ e declaration to or fixnum null Note that there is usually

little p erformance p enaltyforweakening a declaration in this wayAnynumeric op erations in the b ody can still

assume the variable is a fixnumsince nil is not a legal numeric argument Another p ossible x would b e to

say

do pos position a string start pos

null pos

let pos pos

declare fixnum pos

This would b e preferable in some circumstances since it would allow a nonstandard represen tation to b e used

for the local pos variable in the lo op b o dy see section

In summary rememb er that all values that a variable ever has must b e of the declared typ e and that you

should test using safe co de initially

Compiler Policy

The p olicy is what tells the compiler how to compile a program This is logically and often textually distinct

from the program itself Broad control of p olicy is provided bytheoptimize declaration other declarations and

variables control more sp ecic asp ects of compilation



Actually this declaration is totally unnecessary in Python since it already knows position returns a nonnegative fixnum or

nil

CHAPTER THE COMPILER

The Optimize Declaration

The optimize declaration recognizes six dierent qualities The qualities are conceptually indep endent asp ects

of program p erformance In reality increasing one quality tends to haveadverse eects on other qualities The

compiler compares the relativevalues of qualities when it needs to make a tradeo ie if speed is greater than

safety then improve sp eed at the cost of safety

The default for all qualities except debugis Whenever qualities are equal ties are broken according to

a broad idea of what a go o d default environment is supp osed to b e Generally this downplays speed compile

speed and space in favor of safety and debugNovice and casual users should stick to the default p olicy

Advanced users often wanttoimprove sp eed and memory usage at the cost of safety and debuggability

If the value for a qualityis or thenitmayhave a sp ecial interpretation A value of means totally

unimportant and a means ultimately important These extreme optimization values enable heroic com

pilation strategies that are not always desirable and sometimes selfdefeating Sp ecifying more than one quality

as is not desirable since it do esnt tell the compiler which quality is most important

These are the optimization qualities

speed How fast the program should is run speed enables some optimizations that hurt debuggability

compilationspeed How fast the compiler should run Note that increasing this ab ove safety weakens typ e

checking

space Howmuch space the compiled co de should take up Inline expansion is mostly inhibited when space

is greater than speedAvalue of enables promiscuous inline expansion Wide use of a value is not

recommended as it maywaste so much space that run time is slowed See section page for a

discussion of inline expansion

debug How debuggable the program should b e The quality is treated dierently from the other qualities each

value indicates a particular level of debugger information it is not compared with the other qualities See

section page for more details

safety Howmuch error checking should b e done If speed space or compilationspeed is more important

than safetythentyp e checking is weakened see section page If safety if then no run time

error checking is done In addition to suppressing typ e checks also suppresses argumentcountchecking

unb oundsymb ol checking and arrayboundschecks

extensionsinhibitwarnin gs This is a CMU extension that determines how little or howmuch diagnostic

output should b e printed during compilation This quality is compared to other qualities to determine

whether to printstyle notes and warnings concerning those qualities If speed is greater than inhibit

warnings then notes ab out howtoimprove sp eed will b e printed etc The default value is so raising

the value for any standard qualityabove its default enables notes for that qualityIfinhibitwarnings

is then all notes and most nonserious warnings are inhibited This is useful with declare to suppress

warnings ab out unavoidable problems

The OptimizeInterface Declaration

The extensionsoptimizeinterface declaration is identical in syntax to the optimize declaration but it

sp ecies the p olicy used during compilation of co de the compiler automatically generates to checkthenumber

and typ e of arguments supplied to a function It is useful to sp ecify this p olicy separately since even thoroughly

debugged functions are vulnerable to b eing passed the wrong arguments The optimizeinterface declaration

can sp ecify that arguments should b e checked even when the general optimize p olicy is unsafe

Note that this argumentchecking is the checking of usersupplied arguments to any functions dened within

the scop e of the declaration not the checking of arguments to Common Lisp primitives that app ear in those

denitions

The idea b ehind this declaration is that it allows the denition of functions that app ear fully safe to other

callers but that do no internal error checking Of course it is p ossible that arguments maybeinvalid in wa ys

other than having incorrect typ e Functions compiled unsafely must still protect themselves against things like

usersupplied array indices that are out of b ounds and improper lists See also the contextdeclarations

option to withcompilationunit page

CHAPTER THE COMPILER

Op en Co ding and Inline Expansion



Since Common Lisp forbids the redenition of standard functions the compiler can have sp ecial knowledge of

these standard functions emb edded in it This sp ecial knowledge is used in various ways op en co ding inline

expansion source transformation but the implications to the user are basically the same

Attempts to redene standard functions may b e frustrated since the function maynever b e called Al

though it is technically illegal to redene standard functions users sometimes want to implicitly redene

these functions when they are debugging using the trace macro Sp ecialcasing of standard functions can

b e inhibited using the notinline declaration

The compiler can havemultiple alternate implementations of standard functions that implement dierent

tradeos of sp eed space and safety This selection is based on the compiler p olicy see section page

When a function call is op en co ded inline co de whose eect is equivalent to the function call is substituted

for that function call When a function call is closed co ded it is usually left as is although it might b e turned

into a call to a dierent function with dierent arguments As an example if nthcdr were to b e op en co ded

then

nthcdr foobar

might turn into

cdr cdr cdr cdr foobar

or even

do i i

list foobar cdr foobar

i list

If nth is closed co ded then

nth x l

might stay the same or turn into something like

car nthcdr x l

In general op en co ding sacrices space for sp eed but some functions suchascar are so simple that they

are always op enco ded Even when not op enco ded a call to a standard function may b e transformed into a

dierent function call as in the last example or compiled as static call Static function call uses a more ecient

calling convention that forbids redenition



See the prop osed XJ lispsymbolredenition cleanup

Chapter

Advanced Compiler Use and Eciency

Hints

By Rob ert MacLachlan

Advanced Compiler Intro duction

In CMU Common Lisp as is any language on any computer the path to ecient co de starts with goo d algo

rithms and sensible programming techniques but to avoid ineciency pitfalls you need to know some of this

implementations quirks and features This chapter is mostly a fairly long and detailed overview of what opti

mizations Python do es Although there are the usual negative suggestions of inecient features to avoid the

main emphasis is on describing the things that programmers can count on b eing ecient

The optimizations describ ed here can have the eect of sp eeding up existing programs written in conventional

styles but the p otential for new programming styles that are clearer and less errorprone is at least as signicant

For this reason several sections end with a discussion of the implications of these optimizations for programming

style

Typ es

Pythons supp ort for typ es is unusual in three ma jor ways

Precise typ e checking encourages the sp ecic use of typ e declarations as a form of runtime consistency

checking This sp eeds developmentby localizing typ e errors and giving more meaningful error messages

See section page Python pro duces completely safe co de optimized typ e checking maintains

reasonable eciency on conventional hardware see section page

Comprehensive supp ort for the Common Lisp typ e system makes complex typ e sp eciers useful Using typ e

sp eciers such as or and member has b oth eciency and robustness advantages See section page

Typ e inference eliminates the need for some declarations and also aids compiletime detection of typ e

errors Given detailed typ e declarations typ e inference can often eliminate typ e checks and enable more

ecient ob ject represen tations and co de sequences Checking all typ es results in fewer typ e checks See

sections and

Optimization

The main barrier to ecient Lisp programs is not that there is no ecientway to co de the program in Lisp but

that it is dicult to arrive at that ecient co ding Common Lisp is a highly complex language and usually has

many semantically equivalent reasonable ways to co de a given problem It is desirable to make all of these

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

equivalent solutions have comparable eciency so that programmers dont havetowaste time discovering the

most ecient solution

Source level optimization increases the numb er of ecientways to solve a problem This eect is much

larger than the increase in the eciency of the b est solution Source level optimization transforms the orig

inal program into a more ecient but equivalent program Although the optimizer isnt doing anything the

programmer couldnt have done this highlevel optimization is important b ecause

The programmer can co de simply and directly rather than obfuscating co de to please the compiler

When presented with a choice of similar co ding alternatives the programmer can chose whichever happ ens

to b e most convenient instead of worrying ab out which is most ecient

Source level optimization eliminates the need for macros to optimize their expansion and also increases the

eectiveness of inline expansion See sections and

Ecient supp ort for a safer programming style is the biggest advantage of source level optimization Existing

tuned programs typically wont b enet much from source optimization since their source has already b een

optimized by hand However even tuned programs tend to run faster under Python b ecause

Lowlevel optimization and register allocation provides modest sp eedups in any program

Blo ck compilation and inline expansion can reduce function call overhead but may require some program

restructuring See sections and

Eciency notes will p oint out importanttyp e declarations that are often missed even in highly tuned

programs See section page

Existing programs can b e compiled safely without prohibitive speed penalty although they w ould b e faster

and safer with added declarations See section page

The context declaration mechanism allows b oth space and runtime of large systems to b e reduced without

sacricing robustness by semiautomaticallyvarying compilation p olicy without addition any optimize

declarations to the source See section page

Byte compilation can b e used to dramatically reduce the size of co de that is not sp eedcritical See section

page

Function Call

The sort of symb olic programs generally written in Common Lisp often favor recursion over iteration or have

inner loops so complex that they involvemultiple function calls Such programs sp end a larger fraction of their

time doing function calls than is the norm in other languages for this reason Common Lisp implementations

strive to make the general or full function call as inexp ensive as p ossible Python go es b eyond this byproviding

two go od alternatives to full call

Lo cal call resolves function references at compile time allowing b etter calling sequences and optimization

across function calls See section page

Inline expansion totally eliminates call overhead and allows manycontext dep endent optimizations This

provides a safe and ecient implementation of op erations with function semantics eliminating the need

for errorprone macro denitions or manual case analysis Although most Common Lisp implementations

supp ort inline expansion it b ecomes a more p owerful to ol with Pythons source level optimization See

sections and

Generally Python provides simple implementations for simple uses of function call rather than having only

a single calling convention These features allow a more natural programming style

Prop er tail recursion See section page

Relatively ecient closures

A funcall that is as ecient as normal named call

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Calls to local functions such as from labels are optimized

Control transfer is a direct jump

The closure environment is passed in registers rather than heap allocated

Keyword arguments and multiple values are implemented more eciently

See section page

Representation of Ob jects

Sometimes traditional Common Lisp implementation techniques compare so p o orly to the techniques used in

other languages that Common Lisp can b ecome an impractical language choice Terrible ineciencies app ear in

numb ercrunc hing programs since Common Lisp numeric op erations often involvenumb erconsing and generic

arithmetic Python supp orts ecient natural represen tations for numb ers and some other typ es and allows

these ecient represen tations to b e used in more contexts Python also provides goo d eciency notes that warn

when a crucial declaration is missing

See section for more ab out ob ject represen tations and numeric typ es Also see section page

ab out eciency notes

Writing EcientCode

Writing ecient co de that works is a complex and prolonged pro cess It is important not to get so involved in

the pursuit of eciency that you lose sight of what the original problem demands Remember that

The program should b e correct it doesnt matter how quickly you get the wrong answer

Both the programmer and the user will make errors so the program mustberobustitmust detect

errors in a waythatallows easy correction

A small p ortion of the program will consume most of the resources with the bulk of the co de b eing

virtually irrelevant to eciency considerations Even exp erienced programmers familiar with the problem

area cannot reliably predict where these hot sp ots will b e

The b est way to get ecient co de that is still worth using is to separate co ding from tuning During co ding

you should

Use a co ding style that aids correctness and robustness without b eing incompatible with eciency

Cho ose appropriate data structures that allow ecient algorithms and ob ject represen tations see section

page Try to makeinterfaces abstract enough so that you can change to a dierent represen tation

if proling reveals a need

Whenever you make an assumption ab out a function argument or global data structure add consistency

assertions either with typ e declarations or explicit uses of assert ecase etc

During tuning you should

Identify the hot sp ots in the program through proling section

Identify inecient constructs in the hot sp ot with eciency notes more proling or manual insp ection of

the source See sections and

Add declarations and consider the application of optimizations See sections and

If all else fails consider algorithm or data structure changes If you did a go o d job co ding changes will b e

easy to intro duce

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

More Ab out Typ es in Python

This section go es into more detail describing what typ es and declarations are recognized by Python The area

where Python diers most radically from previous Common Lisp compilers is in its supp ort for typ es

Precise typ e checking helps to nd bugs at run time

Compiletimetyp e checking helps to nd bugs at compile time

Typ e inference minimizes the need for generic op erations and also increases the eciency of run time typ e

checking and the eectiveness of compile time typ e checking

Supp ort for detailed typ es provides a wealth of opp ortunity for op erationsp ecic typ e inference and opti

mization

More Typ es Meaningful

Common Lisp has a very p owerful typ e system but conventional Common Lisp implementations typically only

recognize the small set of typ es sp ecial in that implementation In these systems there is an unfortunate paradox

a declaration for a relatively general typ e like fixnum will b e recognized by the compiler but a highly sp ecic

declaration such as integer is totally ignored

This is obviously a problem since the user has to knowhow to sp ecify the typ e of an ob ject in the waythe

compiler wants it A very minimal but rarely satised criterion for typ e system supp ort is that it b e no worse

to make a sp ecic declaration than to make a general one Python go es b eyond this by exploiting a number of

advantages obtained from detailed typ e information

Using more restrictive typ es in declarations allows the compiler to do b etter typ e inference and more compile

time typ e checking Also when typ e declarations are considered to b e consistency assertions that should b e

veried conditional on p olicy then complex t yp es are useful for making more detailed assertions

Python understands the liststyle or member function array and number typ e sp eciers Understanding

means that

If the typ e contains more information than is used in a particular context then the extra information is

simply ignored rather than derailing typ e inference

In many contexts the extra information from these typ e sp ecier is used to go od eect In particular

typ e checking in Python is precise so these complex typ es can b e used in declarations to makeinteresting

assertions ab out functions and data structures see section page More sp ecic declarations also

aid typ e inference and reduce the cost for typ e checking

For related information see section page for numeric typ es and section for arraytyp es

Canonicalization

When given a typ e sp ecier Python will often rewrite it into a dierentbutequivalent typ e This is the

mechanism that Python uses for detecting typ e equivalence For example in Pythons canonical represen tation

these typ es are equivalent

or list member end or cons member nil end

This has two implications for the user

The standard symbol typ e sp eciers for atom null fixnum etc are in no way magical The null typ e

is actually dened to b e member nil list is or cons nulland fixnum is signedbyte

When the compiler prints out a typ e it may not look likethetyp e sp ecier that originally app eared in the

program This is generally not a problem but it must b e taken into consideration when reading compiler error messages

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Member Typ es

The member typ e sp ecier can b e used to represen t symbolic values analogous to the enumerated typ es of

Pascal For example the second value of findsymbol has this typ e

member internal external inherited nil

Member typ es are very useful for expressing consistency constraints on data structures for example

defstruct icecream

flavor vanilla type member vanilla chocolate strawberry

Member typ es are also useful in typ e inference as the number of memb ers can sometimes b e pared down to one

in which case the value is a known constant

Union Typ es

The or union typ e sp ecier is understo o d and is meaningfully applied in manycontexts The use of or allows

assertions to b e made ab out typ es in dynamically typ ed programs For example

defstruct box

next nil type or box null

top removed type or boxtop member removed

The typ e assertion on the top slot ensures that an error will b e signalled when there is an attempt to store an

illegal value suchasrmoved Although somewhat weak these union typ e assertions provide a useful input

into typ e inference allowing the cost of typ e checking to b e reduced For example this lo op is safely compiled

with no typ e checks

defun findboxwithtop box

declare type or box null box

do current box boxnext current

null current

unless eq boxtop current removed

return current

Union typ es are also useful in typ e inference for represen ting typ es that are partially constrained For example

the result of this expression

if foo

logior x y

list x y

can b e expressed as or integer cons

The EmptyTyp e

The typ e nil is also called the emptytyp e since no ob ject is of typ e nil The union of no typ es or is also

empty Pythons interpretation of an expression whose typ e is nil is that the expression never yields anyvalue

but rather fails to terminate or is thrown out of For example the typ e of a call to error orauseofreturn

is nil When the typ e of an expression is empty compiletimetyp e warnings ab out its value are suppressed

presumably someb o dy else is signalling an error If a function is declared to havereturntyp e nil but do es in

fact return then in safe compilation p olicies a NIL Function returned error will b e signalled See also the

function requiredargument page

Function Typ es

function typ es are understo o d in the restrictive sense sp ecifying

The argumentsyntax that the function must b e called with This is information ab out what argument

counts are acceptable and whichkeyword arguments are recognized In Python warnings ab out argument

syntax are a consequence of function typ e checking

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

The typ es of the argumentvalues that the caller must pass If the compiler can prove that some argument

to a call is of a typ e disallowed by the called functions typ e then it will give a compiletime typ e warning

In addition to b eing used for compiletime typ e checking these typ e assertions are also used as output typ e

assertions in co de generation For example if foo is declared to haveafixnum argument then the in

foo x is compiled with knowledge that the result must b e a xnum

The typ es the values that will b e b ound to argumentvariables in the functions denition Declaring a

functions typ e with ftype implicitly declares the typ es of the arguments in the denition Python checks

for consistency b etween the denition and the ftype declaration Because of precise typ e checking an

error will b e signalled when a function is called with an argumentofthewrongtyp e

The typ e of return values that the caller can exp ect This information is a useful input to typ e inference

For example if a function is declared to return a fixnum then when a call to that function app ears in an

expression the expression will b e compiled with knowledge that the call will return a fixnum

The typ e of return values that the denition must return The result typ e in an ftype declaration is

treated like an implicit the wrapp ed around the b o dy of the denition If the denition returns a value of

the wrong typ e an error will b e signalled If the compiler can prove that the function returns the wrong

typ e then it will give a compiletimewarning

This is consisten t with the new interpretation of function typ es and the ftype declaration in the prop osed

XJ functiontyp eargumenttyp esemantics cleanup Note also that if you dont explicitly declare the typ e

of a function using a global ftype declaration then Python will compute a function typ e from the denition

providing a degree of interroutine typ e inference see section page

The Values Declaration

CMU Common Lisp supp orts the values declaration as an extension to Common Lisp The syntax is

values typ e typ e typ en This declaration is semantically equivalenttoathe form wrapp ed around the

b o dy of the sp ecial form in whichthevalues declaration app ears The advantage of values over the is purely

syntactic it do esnt intro duce more indentation For example

defun foo x

declare values singlefloat

ecase x

this

that

theother

is equivalentto

defun foo x

the singlefloat

ecase x

this

that

theother

and

defun floor number optional divisor

declare values integer real

is equivalentto

defun floor number optional divisor

the values integer real

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

In addition to b eing recognized by lambda and hence by defun the values declaration is recognized byall

the other sp ecial forms with b o dies and declarations let let labels and flet Macros with declarations

usually splice the declarations into one of the ab ove forms so they will accept this declaration to o but the exact

eect of a values declaration will dep end on the macro

If you declare the typ es of all arguments to a function and also declare the return value typ es with values

you have describ ed the typ e of the function Python will use this argument and result typ e information to derive

a function typ e that will then b e applied to calls of the function see section page This provides a

way to declare the typ es of functions that is much less syntactically awkward than using the ftype declaration

with a function typ e sp ecier

Although the values declaration is nonstandard it is relatively harmless to use it in otherwise p ortable co de

since anywarning in nonCMU implementations can b e suppressed with the standard declaration pro clamation

Structure Typ es

Because of precise typ e checking structure typ es are much b etter supp orted by Python than by conventional

compilers

The structure argument to structure accessors is precisely checked if you call fooa on a bar an error

will b e signalled

The typ es of slot v alues are precisely checked if you pass the wrong typ e argument to a constructor or

a slot setter then an error will b e signalled

This error checking is tremendously useful for detecting bugs in programs that manipulate complex data struc

tures

An additional advantage of checking structure typ es and enforcing slot typ es is that the compiler can safely

b elieve slot typ e declarations Python eectively moves the typ e checking from the slot access to the slot setter

or constructor call This is more ecient since caller of the setter or constructor often knows the typ e of the

value entirely eliminating the need to check the values typ e Consider this example

defstruct coordinate

x nil type singlefloat

y nil type singlefloat

defun makeit

makecoordinate x y

defun useit it

declare type coordinate it

sqrt expt coordinatex it expt coordinatey it

makeit and useit are compiled with no checking on the typ es of the oat slots yet useit can use single

float arithmetic with p erfect safety Note that makecoordinate must still check the values of x and y unless

the call is block compiled or inline expanded see section page But even without this advantage it is

almost always more ecienttocheck slot values on structure initialization since slots are usually written once

and read many times

The FreezeTyp e Declaration

The extensionsfreezetype declaration is a CMU extension that enables more ecient compilation of user

dened typ es by asserting that the denition is not going to change This declaration may only b e used glob

ally with declaim or proclaim Currently freezetype only aects structure typ e testing done by typep

typecase etc Here is an example

declaim freezetype foo bar

This asserts that the typ es foo and bar and their subtyp es are not going to change This allows more ecient

typ e testing since the compiler can op enco de a test for all p ossible subtyp es rather than having to examine

the typ e hierarchy at runtime

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Typ e Restrictions

Avoid use of the and not and satisfies typ es in declarations since typ e inference has problems with them

When these typ es do app ear in a declaration they are still checked preciselybutthetyp e information is of

limited use to the compiler and typ es are eective as long as the intersection can b e canonicalized to a typ e

that do esnt use andFor example

and fixnum unsignedbyte

is ne since it is the same as

integer mostpositivexnum

but this typ e

and symbol not member end

will not b e fully understo o d bytyp e interference since the and cant b e removed by canonicalization

Using any of these typ e sp eciers in a typ e test with typep or typecase is ne since as tests these typ es

can b e translated into the and macro the not function or a call to the satises predicate

Typ e Style Recommendations

Python provides go od supp ort for some curren tly unconventional ways of using the Common Lisp typ e system

With Python it is desirable to make declarations as precise as p ossible but typ e inference also makes some

declarations unnecessary Here are some general guidelines for maximum robustness and eciency

Declare the typ es of all function arguments and structure slots as precisely as p ossible while avoiding not

and and satisfies Put these declarations in during initial co ding so that typ e assertions can nd bugs

for you during debugging

Use the member typ e sp ecier where there are a small numb er of p ossible symbol values for example

member red blue green

Use the or typ e sp ecier in situations where the typ e is not certain but there are only a few p ossibilities

for example or list vector

Declare integer typ es with the tightest b ounds that you can such as integer

Dene deftype or defstruct typ es b efore they are used Denition after use is legal pro ducing no

undened typ e warnings but typ e tests and structure op erations will b e compiled much less eciently

Use the extensionsfreezetype declaration to sp eed up typ e testing for structure typ es whichwont

have new subtyp es added later See section page

In addition to declaring the arrayelementtyp e and simpleness also declare the dimensions if they are

xed for example

simplearray singlefloat

This b ounds information allows arrayindexingformultidimensional arrays to b e compiled much more

eciently and may also allowarray b ounds checking to b e done at compile time See section

page

Avoid use of the the declaration within expressions Not only do es it clutter the co de but it is also almost

worthless under safe p olicies If the need for an output typ e assertion is revealed by eciency notes during

tuning then you can consider the but it is preferable to constrain the argumenttyp es more allowing the

compiler to prove the desired result typ e

Dont b other declaring the typ e of let or other nonargumentvariables unless the typ e is nonobvious If

you declare function return typ es and structure slot typ es then the typ e of a variable is often obvious b oth

to the programmer and to the compiler An important case where the typ e isnt obvious and a declaration

is appropriate is when the value for a variable is pulled out of untyp ed structure eg the result of car

or comes from some weakly typ ed function suchasread

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Declarations are sometimes necessary for integer loop variables since the compiler cant always prove that

the value is of a go o d integer typ e These declarations are b est added during tuning when an eciency

note indicates the need

Typ e Inference

Typ e inference is the pro cess by which the compiler tries to gure out the typ es of expressions and variables

given an inevitable lack of complete typ e information Although Python do es muchmoretyp e inference than

most Common Lisp compilers rememb er that the more precise and comprehensivetyp e declarations are the

more typ e inference will b e able to do

Variable Typ e Inference

The typeofavariable is the union of the typ es of all the denitions In the degenerate case of a let the typ e of

the variable is the typ e of the initial value This inferred typ e is intersected with any declared typ e and is then

propagated to all the variables references The typ es of multiplevaluebind variables are similarly inferred

from the typ es of the individual values of the values form

If multiple typ e declarations apply to a single variable then all the declarations must b e correct it is as

though all the typ es were intersected pro ducing a single and typ e sp ecier In this example

defmacro mydotimes var count body body

do var var

var count

declare type integer var

body

mydotimes i

declare fixnum i

the two declarations for i are intersected so i is known to b e a nonnegativexnum

In practice this typ e inference is limited to lets and local functions since the compiler cant analyze all the

calls to a global function But typ e inference works w ell enough on lo cal variables so that it is often unnecessary

to declare the typ e of lo cal variables This is esp ecially likely when function result typ es and structure slot typ es

are declared The main areas where typ e inference breaks down are

When the initial value of a variable is a untyp ed expression such as car xand

When the typ e of one of the variables denitions is a function of the variables current value as in setq

x x

Lo cal Function Typ e Inference

The typ es of arguments to lo cal functions are inferred in the same was as any other local variable the typ e is

the union of the argumenttyp es across all the calls to the function intersected with the declared typ e If there

are any assignments to the argumentvariables the typ e of the assigned value is unioned in as well

The result typ e of a local function is computed in a sp ecial way that takes tail recursion see section

page into consideration The result typ e is the union of all p ossible return values that arent tailrecursive

calls For example Python will infer that the result typ e of this function is integer

defun n res

declare integer n res

if zerop n

res

n n res

Although this is a rather obvious result it b ecomes somewhat less trivial in the presence of mutual tail recursion

of multiple functions Lo cal function result typ e inference interacts with the mechanisms for ensuring prop er tail

recursion mentioned in section

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Global Function Typ e Inference

As describ ed in section a global function typ e ftype declaration places implicit typ e assertions on the

call arguments and also guarantees the typ e of the return value So wherever a call to a declared function

app ears there is no doubt as to the typ es of the arguments and return value Furthermore Python will infer

a function typ e from the functions denition if there is no ftype declaration Anytyp e declarations on the

argumentvariables are used as the argumenttyp es in the derived function typ e and the compilers b est guess

for the result typ e of the function is used as the result typ e in the derived function typ e

This method of deriving function typ es from the denition implicitly assumes that functions wont b e redened

at runtime Consider this example

defun foop x

let res and consp x eq car x foo

format t It is not foo res

defun frob it

if foop it

setf cadr it yow

it

Presumably the programmer really meant to return res from foop but he seems to have forgotten When

he tries to call do frob list foo nil frob will ame out when it tries to add to a cons Realizing his

error he xes foop and recompiles it But when he retries his test case he is baed b ecause the error is

still there What happ ened in this example is that Python proved that the result of foop is null and then

pro ceeded to optimize awaythe setf in frob

Fortunately in this example the error is detected at compile time due to notes ab out unreachable co de see

section page Still some users maynotwanttoworry ab out this sort of problem during incremental

development so there is a variable to control deriving function typ es

V extensionsderivefunctiontypes ariable

If true the default argument and result typ e information derived from compilation of defuns is used when

compiling calls to that function If false only information from ftype pro clamations will b e used

Op eration Sp ecic Typ e Inference

Many of the standard Common Lisp functions havespecialtyp e inference pro cedures that determine the result

typ e as a function of the argumenttyp es For example the result typ e of aref is the arrayelementtyp e Here

are some other examples of typ e inferences

logand x xFF unsignedbyte

the integer x the integer y integer

ash the unsignedbyte x unsignedbyte

Dynamic Typ e Inference

Python uses ow analysis to infer typ es in dynamically typ ed programs For example

ecase x

list length x

Here the compiler knows the argumenttolength is a list b ecause the call to length is only done when x is a

list The most signicant eciency eect of inference from assertions is usually in typ e check optimization

Dynamic typ e inference has two inputs explicit conditionals and implicit or explicit typ e assertions Flow

analysis propagates these constraints on variable typ e to any co de that can b e executed only after passing though

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

the constraint Explicit typ e constraints come from ifs where the test is either a lexical variable or a function

of lexical variables and constants where the function is either a typ e predicate a numeric comparison or eq

If there is an eq or eql test then the compiler will actually substitute one argument for the other in the

true branch For example

when eq x yow return x

b ecomes

when eq x yow return yow

This substitution is done when one argument is a constant or one argument has b etter typ e information than

the other This transformation reveals opp ortunities for constant folding or typ esp ecic optimizations If the

test is against a constant then the compiler can prove that the variable is not that constantvalue in the false

branch or not member yow in the example ab ove This can eliminate redundant tests for example

if eq x nil

if x a b

is transformed to this

if eq x nil

a

Variables app earing as if tests are interpreted as not eq var nil tests The compiler also converts into

eql where p ossible It is dicult to do inference directly on since it do es implicit co ercions

When there is an explicit or test on integer variables the compiler makes inferences ab out the ranges

the variables can assume in the true and false branches This is mainly useful when it proves that the values

are small enough in magnitude to allow op enco ding of arithmetic op erations For example in many uses of

dotimes with a fixnum rep eat count the compiler proves that xnum arithmetic can b e used

Implicit t yp e assertions are quite common esp ecially if you declare function argumenttyp es Dynamic

inference from implicit typ e assertions sometimes helps to disambiguate programs to a useful degree but is most

noticeable when it detects a dynamic typ e error For example

defun foo x

car x x

results in this warning

In DEFUN FOO

CAR X X

X

Warning Result is a LIST not a NUMBER

Note that Common Lisps dynamic typ e checking semantics make dynamic typ e inference useful even in

programs that arent really dynamically typ ed for example

car x length x

Here x presumably always holds a list but in the absence of a declaration the compiler cannot assume x is a

list simply b ecause listsp ecic op erations are sometimes done on it The compiler must consider the program

to b e dynamically typ ed until it proves otherwise Dynamic typ e inference proves that the argumenttolength

is always a list b ecause the call to length is only done after the listsp ecic car op eration

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Typ e Check Optimization

Python backs up its supp ort for precise typ e checking by minimizing the cost of runtime typ e checking This is

done b oth through typ e inference and though optimizations of typ e checking itself

Typ e inference often allows the compiler to prove thatavalue is of the correct typ e and thus no typ e check

is necessaryFor example

defstruct foo a b c

defstruct link

foo requiredargument type foo

next nil type or link null

fooa linkfoo x

Here there is no need to check that the result of linkfoo is a foo since it always is Even when some typ e

checks are necessarytyp e inference can often reduce the number

defun test x

let a fooa x

b foob x

c fooc x

In this example only one foop x check is needed This applies to a lesser degree in list op erations suchas

if eql car x cdr x y

Here we only havetocheck that x is a list once

Since Python recognizes explicit typ e tests co de that explicitly protects itself against typ e errors has little

intro duced overhead due to implicit typ e checking For example this loop compiles with no implicit checks

checks for car and cdr

defun memq e l

do current l cdr current

atom current nil

when eq car current e return current

Python reduces the cost of checks that must b e done through an optimization called complementingA

complemented checkfortyp e is simply a chec kthatthevalue is not of the typ e not typ e This is only

interesting when something is known ab out the actual typ e in which case we can test for the complementof

and knowntyp e not typ e or the dierence b etween the known typ e and the assertion An example

linkfoo linknext x

Here we change the typ e checkforlinkfoo from a test for foo to a test for

not and or foo null not foo

or more simply not null This is probably the most important use of complementing since the situation is

fairly common and a null test is much cheap er than a structure typ e test

Here is a more complicated example that illustrates the combination of complementing with dynamic typ e

inference

defun finda a x

declare type or link null x

do current x linknext current

null current nil

let foo linkfoo current

when eq fooa foo a return foo

This lo op can b e compiled with no typ e checks The link test for linkfoo and linknext is complemented to

not null and then deleted b ecause of the explicit null test As b efore no check is necessary for fooa since

the linkfoo is always a foo This sort of situation shows how precise typ e checking combined with precise

declarations can actually result in reduced typ e checking

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Source Optimization

This section describ es sourcelevel transformations that Python do es on programs in an attempt to make them

more ecient Although sourcelevel optimizations can make existing programs more ecient the biggest advan

tage of this sort of optimization is that it makes it easier to write ecient programs If a clean straightforward

implementation is can b e transformed into an ecient one then there is no need for tricky and dangerous hand

optimization

Let Optimization

The primary optimization of let variables is to delete them when they are unnecessary Whenever the value of

a let variable is a constant a constant variable or a constant lo cal or nonnotinline function the variable is

deleted and references to the variable are replaced with references to the constant expression This is useful

primarily in the expansion of macros or inline functions where argumentvalues are often constant in anygiven

call but are in general nonconstant expressions that must b e b ound to preserv e order of evaluation Let variable

optimization eliminates the need for macros to carefully avoid spurious bindings and also makes inline functions

just as ecient as macros

A particularly interesting class of constant is a local function Substituting for lexical variables that are

b ound to a function can substantially improve the eciency of functional programming styles for example

let a lambda x zow x

funcall a

eectively transforms to

zow

This transformation is done even when the function is a closure as in

let a let y zug

lambda x zow x y

funcall a

b ecoming

zow zug

A constantvariable is a lexical variable that is never assigned to always keeping its initial value Whenever

p ossible avoid setting lexical variables instead bind a new variable to the new value Except for loop variables

it is almost always p ossible to avoid setting lexical variables This form

let x f x

is more ecient than this form

setq x f x

Setting variables makes the program more dicult to understand b oth to the compiler and to the program

mer Python compiles assignments at least as eciently as any other Common Lisp compiler but most let

optimizations are only done on constant variables

Constantvariables with only a single use are also optimized awayeven when the initial value is not constant

For example this expansion of incf

let g x

setq x G

b ecomes

The source transformation in this example do esnt represent the preservation of evaluation order implicit in the compilers

internal representation Where necessary the back end will reintro duce temp oraries to preserve the semantics

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

setq x x

The typ e semantics of this transformation are more important than the eliminationofthevariable itself Consider

what happ ens when x is declared to b e a fixnum after the transformation the compiler can compile the addition

knowing that the result is a fixnum whereas b efore the transformation the addition would have to allow for

xnum overow

Another variable optimization deletes anyvariable that is never read This causes the initial value and any

assigned values to b e unused allowing those expressions to b e deleted if they have no sideeects

Note that a let is actually a degenerate case of local call see section page and that let optimization

can b e done on calls that werent created by a let Also lo cal call allows an applicative style of iteration that is

totally assignment free

ConstantFolding

Constant folding is an optimization that replaces a call of constant arguments with the constant result of that

call Constant folding is done on all standard functions for which it is legal Inline expansion allows folding of

any constant parts of the denition and can b e done even on functions that have sideeects

It is convenient to rely on constant folding when programming as in this example

defconstant limit

defun foo

limit

Constant folding is also helpful when writing macros or inline functions since it usually eliminates the need to

write a macro that sp ecialcases constant arguments

Constant folding of a user dened function is enabled bytheextensionsconstantfunction pro clamation

In this example

declaim extconstantfunction myfun

defun myexp x y

declare singlefloat x y

exp log x y

myexp

The call to myexp is constantfolded to

Unused Expression Elimination

If the value of any expression is not used and the expression has no sideeects then it is deleted As with

constant folding this optimization applies most often when cleaning up after inline expansion and other op

timizations Any function declared an extensionsconstantfunction is also sub ject to unused expression

elimination

Note that Python will eliminate parts of unused expressions known to b e sideeect free even if there are

other unknown parts For example

let a list foo bar

if t

zow

raz a

b ecomes

progn foo bar zow

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Control Optimization

The most important optimization of control is recognizing when an if test is known at compile time then

deleting the if the test expression and the unreachable branchoftheif This can b e considered a sp ecial case

of constant folding although the test do esnt have to b e truly constant as long as it is denitely not nil Note

also that typ e inference propagates the result of an if test to the true and false branches see section

page



A related if optimization is this transformation

if if a b c x y

into

if a

if b x y

if c x y

The opp ortunity for this sort of optimization usually results from a conditional macro For example

if not a x y

is actually implemented as this

if if a nil t x y

which is transformed to this

if a

if nil x y

if t x y

which is then optimized to this

if a y x

Note that due to Pythons internal represen tations the ifif situation will b e recognized even if other forms

are wrapp ed around the inner iflike

if let g

loop

return not g

xy

In Python all the Common Lisp macros really are macros written in terms of if block and tagbodyso

userdened control macros can b e just as ecient as the standard ones Python emits basic blocks using a

heuristic that minimizes the numb er of unconditional branches The co de in a tagbody will not b e emitted in

the order it app eared in the source so there is no p oint in arranging the co de to makecontrol drop through to

the target

Unreachable Co de Deletion

Python will delete co de whenever it can prov e that the co de can never b e executed Co de b ecomes unreachable

when

An if is optimized awayor

There is an explicit unconditional control transfer such as go or returnfromor

The last reference to a local function is deleted or there never was any reference



Note that the co de for x and y isnt actually replicated

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

When co de that app eared in the original source is deleted the compiler prints a note to indicate a p ossible

problem or at least unnecessary co de For example

defun foo

if t

writeline True

writeline False

will result in this note

In DEFUN FOO

WRITELINE False

Note Deleting unreachable code

It is importanttopay attention to unreachable co de notes since they often indicate a subtle typ e error For

example

defstruct foo a b

defun lose x

let a fooa x

b if x foob x none

results in this note

In DEFUN LOSE

IF X FOOB X NONE

NONE

Note Deleting unreachable code

The none is unreachable b ecause typ e inference knows that the argumentto fooa mustbeafooandthus

cant b e nil Presumably the programmer forgot that x could b e nil when he wrote the binding for a

Here is an example with an incorrect declaration

defun counta string

do pos position a string start pos

count count

null pos count

declare fixnum pos

This time our note is

In DEFUN COUNTA

DO POS COUNT

NULL POS COUNT

DECLARE FIXNUM POS

BLOCK LET TAGBODY RETURNFROM PROGN

COUNT

Note Deleting unreachable code

The problem here is that pos can never b e null since it is declared a fixnum

It takes some exp erience with unreachable co de notes to b e able to tell what they are trying to sayIn

nonobvious cases the b est thing to do is to call the function in a way that should cause the unreachable co de

to b e executed Either you will get a typ e error or you will nd that there truly is no wayforthecodetobe

executed Not all unreachable co de results in a note

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

A note is only given when the unreachable co de textually app ears in the original source This prevents

spurious notes due to the optimization of macros and inline functions but sometimes also forego es a note

that would have b een useful

Since accurate source information is not available for nonlist forms there is an element of heuristic in

determining whether or not to give a note about an atom Spurious notes maybegiven when a macro

or inline function denes a variable that is also present in the calling function Notes ab out nil and t

are never given since it is to o easy to confuse these constants in expanded co de with ones in the original

source

Notes are only given ab out co de unreachable due to control ow There is no note when an expression is

deleted b ecause its value is unused since this is a common consequence of other optimizations

Somewhat spurious unreachable co de notes can also result when a macro inserts multiple copies of its argu

ments in dierent contexts for example

defmacro tandf var form

if var form form

defun foo x

tandf x if x True False

results in these notes

In DEFUN FOO

IF X True False

False

Note Deleting unreachable code

True

Note Deleting unreachable code

It seems like it has deleted b oth branches of the if but it has really deleted one branch in one copy and the

other branchintheothercopy Note that these messages are only spurious in not satisfying the intent of the

rule that notes are only given when the deleted co de app ears in the original source there is always some co de

b eing deleted when a unreachable co de note is printed

Multiple Values Optimization

Within a function Python implements uses of multiple values particularly eciently Multiple values can b e kept

in arbitrary registers so using multiple values do esnt imply stack manipulation and represen tation conversion

For example this co de

let a if x foo x u

b if x bar x v

is actually more ecien t written this way

multiplevaluebind

a b

if x

values foo x bar x

values u v

Also see section page for information on how lo cal call provides ecient supp ort for multiple function

return values

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Source to Source Transformation

The compiler implements a numb er of op erationsp ecic optimizations as sourcetosource transformations You

will often see unfamiliar co de in error messages for example

defun myzerop zerop x

gives this warning

In DEFUN MYZEROP

ZEROP X

X

Warning Undefined variable X

The original zerop has b een transformed into a call to This transformation is indicated with the same

used to mark macro and function inline expansion Although it can b e confusing display of the transformed

source is important since warnings are given with resp ect to the transformed source This a more obscure

example

defun foo x logand x

gives this eciency note

In DEFUN FOO

LOGAND X

LOGAND CY CX

Note Forced to do staticfunction Twoargand cost

Unable to do inline fixnum arithmetic cost because

The first argument is a INTEGER not a FIXNUM

etc

Here the compiler commuted the call to logandintro ducing temp oraries The note complains that the rst

argumentisnotafixnum when in the original call it was the second argument Tomake things more confusing

the compiler intro duced temp oraries called cx and cy that are b ound to y and resp ectively

You will also notice sourcetosource optimizations when eciency notes are enabled see section

page When the compiler is unable to do a transformation that might b e p ossible if there was more in

formation then an eciency note is printed For example myzerop ab ove will also give this eciency note

In DEFUN FOO

ZEROP X

X

Note Unable to optimize because

Operands might not be the same type so cant open code

Style Recommendations

Source level optimization makes p ossible a clearer and more relaxed programming style

Dont use macros purely to avoid function call If you want an inline function write it as a function and

declare it inline Its clearer less errorprone and works just as well

Dont write macros that try to optimize their expansion in trivial ways such as avoiding binding variables

for simple expressions The compiler do es these optimizations to o and is less likely to make a mistake

Make use of local functions ie labels or flet and tailrecursion in places where it is clearer Lo cal

function call is faster than full call

Avoid setting local variables when p ossible Binding a new let variable is at least as ecient as setting an

existing variable and is easier to understand b oth for the compiler and the programmer

Instead of writing similar co de over and over again so that it can b e hand customized for each use dene

a macro or inline function and let the compiler do the work

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Tail Recursion

A call is tailrecursive if nothing has to b e done after the the call returns ie when the call returns the

returned value is immediately returned from the calling function In this example the recursive call to myfun is

tailrecursive

defun myfun x

if oddp random x

isqrt x

myfun x

Tail recursion is interesting b ecause it is form of recursion that can b e implemented much more eciently

than general recursion In general a recursive call requires the compiler to allocate storage on the stackat

runtime for every call that has not yet returned This memory consumption makes recursion unacceptably

inecient for represen ting rep etitive algorithms having large or unb ounded size Tail recursion is the sp ecial case

of recursion that is semantically equivalent to the iteration constructs normally used to represen t rep etition in

programs Because tail recursion is equivalent to iteration tailrecursive programs can b e compiled as eciently

as iterative programs

So whywould you want to write a program recursively when you can write it using a lo op Well the main

answer is that recursion is a more general mechanism so it can express some solutions simply that are awkward

to write as a loop Some programmers also feel that recursion is a stylistically preferable way to write loops

b ecause it avoids assigning variables For example instead of writing

defun fun x

somethingthatusesx

defun fun y

somethingthatusesy

do x something fun fun x

nil

You can write

defun fun x

fun somethingthatusesx

defun fun y

fun somethingthatusesy

fun something

The tailrecursive denition is actually more ecient in addition to b eing arguably clearer As the number of

functions and the complexity of their call graph increases the simplicity of using recursion b ecomes compelling

Consider the advantages of writing a large nitestate mac hine with separate tailrecursive functions instead of

using a single huge prog

It helps to understand how to use tail recursion if you think of a tailrecursivecallasapsetq that assigns

the argumentvalues to the called functions variables followed bya go to the start of the called function This

makes clear an inherent eciency advantage of tailrecursive call in addition to not having to allocate a stack

frame there is no need to prepare for the call to return eg by computing a return PC

Is there any disadvantage to tail recursion Other than an increase in eciency the only wayyou can tell

that a call has b een compiled tailrecursively is if you use the debugger Since a tailrecursive call has no stack

frame there is no way the debugger can print out the stack frame represen ting the call The eect is that

backtrace will not show some calls that would have b een displayed in a nontailrecursive implementation In

practice this is not as bad as it sounds in fact it isnt really clearly worse just dierent See section

page for information ab out the debugger implications of tail recursion

In order to ensure that tailrecursion is preserv ed in arbitrarily complex calling patterns across separately

compiled functions the compiler must compile any call in a tailrecursive p osition as a tailrecursive call This is

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

done regardless of whether the program actually exhibits any sort of recursive calling pattern In this example

the call to fun will always b e compiled as a tailrecursivecall

defun fun x

fun x

So tail recursion do esnt necessarily haveanything to do with recursion as it is normally thought of See section

page for more discussion of using tail recursion to implement loops

Tail Recursion Exceptions

Although Python is claimed to b e prop erly tailrecursive some might dispute this since there are situations

where tail recursion is inhibited

When the call is enclosed by a sp ecial binding or

When the call is enclosed bya catch or unwindprotector

When the call is enclosed bya block or tagbody and the blo cknameorgo tag has b een closed over

These dynamic extent binding forms inhibit tail recursion b ecause they allocate stack space to represen t the

binding Shallowbinding implementations of dynamic scoping also require cleanup co de to b e evaluated when

the scop e is exited

Lo cal Call

Python supp orts two kinds of function call full call and lo cal call Full call is the standard calling convention

its late binding and generalitymake Common Lisp what it is but create unavoidable overheads When the

compiler can compile the calling function and the called function simultaneously it can use local call to avoid

some of the overhead of full call Lo cal call is really a collection of compilation strategies If some asp ect of call

overhead is not needed in a particular lo cal call then it can b e omitted In some cases local call can b e totally

free Lo cal call provides two main advantages to the user

Lo cal call makes the use of the lexical function binding forms flet and labels much more ecient A

localcallisalways faster than a full call and in many cases is much faster

Lo cal call is a natural approachtoblock compilation a compilation technique that resolves function

references at compile time Block compilation sp eeds function call but increases compilation times and

prevents function redenition

SelfRecursiveCalls

Lo cal call is used when a function dened by defun calls itself For example

defun fact n

if zerop n

n fact n

This use of local call sp eeds recursion but can also complicate debugging since trace will only show the rst call

to fact and not the recursiv e calls This is b ecause the recursive calls directly jump to the start of the function

and dont indirect through the symbolfunction Selfrecursive lo cal call is inhibited when the blockcompile

argumenttocompilefile is nil see section page

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Let Calls

Because local call avoids unnecessary call overheads the compiler internally uses lo cal call to implement some

macros and sp ecial forms that are not normally thoughtofasinvolving a function call For example this let

let a foo

b bar

is internally represen ted as though it was macroexpanded into

funcall lambda a b

foo

bar

This implementation is acceptable b ecause the simple cases of lo cal call equivalenttoalet result in go o d co de

This do esnt make let any more ecient but do es make local calls that are semantically the same as let much

more ecient than full calls For example these denitions are all the same as far as the compiler is concerned

defun foo

some other stuff

let a something

some stuff

defun foo

flet localfun a

some stuff

some other stuff

localfun something

defun foo

let funvar lambda a

some stuff

some other stuff

funcall funvar something

Although lo cal call is most ecient when the function is called only once a call do esnt havetobeequivalent

to a let to b e more ecient than full call All lo cal calls avoid the overhead of argumentcountchecking and

keyword argument parsing and there are a numb er of other advantages that apply in many common situations

See section page for a discussion of the optimizations done on let calls

Closures

Lo cal call allows for much more ecient use of closures since the closure environment do esnt need to b e allocated

on the heap or even stored in memory at all In this example there is no p enalty for localfun referencing a

and b

defun foo a b

flet localfun x

a b x

if a b

localfun x

localfun x

In local call the compiler eectively passes closedover values as extra arguments so there is no need for you to

optimize lo cal function use by explicitly passing in lexically visible values Closures may also b e sub ject to let

optimization see section page

Note indirect value cells are curren tly always allocated on the heap when a variable is b oth assigned to with

setq or setf and closed over regardless of whether the closure is a lo cal function or not This is another reason

to avoid setting variables when you dont have to

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Lo cal Tail Recursion

Tailrecursive local calls are particularly ecient since they are in eect an assignment plus a control transfer

Scheme programmers write lo ops with tailrecursive lo cal calls instead of using the imperative go and setq This

has not caught on in the Common Lisp community since conventional Common Lisp compilers dont implement

lo cal call In Python users can cho ose to write lo ops suchas

defun n

labels loop n total

if zerop n

total

loop n n total

loop n

extensionsiterate name fvar initialvalue g fdeclarationg fformg Macro

This macro provides syntactic sugar for using labels to do iteration It creates a local function name with

the sp ecied var s as its arguments and the declarationsandformsasitsbody This function is then called with

the initialvalues and the result of the call is return from the macro

Here is our factorial example rewritten using iterate

defun n

iterate loop

n n

total

if zerop n

total

loop n n total

The main advantage of using iterate over do is that iterate naturally allows stepping to b e done dierently

dep ending on conditionals in the b o dy of the loop iterate can also b e used to implement algorithms that

arent really iterativeby simply doing a nontail call For example the standard recursive denition of factorial

can b e written like this

iterate fact

n n

if zerop n

n fact n

Return Values

One of the more subtle costs of full call comes from allowing arbitrary numb ers of return values This overhead

can b e avoided in lo cal calls to functions that always return the same number of values For eciency reasons

as well as stylistic ones you should write functions so that they always return the same number of values This

may require passing extra nil arguments to values in some cases but the result is more ecient not less so

When eciency notes are enabled see section page and the compiler wants to use known values

return but cant prove that the function always returns the same number of values then it will print a note like

this

In DEFUN GRUE

DEFUN GRUE X DECLARE FIXNUM X COND NIL T

Note Return type not fixed values so cant use known return convention

VALUES OR INTEGER NULL REST T

In order to implement prop er tail recursion in the presence of known values return see section page

the compiler sometimes must provethatmultiple functions all return the same number of values When this

cant b e proven the compiler will print a note like this

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

In DEFUN BLUE

DEFUN BLUE X DECLARE FIXNUM X COND T

Note Return value count mismatch prevents known return from

these functions

BLUE

SNOO

See section page for the interaction b etween lo cal call and the represen tation of numeric typ es

Blo ck Compilation

Blo ck compilation allows calls to global functions dened by defun to b e compiled as lo cal calls The function

call can b e in a dierent toplevel form than the defunoreven in a dierent le

In addition blo ck compilation allows the declaration of the entry p oints to the blo ck compiled p ortion An

entry p ointisany function that may b e called from outside of the block compilation If a function is not an

entry p oint then it can b e compiled more eciently since all calls are known at compile time In particular if

a function is only called in one place then it will b e let converted This eectively inline expands the function

but without the co de duplication that results from dening the function normally and then declaring it inline

The main advantage of blo ck compilation is that it it preserv es eciency in programs even when for read

ability and syntactic convenience they are broken up into many small functions There is absolutely no overhead

for calling a nonentry p oint function that is dened purely for modularity ie called only in one place

Blo ck compilation also allows the use of nondescriptor arguments and return values in nontrivial programs

see section page

Blo ck Compilation Semantics

The eect of block compilation can b e envisioned as the compiler turning all the defuns in the block compilation

into a single labels form

declaim startblock fun fun

defun fun

defun fun

fun

defun fun x

if x

fun

fun

declaim endblock

b ecomes

labels fun

fun

fun

fun x

if x fun

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

fun

setf fdefinition fun fun

setf fdefinition fun fun

Calls b etween the block compiled functions are lo cal calls so changing the global denition of fun will haveno

eect on what fun do es fun will keep calling the old fun

The entry p oints fun and fun are still installed in the symbolfunction as the global denitions of the

functions so a full call to an entry p ointworks just as b efore However fun is not an entry p oint so it is not

globally dened In addition fun is only called in one place so it will b e let converted

Blo ck Compilation Declarations

The extensionsstartblock and extensionsendblock declarations allow negrained control of blockcom

pilation These declarations are only legal as a global declarations declaim or proclaim

The startblock declaration has this syntax

startblock fentryp ointname g

When pro cessed by the compiler this declaration marks the start of block compilation and sp ecies the entry

p oints to that blo ck If no entry p oints are sp ecied then all functions are made into entry p oints If already

blo ck compiling then the compiler ends the curren t block and starts a new one

The endblock declaration has no arguments

endblock

The endblock declaration ends a blo ck compilation unit without starting a new one This is useful mainly

when only a p ortion of a le is worth blo ck compiling

Compiler Arguments

The blockcompile and entrypoints arguments to extensionscompilefromstream and compilefile

page provide overall control of blo ck compilation and allow blo ck compilation without requiring modication

of the program source

There are three p ossible values of the blockcompile argument

nil Do no compiletime resolution of global function names not even for selfrecursive calls This inhibits any

startblock declarations app earing in the le allowing all functions to b e incrementally redened

t Start compiling in block compilation mode This is mainly useful for block compiling small les that contain

no startblock declarations See also the entrypoints argument

specified Start compiling in formatatime mode but exploit startblock declarations and compile self

recursive calls as local calls Normally specified is the default for this argumentsee blockcompile

default page

The entrypoints argument can b e used in conjunction with blockcompile t to sp ecify the entryp oints

to a blo ckcompiled le If not sp ecied or nil all global functions will b e compiled as entry p oints When

blockcompile is not t this argument is ignored

blockcompiledefault Variable

This variable determines the default value for the blockcompile argumenttocompilefile and compile

fromstream The initial value of this v ariable is specifiedbut nil is sometimes useful for totally inhibiting

blo ck compilation

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Practical Diculties

The main problem with blo ck compilation is that the compiler uses large amounts of memory when it is block

compiling This places an upp er limit on the amount of co de that can b e block compiled as a unit To makebest

use of blo ck compilation it is necessary to lo cate the parts of the program containing manyinternal calls and

then add the appropriate startblock declarations When writing new co de it is a goo d idea to put in block

compilation declarations from the very b eginning since writing block declarations correctly requires accurate

knowledge of the programs function call structure If you want to initially develop co de with full incremental

redenition you can compile with blockcompiledefault page set to nil

Note if a defun app ears in a nonnull lexical environment then calls to it cannot b e blo ck compiled

Unless les are very small it is probably impractical to block compile multiple les as a unit by sp ecifying a

list of les to compilefile Semiinline expansion see section page provides another way to extend

blo ck compilation across le b oundaries

Context Declarations

CMU Common Lisp has a contextsensitive declaration mechanism which is useful b ecause it allows exible

control of the compilation p olicy in large systems without requiring changes to the source les The primary

use of this feature is to allow the exp orted interfaces of a system to b e compiled more safely than the system

internals The context used is the name b eing dened and the kind of denition function macro etc

The contextdeclarations option to withcompilationunit page has dynamic scop e aecting all

compilation done during the evaluation of the b o dy The argument to this option should evaluate to a list of

lists of the form



contextsp ec fdeclareformg

In the indicated context the sp ecied declare forms are inserted at the head of each denition The declare

forms for all contexts that match are app ended together with earlier declarations getting precedence o ver later

ones A simple example

contextdeclarations

external declare optimize safety

This will cause all functions that are named by external symb ols to b e compiled with safety

The full syntax of context sp ecs is

internal external True if the symbol is internal external in its home package

uninterned True if the symb ol has no home package

package fpackagename g True if the symb ols home packageisinany of the named packages false if

uninterned

anonymous True if the function do esnt haveanyinteresting name not defmacro defun labels or flet

macro function macro is a global defmacro macro function is anything else

local global local is a labels or flet global is anything else

or fcontextsp ec g True when any supplied contextsp ec is true

and fcontextsp ec g True only when all supplied contextsp ec s are true

not fcontextsp ec g True when contextsp ec is false

member fname g True when the dened name is one of these names equal test

match fpatterng True when any of the patterns is a substring of the name The name is wrapp ed with s

so FOO matches names b eginning with FOO etc

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Context Declaration Example

Here is a more complex example of withcompilationunit options

optimize optimize speed space inhibitwarnings

debug safety

optimizeinterface optimizeinterface safety debug

contextdeclarations

or external and match match SET

declare optimizeinterface safety

or and external macro

match PARSE

declare optimize safety

The optimize and extensionsoptimizeinterface declarations see section page set up the global

compilation p olicy The b o dies of functions are to b e compiled completely unsafe safety but argument

count and weakened argumenttyp e checking is to b e done when a function is called speed safety

The rst declaration sp ecies that all functions that are external or whose names contain b oth and SET

are to b e compiled compiled with completely safe interfaces safety The reason for this particular match

rule is that setf inverse functions in this system tend to have b oth strings in their name somewhere Wewant

setf inverses to b e safe b ecause they are implicitly called by users even though their name is not exp orted

The second declaration makes external macros or functions whose names start with PARSE have safe b o dies

as well as interfaces This is desirable b ecause a syntax error in a macro may cause a typ e error inside the b ody

The match rule is used b ecause macros often have auxiliary functions whose names b egin with this string

This particular example is used to build part of the standard CMU Common Lisp system Note however

that context declarations must b e set up according to the needs and co ding conventions of a particular system

dierent parts of CMU Common Lisp are compiled with dierent context declarations and y our system will

probably need its own declarations In particular any use of the match option dep ends on naming conventions

used in co ding

Inline Expansion

Python can expand almost any function inline including functions with keyword arguments The only restrictions

are that keyword argumentkeywords in the call must b e constant and that global function denitions defun

must b e done in a null lexical environment not nested in a let or other binding form Lo cal functions flet

can b e inline expanded in anyenvironment Combined with Pythons sourcelevel optimization inline expansion

can b e used for things that formerly required macros for ecient implementation In Python macros dont have

any eciency advantage so they need only b e used where a macros syntactic exibilityisrequired

Inline expansion is a compiler optimization technique that reduces the overhead of a function call by simply

not doing the call instead the compiler eectively rewrites the program to app ear as though the denition of the

called function was inserted at each call site In Common Lisp this is straightforwardly expressed by inserting

the lambda corresp onding to the original denition

proclaim inline my

defun my x x

my someval lambda x x someval

When the function expanded inline is large the program after inline expansion may b e substantially larger

than the original program If the program b ecomes to o large inline expansion hurts sp eed rather than helping

it since hardware resources suchasphysical memory and cache will b e exhausted Inline expansion is called for

When proling has shown that a relatively simple function is called so often that a large amount of time

is b eing wasted in the calling of that function as opp osed to running in that function If a function is

complex it will take a long time to run relative the time sp ent in call so the sp eed advantage of inline

expansion is diminished at the same time the space cost of inline expansion is increased Of course if a

function is rarely called then the overhead of calling it is also insignicant

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

With functions so simple that they take less space to inline expand than would b e taken to call the

function such as my ab ove It would require intimate knowledge of the compiler to b e certain when

inline expansion would reduce space but it is generally safe to inline expand functions whose denition is

a single function call or a few calls to simple Common Lisp functions

In addition to this sp eedspace tradeo from inline expansions avoidance of the call inline expansion can

also reveal opp ortunities for optimization Pythons extensive sourcelevel optimization can make use of context

information from the caller to tremendously simplify the co de resulting from the inline expansion of a function

The main form of caller context is local information ab out the actual argumentvalues what the argument

typ es are and whether the arguments are constant Knowledge ab out argumenttyp es can eliminate runtime

typ e tests eg for generic arithmetic Constant arguments in a call provide opp ortunities for constant folding

optimization after inline expansion

A hidden way that constant arguments are often supplied to functions is through the defaulting of unsupplied

optional or keyword arguments There can b e a huge eciency advantage to inline expanding functions that

have complex keywordbased interfaces suchasthisdenitionofthemember function

proclaim inline member

defun member item list key

key identity

test eql testp

testnot nil notp

do list list cdr list

null list nil

let car car list

if cond testp

funcall test item funcall key car

notp

not funcall testnot item funcall key car

t

funcall test item funcall key car

return list

After inline expansion this call is simplied to the obvious co de

member a l key fooa test char

do list list cdr list

null list nil

let car car list

if char item fooa car

return list

In this example there could easily b e more than an order of magnitude improvement in sp eed In addition

to eliminating the original call to member inline expansion also allows the calls to char and fooa to b e

op enco ded We go from a lo op with three tests and two calls to a lo op with one test and no calls

See section page for more discussion of source level optimization

Inline Expansion Recording

Inline expansion requires that the source for the inline expanded function to b e available when calls to the

function are compiled The compiler do esnt rememb er the inline expansion for every function since that would

take an excessive ab out of space Instead the programmer must tell the compiler to record the inline expansion

b efore the denition of the inline expanded function is compiled This is done by globally declaring the function

inline b efore the function is dened by using the inline and extensionsmaybeinline see section

page declarations

In addition to recording the inline expansion of inline functions at the time the function is compiled compile

file also puts the inline expansion in the output le When the output le is loaded the inline expansion is

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

made available for subsequen t compilations there is no need to compile the denition again to record the inline

expansion

If a function is declared inline but no expansion is recorded then the compiler will give an eciency note

like

Note MYFUN is declared inline but has no expansion

When you get this note check that the inline declaration and the denition app ear b efore the calls that are

to b e inline expanded This note will also b e given if the inline expansion for a defun could not b e recorded

b ecause the defun was in a nonnull lexical environment

SemiInline Expansion

Python supp orts semiinline functions Semiinline expansion shares a single copy of a function across all the calls

in a component byconverting the inline expansion into a lo cal function see section page This takes up

less space when there are multiple calls but also provides less opp ortunity for context dep endent optimization

When there is only one call the result is identical to normal inline expansion Semiinline expansion is done

when the space optimization qualityis and the function has b een declared extensionsmaybeinline

This mechanism of inline expansion combined with lo cal call also allows recursive functions to b e inline

expanded If a recursiv e function is declared inline calls will actually b e compiled semiinline Although

recursiv e functions are often so complex that there is little advantage to semiinline expansion it can still b e

useful in the same sort of cases where normal inline expansion is esp ecially advantageous ie functions where

the calling context can help a lot

The Mayb eInline Declaration

The extensionsmaybeinline declaration is a CMU Common Lisp extension It is similar to inline but

indicates that inline expansion may sometimes b e desirable rather than saying that inline expansion should

almost always b e done When used in a global declaration extensionsmaybeinline causes the expansion for

the named functions to b e recorded but the functions arent actually inline expanded unless space is or the

function is eventually p erhaps lo cally declared inline

Use of the extensionsmaybeinline declaration followed bythe defun is preferable to the standard idiom

of

proclaim inline myfun

defun myfun

proclaim notinline myfun

Anycallstomyfun here are not inline expanded

defun somefun

declare inline myfun

Calls to myfun here are inline expanded

The problem with using notinline in this way is that in Common Lisp it do es more than just suppress inline

expansion it also forbids the compiler to use anyknowledge of myfun untilalater inline declaration overrides

the notinline This prevents compiler warnings ab out incorrect calls to the function and also prevents block

compilation

The extensionsmaybeinline declaration is used like this

proclaim extensionsmaybeinline myfun

defun myfun

Anycallstomyfun here are not inline expanded defun somefun

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

declare inline myfun

Calls to myfun here are inline expanded

defun someotherfun

declare optimize space

Calls to myfun here are expanded semiinline

In this example the use of extensionsmaybeinline causes the expansion to b e recorded when the defun for

somefun is compiled and do esnt waste space through doing inline expansion by default Unlike notinline

this declaration still allows the compiler to assume that the known denition really is the one that will b e called

when giving compiler warnings and also allows the compiler to do semiinline expansion when the p olicy is

appropriate

When the goal is merely to control whether inline expansion is done by default it is preferable to use

extensionsmaybeinline rather than notinlineThenotinline declaration should b e reserved for those

sp ecial o ccasions when a function may b e redened at runtime so the compiler mustbetoldthattheobvious

denition of a function is not necessarily the one that will b e in eect at the time of the call

Byte Co ded Compilation

Python supp orts byte compilation to reduce the size of Lisp programs by allowing functions to b e compiled more

compactly Byte compilation provides an extreme sp eedspace tradeo byte co de is typically six times more

compact than native co de but runs fty times or more slower This is ab out ten times faster than the standard

interpreter which is itself considered fast in comparison to other Common Lisp interpreters

Large Lisp systems such as CMU Common Lisp itself often have large amounts of userinterface co de

compiletime macro co de debugging co de or rarely executed sp ecialcase co de This co de is a go o d target for

byte compilation very little time is sp ent running in it but it can take up quite a bit of space Straightline

co de with many function calls is much more suitable than inner loops

When bytecompiling the compiler compiles ab out twice as fast and can pro duce a hardware indep endent

ob ject le byteftyp e This le can b e loaded like a normal fasl le on any implementation of CMU CL

with the same byteordering DEC PMAX has lbyteft yp e

The decision to byte compile or native compile can b e done on a p erle or p erco deob ject basis The

bytecompile argumenttocompilefile page has these p ossible values

nil Dont byte compile anything in this le

t Byte compile everything in this le and pro duce a pro cessorindep endent bytef le

maybe Pro duce a normal fasl le but byte compile any functions for which the speed optimization qualityis

and the debug quality is not greater than

extensionsbytecompiletoplevel Variable

If this variable is true the default and the bytecompile argumenttocompilefile is maybethenbyte

compile toplevel co de co de outside of any defun defmethod etc

extensionsbytecompiledefault Variable

This variable determines the default value for the bytecompile argumenttocompilefile initially

maybe

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Ob ject Representation

A somewhat subtle asp ect of writing ecient Common Lisp programs is cho osing the correct data structures

so that the underlying ob jects can b e implemented eciently This is partly b ecause of the need for multiple

represen tations for a given value see section page but is also due to the sheer numb er of ob ject

typ es that Common Lisp has built in The numb er of p ossible represen tations complicates the choice of a go od

represen tation b ecause semantically similar ob jects mayvary in their eciency dep ending on how the program

op erates on them

Think Before You Use a List

Although Lisps creator seemed to think that it was for LISt Pro cessing the astute observer mayhave noticed

that the chapter on list manipulation makes up less that three p ercen t of Common Lisp the Language I IThe

language has grown since Lisp new data typ es sup ersede lists for many purp oses

Structure Representation

One of the b est ways of building complex data structures is to dene appropriate structure typ es using defstruct

In Python access of structure slots is always at least as fast as list or vector access and is usually faster In

comparison to a list represen tation of a tuple structures also have a space advantage

Even if structures werent more ecient than other represen tations structure use would still b e attractive

b ecause programs that use structures in appropriate ways are much more maintainable and robust than programs

written using only lists For example

rplaca caddr cadddr x caddr y

could have b een written using structures in this way

setf beverageflavor astronautbeverage x beverageflavor y

The second version is more maintainable b ecause it is easier to understand what it is doing It is more robust

b ecause structures accesses are typ e checked An astronaut will nev er b e confused with a beverage and the

result of beverageflavor is always a avor See sections and for more information ab out structure

typ es See section page for a numb er of examples that make clear the advantages of structure typing

Note that the structure denition should b e compiled b efore any uses of its accessors or typ e predicate so

that these function calls can b e eciently op enco ded

Arrays

Arrays are often the most ecient represen tation for collections of ob jects b ecause

Array represen tations are often the most compact An arrayisalways more compact than a list containing

the same numb er of elements

Arrays allow fast constanttime access

Arrays are easily destructiv ely modied which can reduce consing

Array elementtyp es can b e sp ecialized which reduces b oth overall size and consing see section

page

Access of arrays that are not of typ e simplearray is less ecient so declarations are appropriate when an

array is of a simple typ e like simplestring or simplebitvector Arrays are almost always simple but the

compiler may not b e able to prove simpleness at every use The only way to get a nonsimple arrayistousethe

displacedto fillpointer or adjustable arguments to makearrayIfyou dont use these hairy options

then arrays can always b e declared to b e simple

Because of the many sp ecialized arraytyp es and the p ossibility of nonsimple arrays array access is much

like generic arithmetic see section page In order for arra y accesses to b e eciently compiled the

elementtyp e and simpleness of the arraymust b e known at compile time If there is inadequate information

the compiler is forced to call a generic array access routine You can detect inecientarray accesses by enabling eciency notes see section page

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Vectors

Vectors one dimensional arrays are particularly useful since in addition to their obvious arraylike applications

they are also well suited to represen ting sequences In comparison to a list represen tation vectors are faster

to access and takeupbetween two and sixtyfour times less space dep ending on the elementtyp e As with

arbitrary arrays the compiler needs to knowthatvectors are not complex so you should use simplestring in

preference to string etc

The only advantage that lists haveover vectors for represen ting sequences is that it is easy to change the

length of a list add to it and remove items from it Likely signs of archaic slow lisp co de are nth and nthcdr

If you are using these functions you should probably b e using a vector

BitVectors

Another thing that lists have b een used for is set manipulation In applications where there is a known reasonably

small universe of items bitvectors can b e used to improve p erformance This is much less convenient than using

lists b ecause instead of symb ols each element in the universe must b e assigned a numeric index into the bit

vector Using a bitvector will nearly always b e faster and can b e tremendously faster if the numb er of elements

in the set is not small The logical op erations on simplebitvectors are ecient since they op erate on a word

at a time

Hashtables

Hashtables are an ecient and general mechanism for main taining asso ciations such as the asso ciation b etween

an ob ject and its name Although hashtables are usually the b est way to maintain asso ciations eciency and

style considerations sometimes favor the use of an asso ciation list alist

assoc is fairly fast when the test argumentiseq or eql and there are only a few elements but the time

go es up in prop ortion with the numb er of elements In contrast the hashtable lookup has a somewhat higher

overhead but the sp eed is largely unaected bythenumb er of entries in the table For an equal hashtable or

alist hashtables haveaneven greater advantage since the test is more exp ensive Whatever you do b e sure to

use the most restrictive test function p ossible

The style argument observes that although hashtables and alists overlap in function they do not do all

things equally well

Alists are go o d for maintaining scop ed environments They were originally invented to implement scoping

in the Lisp interpreter and are still used for this in Python With an alist one can nondestructively change

an asso ciation simply by consing a new element on the front This is something that cannot b e done with

hashtables

Hashtables are go o d for maintaining a global asso ciation The value asso ciated with an entry can easily

be changed with setf With an alist one has to go through contortions either rplacding the cons if the

entry exists or pushing a new one if it do esnt The sideeecting nature of hashtable op erations is an

advantage here

Historically symb ol prop erty lists were often used for global name asso ciations Prop erty lists provide an

awkward and errorprone combination of name asso ciation and record structure If you must use the prop erty

list please store all the related values in a single structure under a single prop erty rather than using many

dicum of typing and abstraction See section prop erties This makes access more ecient and also adds a mo

page for information on typ es in CMU Common Lisp

Numb ers

Numb ers are interesting b ecause numb ers are one of the few Common Lisp data typ es that have direct supp ort

in conventional hardware If a numb er can b e represen ted in the way that the hardware exp ects it then there is

a big eciency advantage

Using hardware represen tations is problematical in Common Lisp due to dynamic typing where the typ e

of a value may b e unknown at compile time It is p ossible to compile co de for statically typ ed p ortions of

a Common Lisp program with eciency comparable to that obtained in statically typ ed languages suchasC

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

but not all Common Lisp implementations succeed There are two main barriers to ecientnumerical co de in

Common Lisp

The compiler must prove that the numerical expression is in fact statically typ ed and

The compiler must b e able to somehow reconcile the conicting demands of the hardware mandated number

represen tation with the Common Lisp requirements of dynamic typing and garbagecollecting dynamic

storage allocation

Because of its typ e inference see section page and eciency notes see section page Python

is b etter than conventional Common Lisp compilers at ensuring that numerical expressions are statically typ ed

Python also go es somewhat farther than existing compilers in the area of allowing nativemachine number

represen tations in the presence of garbage collection

Descriptors

Common Lisps dynamic typing requires that it b e p ossible to represen t anyvalue with a xed length ob ject

known as a descriptor This xedlength requirement is implicit in features such as

Data typ es like simplevector that can contain anytyp e of ob ject and that can b e destructiv ely

modied to contain dierent ob jects of p ossibly dierent typ es

Functions that can b e called with anytyp e of argument and that can b e redened at run time

In order to save space a descriptor is invariably represen ted as a single word Ob jects that can b e directly

represen ted in the descriptor itself are said to b e immediate Descriptors for ob jects larger than one word are in

reality p ointers to the memory actually containing the ob ject

Representing ob jects using p ointers has two ma jor disadvantages

The memory p ointed to m ust b e allocated on the heap so it must eventually b e freed by the garbage

collector Excessiv e heap allocation of ob jects or consing is inecient in several ways See section

page

Represen ting an ob ject in memory requires the compiler to emit additional instructions to read the actual

value in from memory and then to write the value back after op erating on it

The intro duction of garbage collection makes things even worse since the garbage collector must b e able

to determine whether a descriptor is an immediate ob ject or a p ointer This requires that a few bits in each

descriptor b e dedicated to the garbage collector The loss of a few bits do esnt seem likemuch but it has a ma jor

eciency implication ob jects whose natural machine represen tation is a full word integers and singleoats

cannot have an immediate represen tation So the compiler is forced to use an unnatural immediate represen tation

such as fixnum or a natural p ointer represen tation with the attendantconsingoverhead

NonDescriptor Representations

From the discussion ab ove we can see that the standard descriptor represen tation has many problems the

worst b eing numb er consing Common Lisp compilers try to avoid these descriptor eciency problems byusing

nondescriptor represen tations A compiler that uses nondescriptor represen tations can compile this function

so that it do es no numb er consing

defun multby vec n

declare type simplearray singlefloat vec

singlefloat n

dotimes i length vec

setf aref vec i

n aref vec i

If a descriptor represen tation were used each iteration of the loop might cons two oats and do three times as

many memory references

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

As its negative denition suggests the range of p ossible nondescriptor represen tations is large The p er

formance improvement from nondescriptor represen tation dep ends up on b oth the number of typ es that have

nondescriptor represen tations and the number of contexts in which the compiler is forced to use a descriptor

represen tation

Many Common Lisp compilers supp ort nondescriptor represen tations for oat typ es such as singlefloat

and doublefloat section Python adds supp ort for full word integers see section page

characters see section page and systemarea p ointers unconstrained p ointers see section

page Many Common Lisp compilers supp ort nondescriptor represen tations for variables section

and array elements section Python adds supp ort for nondescriptor arguments and return values in

lo cal call see section page and structure slots see section page

Variables

In order to use a nondescriptor represen tation for a variable or expression intermediate value the compiler

must b e able to prove that the value is always of a particular typ e having a nondescriptor represen tation Typ e

inference see section page often needs some help from usersupplied declarations The b est kind of typ e

declaration is a variable typ e declaration placed at the binding p oint

let x car l

declare singlefloat x

Use of theorofvariable declarations not at the binding form is insucienttoallow nondescriptor represen tation

of the variable with these declarations it is not certain that all values of the variable are of the righttyp e

It is sometimes useful to intro duce a gratuitous binding that allows the compiler to change to a nondescriptor

represen tation like

etypecase x

signedbyte

let x x

declare type signedbyte x

The declaration on the inner x is necessary here due to a phase ordering problem Although the compiler will

eventually prove that the outer x is a signedbyte within that etypecase branch the inner x would have

b een optimized awayby that time Declaring the typ e makes let optimization more cautious

Note that storing a value into a global or specialvariable always forces a descriptor represen tation

Wherever p ossible you should op erate only on local variables binding any referenced globals to local variables

at the b eginning of the function and doing any global assignments at the end

Eciency notes signal use of inecient represen tations so programmers neednt continuously worry ab out

the details of represen tation selection see section page

Generic Arithmetic



In Common Lisp arithmetic op erations are generic The function can b e passed fixnums bignums ratios

and various kinds of floatsandcomplexes in anycombination In addition to the inherent complexityofbignum

and ratio op erations there is also a lot of overhead in just guring out which op eration to do and what contagion

and canonicalization rules apply The complexity of generic arithmetic is so great that it is inconceivable to op en

co de it Instead the compiler do es a function call to a generic arithmetic routine consuming many instructions

b efore the actual computation even starts

This is ridiculous since even Common Lisp programs do a lot of arithmetic and the hardware is capable of

doing op erations on small integers and oats with a single instruction To get acceptable eciency the compiler

sp ecialcases uses of generic arithmetic that are directly implemented in the hardware In order to op en co de

arithmetic several constraints must b e met



As Steele notes in CLTL I I this is a generic conception of generic and is not to b e confused with the CLOS concept of a generic function

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

All the arguments must b e known to b e a goo d typ e of numb er

The result must b e known to be a good typ e of number

Anyintermediate values such as the result of a b in the call a b c must b e knowntobeagood

typ e of numb er

All the ab ovenumb ers with go o d typ es must b e of the same goo d typ e Dont try to mix integers and

oats or dierent oat formats

The good typ es are signedbyte unsignedbyte singlefloat and doublefloat See

sections and for more discussion of goo d numeric typ es

float is not a go o d typ e since it might mean either singlefloat or doublefloat integer isnotagood

typ e since it mightmeanbignum rational is not a good typ e since it might mean ratioNotehowever that

these typ es are still useful in declarations since typ e inference maybeabletostrengthenaweak declaration into

a go o d one when it would b e at a loss if there was no declaration at all see section page The integer

and unsignedbyte or nonnegativeinteger typ es are esp ecially useful in this regard since they can often b e

strengthened to a go od integer typ e

Arithmetic with complex numb ers is inecient in comparison to oat and integer arithmetic Complex

numb ers are always represen ted with a p ointer descriptor causing consing overhead and complex arithmetic is

always closed co ded using the general generic arithmetic functions But arithmetic with complex typ es such as

complex float

complex fixnum

is still faster than bignum or ratio arithmetic since the implementation is much simpler

Note dont use to divide integers unless you wanttheoverhead of rational arithmetic Use truncate even

when you know that the arguments divide evenly

You dont need to rememb er all the rules for how to get op enco ded arithmetic since eciency notes will tell

you when and where there is a problem see section page

Fixnums

Axnum is a FIXed precision NUMb er In modern Common Lisp implementations xnums can b e represen ted

with an immediate descriptor so op erating on xnums requires no consing or memory references Clever choice

of represen tations also allows some arithmetic op erations to b e done on xnums using hardware supp orted

wordinteger instructions somewhat reducing the sp eed p enalty for using an unnatural integer represen tation

It is useful to distinguish the fixnum typ e from the xnum represen tation of integers In Python there

is absolutely nothing magical ab out the fixnum typ e in comparison to other nite integer typ es fixnum is

equiv alent to is dened with deftype to b e signedbyte fixnum is simply the largest subset of integers

that can b e represen ted using an immediate xnum descriptor

Unlike in other Common Lisp compilers it is in no way desirable to use the fixnum typ e in declarations

in preference to more restrictive integer typ es suchasbit integer and unsignedbyte Since

Python do es understand these integer typ es it is preferable to use the more restrictive typ e as it allows b etter

typ e inference see section page

The small ecientxnum is contrasted with bignum or BIG NUMb er This is another descriptor repre

sentation for integers but this time a p ointer represen tation that allows for arbitrarily large integers Bignum

op erations are less ecient than xnum op erations b oth b ecause of the consing and memory reference over

heads of a p ointer descriptor and also b ecause of the inherent complexity of extended precision arithmetic

While xnum op erations can often b e done with a single instruction bignum op erations are so complex that

they are always done using generic arithmetic

A crucial p oint is that the compiler will use generic arithmetic if it cant prove that all the arguments

intermediate values and results are xnums With b ounded integer typ es such as fixnum the result typ e proves

to b e esp ecially problematical since these typ es are not closed under common arithmetic op erations such as

and For example the fixnum x do es not necessarily evaluate to a fixnum Bign ums were added

to Common Lisp to get around this problem but they really just transform the correctness problem if this

add overows you will get the wrong answer to the eciency problem if this add might overow then your

program will run slowly b ecause of generic arithmetic

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

There is just no getting around the fact that the hardware only directly supp orts short integers To get the

most ecient op en co ding the compiler must b e able to prove that the result is a go o d integer typ e This is an

argumentinfavor of using more restrictive integer typ es the fixnum x maynotalways b e a fixnum

but the unsignedbyte x always is Of course you can also assert the result typ e by putting in

lots of the declarations and then compiling with safety

Word Integers

Python is unique in its ecient implementation of arithmetic on fullword integers through nondescriptor rep

resen tations and op en co ding Arithmetic on anysubtyp e of these typ es

signedbyte

unsignedbyte

is reasonably ecient although subtyp es of fixnum remain somewhat more ecient

If a word integer must b e represen ted as a descriptor then the bignum represen tation is used with its

asso ciated consing overhead The supp ort for word integers in no way changes the language semantics it just

makes arithmetic on small bignums vastly more ecient It is ne to do arithmetic op erations with mixed fixnum

and word integer op erands just declare the most sp ecic integer typ e you can and let the compiler decide what

represen tation to use

In fact to most users the greatest advantage of word integer arithmetic is that it eectively provides a few

guard bits on the xnum represen tation If there are missing assertions on intermediate values in a xnum

expression the intermediate results can usually b e pro ved to t in a word After the whole expression is

evaluated there will often b e a xnum assertion on the nal result allowing creation of a xnum result without

even checking for overow

The remarks in section ab out xnum result typ e also apply to word integers you must b e careful to

give the compiler enough information to prove that the result is still a word integer This time though when

we blow out of word integers welandininto generic bignum arithmetic whichismuch worse than sleazing from

fixnumstoword integers Note that mixing unsignedbyte arguments with arguments of any signed typ e

such as fixnum is a nono since the result might not b e unsigned

Floating Point Eciency

Arithmetic on ob jects of typ e singlefloat and doublefloat is eciently implemented using nondescriptor

represen tations and op en co ding As for integer arithmetic the arguments mustbeknown to b e of the same

oat typ e Unlikeforinteger arithmetic the results and intermediate values usually take care of themselves due

to the rules of oat contagion ie the singlefloat x is always a singlefloat

Although they are not sp ecially implemented shortfloat and longfloat are also acceptable in decla

rations since they are synonyms for the singlefloat and doublefloat typ es resp ectively Itisharmless

to use liststyle oat typ e sp eciers such as singlefloat but Python currently makes little use of

b ounds on oat typ es

When a oat must b e represen ted as a descriptor a p ointer represen tation is used creating consing overhead

For this reason you should try to avoid situations such as full call and nonsp ecialized data structures that

force a descriptor represen tation See sections and

See section page for information on the extensions to supp ort IEEE oating p oint

Sp ecialized Arrays

Common Lisp supp orts sp ecialized arrayelementtyp es through the elementtype argumenttomakearray

When an array has a sp ecialized elementtyp e only elements of that typ e can b e stored in the arrayFrom this

restriction comes two ma jor eciency advantages

A sp ecialized array can savespaceby packing multiple elements into a single word For example a base

char array can have elements p er word and a bit arraycanhave This spaceecient represen tation

is p ossible b ecause it is not necessary to separately indicate the typ e of eachelement

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

The elements in a sp ecialized arraycanbegiven the same nondescriptor represen tation as the one used in

registers and on the stack eliminating the need for represen tation conversions when reading and writing

array elements For ob jects with p ointer descriptor represen tations such as oats and word integers there

is also a substantial consing reduction b ecause it is not necessary to allocate a new ob ject every time an

array elementismodied

These are the sp ecialized elementtyp es curren tly supp orted

bit

unsignedbyte

unsignedbyte

unsignedbyte

unsignedbyte

unsignedbyte

basecharacter

singlefloat

doublefloat

Although a simplevector can hold anytyp e of ob ject t should still b e considered a sp ecialized arraytyp e

since arrays with elementtyp e t are sp ecialized to hold descriptors

When using nondescriptor represen tations it is particularly importanttomake sure that array accesses

are op enco ded since in addition to the generic op eration overhead eciency is lost when the array element

is converted to a descriptor so that it can b e passed to or from the generic access routine You can detect

inecient array accesses by enabling eciency notes see section page See section page

Sp ecialized Structure Slots

Structure slots declared by the type defstruct slot option to have certain known numeric typ es are also given

nondescriptor represen tations These typ es and subtyp es of these typ es are supp orted

unsignedbyte

singlefloat

doublefloat

The primary advantage of sp ecialized slot represen tations is a large reduction spurious memory allocation

and access overhead of programs that intensively use these typ es

Interactions With Lo cal Call

Lo cal call has manyadvantages see section page one relevant to our discussion here is that local call

extends the usefulness of nondescriptor represen tations If the compiler knows from the argumenttyp e that

an argument has a nondescriptor represen tation then the argument will b e passed in that represen tation The

easiest way to ensure that the argumenttyp e is known at compile time is to always declare the argumenttyp e

in the called function like

defun f x

declare singlefloat x

x

The advantages of passing arguments and return values in a nondescriptor represen tation are the same as for

nondescriptor represen tations in general reduced consing and memory access see section page This

extends the applicative programming styles discussed in section to numeric co de Also if source les are kept

reasonably small blo ck compilation can b e used to reduce numb er consing to a minimum

Note that nondescriptor return values can only b e used with the known return convention section If

the compiler cant prove that a function always returns the same number of values then it must use the unknown

values return convention which requires a descriptor represen tation Pay attention to the known return eciency

notes to avoid numb er consing

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Representation of Characters

Python also uses a nondescriptor represen tation for characters when convenient This improves the eciency of

string manipulation but is otherwise pretty invisible characters have an immediate descriptor represen tation so

there is not a great p enalty for converting a character to a descriptor Nonetheless it may sometimes b e helpful

to declare charactervalued variables as basecharacter

General Eciency Hints

This section is a summary of various implementation costs and ways to get around them These hints are

relatively unrelated to the use of the Python compiler and probably also apply to most other Common Lisp

implementations In each section there are references to related indepth discussion

Compile Your Co de

At this p oint the advantages of compiling co de relativetorunningitinterpreted probably need not b e emphasized

to o much but rememb er that in CMU Common Lisp compiled co de typically runs hundreds of times faster

than interpreted co de Also compiled fasl les load signicantly faster than source les so it is worthwhile

compiling les which are loaded many times even if the sp eed of the functions in the le is unimportant

Even disregarding the eciency advantages compiled co de is as go od or b etter than interpreted co de Com

piled co de can b e debugged at the source level see chapter and compiled co de do es more error checking For

these reasons the interpreter should b e regarded mainly as an interactive command interpreter rather than as

a programming language implementation

Do not b e concerned ab out the p erformance of your program until you see its sp eed compiled Some

techniques that make compiled co de run faster makeinterpreted co de run slow er

Avoid Unnecessary Consing

Consing is another name for allocation of storage as done bythe cons function hence its name cons is by

no means the only function which conses so do es makearray and many other functions Arithmetic and

function call can also have hidden consing overheads Consing hurts p erformance in the following ways

Consing reduces memory access locality increasing paging activity

Consing takes time just likeanything else

Any space allocated eventually needs to b e reclaimed either by garbage collection or by starting a new

lisp pro cess

Consing is not undiluted evil since programs do things other than consing and appropriate consing can

sp eed up the real work It would certainly save time to allocate a vector of intermediate results that are reused

hundreds of times Also if it is necessary to copy a large data structure many times it may b e more ecient

to up date the data structure nondestructively this somewhat increases up date overhead but makes copying

trivial

Note that the remarks in section ab out the importance of separating tuning from co ding also apply to

consing overhead The majority of consing will b e done by a small p ortion of the program The consing hot sp ots

are even less predictable than the CPU hot sp ots so dont waste time and create bugs by doing unnecessary

consing optimization During initial co ding avoid unnecessary sideeects and cons where it is convenient If

proling reveals a consing problem then go back and x the hot sp ots

See section page for a discussion of howtoavoid numb er consing in Python

Complex Argument Syntax

Common Lisp has very p owerful argument passing mec hanisms Unfortunatelytwoofthemostpowerful mech

anisms rest arguments and keyword arguments have a signicant p erformance p enalty

With keyword arguments the called function has to parse the supplied keywords by iterating over them

and checking them against the desired keywords

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

With rest arguments the function must cons a list to hold the arguments If a function is called many

times or with many arguments large amounts of memory will b e allocated

Although rest argument consing is worse than keyword parsing neither problem is serious unless thousands

of calls are made to such a function The use of keyword arguments is strongly encouraged in functions with

many arguments or with interfaces that are likely to b e extended and rest arguments are often natural in user

interface functions

Optional arguments have some eciency advantage over keyword arguments but their syntactic clumsiness

and lack of extensibility has caused many Common Lisp programmers to abandon use of optionals except in

functions that haveobviously simple and immutable interfaces such as subseq or in functions that are only

called in a few places When dening an interface function to b e used by other programmers or users use of

only required and keyword arguments is recommended

Parsing of defmacro keyword and rest arguments is done at compile time so a macro can b e used to provide

a convenientsyntax with an ecient implementation If the macroexpanded form contains no keyword or rest

arguments then it is p erfectly acceptable in inner lo ops

Keyword argument parsing overhead can also b e avoided by use of inline expansion see section page

and blo ck compilation section

Note the compiler op enco des most heavily used system functions whichhavekeyword or rest arguments

so that no runtime overhead is inv olved

Mapping and Iteration

One of the traditional Common Lisp programming styles is a highly applicative one involving the use of mapping

functions and many lists to store intermediate results To compute the sum of the squarero ots of a list of numbers

one mightsay

apply mapcar sqrt listofnumbers

This programming style is clear and elegant but unfortunately results in slow co de There are two reasons

why

The creation of lists of intermediate results causes much consing see

Each level of application requires another scan down the list Thus disregarding other eects the ab ove

co de would probably taketwice as long as a straightforward iterativeversion

An example of an iterativeversion of the same co de

do num listofnumbers cdr num

sum sqrt car num sum

null num sum

See sections and for a discussion of the interactions of iteration constructs with typ e inference and

variable optimization Also section discusses an applicativestyle of iteration

Trace Files and Disassembly

In order to write ecient co de you need to know the relative costs of dierent op erations The main reason

why writing ecient Common Lisp co de is dicult is that there are so many op erations and the costs of these

op erations vary in obscure contextdep endent ways Although eciency notes p oint out some problem areas

the only way to ensure generation of the b est co de is to look at the assembly co de output

The disassemble function is a convenientway to get the assembly co de for a function but it can b e very

dicult to interpret since the corresp ondence with the original source co de is weak A b etter but more awkward

option is to use the tracefile argumenttocompilefile to generate a trace le

A trace le is a dump of the compilers internal represen tations including annotated assembly co de Each

comp onent in the program gets four pages in the trace le separated by L

The implicitcontinuation or IR represen tation of the optimized source This is a dump of the ow graph

represen tation used for source level optimizations As you will quickly notice it is not really very close

to the source This represen tation is not very useful to even sophisticated users

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

The Virtual Machine VM or IR represen tation of the program This dump represen ts the generated

co de as sequences of Virtual OPerations VOPs This represen tation is intermediate b etween the source

and the assembly co de eachVOP corresp onds fairly directly to some primitive function or construct

but a given VOP also has a fairly predictable instruction sequence An op eration such as mayhave

multiple implementations with dierent cost and applicability The choice of a particular VOP such as

fixnum or singlefloat represen ts this choice of implementation Once you are familiar with it the

VM represen tation is probably the most useful for determining what implementation has b een used

An assembly listing annotated with the VOP resp onsible for generating the instructions This listing is

useful for guring out what a VOP do es and howitisimplemented in a particular context but its large

size makes it more dicult to read

A disassembly of the generated co de which has all pseudoop erations expanded out but is not annotated

with VOPs

Note that trace le generation takes much space and time since the trace le is tens of times larger than the

source le Toavoid huge confusing trace les and muchwasted time it is b est to separate the critical program

p ortion into its own le and then generate the trace le from this small le

Eciency Notes

Eciency notes are messages that warn the user that the compiler has chosen a relatively inecient implemen

tation for some op eration Usually an eciency note reects the compilers desire for more typ e information If

the typ e of the values concerned is known to the programmer then additional declarations can b e used to get a

more ecient implementation

Eciency notes are controlled by the extensionsinhibitwarnings optimization quality see section

page When speed is greater than extensionsinhibitwarnings eciency notes are enabled Note that

this implicitly enables eciency notes whenever speed is increased from its default of

Consider this program with an obscure missing declaration

defun effnote x y z

declare fixnum x y z

the fixnum x y z

If compiled with speed safety this note is given

In DEFUN EFFNOTE

X Y Z

X Y Z

Note Forced to do inline signedbyte arithmetic cost

Unable to do inline fixnum arithmetic cost because

The first argument is a INTEGER

not a FIXNUM

This eciency note tells us that the result of the intermediate computation x y is not known to b e a fixnum

so the addition of the intermediate sum to z must b e done less eciently This can b e xed by changing the

denition of effnote

defun effnote x y z

declare fixnum x y z

the fixnum the fixnum x y z

Typ e Uncertainty

The main cause of ineciency is the compilers lack of adequate information ab out the typ es of function argument

and result values Many important op erations such as arithmetic have an inecient general generic case but

have ecient implementations that can usually b e used if there is sucient argumenttyp e information

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Typ e eciency notes are given when a values typ e is uncertain There is an important distinction b etween

values that are not known to b e of a goo d typ e uncertain and values that are known not to b e of a goo d typ e

Eciency notes are given mainly for the rst case uncertain typ es If it is clear to the compiler that that there

is not an ecient implementation for a particular function call then an eciency note will only b e given if the

extensionsinhibitwarnings optimization qualityis see section page

In other words the default eciency notes only suggest that you add declarations not that you change the

semantics of your program so that an ecient implementation will applyFor example compilation of this form

will not give an eciency note

elt the list l i

even though a vector access is more ecient than indexing a list

Eciency Notes and Typ e Checking

It is importantthatthe effnote example ab ove used safety When typ e checking is enabled you may

get apparently spurious eciency notes With safety the note has this extra line on the end

The result is a INTEGER not a FIXNUM

This seems strange since there is a the declaration on the result of that second addition

In fact the ineciency is real and is a consequence of Pythons treating declarations as assertions to b e

veried The compiler cant assume that the result typ e declaration is true it must generate the result and

then test whether it is of the appropriate typ e

In practice this means that when you are tuning a program to run without typ e checks you should work

from the eciency notes generated by unsafe compilation If you want co de to run eciently with typ e checking

then y ou should pay attention to all the eciency notes that you get during safe compilation Since user supplied

output typ e assertions eg from the are disregarded when selecting op eration implementations for safe co de

you must somehowgive the compiler information that allows it to prove that the result truly mustbeofagood

typ e In our example it could b e done by constraining the argumenttyp es more

defun effnote x y z

declare type unsignedbyte x y z

x y z

Of course this declaration is acceptable only if the arguments to effnote always are unsignedbyte

integers

Representation Eciency Notes

When operating on values that have nondescriptor represen tations see section page there can b e

a substantial time and consing p enalty for converting to and from descriptor represen tations For this reason

the compiler gives an eciency note whenever it is forced to do a represen tation co ercion more exp ensivethan

efficiencynotecostthreshold page

Inecient represen tation co ercions maybeduetotyp e uncertaintyasinthisexample

defun setflo x

declare singlefloat x

prog var

setq var gorp

setq var x

return var

which pro duces this eciency note

In DEFUN SETFLO

SETQ VAR X Note Doing float to pointer coercion cost from X to VAR

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

The variable var is not known to always hold values of typ e singlefloat so a descriptor represen tation must

b e used for its value In sort of situation and adding a declaration will eliminate the ineciency

Often inecient represen tation conversions are not due to typ e uncertainty instead they result from

evaluating a nondescriptor expression in a context that requires a descriptor result

Assignment to or initialization of any data structure other than a sp ecialized array see section

page or

Assignmenttoaspecial variable or

Passing as an argument or returning as a value in any function call that is not a local call see section

page

If such inecient co ercions app ear in a hot sp ot in the program data structures redesign or program

reorganization may b e necessary to improve eciency See sections and

Because represen tation selection is done rather late in compilation the source context in these eciency notes

is somewhat vague making interpretation more dicult This is a fairly straightforward example

defun cf x y

declare singlefloat x y

cons x y t

which gives this eciency note

In DEFUN CF

CONS X Y T

Note Doing float to pointer coercion cost for

The first argument of CONS

The source context form is almost always the form that receives the value b eing co erced as it is in the preceding

example but can also b e the source form which generates the co erced value Compiling this example

defun ifcf x y

declare singlefloat x y

cons if grue x y snoc t

pro duces this note

In DEFUN IFCF

X Y

Note Doing float to pointer coercion cost

In either case the notes text explanation attempts to include additional information ab out what locations

are the source and destination of the co ercion Here are some example notes

IF GRUE X SNOC

Note Doing float to pointer coercion cost from X

SETQ VAR X

Note Doing float to pointer coercion cost from X to VAR

Note that the return value of a function is also a place to which co ercions mayha vetobedone

DEFUN F X Y DECLARE SINGLEFLOAT X Y X Y

Note Doing float to pointer coercion cost to return value

Sometimes the compiler is unable to determine a name for the source or destination in which case the source context is the only clue

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Verb osityControl

These variables control the verb osity of eciency notes

efficiencynotecostthreshold Variable

Before printing some eciency notes the compiler compares the value of this variable to the dierence in

cost b etween the chosen implementation and the b est p otential implementation If the dierence is not greater

than this limit then no note is printed The units are implementation dep endent the initial value suppresses

notes ab out trivial ineciencies A value of will note any ineciency

efficiencynotelimit Variable

When printing some eciency notes the compiler rep orts p ossible ecient implementations The initial

value of prevents excessively long eciency notes in the common case where there is no typ e information so

all implementations are p ossible

Proling

The rst step in improving a programs p erformance is to prole the activity of the program to nd where it

sp ends its time The b est way to do this is to use the proling utility found in the profile package This

package provides a macro profile that encapsulates functions with statistics gathering co de

Prole Interface

timedfunctions Variable

This variable holds a list of all functions that are currently b eing proled

profile fname j Macro callers tg

This macro wraps proling co de around the named functions As in tracethe name s are not evaluated If a

function is already proled then the function is unproled and reproled useful to notice function redenition

Awarning is printed for each name that is not a dened function

If CALLERS T is sp ecied then each function that calls this function is recorded along with the number of

calls made

unprofile fname g Macro

This macro removes proling co de from the named functions If no name s are supplied all currently proled

functions are unproled

reporttime fnameg Macro

This macro prints a rep ort for each name d function of the following information

The total CPU time used in that function for all calls

the total number of bytes consed in that function for all calls

the total numb er of calls

the average amount of CPU time p er call

Summary totals of the CPU time consing and calls columns are printed An estimate of the proling overhead is

also printed see b elow If no name s are supplied then the times for all curren tly proled functions are printed

resettime fname g Macro

This macro resets the proling counters asso ciated with the name d functions If no name s are supplied then all curren tly proled functions are reset

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Proling Techniques

Start by proling big pieces of a program then carefully cho ose which functions close to but not in the inner

lo op are to b e proled next Avoid proling functions that are called by other proled functions since this op ens

the p ossibility of proling overhead b eing included in the rep orted times

If the p ercall time rep orted is less than second then consider the clo ck resolution and proling overhead

b efore you b elieve the time It may b e that you will need to run your program many times in order to average

out to a higher resolution

Nested or Recursive Calls

The proler attempts to compensate for nested or recursive calls Time and consing overhead will b e charged

to the dynamically innermost most recen t call to a proled function So proling a subfunction of a proled

function will cause the rep orted time for the outer function to decrease However if an inner function has a large

numb er of calls some of the proling overhead may leak into the rep orted time for the outer function In

general b e wary of proling short functions that are called many times

Clo ck resolution

Unless you are very lucky the length of your machines clo ck tick is probably much longer than the time it

takes simple function to run For example on the IBM RT the clo ck resolution is second This means that

if a function is only called a few times then only the rst couple decimal places are really meaningful

Note however that if a function is called many times then the statistical averaging across all calls should

result in increased resolution For example on the IBM RT if a function is called a thousand times then a

resolution of tens of microseconds can b e exp ected

Proling overhead

The added proling co de takes time to run every time that the proled function is called whic h can disrupt the

attempt to collect timing information In order to avoid serious ination of the times for functions that take

little time to run an estimate of the overhead due to proling is subtracted from the times rep orted for each

function

Although this correction works fairly well it is not totally accurate resulting in times that b ecome increasingly

meaningless for functions with short runtimes This is only a concern when the estimated proling overhead is

many times larger than rep orted total CPU time

The estimated proling overhead is not represen ted in the rep orted total CPU time The sum of total CPU

time and the estimated proling overhead should b e close to the total CPU time for the entire proling run as

determined by the time macro Time unaccounted for is probably b eing used by functions that you forgot to

prole

Additional Timing Utilities

time form Macro

This macro evaluates form prints some timing and memory allocation information to traceoutput and

returns anyvalues that form returns The timing information includes real time user run time and system

run time This macro executes a form and rep orts the time and consing overhead If the time form is not

compiled eg it was typ ed at toplevel then compile will b e called on the form to give more accurate timing

information If you really wanttotimeinterpreted sp eed you can say

time eval form

Things that execute fairly quickly should b e timed more than once since there may b e more paging overhead in

the rst timing To increase the accuracy of very short times you can time multiple evaluations

time dotimes i form

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

extensionsgetbytesconsed Function

This function returns the number of bytes allocated since the rst time you called it The rst time it is

called it returns zero The ab ove proling routines use this to rep ort consing information

extensionsgcruntime Variable

This variable accumulates the runtime consumed by garbage collection in the units returned by get

internalruntime

internaltimeunitspersecond Constant

The value of internaltimeunitspersecond is

A Note on Timing

There are two general kinds of timing information provided bythe time macro and other proling utilities real

time and run time Real time is elapsed wall clo ck time It will b e aected in a fairly obvious waybyany

other activity on the machine The more other pro cesses contending for CPU and memory the more real time

will increase This means that real time measurements are dicult to replicate though this is less true on a

dedicated workstation The advantage of real time is that it is real It tells you really how long the program to ok

to run under the b enchmarking conditions The problem is that you dont know exactly what those conditions

were

Run time is the amount of time that the pro cessor supp osedly sp ent running the program as opp osed to

waiting for IO or running other pro cesses User run time and system run time are numb ers rep orted by

the Unix kernel They are supp osed to b e a measure of howmuch time the pro cessor sp ent running y our user

program which will include GC overhead etc and the amount of time that the kernel sp ent running on your

b ehalf

Ideally user time should b e totally unaected by b enchmarking conditions in reality user time do es dep end

on other system activity though in rather nonobvious ways

System time will clearly dep end on b enchmarking conditions In Lisp b enchmarking paging activity increases

system run time but not byasmuch as it increases real time since the kernel sp ends some time waiting for the

disk and this is not run time kernel or otherwise

In my exp erience the biggest trap in interpreting kerneluser run time is to look only at user time In reality

it seems that the sum of kernel and user time is more repro ducible The problem is that as system activity

increases there is a spurious decrease in user run time In eect as paging etc increases user time leaks into

system time

So in practice the only way to get truly repro ducible results is to run with the same competing activityon

the system Try to run on a machine with nob o dy else logged in and check with ps aux to see if there are

any system pro cesses munching large amounts of CPU or memory If the ratio b etween real time and the sum

of user and system time varies much b etween runs then you have a problem

Benchmarking Techniques

Given these imperfect timing to ols how do should you do b enchmarking The answer dep ends on whether you

are trying to measure improvements in the p erformance of a single program on the same hardware or if you are

trying to compare the p erformance of dierent programs andor dierent hardware

For the rst use measuring the eect of program modications with constant hardware you should lo ok at

b oth systemuser and real time to understand what eect the change had on CPU use and on IO including

paging If you are working on a CPU intensive program the change in systemuser time will giveyou a moder

ately repro ducible measure of p erformance across a fairly wide range of system conditions For a CPU intensive

program you can think of systemuser as howlongitwould havetaken to run if I had myown machine So

in the case of comparing CPU intensive programs systemuser time is relatively real and reasonable to use

For programs that sp end a substantial amount of their time paging you really cant predict elapsed time

under a given op erating condition without b enchmarking in that condition User or systemuser time maybe

fairly repro ducible but it is also relatively meaningless since in a paging or IO intensive program the program

is sp ending its time waiting not running and system time and user time are b oth measures of run time A

change that reduces run time might increase real time by increasing paging

CHAPTER ADVANCED COMPILER USE AND EFFICIENCY HINTS

Another common use for b enchmarking is comparing the p erformance of the same program on dierent hard

ware You wanttoknowwhich machine to run your program on For comparing dierent machines op erating

systems etc the only way to compare that makes sense is to set up the machines in exactly the way that they

will normally b e run and then measure real time If the program will normally b e run along with X then run X

If the program will normally b e run on a dedicated workstation then b e sure nob o dy else is on the b enchmarking

machine If the program will normally b e run on a machine with three other Lisp jobs then run three other

Lisp jobs If the program will normally b e run on a machine with meg of memory then run with meg Here

normal means normal for that machineIfyou the choice of an unloaded RT or a heavily loaded PMAX

do your b enchmarking on an unloaded RTandaheavily loaded PMAX

If you have a program you b elievetobeCPUintensive then you might b e tempted to compare run times

across systems hoping to get a meaningful result even if the b enchmarking isnt done under the exp ected running

condition Dont to this for two reasons

The op erating systems might not compute run time in the same way

Under the real running condition the program mightnotbeCPUintensive after all

In the end only real time means anything it is the amount of time you havetowait for the result The

only valid uses for run time are

To develop insightinto the program For example if run time is muc h less than elapsed time then you are

probably sp ending lots of time paging

Toevaluate the relative p erformance of CPU intensive programs in the same environment

Chapter

UNIX Interface

By Robert MacLachlan Skef Wholey

Bill Chiles and William Lott

CMU Common Lisp attempts to make the full p ower of the underlying environmentavailable to the Lisp

programmer This is done using combination of handco ded interfaces and foreign function calls to C libraries

Although the techniques dier the style of interface is similar This chapter provides an overview of the facilities

available and general rules for using them as well as describing sp ecic features in detail It is assumed that the

reader has a working familiarity with Mach Unix and X as well as access to the standard system do cumentation

Reading the Command Line

The shell parses the command line with which Lisp is invoked and passes a data structure containing the parsed

information to Lisp This information is then extracted from that data structure and put into a set of Lisp data

structures

extensionscommandlinestrings Variable

extensionscommandlineutilityname Variable

extensionscommandlinewords Variable

extensionscommandlineswitches Variable

The value of commandlinewords is a list of strings that make up the command line one word p er string

The rst word on the command line ie the name of the program invoked usually lisp is stored in command

lineutilityname The value of commandlineswitches is a list of commandlineswitch structures

with a structure for eachword on the command line starting with a hyphen All the command line words b etween

the program name and the rst switch are stored in commandlinewords

The following functions may b e used to examine commandlineswitch structures

extensionscmdswitchname switch Function

Returns the name of the switch less the preceding hyphen and trailing equal sign if any

extensionscmdswitchvalue switch Function

Returns the value designated using an emb edded equal sign if any If the switch has no equal sign then this

is null

extensionscmdswitchwords switch Function

Returns a list of the words b etween this switch and the next switch or the end of the command line

CHAPTER UNIX INTERFACE

Useful Variables

systemstdin Variable

systemstdout Variable

systemstderr Variable

Streams connected to the standard input output and error le descriptors

systemtty Variable

A stream connected to devtty

Lisp Equivalents for C Routines

The UNIX do cumentation describ es the system interface in terms of C pro cedure headers The corresp onding

Lisp function will have a somewhat dierent interface since Lisp argument passing conventions and datatyp es

are dierent

The main dierence in the argument passing conventions is that Lisp do es not supp ort passing values by

reference In Lisp all argument and results are passed byvalue Interface functions take some xed number

of arguments and return some xed number of values A given parameter in the C sp ecication will app ear

as an argument return value or b oth dep ending on whether it is an In parameter Out parameter or InOut

parameter The basic transformation one makes to come up with the Lisp equivalent of a C routine is to remove

the Out parameters from the call and treat them as extra return values InOut parameters app ear b oth as

arguments and return values Since Out and InOut parameters are only conventions in C you must determine

the usage from the do cumentation

Thus the C routine declared as

kernreturnt lookupservport portsname portsid

port servport

char portsname

int portsid out

portsid expression to compute portsid field

returnKERNSUCCESS

has as its Lisp equivalent something like

defun lookup ServPort PortsName

values

success

expression to compute portsid field

If there are multiple out or inout arguments then there are multiple additional returns values

Fortunately CMU Common Lisp programmers rarely havetoworry ab out the nuances of this translation

pro cess since the names of the arguments and return values are do cumented in a waysothatthe describe

function and the Hemlock Describe Function Call command invoked with CMShiftA will list this infor

mation Since the names of arguments and return values are usually descriptive the information that describe

prints is usually all one needs to write a call Most programmers use this online do cumentation nearly all of the

time and thereby avoid the need to handle bulky manuals and p erform the translation from barbarous tongues

CHAPTER UNIX INTERFACE

Typ e Translations

Lisp data typ es havevery dierent represen tations from those used byconventional languages such as C Since

the system interfaces are designed for conventional languages Lisp must translate ob jects to and from the

Lisp represen tations Many simple ob jects have a direct translation integers characters strings and oating

p ointnumb ers are translated to the corresp onding Lisp ob ject A number of typ es however are implemented

dierently in Lisp for reasons of clarity and eciency

Instances of enumerated typ es are expressed as keywords in Lisp Records arrays and p ointer typ es are

implemented with the Alien facility see page Access functions are dened for these typ es whichconvert

elds of records elements of arrays or data referenced bypointers into Lisp ob jects p ossibly another ob ject to

b e referenced with another access function

One should disp ose of Alien ob jects created by constructor functions or returned from remote pro cedure calls

when they are no longer of any use freeing the virtual memory asso ciated with that ob ject Since Aliens contain

p ointers to nonLisp data the garbage collector cannot do this itself If the memory was obtained from make

alien page or from a foreign function call to a routine that used malloc then freealien page

should b e used If the Alien was created using MACH memory allocation eg vmallocate then the storage

should b e freed using vmdeallocate

System Area Pointers

Note that in some cases an address is represen ted by a Lisp integer and in other cases it is represen ted by a real

p ointer Pointers are usually used when an ob ject in the curren t address space is b eing referred to The MACH

virtual memory manipulation calls m ust use integers since in principle the address could b e in any pro cess and

Lisp cannot abide random p ointers Because these typ es are represen ted dierently in Lisp one must explicitly

co erce b etween these represen tations

System Area Pointers SAPs provide a mechanism that bypasses the Alien typ e system and accesses virtual

memory directly A SAP is a rawbyte p ointer into the lisp pro cess address space SAPs are represen ted

with a p ointer descriptor so SAP creation can cause consing However the compiler uses a nondescriptor

represen tation for SAPs when p ossible so the consing overhead is generally minimal See section page

systemsapint sap Function

systemintsap int Function

The function sapint is used to generate an integer corresp onding to the system area p ointer suitable for

passing to the kernel interfaces whichwant all addresses sp ecied as integers The function intsap is used to

do the opp osite conversion The integer represen tation of a SAP is the byte oset of the SAP from the start of

the address space

systemsap sap oset Function

This function adds a byte oset to sap returning a new SAP

systemsapref sap oset Function

systemsapref sap oset Function

systemsapref sap oset Function

These functions return the or bit unsigned integer at oset from sapTheoset is alwaysabyte

oset regardless of the numb er of bits accessed setf may b e used with the these functions to dep osit values

into virtual memory

systemsignedsapref sap oset Function

systemsignedsapref sap oset Function

systemsignedsapref sap oset Function

These functions are the same as the ab ove unsigned op erations except that they signextend returning a

negativenumb er if the high bit is set

CHAPTER UNIX INTERFACE

Unix System Calls

You probably wont havemuch cause to use them but all the Unix system calls are available The Unix system

call functions are in the Unix package The name of the interface for a particular system call is the name of

the system call prep ended with unix The system usually denes the asso ciated constants without anyprex

name To nd out how to use a particular system call try using describe on it If that is unhelpful look at the

source in syscalllisp or consult your system maintainer

The Unix system calls indicate an error by returning nil as the rst value and the Unix error number as the

second value If the call succeeds then the rst value will always b e nonnil often t

Unixgetunixerrormsg error Function

This function returns a string describing the Unix error number error

File Descriptor Streams

Many of the UNIX system calls return le descriptors Instead of using other UNIX system calls to p erform IO

on them you can create a stream around them For this purp ose fdstreams exist

systemmakefdstream descriptor key input output elementtype Function

buffering name file original

deleteoriginal autoclose

timeout pathname

This function creates a le descriptor stream using descriptor If input is nonnil input op erations are

allowed If output is nonnil output op erations are allowed The default is input only These keywords are

dened

elementtyp e is the typ e of the unit of transaction for the stream which defaults to stringcharSeethe

Common Lisp description of open for valid values

buering is the kind of output buering desired for the stream Legal values are none for no buering line

for buering up to each newline and full for full buering

name is a simplestring name to use for descriptive purp oses when the system prints an fdstream When printing

fdstreams the system prep ends the streams name with Stream for Ifname is unsp ecied it defaults to

a string containing le or descriptor in order of preference

le original le sp ecies the defaulted namestring of the asso ciated le when creating a le stream must b e

a simplestring original is the simplestring name of a backup le containing the original contents

of le while writing le

When you ab ort the stream by passing t to close as the second argument if you supplied b oth le and

original close will rename the original name to the le name When you close the stream normally

if you supplied originaland deleteoriginal is nonnil close deletes originalIfautoclose is true the

default then descriptor will b e closed when the stream is garbage collected

pathname The original pathname passed to op en and returned by pathname not defaulted or translated

timeout if nonnull then timeout is an integer numb er of seconds after which an input wait should time out If

a read do es time out then the systemiotimeout condition is signalled

systemfdstreamp ob ject Function

This function returns t if ob ject is an fdstream and nil if not Obsolete use the p ortable typep x

filestream

systemfdstreamfd stream Function

This returns the le descriptor asso ciated with stream

CHAPTER UNIX INTERFACE

Making Sense of Mach Return Co des

Whenever a remote pro cedure call returns a Unix error co de such as kernreturnt it is usually prudent to

check that co de to see if the call was successful To relieve the programmer of the hassle of testing this value

himself and to centralize the information ab out the meaning of nonsuccess return co des CMU Common Lisp

provides a numb er of macros and functions See also getunixerrormsg page

systemgrerror function gr optional context Function

Signals a Lisp error printing a message indicating that the call to the sp ecied function failed with the

return co de gr If supplied the context string is printed after the function name and b efore the string asso ciated

with the grFor example

grerror nukegarbage lost big

Error in function GRERROR

NUKEGARBAGE lost big no space

Proceed cases

Return to TopLevel

Debug type H for help

Signal ConditionsSimpleErrorFDE

systemgrcall function rest args Macro

systemgrcall function rest args Macro

These macros can b e used to call a function and automatically check the GeneralReturn co de and signal

an appropriate error in case of nonsuccessful return grcall returns nil if no error o ccurs while grcall

returns the second value of the function called

grcall machportallocate taskself

NIL

systemgrbind fvar g Macro function farg g fformg

This macro can b e used much like multiplevaluebind to bind the var storeturnvalues resulting from

calling the function with the given arg s The rst return value is not b ound to a variable but is checked as a

GeneralReturn co de as in grcall

grbind portlist portlistcnt

machportselect taskself

format t The port count is S portlistcnt

portlist

The port count is

Alien value

Unix Interrupts

CMU Common Lisp allows access to all the Unix signals that can b e generated under Unix It should b e noted

that if this capability is abused it is p ossible to completely destroy the running Lisp The following macros

and functions allow access to the Unix interrupt system The signal names as sp ecied in section of the Unix

Programmers Manual are exp orted from the Unix package

CHAPTER UNIX INTERFACE

Changing Interrupt Handlers

systemwithenabledinterrupts sp ecs rest body Macro

This macro should b e called with a list of signal sp ecications sp ecs Each elementofsp ecs should b e a list

of two elements the rst should b e the Unix signal for which a handler should b e established the second should

b e a function to b e called when the signal is received One or more signal handlers can b e established in this way

withenabledinterrupts establishes the correct signal handlers and then executes the forms in bodyThe

forms are executed in an unwindprotect so that the state of the signal handlers will b e restored to what it was

b efore the withenabledinterrupts was entered A signal handler function sp ecied as NIL will set the Unix

signal handler to the default which is normally either to ignore the signal or to cause a core dump dep ending on

the particular signal

systemwithoutinterrupts rest body Macro

It is sometimes necessary to execute a piece a co de that can not b e interrupted This macro the forms in

body with interrupts disabled Note that the Unix interrupts are not actually disabled rather they are queued

until after body has nished executing

systemwithinterrupts rest body Macro

When executing an interrupt handler the system disables interrupts as if the handler was wrapp ed in in a

withoutinterrupts The macro withinterrupts can b e used to enable interrupts while the forms in body

are evaluated This is useful if body is going to enter a break loop or do some long computation that might need

to b e interrupted

systemwithouthemlock rest body Macro

For some interrupts such as SIGTSTP susp end the Lisp pro cess and return to the Unix shell it is necessary

to leave Hemlock and then return to it This macro executes the forms in body after exiting Hemlock When

body has b een executed control is returned to Hemlock

systemenableinterrupt signal function Function

This function establishes function as the handler for signal Unless you want to establish a global sig

nal handler you should use the macro withenabledinterrupts to temporarily establish a signal handler

enableinterrupt returns the old function asso ciated with the signal

systemignoreinterrupt signal Function

Ignoreinterrupt sets the Unix signal mechanism to ignore signal which means that the Lisp pro cess will never

see the signal Ignoreinterrupt returns the old function asso ciated with the signal or nil if none is currently

dened

systemdefaultinterrupt signal Function

Defaultinterrupt can b e used to tell the Unix signal mechanism to p erform the default action for signalFor

details on what the default action for a signal is see section of the Unix Programmers Manual In general it

is likely to ignore the signal or to cause a core dump

CHAPTER UNIX INTERFACE

Examples of Signal Handlers

The following co de is the signal handler used by the Lisp system for the SIGINT signal

defun ihsigint signal code scp

declare ignore signal code scp

withouthemlock

withinterrupts

break Software Interrupt t

The withouthemlock form is used to make sure that Hemlock is exited b efore a break loop is entered The

withinterrupts form is used to enable interrupts b ecause the user maywant to generate an interrupt while

in the break lo op Finally break is called to enter a break loop so the user can lo ok at the current state of the

computation If the user pro ceeds from the break lo op the computation will b e restarted from where it was

interrupted

The following function is the Lisp signal handler for the SIGTSTP signal which susp ends a pro cess and

returns to the Unix shell

defun ihsigtstp signal code scp

declare ignore signal code scp

withouthemlock

Unixunixkill Unixunixgetpid Unixsigstop

Lisp uses this interrupt handler to catch the SIGTSTP signal b ecause it is necessary to get out of Hemlockina

clean way b efore returning to the shell

To set up these interrupt handlers the following is recommended

withenabledinterrupts UnixSIGINT ihsigint

UnixSIGTSTP ihsigtstp

user code to execute with the above signal handlers enabled

Chapter

Event Dispatching with

SERVEEVENT

By Bill Chiles and Rob ert MacLachlan

It is common to havemultiple activities simultaneously op erating in the same Lisp pro cess Furthermore

Lisp programmers tend to exp ect a exible developmentenvironment It must b e p ossible to load and modify

application programs without requiring modications to other running programs CMU Common Lisp achieves

this byhaving a central scheduling mechanism based on an eventdriven ob jectoriented paradigm

An event is some interesting happ ening that should cause the Lisp pro cess to wake up and do something

These events include X events and activity on Unix le descriptors The ob jectoriented mechanism is only

available with the rst two and it is optional with X events as describ ed later in this chapter In an X event the

window ID is the ob ject capability and the X eventtyp e is the op eration co de The Unix le descriptor input

mechanism simply consists of an asso ciation list of a handler to call when input shows up on a particular le

descriptor

Ob ject Sets

An ob ject set is a collection of ob jects that have the same implementation for each op eration Externally the

ob ject is represen ted by the ob ject capability and the op eration is represen ted by the op eration co de Within Lisp

the ob ject is represen ted by an arbitrary Lisp ob ject and the implementation for the op eration is represen ted

by an arbitrary Lisp function The ob ject set mechanism maintains this translation from the external to the

internal represen tation

systemmakeobjectset name optional defaulthandler Function

This function makes a new ob ject set Name is a string used only for purp oses of identifying the ob ject set

when it is printed Defaulthandler is the function used as a handler when an undened op eration occurs on

an ob ject in the set You can dene op erations with the serveoperation functions exp orted the extensions

package for X events see section page Ob jects are added with systemaddxwindowobject Initially

the ob ject set has no ob jects and no dened op erations

systemobjectsetoperation ob jectset op erationco de Function

This function returns the handler function that is the implementation of the op eration corresp onding to

op erationco de in ob jectset When set with setf the setter function establishes the new handler The serve

op eration functions exp orted from the extensions packageforXevents see section page call this on

b ehalf of the user when announcing a new op eration for an ob ject set

systemaddxwindowobject window ob ject ob jectset Function

These functions add port or window to ob jectset Ob ject is an arbitrary Lisp ob ject that is asso ciated with

the port or window capability Window is a CLX window When an event o ccurs systemserveevent passes

ob ject as an argument to the handler function

CHAPTER EVENT DISPATCHING WITH SERVEEVENT

The SERVEEVENT Function

The systemserveevent function is the standard way for an application to wait for something to happ en For

example the Lisp system calls systemserveevent when it wants input from X or a terminal stream The idea

b ehind systemserveevent is that it knows the appropriate action to takewhenanyinteresting event happ ens

If an application calls systemserveevent when it is idle then any other applications with p ending events can

run This allows several applications to run at the same time without interference even though there is only

one thread of control Note that if an application is waiting for input of any kind then other applications will

get events

systemserveevent optional timeout Function

This function waits for an event to happ en and then dispatches to the correct handler function If sp ecied

timeout is the numb er of seconds to wait b efore timing out A time out of zero seconds is legal and causes

systemserveevent to p oll for anyevents immediately available for pro cessing systemserveevent returns

t if it serviced at least one event and nil otherwise Dep ending on the application when systemserveevent

returns tyou mightwant to call it rep eatedly with a timeout of zero until it returns nil

If input is available on any designated le descriptor then this calls the appropriate handler function supplied

by systemaddfdhandler

Since events for many dierent applications may arrive simultaneously an application waiting for a sp ecic

eventmust loop on systemserveevent until the desired event happ ens Since programs such as Hemlockcall

systemserveevent for input applications usually do not need to call systemserveevent at all Hemlock

allows other applications handlers to run when it go es into an input wait

systemserveallevents optional timeout Function

This function is similar to systemserveevent except it serves all the p ending events rather than just one

It returns t if it serviced at least one event and nil otherwise

Using SERVEEVENT with Unix File Descriptors

Ob ject sets are not available for use with le descriptors as there are only two op erations p ossible on le

descriptors input and output Instead a handler for either input or output can b e registered with systemserve

event for a sp ecic le descriptor Whenever any input shows up or output is p ossible on this le descriptor the

function asso ciated with the handler for that descriptor is funcalled with the descriptor as its single argument

systemaddfdhandler fd direction function Function

This function installs and returns a new handler for the le descriptor fd Direction can b e either input if

the system should invoke the handler when input is available or output if the system should invoke the handler

when output is p ossible This returns a unique ob ject represen ting the handler and this is a suitable argument

for systemremovefdhandler Function must take one argument the le descriptor

systemremovefdhandler handler Function

This function removes handlerthataddfdhandler must have previously returned

systemwithfdhandler direction fd function fformg Macro

This macro executes the supplied forms with a handler installed using fd directionandfunction See

systemaddfdhandler

systemwaituntilfdusable direction fd optional timeout Function

This function waits for up to timeout seconds for fd to b ecome usable for direction either input or output

If timeout is nil or unsp ecied this waits forever

systeminvalidatedescriptor fd Function

This function removes all handlers asso ciated with fd This should only b e used in drastic cases such as IO

errors but not necessarily EOF Normallyyou should use removefdhandler to remove the sp ecic handler

CHAPTER EVENT DISPATCHING WITH SERVEEVENT

Using SERVEEVENT with the CLX Interface to X

Rememb er from section an ob ject set is a collection of ob jects CLX windows in this case with some

set of op erations event keywords with corresp onding implementations the same handler functions Since X

allows multiple display connections from a given pro cess you can avoid using ob ject sets if every windowinan

application or display connection b ehaves the same If a particular X application on a single display connection

has windows that want to handle certain events dierently then using ob ject sets is a convenientway to organize

this since you need some way to map the windowevent combination to the appropriate functionality

The following is a discussion of functions exp orted from the extensions package that facilitate handling

CLX events through systemserveevent The rst two routines are useful regardless of whether you use

systemserveevent

extopendisplay optional string Function

This function parses string for an X display sp ecication including display and screen numb ers String

defaults to the following

cdr assoc display extenvironmentlist test eq

If any eld in the display sp ecication is missing this signals an error extopenclxdisplay returns the CLX

display and screen

extflushdisplayev Function ents display

This function ushes all the events in display s event queue including the current event in case the user calls

this from within an event handler

Without Ob ject Sets

Since most applications that use CLX can avoid the complexity of ob ject sets these routines are describ ed in

a separate section The routines describ ed in the next section that use the ob ject set mechanism are based on

these interfaces

extenableclxeventhandling display handler Function

This function causes systemserveevent to notice when there is input on display s connection to the X

server When this happ ens systemserveevent invokes handler on display in a dynamic context with an

error handler b ound that ushes all events from display and returns By returning the error handler declines

to handle the error but it will have cleared all events thus entering the debugger will not result in innite

errors due to streams that wait via systemserveevent for input Calling this rep eatedly on the same display

establishes handler as a new handler replacing any previous one for display

extdisableclxeventhandling display Function

This function undo es the eect of extenableclxeventhandling

extwithclxeventhandling display handler Macro fform g

This macro evaluates each form in a context where systemserveevent invokes handler on display whenever

there is input on display s connection to the X server This destroys any previously established handler for display

CHAPTER EVENT DISPATCHING WITH SERVEEVENT

With Ob ject Sets

This section discusses the use of ob ject sets and systemserveevent to handle CLX events This is necessary

when a single X application has distinct windows that want to handle the same events in dierent ways Basically

you need some way of asking for a given windowwhichwayyou want to handle some event b ecause this event

is handled dierently dep ending on the window Ob ject sets provide this feature

For each CLX eventkey symb olname XXX for example keypress there is a function serveXXX of two

arguments an ob ject set and a function The serveXXX function establishes the function as the handler for

the XXX event in the ob ject set Recall from section systemaddxwindowobject asso ciates some Lisp

ob ject with a CLX window in an ob ject set When systemserveevent notices activity on a window it calls

the function given to extenableclxeventhandling If this function is extobjectseteventhandler

it calls the function given to serveXXX passing the ob ject given to systemaddxwindowobject and the

events slots as well as a couple other arguments describ ed b elow

To use ob ject sets in this way

Create an ob ject set

Dene some op erations on it using the serveXXX functions

Add an ob ject for every windowonwhichyou receive requests This can b e the CLX window itself or some

structure more meaningful to your application

Call systemserveevent to service an X event

extobjectseteventhandler display Function

This function is a suitable argumentto extenableclxeventhandling The actual event handlers dened

for particular events within a given ob ject set must take an argument for every slot in the appropriate event In

addition to the event slots extobjectseteventhandler passes the following arguments

The ob ject as established by systemaddxwindowobjectonwhichtheevent o ccurred

eventkeysee xlibeventcase

sendeventp see xlibeventcase

Describing any extserveeventkeyname function where eventkeyname is an eventkey symb olname for

example extservekeypress indicates exactly what all the argumen ts are in their correct order

When creating an ob ject set for use with extobjectseteventhandler sp ecify extdefaultclx

eventhandler as the default handler for events in that ob ject set If no default handler is sp ecied and

the system invokes the default default handler it will cause an error since this function takes arguments suitable

for handling p ort messages

A SERVEEVENT Example

This section contains two examples using systemserveevent The rst one does not use ob ject sets and the

second slightly more complicated one do es

Without Ob ject Sets Example

This example denes an input handler for a CLX display connection It only recognizes keypress events The

b o dy of the example loops over systemserveevent to get input

inpackage SERVEREXAMPLE

defun myinputhandler display

xlibeventcase display timeout

keypress eventwindow code state format t KEYPRESSED Window D S

CHAPTER EVENT DISPATCHING WITH SERVEEVENT

xlibwindowid eventwindow

See Hemlock Command Implementors Manual for convenient

input mapping function

exttranslatecharacter display code state

Make XLIBEVENTCASE discard the event

t

defun serverexample

An example of using the SYSTEMSERVEEVENT function and object sets to

handle CLX events

let display extopenclxdisplay

screen displaydefaultscreen display

black screenblackpixel screen

white screenwhitepixel screen

window createwindow parent screenroot screen

x y width height

background white border black

borderwidth

eventmask

xlibmakeeventmask keypress

Wrap code in UNWINDPROTECT so we clean up after ourselves

unwindprotect

progn

Enable event handling on the display

extenableclxeventhandling display myinputhandler

Map the windows to the screen

mapwindow window

Make sure we send all our requests

displayforceoutput display

Call serveevent for events or immediate timeouts

dotimes i systemserveevent

Disable event handling on this display

extdisableclxeventhandling display

Get rid of the window

destroywindow window

Pick off any events the X server has already queued for our

windows so we dont choke since SYSTEMSERVEEVENT is no longer

prepared to handle events for us

loop

unless deletingwindowdropevent display window

return

Close the display

xlibclosedisplay display

defun deletingwindowdropevent display win

Check for any events on win If there is one remove it from the

event queue and return t otherwise return nil

xlibdisplayfinishoutput display

let result nil

xlibprocessevent

display timeout

handler lambda key eventwindow allowotherkeys

if eq eventwindow win

setf result t

nil result

CHAPTER EVENT DISPATCHING WITH SERVEEVENT

With Ob ject Sets Example

This example involves more work but you get a little more for your eort It denes two ob jects inputbox

and slider and establishes a keypress handler for each ob ject keypressed and sliderpressedWehave

two ob ject sets b ecause we handle events on the windows manifesting these ob jects dierently but the events

come over the same display connection

inpackage SERVEREXAMPLE

defstruct inputbox printfunction printinputbox

constructor makeinputbox display window

Our program knows about inputboxes and it doesnt care how they

are implemented

display The CLX display on which my inputbox is displayed

window The CLX window in which the user types

defun printinputbox object stream n

declare ignore n

format stream InputBox S inputboxdisplay object

defvar inputboxwindows

systemmakeobjectset Input Box Windows

extdefaultclxeventhandler

defun keypressed inputbox eventkey eventwindow root child

samescreenp x y rootx rooty modifiers time

keycode sendeventp

This is our keypress event handler

declare ignore eventkey root child samescreenp x y

rootx rooty time sendeventp

format t KEYPRESSED Window D S

xlibwindowid eventwindow

See Hemlock Command Implementors Manual for convenient

input mapping function

exttranslatecharacter inputboxdisplay inputbox

keycode modifiers

extservekeypress inputboxwindows keypressed

defstruct slider printfunction printslider

include inputbox

constructor makeslider

display window windowwidth max

Our program knows about sliders too and these provide input values

zero to max

bitspervalue bits per discrete value up to max

max End value for slider

defun printslider object stream n

declare ignore n

format stream Slider S D

inputboxdisplay object

slidermax object

defun makeslider display window max

makeslider display window

truncate xlibdrawablewidth window max

CHAPTER EVENT DISPATCHING WITH SERVEEVENT

max

defvar sliderwindows

systemmakeobjectset Slider Windows

extdefaultclxeventhandler

defun sliderpressed slider eventkey eventwindow root child

samescreenp x y rootx rooty modifiers time

keycode sendeventp

This is our keypress event handler for sliders Probably this is

a mouse thing but for simplicity here we take a character typed

declare ignore eventkey root child samescreenp x y

rootx rooty time sendeventp

format t KEYPRESSED Window D S D

xlibwindowid eventwindow

See Hemlock Command Implementors Manual for convenient

input mapping function

exttranslatecharacter inputboxdisplay slider

keycode modifiers

truncate x sliderbitspervalue slider

extservekeypress sliderwindows sliderpressed

defun serverexample

An example of using the SYSTEMSERVEEVENT function and object sets to

handle CLX events

let display extopenclxdisplay

screen displaydefaultscreen display

black screenblackpixel screen

white screenwhitepixel screen

iwindow createwindow parent screenroot screen

x y width height

background white border black

borderwidth

eventmask

xlibmakeeventmask keypress

swindow createwindow parent screenroot screen

x y width height

background white border black

borderwidth

eventmask

xlibmakeeventmask keypress

inputbox makeinputbox display iwindow

slider makeslider display swindow

Wrap code in UNWINDPROTECT so we clean up after ourselves

unwindprotect

progn

Enable event handling on the display

extenableclxeventhandling display

extobjectseteventhandler

Add the windows to the appropriate object sets

systemaddxwindowobject iwindow inputbox

inputboxwindows

systemaddxwindowobject swindow slider

sliderwindows Map the windows to the screen

CHAPTER EVENT DISPATCHING WITH SERVEEVENT

mapwindow iwindow

mapwindow swindow

Make sure we send all our requests

displayforceoutput display

Call server for events or immediate timeouts

dotimes i systemserveevent

Disable event handling on this display

extdisableclxeventhandling display

deletewindow iwindow display

deletewindow swindow display

Close the display

xlibclosedisplay display

defun deletewindow window display

Remove the windows from the object sets before destroying them

systemremovexwindowobject window

Destroy the window

destroywindow window

Pick off any events the X server has already queued for our

windows so we dont choke since SYSTEMSERVEEVENT is no longer

prepared to handle events for us

loop

unless deletingwindowdropevent display window

return

defun deletingwindowdropevent display win

Check for any events on win If there is one remove it from the

event queue and return t otherwise return nil

xlibdisplayfinishoutput display

let result nil

xlibprocessevent

display timeout

handler lambda key eventwindow allowotherkeys

if eq eventwindow win

setf result t

nil result

Chapter

Alien Ob jects

By Robert MacLachlan and William Lott

Intro duction to Aliens

Because of Lisps emphasis on dynamic memory allocation and garbage collection Lisp implementations use

unconventional memory represen tations for ob jects This represen tation mismatch creates problems when a Lisp

program must share ob jects with programs written in another language There are three dierent approaches to

establishing communication

The burden can b e placed on the foreign program and programmer by requiring the use of Lisp ob ject

represen tations The main diculty with this approach is that either the foreign program must b e written

with Lisp interaction in mind or a substantial amount of foreign glue co de must b e written to p erform

the translation

The Lisp system can automatically convert ob jects back and forth b etween the Lisp and foreign represen ta

tions This is convenient but translation b ecomes prohibitively slow when large or complex data structures

must b e shared

The Lisp program can directly manipulate foreign ob jects through the use of extensions to the Lisp lan

guage Most Lisp systems make use of this approach but the language for describing typ es and expressing

accesses is often not p owerful enough for complex ob jects to b e easily manipulated

CMU Common Lisp relies primarily on the automatic conversion and direct manipulation approaches Aliens of

simple scalar typ es are automatically converted while complex typ es are directly manipulated in their foreign

represen tation Any foreign ob jects that cant automatically b e converted into Lisp values are represen ted by

ob jects of typ e alienvalue Since Lisp is a dynamically typ ed language even foreign ob jects must havea

runtime typ e this typ e information is provided by encapsulating the rawpointer to the foreign data within an

alienvalue ob ject

The Alien typ e language and op erations are most similar to those of the C language but Aliens can also b e

used when communicating with most other languages that can b e linked with C

Alien Typ es

Alien typ es have a description language based on nested list structure For example

struct foo

int a

struct foo b

CHAPTER ALIEN OBJECTS

has the corresp onding Alien typ e

struct foo

a int

b array struct foo

Dening Alien Typ es

Typ es may b e either named or anonymous With structure and union typ es the name is part of the typ e

sp ecier allowing recursively dened typ es such as

struct foo a struct foo

An anonymous structure or union typ e is sp ecied by using the name nilThewithalien page macro

denes a lo cal scop e which captures any named typ e denitions Other typ es are not inherently named but

can b e given named abbreviations using defalientype

aliendefalientype name typ e Macro

This macro globally denes name as a shorthand for the Alien typ e typ eWhenintro ducing global structure

and union typ e denitions name maybe nilinwhich case the name to dene is taken from the typ es name

Alien Typ es and Lisp Typ es

The Alien typ es form a subsystem of the CMU Common Lisp typ e system An alien typ e sp ecier provides a

way to use any Alien typ e as a Lisp typ e sp ecier For example

typep foo alien int

can b e used to determine whether foo is a p ointer to an int alien typ e sp eciers can b e used in the same ways

as ordinary typ e sp eciers like string Alien typ e declarations are sub ject to the same precise typ e c hecking

as any other declaration section See section page

Note that the Alien typ e system overlaps with normal Lisp typ e sp eciers in some cases For example the

typ e sp ecier alien singlefloat is identical to singlefloat since Alien oats are automatically converted

to Lisp oats When typeof is called on an Alien value that is not automatically converted to a Lisp value

then it will return an alien typ e sp ecier

Alien Typ e Sp eciers

Some Alien typ e names are Common Lispsymb ols but the names are still exp orted from the alien package so

it is legal to say aliensinglefloat These are the basic Alien typ e sp eciers

typ e Alien typ e

A p ointer to an ob ject of the sp ecied typ eIftyp e is t then it means a p ointer to anything

similar to void in ANSI C Currently the only way to detect a null p ointer is

zerop sapint aliensap ptr

See section page

array typ e fdimensiong Alien typ e

An array of the sp ecied dimensions holding elements of typ e typ eNotethat int and array

int are considered to b e dierent typ es when typ e checking is done p ointer and arrayt yp es must

b e explicitly co erced using cast

Arrays are accessed using deref passing the indices as additional arguments Elements are stored

in columnmajor order as in C so the rst dimension determines only the size of the memory

blo ck and not the layout of the higher dimensions An array whose rst dimension is variable

may b e sp ecied by using nil as the rst dimension Fixedsize arrays can b e allocated as array

elements structure slots or withalien variables Dynamic arrays can only b e allocated using

makealien page

CHAPTER ALIEN OBJECTS

struct name feld typ e bits g Alien typ e

A structure typ e with the sp ecied name and elds Fields are allocated at the same p ositions used

by the implementations C compiler bits is intended for Clike bit eld supp ort but is currently

unused If name is nil then the typ e is anonymous

If a named Alien struct sp ecier is passed to defalientype page or withalien

page then this denes resp ectively a new global or local Alien structure typ e If no elds are

sp ecied then the elds are taken from the curren t local or global Alien structure typ e denition

of name

union name feld typ e bits g Alien typ e

Similar to struct but denes a union typ e All elds are allocated at the same oset and the size

of the union is the size of the largest eld The programmer must determine which eld is active

from context

enum name fsp ec g Alien typ e

An enumeration typ e that maps b etween integer values and keywords If name is nil then the

typ e is anonymous Eac h sp ec is either a keyword or a list keyword value Ifinteger is not

supplied then it defaults to one greater than the value for the preceding sp ec or to zero if it is the

rst sp ec

signed bits Alien typ e

A signed integer with the sp ecied numb er of bits precision The upp er limit on integer precision

is determined by the machines word size If no size is sp ecied the maximum size will b e used

integer bits Alien typ e

Identical to signed the distinction b etween signed and integer is purely stylistic

unsigned bits Alien typ e

Like signed but sp ecies an unsigned integer

boolean bits Alien typ e

Similar to an enumeration typ e that maps to nil and all other values to t bits determines the

amount of storage allocated to hold the truth value

singlefloat Alien typ e

A oatingp ointnumb er in IEEE single format

doublefloat Alien typ e

A oatingp ointnumb er in IEEE double format

fargtyp e g function resulttyp e Alien typ e

A Alien function that takes arguments of the sp ecied argtyp es and returns a result of typ e result

typ e Note that the only context where a function typ e is directly sp ecied is in the argument

to alienfuncall see section In all other contexts functions are represen ted by function

p ointer typ es function

systemareapointer Alien typ e

A p ointer which is represen ted in Lisp as a systemareapointer ob ject see section page

The CCall Package

The ccall package exp orts these typ eequivalents to the C typ e of the same name char short int long

unsignedchar unsignedshort unsignedint unsignedlong float double ccall also exp orts these

typ es

CHAPTER ALIEN OBJECTS

void Alien typ e

This typ e is used in function typ es to declare that no useful value is returned Evaluation of an

alienfuncall form will return zero values

cstring Alien typ e

This typ e is similar to char but is interpreted as a nullterminated string and is automatically

converted into a Lisp string when accessed If the p ointer is C NULL or then accessing gives

Lisp nil

Assigning a Lisp string to a cstring structure eld or variable stores the contents of the string

to the memory already p ointed to bythatvariable When an Alien of typ e char is assigned

to a cstring then the cstring pointer is assigned to This allows cstring p ointers to b e

initialized For example

defalientype nil struct foo str cstring

defun makefoo str

let myfoo makealien struct foo

setf slot myfoo str makealien char length str

setf slot myfoo str str

myfoo

Storing Lisp nil writes C NULL to the cstring pointer

Alien Op erations

This section describ es the basic op erations on Alien values

Alien Access Op erations

alienderef p ointerorarray rest indices Function

This function returns the value p ointed to by an Alien p ointer or the value of an Alien array element If a

p ointer an optional single index can b e sp ecied to give the equivalentofCpointer arithmetic this index is

scaled b y the size of the typ e p ointed to If an arraythenumb er of indices must b e the same as the number of

dimensions in the arraytyp e deref can b e set with setf to assign a new value

alienslot structorunion slotname Function

This function extracts the value of slot slotname from the an Alien struct or unionIfstructorunion is

a p ointer to a structure or union then it is automatically dereferenced This can b e set with setf to assign a

new value Note that slotname is evaluated and need not b e a compiletime constant but only constant slot

accesses are eciently compiled

Alien Co ercion Op erations

alienaddr alienexpr Macro

This macro returns a p ointer to the location sp ecied by alienexpr whichmust b e either an Alien variable

a use of deref a use of slot or a use of externalien page

aliencast alien newtyp e Macro

This macro converts alien to a new Alien with the sp ecied newtyp eBothtyp es must b e an Alien p ointer

array or function typ e Note that the result is not eq to the argument but do es refer to the same data bits

CHAPTER ALIEN OBJECTS

aliensapalien sap typ e Macro

alienaliensap alienvalue Function

sapalien converts sap a system area p ointer see section page to an Alien value with the sp ecied

typ e typ e is not evaluated

aliensap returns the SAP whichpoints to alienvalue s data

The typ e to sapalien and the typ e of the alienvalue to aliensap must some Alien p ointer arrayor

record typ e

Alien Dynamic Allo cation

Dynamic Aliens are allocated using the malloc library so foreign co de can call free on the result of makealien

and Lisp co de can call freealien on ob jects allocated by foreign co de

alienmakealien typ e size Macro

This macro returns a dynamically allocated Alien of the sp ecied typ e which is not evaluated The allocated

memory is not initialized and may contain arbitrary junk If supplied size is an expression to evaluate to compute

the size of the allocated ob ject There are two ma jor cases

When typ e is an arraytyp e an arrayofthatt yp e is allocated and a pointer to it is returned Note that

you must use deref to change the result to an array b efore you can use deref to read or write elements

defvar foo makealien array char

typeof foo

alien array signed

setf deref deref foo

If supplied size is used as the rst dimension for the array

When typ e is any other typ e then then an ob ject for that typ e is allocated and a pointer to it is returned

So makealien int returns a intIfsize is sp ecied then a blo ck of that many ob jects is allocated

with the result p ointing to the rst one

alienfreealien alien Function

This function frees the storage for alien whichmust have b een allocated with makealien or malloc

See also withalien page which stackallocates Aliens

Alien Variables

Both local stack allocated and external C global Alien variables are supp orted

Lo cal Alien Variables

alienwithalien fname typ e initialvalue g fform g Macro

This macro establishes local alien v ariables with the sp ecied Alien typ es and names for dynamic extent

of the b o dyThevariable names are established as symb olmacros the bindings have lexical scop e and may

b e assigned with setq or setf This form is analogous to dening a lo cal variable in C additional storage is

allocated and the initial value is copied

withalien also establishes a new scop e for named structures and unions Any typ e sp ecied for a variable

may contain name structure or union typ es with the slots sp ecied Within the lexical scop e of the binding

sp eciers and b o dy a locally dened structure typ e foo can b e referenced by its name using struct foo

CHAPTER ALIEN OBJECTS

External Alien Variables

External Alien names are strings and Lisp names are symb ols When an external Alien is represen ted using a

Lisp variable there must b e a way to convert from one name syntax into the other The macros externalien

defalienvariable and defalienroutine page use this conversion heuristic

Alien names are converted to Lisp names by upp ercasing and replacing underscores with hyphens

Conversely Lisp names are converted to Alien names bylowercasing and replacing hyphens with under

scores

Both the Lisp symb ol and Alien string names may b e separately sp ecied by using a list of the form

lispsymb ol alienstring

aliendefalienvariable name typ e Macro

This macro denes name as an external Alien variable of the sp ecied Alien typ e name and typ e are not

evaluated The Lisp name of the variable see ab ove b ecomes a global Alien variable in the Lisp namespace

Global Alien variables are eectively global symb ol macros a reference to the variable fetches the contents

of the external variable Similarly setting the variable stores new contents the new contents mustbeofthe

declared typ e

For example it is often necessary to read the global C variable errno to determine why a particular function

call failed It is p ossible to dene errno and mak e it accessible from Lisp by the following

defalienvariable errno int

Now it is possible to get the value of the C variable errno simply by

referencing that Lisp variable

print errno

alienexternalien name typ e Macro

This macro returns an Alien with the sp ecied typ e whichpoints to an externally dened value name is not

evaluated and may b e sp ecied either as a string or a symb ol typ e is an unevaluated Alien typ e sp ecier

Alien Data Structure Example

Now that wehave Alien typ es op erations and variables we can manipulate foreign data structures This C

declaration can b e translated into the following Alien typ e

struct foo

int a

struct foo b

defalientype nil

struct foo

a int

b array struct foo

With this denition the following C expression can b e translated in this way

CHAPTER ALIEN OBJECTS

struct foo f

fba

withalien f struct foo

slot deref slot f b a

Do something with f

Or consider this example of an external C variable and some accesses

struct cstruct

short x y

char a b

int z

cstruct n

extern struct cstruct mystruct

mystructx

mystructa

mystruct mystructn

which can b e made b e manipulated in Lisp like this

defalientype nil

struct cstruct

x short

y short

a char

b char

z int

n cstruct

defalienvariable mystruct cstruct

incf slot mystruct x

setf slot mystruct a

setq mystruct slot mystruct n

Loading Unix Ob ject Files

Foreign ob ject les are loaded into the running Lisp pro cess by loadforeign First it runs the linker on the les

and libraries creating an absolute Unix ob ject le This ob ject le is then loaded into into the currently running

Lisp The external symb ols dening routines and variables are made available for future external references eg

by externalien loadforeign must b e run b efore any of the dened symb ols are referenced

Note that if a Lisp core image is saved using savelisp page all loaded foreign co de is lost when the

image is restarted

alienloadforeign les key libraries basele env Function

les is a simplestring or list of simplestrings sp ecifying the names of the ob ject les libraries is a list of

simplestrings sp ecifying libraries in a format that ld the Unix linker exp ects The default value for libraries

is lc ie the standard C library basele is the le to use for the initial symb ol table information

CHAPTER ALIEN OBJECTS

The default is the Lisp start up co de pathlisp env should b e a list of simple strings in the format of Unix

environmentvariables ie AB where A is an environmentvariable and B is its value The default value for

env is the environment information available at the time Lisp was invoked Unless you are certain that you want

to change this you should just use the default

Alien Function Calls

The foreign function call interface allows a Lisp program to call functions written in other languages The current

implementation of the foreign function call interface assumes a C calling convention and thus routines written

in any language that adheres to this convention may b e called from Lisp

Lisp sets up various interrupt handling routines and other environment information when it rst starts up

and exp ects these to b e in place at all times The C functions called by Lisp should either not change the

environment esp ecially the interrupt entry p oints or should make sure that these entry p oints are restored

when the C function returns to Lisp If a C function makes changes without restoring things to the waythey

were when the C function was entered there is no telling what will happ en

The alienfuncall Primitive

alienalienfuncall alienfunction rest arguments Function

This function is the foreign function call primitive alienfunction is called with the supplied arguments and

its value is returned The alienfunction is an arbitrary runtime expression to call a constant function use

externalien page or defalienroutine

The typ e of alienfunction must b e alien function or alien function See section

page The function typ e is used to determine how to call the function as through it was declared with

a prototyp e The typ e need not b e known at compile time but only knowntyp e calls are eciently compiled

Limitations

Structure typ e return values are not implemented

Passing of structures byvalue is not implemented

Here is an example which allocates a struct foo calls a foreign function to initialize it then returns a

Lisp vector of all the struct foo ob jects lled in by the foreign call

Allocate a foo on the stack

withalien f struct foo

Call some C function to fill in foo fields

alienfuncall externalien manglefoo function void foo

addr f

Find how many foos to use by getting the A field

let num slot f a

result makearray num

Get a pointer to the array so that we dont have to keep extracting it

withalien a array struct foo 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 result

CHAPTER ALIEN OBJECTS

The defalienroutine Macro

aliendefalienroutine name resulttyp e faname atyp e style g Macro

This macro is a convenience for automatically generating Lisp interfaces to simple foreign functions The

primary feature is the parameter style sp ecication which translates the C passbyreference idiom into additional

return values

name is usually a string external symb ol but may also b e a symb ol Lisp name or a list of the Lisp name and

the foreign name If only one name is sp ecied the other is automatically derived see section page

resulttyp e is the Alien typ e of the return value Each remaining subform sp ecies an argumenttothe

foreign function aname is the symb ol name of the argument to the constructed function for documentation

and atyp e is the Alien typ e of corresp onding foreign argument The semantics of the actual call are the same as

for alienfuncall page style should b e one of the following

in sp ecies that the argumentispassedbyvalue This is the default in arguments have no corresp onding

return value from the Lisp function

out sp ecies a passbyreference output value The typ e of the argumentmustbeapointer to a xed sized

ob ject such as an integer or p ointer out and inout cannot b e used with p ointers to arrays records or

functions An ob ject of the correct size is allocated 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

copy is similar to in but the argument is copied to a preallo cated ob ject and a p ointer to this ob ject is

passed to the foreign routine

inout is a combination of copy and out The argument is copied to a preallocated ob ject and a p ointer

to this ob ject is passed to the foreign routine On return the contents of this lo cation is returned as an

additional value

Any eciencycritical foreign interface function should b e inline expanded by preceding defalienroutine

with

declaim inline lispname

In addition to avoiding the Lisp call overhead this allows p ointers wordintegers and oats to b e passed using

nondescriptor represen tations avoiding consing see section page

defalienroutine Example

Consider the C function cfoo with the following calling convention

cfoo a i

char str

char a update

int i out

Body of cfoo

which can b e describ ed by the following call to defalienroutine

defalienroutine cfoo void

str cstring

a char inout

i int out

The Lisp function cfoo will havetwo arguments str and aandtwo return values a and i

CHAPTER ALIEN OBJECTS

Calling Lisp from C

Calling Lisp functions from C is sometimes p ossible but is rather hackish See callintolisp and funcall

funcall in the C startup co de The arguments must b e valid CMU CL ob ject descriptors eg xnums

must b e leftshifted bySeecompilergenericobjdeflisp or the derived le lispinternalsh for

details of the ob ject represen tation Note that the garbage collector moves ob jects and wontbeabletoxup

any references in C variables so either turn GC o or dont keep Lisp p ointers in C data unless they are to

statically allocated ob jects

StepbyStep Alien Example

This section presents a complete example of an interface to a somewhat complicated C function This example

should giveafairlygoodideaofhow to get the eect you want for almost any kind of C function Supp ose you

have the following C function whichyou want to b e able to call from Lisp in the le testc

struct cstruct

int x

char s

struct cstruct cfunction i s r a

int i

char s

struct cstruct r

int a

int j

struct cstruct r

printfi dn i

printfs sn s

printfrx dn rx

printfrs sn rs

for j j j printfad dn j aj

r struct cstruct malloc sizeofstruct cstruct

rx i

rs A C string

returnr

It is p ossible to call this function from Lisp using the le testlisp whose contents is

Package testccall

inpackage TESTCCALL

usepackage ALIEN

usepackage CCALL

Define the record cstruct in Lisp

defalientype nil

struct cstruct

x int

s cstring

Define the Lisp function interface to the C routine It returns a

pointer to a record of type cstruct It accepts four parameters i an int s a pointer to a string r a pointer to a cstruct

CHAPTER ALIEN OBJECTS

record and a a pointer to the array of ints

The INLINE declaration eliminates some efficiency notes about heap

allocation of Alien values

declaim inline cfunction

defalienroutine cfunction

struct cstruct

i int

s cstring

r struct cstruct

a array int

A function which sets up the parameters to the C function and

actually calls it

defun callcfun

withalien ar array int

cstruct struct cstruct

dotimes i Fill array

setf deref ar i i

setf slot cstruct x

setf slot cstruct s A Lisp String

withalien res struct cstruct

cfunction Another Lisp String addr cstruct ar

format t Returned from C function

multiplevalueprog

values slot res x

slot res s

Deallocate result after we are done using it

freealien res

To execute the ab ove example it is necessary to compile the C routine as follows

cc c testc

In order to enable incremental loading with some linkers you mayneedtosay

cc G c testc

Once the C co de has b een compiled you can start up Lisp and load it in

lisp

Lisp should start up with its normal prompt

Compile the Lisp file This step can be done separately You dont have

to recompile every time

compilefile testlisp

Load the foreign object file to define the necessary symbols This must

be done before loading any code that refers to these symbols next block

of comments are actually the output of LOADFOREIGN Different linkers

will give different warnings but some warning about redefining the code

size is typical

loadforeign testo

Running libraryloadforeigncsh Loading object file

CHAPTER ALIEN OBJECTS

Parsing symbol table

Warning gp moved from xCC to xC

Warning end moved from xC to xCE

ok now load the compiled Lisp object file

load test

Now we can call the routine that sets up the parameters and calls the C

function

testccallcallcfun

The C routine prints the following information to standard output

i

s Another Lisp string

rx

rs A Lisp string

a

a

a

a

a

a

a

a

a

a

Lisp prints out the following information

Returned from C function

Return values from the call to testccallcallcfun

A C string

If any of the foreign functions do output they should not b e called from within Hemlock Dep ending on the

situation various strange b ehavior o ccurs Under X the output go es to the windowinwhich Lisp was started

on a terminal the output will overwrite the Hemlock screen image in a Hemlockslave standard output is

devnullby default so any output is discarded

Chapter

Interpro cess Communication under

LISP

Written by William Lott and Bill Chiles

CMU Common Lisp oers a facilityforinterpro cess communication IPC on top of using Unix system calls

and the complications of that level of IPC There is a simple remotepro cedurecall RPC package build on top

of TCPIP so ckets

The REMOTE Package

The remote package provides simple RPC facility including interfaces for creating servers connecting to already

existing servers and calling functions in other Lisp pro cesses The routines for establishing a connection b e

tween two pro cesses createrequestserver and connecttoremoteserver return wire structures A wire

maintains the curren t state of a connection and all the RPC forms require a wire to indicate where to send

requests

Connecting Servers and Clients

Before a client can connect to a server it must knowthenetwork address on whichtheserver accepts connections

Network addresses consist of a host address or name and a p ort numb er Host addresses are either a string of

the form VANCOUVERSLISPCSCMUEDU or a bit unsigned integer Port numb ers are bit unsigned integers

Note p ort in this context has nothing to do with Mach p orts and message passing

When a pro cess wants to receive connection requests that is b ecome a server it rst picks an integer to

use as the p ort Only one server Lisp or otherwise can use a given p ort numb er on a given machine at any

particular time This can b e an iterative pro cess to nd a free p ort picking an integer and calling create

requestserver This function signals an error if the c hosen p ort is unusable You will probably want to write

a lo op using handlercase catching conditions of typ e error since this function do es not signal more sp ecic

conditions

wirecreaterequestserver port optional onconnect Function

createrequestserver sets up the curren t Lisp to accept connections on the given p ort If p ort is un

available for any reason this signals an error When a client connects to this p ort the acceptance mechanism

makes a wire structure and invokes the onconnect function Invoking this function has a couple purp oses and

onconnect maybe nil in which case the system forego es invoking any function at connect time

The onconnect function is b oth a ho ok that allows you access to the wire created by the acceptance mecha

nism and it conrms the connection This function takes two arguments the wire and the host address of the

connecting pro cess See the section on host addresses b elow When onconnect is nil the request server allows

all connections When it is nonnil the function returns twovalues whether to accept the connection and a

function the system should call when the connection terminates Either value maybe nil but when the rst

value is nil the acceptance mechanism destroys the wire

CHAPTER INTERPROCESS COMMUNICATION UNDER LISP

createrequestserver returns an ob ject that destroyrequestserver uses to terminate a connection

wiredestroyrequestserver server Function

destroyrequestserver takes the result of createrequestserver and terminates that server Any

existing connections remain intact but all additional connection attempts will fail

wireconnecttoremoteserver host p ort optional ondeath Function

connecttoremoteserver attempts to connect to a remote server at the given p ort on host and returns a

wire structure if it is successful If ondeath is nonnil it is a function the system invokes when this connection

terminates

Remote Evaluations

After the server and clienthave connected they each have a wire allowing function evaluation in the other

pro cess This RPC mechanism has three avors for sideeect only for a single value and for multiple values

Only a limited numb er of data typ es can b e sent across wires as arguments for remote function calls and

as return values integers inclusively less than bits in length symb ols lists and remoteob jects see section

page The system sends symb ols as two strings the package name and the symb ol name and if the

package do esnt exist remotely the remote pro cess signals an error The system ignores other slots of symb ols

Lists maybeany tree of the ab ovevalid data typ es To send other data typ es you must represen t them in

terms of these supp orted typ es For example you could use printostring lo cally send the string and use

readfromstring remotely

wireremote wire fcal lspecs g Macro

The remote macro arranges for the pro cess at the other end of wire to invokeeach of the functions in

the callsp ecs Tomake sure the system sends the remote evaluation requests over the wire you must call

wireforceoutput

Eachofcallspecs lo oks like a function call textually but it has some o dd constraints and semantics The

function p osition of the form must b e the symb olic name of a function remote evaluates each of the argument

subforms for each of the callsp ecs locally in the current context sending these values as the arguments for the

functions

Consider the following example

defun writeremotestring str

declare simplestring str

wireremote wire

writestring str

The value of str in the lo cal pro cess is passed over the wire with a request to invoke writestring on the value

The system do es not exp ect to remotely evaluate str for a v alue in the remote pro cess

wirewireforceoutput wire Function

wireforceoutput ushes all internal buers asso ciated with wire sending the remote requests This is

necessary after a call to remote

wireremotevalue wire callsp ec Macro

The remotevalue macro is similar to the remote macro remotevalue only takes one callsp ec and it

returns the value returned by the function call in the remote pro cess The value must b e a valid typ e the system

can send over a wire and there is no need to call wireforceoutput in conjunction with this interface

If clientunwinds past the call to remotevalue the server continues running but the system ignores the

value the server sends back

If the server unwinds past the remotely requested call instead of returning normally remotevalue returns

twovalues nil and t Otherwise this returns the result of the remote evaluation and nil

CHAPTER INTERPROCESS COMMUNICATION UNDER LISP

wireremotevaluebind wire fvariable g remoteform flocalforms g Macro

remotevaluebind is similar to multiplevaluebind except the values b ound come from remoteforms

evaluation in the remote pro cess The localforms execute in an implicit progn

If the clientunwinds past the call to remotevaluebind the server continues running but the system

ignores the values the server sends back

If the server unwinds past the remotely requested call instead of returning normallythe localforms never

execute and remotevaluebind returns nil

Remote Ob jects

The wire mechanism only directly supp orts a limited numb er of data typ es for transmission as arguments

for remote function calls and as return values integers inclusively less than bits in length symb ols lists

Sometimes it is useful to allow remote pro cesses to refer to local data structures without allowing the remote

pro cess to op erate on the data Wehave remoteob jects to supp ort this without the need to represen t the data

structure in terms of the ab ove data typ es to send the represen tation to the remote pro cess to deco de the

represen tation to later enco de it again and to send it back along the wire

You can convert any Lisp ob ject into a remoteob ject When you send a remoteob ject along a wire the

system simply sends a unique token for it In the remote pro cess the system lo oks up the token and returns a

remoteob ject for the token When the remote pro cess needs to refer to the original Lisp ob ject as an argument

to a remote call back or as a return value it uses the remoteob ject it has which the system converts to the

unique token sending that along the wire to the originating pro cess Up on receipt in the rst pro cess the system

converts the token back to the same eq remoteob ject

wiremakeremoteobject ob ject Function

makeremoteobject returns a remoteob ject that has ob ject as its value The remoteob ject can b e passed

across wires just like the directly supp orted wire data typ es

wireremoteobjectp ob ject Function

The function remoteobjectp returns t if ob ject is a remote ob ject and nil otherwise

wireremoteobjectlocalp remote Function

The function remoteobjectlocalp returns t if remote refers to an ob ject in the local pro cess This is

can only o ccur if the lo cal pro cess created remote with makeremoteobject

wireremoteobjecteq ob j ob j Function

The function remoteobjecteq returns t if ob j and ob j refer to the same eq lisp ob ject regardless of

which pro cess created the remoteob jects

wireremoteobjectvalue remote Function

This function returns the original ob ject used to create the given remote ob ject It is an error if some other

pro cess originally created the remoteob ject

Function wireforgetremotetranslation ob ject

This function removes the information and storage necessary to translate remoteob jects backinto ob ject

so the next gc can reclaim the memoryYou should use this when you no longer exp ect to receive references to

ob ject If some remote pro cess do es send a reference to ob ject remoteobjectvalue signals an error

CHAPTER INTERPROCESS COMMUNICATION UNDER LISP

Host Addresses

The op erating system maintains a database of all the valid host addresses You can use this database to convert

between host names and addresses and viceversa

extlookuphostentry host Function

lookuphostentry searches the database for the given host and returns a hostentry structure for it If it

fails to nd host in the database it returns nil Host is either the address as an integer or the name as a

string of the desired host

exthostentryname hostentry Function

exthostentryaliases hostentry Function

exthostentryaddrlist hostentry Function

exthostentryaddr hostentry Function

hostentryname hostentryaliasesand hostentryaddrlist each return the indicated slot from

the hostentry structure hostentryaddr returns the primary rst address from the list returned by host

entryaddrlist

The WIRE Package

The wire package provides for sending data along wires The remote package sits on top of this package All

data sent with a giv en output routine must b e read in the remote pro cess with the complementary fetching

routine For example if you send so a string with wireoutputstring the remote pro cess must knowtouse

wiregetstringToavoid rigid data transfers and complicated co de the interface supp orts sending tagged

data With tagged data the system sends a tag announcing the typ e of the next data and the remote system

takes care of fetching the appropriate typ e

When using interfaces at the wire level instead of the RPC level the remote pro cess must read everything

sent by these routines If the remote pro cess leaves any input on the wire it will later mistake the data for an

RPC request causing unknown lossage

Untagged Data

When using these routines b oth ends of the wire knowexactlywhattyp es are coming and going and in what

order This data is restricted to the following typ es

bit unsigned bytes

bit unsigned bytes

bit integers

simplestrings less than in length

wirewireoutputbyte wire byte Function

wirewiregetbyte wire Function

wirewireoutputnumber wire number Function

wirewiregetnumber wire optional signed Function

wirewireoutputstring wire string Function

wirewiregetstring Function wire

These functions either output or input an ob ject of the sp ecied data typ e When you use any of these output

routines to send data across the wire you must use the corresp onding input routine interpret the data

CHAPTER INTERPROCESS COMMUNICATION UNDER LISP

Tagged Data

When using these routines the system automatically transmits and interprets the tags for you so b oth ends can

gure out what kind of data transfers o ccur Sending tagged data allows a greater varietyofdatatyp es integers

inclusively less than bits in length symb ols lists and remoteob jects see section page The system

sends symb ols as two strings the package name and the symb ol name and if the package do esnt exist remotely

the remote pro cess signals an error The system ignores other slots of symb ols Lists maybeany tree of the

ab ovevalid data typ es To send other data typ es you must represen t them in terms of these supp orted typ es

For example you could use printostring locally send the string and use readfromstring remotely

wirewireoutputobject wire ob ject optional cacheit Function

wirewiregetobject wire Function

The function wireoutputobject sends ob ject over wire preceded by a tag indicating its typ e

If cacheit is nonnil this function only sends ob ject the rst time it gets ob jectEach end of the wire

asso ciates a token with ob ject similar to remoteob jects allowing you to send the ob ject more eciently on

successiv e transmissions Cacheit defaults to t for symb ols and nil for other typ es Since the RPC level requires

function names a highlevel proto col based on a set of function calls saves time in sending the functions names

rep eatedly

The function wiregetobject reads the results of wireoutputobject and returns that ob ject

Making Your Own Wires

You can create wires manually in addition to the remote packages interface creating them for you To create a

wire you need a Unix le descriptorIfyou are unfamiliar with Unix le descriptors see section of the Unix

manual pages

wiremakewire descriptor Function

The function makewire creates a new wire when supplied with the le descriptor to use for the underlying

IO op erations

wirewirep ob ject Function

This function returns t if ob ject is indeed a wire nil otherwise

wirewirefd wire Function

This function returns the le descriptor used bythewire

OutOfBand Data

The TCPIP proto col allows users to send data asynchronously otherwise known as outofband data When

using this feature the op erating system interrupts the receiving pro cess if this pro cess has chosen to b e notied

ab out outofband data The receiver can grab this input without aecting any information curren tly queued

on the so cket Therefore you can use this without interfering with any current activity due to other wire and

remote interfaces

Unfortunately most implementations of TCPIP are broken so use of outofband data is limited for safety

reasons Y ou can only reliably send one character at a time

This routines in this section provide a mechanism for establishing handlers for outofband characters and

for sending them outofband These all take a Unix le descriptor instead of a wire but you can fetch a wires

le descriptor with wirefd

wireaddoobhandler fd char handler Function

The function addoobhandler arranges for handler to b e called whenever char shows up as outofband

data on the le descriptor fd

CHAPTER INTERPROCESS COMMUNICATION UNDER LISP

wireremoveoobhandler fd char Function

This function removes the handler for the character char on the le descriptor fd

wireremovealloobhandlers fd Function

This function removes all handlers for the le descriptor fd

wiresendcharacteroutofband fd char Function

This function Sends the character char down the le descriptor fd outofband

Chapter

Debugger Programmers Interface

The debugger programmers interface is exp orted from from the DEBUGINTERNALS or DI package This is a

CMU extension that allows debugging to ols to b e written without detailed knowledge of the compiler or runtime

system

Some of the interface routines take a co delo cation as an argument As describ ed in the section on co de

lo cations some co delocations are unknown When a function calls for a basicco delocation it takes either

typ e but when it sp ecically names the argument co delocation the routine will signal an error if you giveitan

unknown co delo cation

DI Exceptional Conditions

Some of these op erations fail dep ending on the availability debugging information In the most severe case when

someone saved a Lisp image stripping all debugging data structures no op erations are valid In this case even

backtracing and nding frames is impossible Some interfaces can simply return values indicating the lackof

information or their return values are naturally meaningful in light missing data Other routines as do cumented

b elow will signal seriousconditions when they discover awkward situations This interface do es not provide

for programs to detect these situations other than by calling a routine that detects them and signals a condition

These are seriousconditions b ecause the program using the interface must handle them b efore it can correctly

continue execution These debugging conditions are not errors since it is no fault of the programmers that the

conditions o ccur

Debugconditions

The debug internals interface signals conditions when it cant adhere to its contract These are seriousconditions

b ecause the program using the interface must handle them b efore it can correctly continue execution These

debugging conditions are not errors since it is no fault of the programmers that the conditions o ccur The

interface do es not provide for programs to detect these situations other than calling a routine that detects them

and signals a condition

debugcondition Condition

This condition inherits from seriouscondition and all debugconditions inherit from this These

must b e handled but they are not programmer errors

nodebuginfo Condition

This condition indicates there is absolutely no debugging information available

nodebugfunctionreturns Condition

This condition indicates the system cannot return values from a frame since its debugfunction

lacks debug information details ab out returning values

nodebugblocks Condition

This condition indicates that a function was not compiled with debugblo ck information but this

information is necessary necessary for some requested op eration

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

nodebugvariables Condition

Similar to nodebugblocks except that variable information was requested

lambdalistunavailable Condition

Similar to nodebugblocks except that lamb da list information was requested

invalidvalue Condition

This condition indicates a debugvariable has invalid or unknown value in a particular frame

ambiguousvariablename Condition

This condition indicates a user supplied debugvariable name identies more than one valid variable

in a particular frame

Debugerrors

These are programmer errors resulting from misuse of the debugging to ols programmers interface You could

haveavoided an o ccurrence of one of these by using some routine to check the use of the routine generating the

error

debugerror Condition

This condition inherits from error and all user programming errors inherit from this condition

unhandledcondition Condition

This error results from a signalled debugcondition o ccurring without anyone handling it

unknowncodelocation Condition

This error indicates the invalid use of an unknownco delo cation

unknowndebugvariable Condition

This error indicates an attempt to use a debugvariable in conjunction with an inappropriate debug

function for example checking the variables validity using a co delo cation in the wrong debug

function will signal this error

framefunctionmismatch Condition

This error indicates you called a function returned by preprocessforeval on a frame other than

the one for which the function had b een prepared

Debugvariables

Debugvariables represen t the constant information ab out where the system stores argument and local variable

values The system uniquely iden ties with an integer every instance of a variable with a particular name and

package To access a value you must supply the frame along with the debugvariable since these are particular

to a function not every instance of a variable on the stack

debugvariablename debugvariable Function

This function returns the name of the debugvariable The name is the name of the symb ol used as an

identier when writing the co de

debugvariablepackage debugvariable Function

This function returns the package name of the debugvariable This is the package name of the symbol used

as an identier when writing the co de

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

debugvariablesymbol debugvariable Function

This function returns the symbol from interning debugvariablename in the package named by debug

variablepackage

debugvariableid debugvariable Function

This function returns the integer that makes debugvariable s name and package name unique with resp ect

to other debugvariable s in the same function

debugvariablevalidity debugvariable basicco delo cation Function

This function returns three values reecting the validityofdebugvariable s value at basicco delo cation

valid The value is known to b e available

invalid The value is known to b e unavailable

unknown The values availabilityisunknown

debugvariablevalue debugvariable frame Function

This function returns the value stored for debugvariable in frame The value maybeinvalid This is

SETFable

debugvariablevalidvalue debugvariable frame Function

This function returns the value stored for debugvariable in frameIfthevalue is not valid then this

signals an invalidvalue error

Frames

Frames describ e a particular call on the stack for a particular thread This is the environment for name resolution

getting arguments and lo cals and returning values The stack conceptually growsupsothetopofthestackis

the most recently called function

topframe framedown frameup and framedebugfunction can only fail when there is absolutely no

debug information available This can only happ en when someone saved a Lisp image sp ecifying that the system

dump all debugging data

topframe Function

This function never returns the frame for itself always the frame b efore calling topframe

framedown frame Function

This returns the frame immediately b elow frame on the stack When frame is the b ottom of the stack this

returns nil

frameup frame Function

This returns the frame immediately ab ove frame on the stack When frame is the top of the stack this

returns nil

framedebugfunction frame Function

This function returns the debugfunction for the function whose call frame represen ts

framecodelocation frame Function

This function returns the co delo cation where frame s debugfunction will continue running when program

execution returns to frame If someone interrupted this frame the result could b e an unknown co delo cation

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

framecatches frame Function

This function returns an alist for all active catches in frame mapping catch tags to the co delo cations at

which the catch reenters

evalinframe frame form Function

This evaluates form in frame s environment This can signal several dierent debugconditions since its

success relies on a variety of inexact debug information invalidvalue ambiguousvariablename frame

functionmismatch See also preprocessforeval page

Debugfunctions

Debugfunctions represen t the static information ab out a function determined at compile time argument and

variable storage their lifetime information etc The debugfunction also contains all the debugblo cks repre

senting basicblocks of co de and these contains information ab out sp ecic co delo cations in a debugfunction

dodebugfunctionblocks blo ckvar debugfunction resultform fform g Macro

This executes the forms in a context with blo ckvar b ound to each debugblo ckindebugfunction successiv ely

Resultform is an optional form to execute for a return value and dodebugfunctionblocks returns nilif

there is no resultform This signals a nodebugblocks condition when the debugfunction lacks debugblock

information

debugfunctionlambdalist debugfunction Function

This function returns a list represen ting the lamb dalist for debugfunction The list has the following

structure

requiredvar requiredvar

optional var suppliedpvar

optional var

rest var rest var

keyword keywordsymbol var suppliedpvar

keyword keywordsymbol var

Each varn isadebugvariable however the symbol deleted app ears instead whenever the argumentremains

unreferenced throughout debugfunction

If there is no lamb dalist information this signals a lambdalistunavailable condition

dodebugfunctionvariables var debugfunction result fform g Macro

This macro executes each form in a context with var b ound to each debugvariable in debugfunction This

returns the value of executing result defaults to nil This may iterate over only some of debugfunctions

variables or none dep ending on debug p olicy for example p ossibly the compilation only preserv ed argument

information

debugvariableinfoavailable debugfunction Function

This function returns whether there is anyvariable information for debugfunction This is useful for distin

guishing whether there were no lo cals in a function or whether there was no variable information For example

if dodebugfuncti onvariables executes its forms zero times then you can use this function to determine the reason

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

debugfunctionsymbolvariables debugfunction symbol Function

This function returns a list of debugvariables in debugfunction having the same name and package as

symbolIfsymbol is uninterned then this returns a list of debugvariables without package names and with

the same name as symbol The result of this function is limited to the availabilityofvariable information in

debugfunction for example p ossibly debugfunction only knows ab out its arguments

ambiguousdebugvariables debugfunction nameprexstring Function

This function returns a list of debugvariables in debugfunction whose names contain nameprexstring as

an initial substring The result of this function is limited to the availabilityofvariable information in debug

function for example p ossibly debugfunction only knows about its arguments

preprocessforeval form basicco delo cation Function

This function returns a function of one argumentthatevaluates form in the lexical context of basicco de

lo cation This allows ecient rep eated evaluation of form at a certain place in a function which could b e useful

for conditional breaking This signals a nodebugvariables condition when the co delocations debugfunction

has no debugvariable information available The returned function tak es a frame as an argument See also

evalinframe page

functiondebugfunction function Function

This function returns a debugfunction that represen ts debug information for function

debugfunctionkind debugfunction Function

This function returns the kind of function debugfunction represen ts The value is one of the following

optional This kind of function is an entry p oint to an ordinary function It handles optional defaulting

parsing keywords etc

external This kind of function is an entry p oint to an ordinary function It checks argumentvalues and count

and calls the dened function

toplevel This kind of function executes one or more random toplevel forms from a le

cleanup This kind of function represen ts the cleanup forms in an unwindprotect

nil This kind of function is not one of the ab ove that is it is not sp ecially marked in anyway

debugfunctionfunction debugfunction Function

This function returns the Common Lisp function asso ciated with the debugfunction This returns nilif the

function is unavailable or is nonexistent as a user callable function ob ject

debugfunctionname debugfunction Function

This function returns the name of the function represen ted by debugfunction This may b e a string or a

cons do not assume it is a symbol

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

Debugblo cks

Debugblo cks contain information p ertinent to a sp ecic range of co de in a debugfunction

dodebugblocklocations co devar debugblo ckresult fform g Macro

This macro executes each form inacontext with co devar b ound to each co delocation in debugblo ck This

returns the value of executing result defaults to nil

debugblocksuccessors debugblo ck Function

This function returns the list of p ossible co delo cations where execution maycontinue when the basicblock

represen ted by debugblo ck completes its execution

debugblockelsewherep debugblo ck Function

This function returns whether debugblo ck represen ts elsewhere co de This is co de the compiler has moved

out of a functions co de sequence for optimization reasons Co delocations in these blocks are unsuitable for

stepping to ols and the rst co delo cation has nothing to do with a normal starting location for the block

Breakp oints

A breakp oint represen ts a function the system calls with the curren t frame when execution passes a certain

co delo cation A break p oint is active or inactive indep endent of its existence They also have an extra slot for

users to tag the breakp oint with information

makebreakpoint ho okfunction what key kind info functionendcookie Function

This function creates and returns a breakp oint When program execution encounters the breakp oint the

system calls ho okfunction Ho okfunction takes the curren t frame for the function in which the program is

running and the breakp oint ob ject

what and kind determine where in a function the system invokes ho okfunction what is either a co delo cation

or a debugfunction kind is one of codelocation functionstartor functionend Since the starts and

ends of functions maynothave co delo cations represen ting them designate these places by supplying what as a

debugfunction and kind indicating the functionstart or functionend When what is a debugfunction

and kind is functionend then ho okfunction must taketwo additional arguments a list of values returned

by the function and a functionendco okie

info is information supplied by and used by the user

functionendco okie is a function To implement functionend breakp oints the system uses starter breakp oints

to establish the functionend breakp oint for each invo cation of the function Up on each entry the system creates

a unique co okie to identify the invo cation and when the user supplies a function for this argument the system

invokes it on the co okie The system later invokes the functionend breakp oint ho ok on the same co okie The

user maysave the co okie when passed to the functionendco okie function for later comparison in the ho ok

function

This signals an error if what is an unknown co delo cation

Note Breakp oints in interpreted co de or bytecompiled co de are not implemented F unctionend breakp oints

are not implemented for compiled functions that use the known local return convention eg for blockcompiled

or selfrecursive functions

activatebreakpoint breakp oint Function

This function causes the system to invokethe breakp oint s ho okfunction until the next call to deactivate

breakpoint or deletebreakpoint The system invokes breakp oint ho ok functions in the opp osite order that

you activate them

deactivatebreakpoint breakp oint Function

This function stops the system from invoking the breakp oint s ho okfunction

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

breakpointactivep breakp oint Function

This returns whether breakp oint is currently active

breakpointhookfunction breakp oint Function

This function returns the breakp oint s function the system calls when execution encounters breakp oint and

it is active This is SETFable

breakpointinfo breakp oint Function

This function returns breakp oint s information supplied by the user This is SETFable

breakpointkind breakp oint Function

This function returns the breakp oint s kind sp ecication

breakpointwhat breakp oint Function

This function returns the breakp oint s what sp ecication

deletebreakpoint breakp oint Function

This function frees system storage and removes computational overhead asso ciated with breakp oint After

calling this breakp oint is useless and can never b ecome active again

Co delo cations

Co delo cations represen t places in functions where the system has correct information ab out the functions

environment and where interesting op erations can o ccur asking for a local variables value setting breakp oin ts

evaluating forms within the functions environment etc

Sometimes the interface returns unknown co delo cations These represen t places in functions but there is

no debug information asso ciated with them Some op erations accept these since they may succeed even with

missing debug data These op erations argumentisnamedbasicco delo cation indicating they take known and

unknown co delo cations If an op eration names its argument co delocation and you supply an unknown one

it will signal an error For example framecodelocation may return an unknown co delo cation if someone

interrupted Lisp in the given frame The system knows where execution will continue but this place in the co de

may not b e a place for which the compiler dumped debug information

codelocationdebugfunction basicco delo cation Function

This function returns the debugfunction represen ting information ab out the function corresp onding to the

co delo cation

codelocationdebugblock basicco delo cation Function

This function returns the debugblock containing co delo cation if it is available Some debug p olicies inhibit

debugblo ck information and if none is available then this signals a nodebugblocks condition

codelocationtoplevelformoffset co delo cation Function

This function returns the numb er of toplevel forms b efore the one containing co delo cation as seen bythe

compiler in some compilation unit A compilation unit is not necessarily a single le see the section on debug

sources

codelocationformnumber co delo cation Function

This function returns the numb er of the form corresp onding to co delo cation The form numb er is derived

alking the subforms of a toplevel form in depthrst order While walking the toplevel form count one in byw

depthrst order for each subform that is a cons See formnumbertranslations page

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

codelocationdebugsource co delo cation Function

This function returns co delo cations debugsource

codelocationunknownp basicco delo cation Function

This function returns whether basicco delo cation is unknown It returns nilwhen the co delo cation is known

codelocation co delo cation co delo cation Function

This function returns whether the two co delo cations are the same

Debugsources

Debugsources represen t how to get back the source for some co de The source is either a le compilefile or

load a lamb daexpression compile defun defmacro or a stream something particular to CMU Common

Lisp compilefromstream

When compiling a source the compiler counts each toplevel form it pro cesses but when the compiler handles

multiple les as one blo ck compilation the toplevel form count continues past le b oundaries Therefore code

locationtoplevelformoffset returns an oset that do es not always start at zero for the co delo cations

debugsource The oset into a particular source is codelocationtoplevelformoffset minus debug

sourcerootnumber

Inside a toplevel form a co delocations form numb er indicates the subform corresp onding to the co de

lo cation

debugsourcefrom debugsource Function

This function returns an indication of the typ e of source The following are the p ossible values

file from a le obtained by compilefile if compiled

lisp from Lisp obtained by compile if compiled

stream from a nonle stream CMU Common Lisp supp orts compilefromstream

debugsourcename debugsource Function

This function returns the actual source in some sense represen ted by debugsource which is related to debug

sourcefrom

file the pathname of the le

lisp a lamb daexpression

stream some descriptive string thats otherwise useless

debugsourcecreated debugsource Function

This function returns the universal time someone created the source This maybe nilif it is unavailable

debugsourcecompiled debugsource Function

This function returns the time someone compiled the source This is nilif the source is uncompiled

debugsourcerootnumber debugsource Function

This returns the numb er of toplevel forms pro cessed by the compiler b efore compiling this source If this

source is uncompiled this is zero This maybezeroeven if the source is compiled since the rst form in the rst

le compiled in one compilation for example must have a ro ot numb er of zero the compiler sawnoother

toplevel forms b efore it

CHAPTER DEBUGGER PROGRAMMERS INTERFACE

Source Translation Utilities

These two functions provide a mechanism for converting the rather obscure but highly compact represen tation

of source locations into an actual source form

debugsourcestartpositions debugsource Function

This function returns the le p osition of each toplevel form a vector if debugsource is from a fileIf

debugsourcefrom is lisp or streamortheleisbytecompiled then the result is nil

formnumbertranslations form tlfnumber Function

This function returns a table mapping form numb ers see codelocationformnumber to sourcepaths A

sourcepath indicates a descent into the toplevelform form going directly to the subform corresp onding to a

form numb er Tlfnumber is the toplevelform number of form

sourcepathcontext form path context Function

This function returns the subform of form indicated by the sourcepath Form is a toplevel form and path

is a sourcepath into it Context is the numb er of enclosing forms to return instead of directly returning the

sourcepath form When context is nonzero the form returned contains a marker HERE immediately

b efore the form indicated by path

Function Index

A debugsourcecompil ed

debugsourcecreated

activatebreakp oint

debugsourcefrom

addfdhandler

debugsourcename

addo obhandler

debugsourcero otnumb er

addxwindo wob ject

debugsourcestartp ositions

addr

debugvariableid

alienfuncal l

debugvariableinfoa vailable

aliensap

debugvariablename

ambiguousdebugv ariables

debugvariablepac kage

ambiguousles

debugvariablesymbol

debugvariablev alidvalue

B

debugvariablev alidit y

break

debugvariablevalue

breakp ointactivep

defalienroutine

breakp ointho okfunction

defalient yp e

breakp ointinfo

defalienvariable

breakp ointkind

defsourcecontext

breakp ointwhat

defaultdirectory

defaultin terrupt

C

defstruct

cast

deftyp e

ceiling

defun

clearsearc hlist

deletebreakp oint

cmdswitchname

deref

cmdswitchvalue

describe

cmdswitchwords

destroyrequestserver

co delo cationdebugblo ck

directory

co delo cationdebugfunction

disableclxev enthandling

co delo cationdebugsource

dodebugblo cklo cations

co delo cationformnumber

dodebugfunctionbl o cks

co delo cationtoplev elformoset

dodebugfunctionv ariables

co delo cationunkno wnp

co delo cation

E

compile

ed

compilele

enableclxev enthandling

compilefromstream

enablein terrupt

completele

encapsulate

connecttoremoteserv er

encapsulatedp

createrequestserv er

enumeratesearchlist

error

D

evalinframe

deactivatebreakp oint

externalien

debug

F

debugblo c kelsewherep

debugblo cksuccessors

fdstreamfd

debugfunctionfuncti on

fdstreamp

debugfunctionki nd

fdenition

debugfunctionl am b dalist

lewritable

debugfunctionname

et

debugfunctionsym b olvariables

oatdigits

FUNCTION INDEX

oatinnit yp makefdstream

oatnanp makeob jectset

oatnormalized p makeremoteob ject

oatprecision makewire

oatsign multiplev aluebind

oattrappingnan p

oor

O

ushdispl a yevents

ob jectseteventhandler

forgetremotetranslation

ob jectsetop eration

formnumb ertranslations

op enclxdispla y

formatdeco dedtime

formatuniv ersaltime

P

framecatches

parsetime

frameco delo cation

prepro cessforeval

framedebugfunction

prin tdirectory

framedown

pro cessaliv ep

frameup

pro cessclose

freealien

pro cesscoredump ed

function

pro cesserror

functiondebugfuncti on

pro cessexitco de

processinput

G

processkill

gc

pro cessoutput

gco

pro cessp

gcon

processpid

getbytesconsed

pro cessplist

getoatingp ointmo des

pro cesspty

getinternalruntime

pro cessstatus

getunixerrormsg

pro cessstatusho ok

grbind

pro cesswait

grcall

prole

grcall

grerror

R

remote

H

remoteob jecteq

hostentryaddr

remoteob jectlo calp

hostentryaddrlist

remoteobjectp

hostentryaliases

remoteob jectvalue

hostentryname

remotevalue

remotevaluebind

I

removeallo obhandlers

if

removefdhandler

ignorein terrupt

removeo obhandler

insp ect

reporttime

intsap

requiredargumen t

invalidatedescriptor

resettime

iterate

round

runprogram

L

lab els S

let

sap

lispcon trolpanel

sapalien

load

sapint

loadforeign

sapref

loadlogica lpa thname defaul ts

sapref

lo okuphosten try

sapref

savelisp

M

searchlist

searchlistdenedp makealien

sendcharacteroutofband makebreakp oint

FUNCTION INDEX

serveallevents

serveevent

setoatingp ointmo des

signedsapref

signedsapref

signedsapref

slot

sourcepathcon text

T

the

time

topframe

trace

truncate

U

unencapsula te

unixnamestrin g

unprole

untrace

V

var

W

waituntilfdusable

wirefd

wireforceoutput

wiregetbyte

wiregetnumber

wiregetob ject

wiregetstring

wireoutputb yte

wireoutputn umber

wireoutputob ject

wireoutputstring

wirep

withalien

withclxev enthandling

withcompilati onun it

withenabledin terrupts

withfdhandler

within terrupts

withouthemlo ck

withoutin terrupts

Variable Index

A L

aftergcho oks loadifsourcenew er

loadob jecttyp es

B loadsourcet yp es

longoatnegativ einnit y

b eforegcho oks

longoatp ositiv einnit y

blo ckcompiledefault

bytecompiledefault

M

bytecompiletoplev el

bytesconsedb etweengcs maxtraceinden tation

C R

commandlinestri ngs readdefaultoatformat

commandlineswitc hes

commandlineuti l it yname S

commandlinew ords

shortoatnegativ einnit y

compileprin t

shortoatp ositiveinnit y

compileprogress

singleoatnegati v einnit y

compilev erb ose

singleoatp ositiv einnit y

stderr

D

stdin

debugprin tlength stdout

debugprin tlevel

deriv efunctiontyp es T

describ einden tation

timedfunctions

describ elevel

traceoutput

describ eprintlength

tracedfunctionlis t

describ eprintlevel

tty

doubleoatnegati v einnit y

doubleoatp ositiv einnit y

U

undenedw arninglimit

E

eciencynotecostthreshol d

eciencynoteli mit

enclosingsou rcecuto

errorprin tlength

errorprin tlevel

G

gcinhibi tho ok

gcnotifyafter

gcnotifyb efore

gcruntime

gcverb ose

I

ignoreextraclosepa ren theses

interfacestyle

internaltimeunitsp ersecond

Typ e Index

N

nodebugblo cks

nodebugfunctionreturn s

A

nodebuginfo

nodebugvariables

ambiguousvariablename

null

and

array

O

or

B

basecharacter

P

bign um

b o olean pathname

C

S

cstring

seriousconditi on

signed

D

singleoat

stringchar

debugconditi on

struct

debugerror

stylewarning

divideb yzero

symb ol

doubleoat

systemareap ointer

E

U

enum

unhandledcon di tion

error

union

F unkno wnco delo cation

unkno wndebugvariable

xnum

unsigned

oatingp ointoverow

oatingp ointunderow

V

framefunctionmismatc h

ftyp e

void

function

W

H

warning

hashtable

I

integer

invalidvalue

L

lamb dalistuna vailable

list

M

member

Concept Index

A

actual source

advising

aliens

argumen t syntax

eciency

arithmetic

generic

arithmetic typ e inference

array typ es

sp ecialized

arrays

eciency of

assembly listing

availabili t y of debug variables

B

b enchmarking techniques

bign ums

bitvectors

eciency of

blo ck

basic

blo ck compilation

debugger implication s

start lo cation

byte co ded compilation

C

call

inline

local

numeric op erands

canonicali zati on of types

characters

clean up

stack frame kind

closures

compatibil it y with other Lisps

compilation

blo ck

units

whyto

compilation sp eed optimization qualit y

compile time typ e errors

compilele

blo ck compilation arguments

compiler error messages

compiler error severity

compiler p olicy

CONCEPT INDEX 

compiling

complemen ted typ e checks

Concept Index

conditional typ e inference

consing

overhead of

constan t folding

constan tfunction declaration

context sensitiv e declarations

continuations

implicit representation

control optimization

CPU time

interpretation of

D

dead co de elimination

debug optimization qualit y

debug variables

debugger

declarations

optimizeinterface

optimize

blo ck compilation

contextsensitiv e

defstruct typ es

derivation of typ es

descriptor representations

forcing of

descriptors

ob ject

dynamic typ e inference

E

eciency

general hints

eciency notes

for representation

verb osity

of argument syntax

of memory use

of numeric variables

ofobjects

of typ e checking

empty typ e

the

encapsulatio n

endblo ck declaration

entry p oints

external

equivalence of types

error messages

compiler

verb osity

errors

result typ e of

runtime

evaluation

debugger

existing programs

to run

expansion

inline

external entry p oints

CONCEPT INDEX 

stack frame kind

F

xnums

oating p oint eciency

folding

constant

frames

stack

free

C function

freezetyp e declaration

function call

inline

local

Function Index

function

names

tracing

typ e inference

types

G

garbage collection

generic arithmetic

H

hashtables

eciency of

I

implici t continuation representation IR

inference of types

inhibitw arnings optimization qualit y

inline expansion

interpretation of run time

interrupts

K

keyword argument eciency

L

let optimization

listing les

trace

lists

eciency of

lo cal call

numeric op erands

return values

typ e inference

lo cations

unknown

logical pathnames

M

macro expansion

errors during

mallo c

C function

mapping

eciency of

CONCEPT INDEX 

mayb einline declaration

member typ es

memory allo cation

multiple value optimization

N

names

function

NIL type

nondescriptor representations

notes

eciency

numb ers in lo cal call

numeric

op eration eciency

typ e inference

types

O

ob ject representation

ob ject representation eciency notes

ob ject sets

op enco ding

op eration sp ecic typ e inference

optimization

control

function call

let

multiple value

typ e check

optimize declaration

optimizein terface declaration

optional

stack frame kind

or union typ es

original source

P

p ointers

p olicy

compiler

debugger

precise typ e checking

pro cessing path

proling

R

read errors

compiler

recording of inline expansions

recursion

self

tail

represen tation eciency notes

ob ject

rest argumen t eciency

return values

lo cal call

run time

interpretation of

S

safety optimization qualit y

CONCEPT INDEX 

search lists

semiinli ne expansion

severity of compiler errors

source lo cation prin ting

debugger

sourcetosource transformation

space optimization

space optimization qualit y

sp ecialized arraytypes

sp ecialized structure slots

sp eed optimization qualit y

stack frames

stack numb ers

startblo ck declaration

static functions

strings

structure types

eciency of

numeric slots

style recommendations

T

tail recursion

time formatting

time parsing

timing

trace les

tracing

transformation

sourcetosource

tuning

typ e checking

at compile time

eciency of

optimization

precise

weakened

typ e declarations

variable

Typ e Index

typ e inference

dynamic

typ es

alien

equivalence

foreign language

function

in python

numeric

p ortabilit y

restrictions on

sp ecialized array

structure

uncertainty

U

uncertain tyoftypes

undened warnings

union ortyp es

unix interrupts

pathnames

unkno wn co de lo cations

CONCEPT INDEX 

unreachable co de deletion

unused expression elimination

V

validit y of debug variables

values declaration

Variable Index

variables

debugger access

nondescriptor

vectors

eciency of

verb osity

of eciency notes

of error messages

Virtual Machine VM or IR representation

W

weakened typ e checking

word integers