Burke_et_al-NIL_Reference_Manual_0286-1984
Burke_et_al-NIL_Reference_Manual_0286-1984
Burke_et_al-NIL_Reference_Manual_0286-1984
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>NIL</strong> <strong>Reference</strong> Manu<strong>al</strong><br />
corresponding to<br />
Release 0.286<br />
January <strong>1984</strong><br />
Glenn S. <strong>Burke</strong><br />
George J. Carr<strong>et</strong>te<br />
Christopher R. Eliot<br />
This report describes ongoing research at the Laboratory for Computer Science of the<br />
Massachus<strong>et</strong>ts Institute of Technology. Support for this research was provided by the Defense<br />
Advanced Research Projects Agency of the Deparuncnt of Defense monitored by the Office of<br />
Nav<strong>al</strong> Research under contract NOO015-75-C-066 1 and N00014·83-K -0125. and by Digit<strong>al</strong><br />
. Equipment Corporation of ~1aynard Massachus<strong>et</strong>ts, with grants of equipment.<br />
CA~1BRIDGE<br />
MASSACHUSJ:n's INS1TruTEOFTECHNOJ.OGY<br />
LABORATORY FOR COMPUTER SCIENCE<br />
MASSACHUSErrS 02139
• • ~ ~ ~ • ~ .. ¥~ • ..'<br />
Abstract<br />
This document describes <strong>NIL</strong>. a New Implementation of Lisp. <strong>NIL</strong> is currently under<br />
development on the DEC VAX under the VAX/VMS operattng system.<br />
Acknowledgments<br />
The chapter on defstruct is a worko\'er of. the chapter appearing in [3]. by Alan Bawden:<br />
added in(lcclIracies are solcly the nUllt of GSB. howe\ er. The chapter on the loop maCfO is a<br />
revision of an earlief published memo [5] which <strong>al</strong>so has appeared in I -isp Machine manu<strong>al</strong>s [12].<br />
'1l1e chaptef on flm'ors was written in part by Patrick SobaIvarro.<br />
documentation are the work of Christopher Eliot.<br />
The editor and its<br />
The interfaces to many functions and .fc'lcilities. and somc of the terminology used in this<br />
document. ~lre taken or derived from thosc used in the ('0\1:\10' I.lSP manu<strong>al</strong> [1]: in particular.<br />
the tCl1llinology llsed for describing scopc and ex/clll in chapter J.<br />
The section on format (section 19.6. page 187) is a reworking of a chapter appearing in [3].<br />
pans of which had earlier appeared in [12] and are the work of Guy Sleele.<br />
Dedication<br />
This publication is dedicated to Randy Davis, may his 750 never crash.<br />
Note<br />
Any comments, suggestions, or criticisms will be welcomed.<br />
n<strong>et</strong>work mail to BUG-<strong>NIL</strong>@MIT-MC.<br />
Please send Arpa or Chaos<br />
Those not on the Arpan<strong>et</strong> may send U.S. mail to<br />
Glenn S. <strong>Burke</strong><br />
Laboratory for Computer Science<br />
545 Technology Square<br />
Cambridge, Mass. 02139<br />
The Arpa n<strong>et</strong>work mail distribution list for announcements pertaining to f\;Il is norm<strong>al</strong>ly used<br />
for announcements about the facilities described here. Contact the author to be placed on it.<br />
- ... - ~ • • - "'~ < ,poo"!, 1.", .... ~ •<br />
'" ~ '" . ~ ~<br />
- • ~ .~~ '" • ~·"'A - - # ~ \ • ~ •• ~<br />
- - (', .<br />
_ 'II: ... • _ '....-v ,
Document History<br />
Earlier versions of this document were distributed as <strong>NIL</strong> Noles for Release 0 (in two revisions).<br />
and <strong>NIL</strong> Noles for Release 0.159. This update corresponds to <strong>NIL</strong> release 0.286, Lisp. system<br />
version 286. It will be revised and reissued with each new Nll. release; because of the constant<br />
changes, it is not the picturc·pcrfcct copy we would like.<br />
Addition<strong>al</strong> Publications<br />
This manu<strong>al</strong>, and other pubJic~ltions~ arc available from the J.ab for Computer Science<br />
Puhlicmions office<br />
MIT LCS Publications<br />
545 Technology Squa~e<br />
Cambridge. MA 02129<br />
who should he contacted directly k)r bibUogr
<strong>NIL</strong> Manu<strong>al</strong><br />
Summary Table of Contents<br />
Sunlmary rrable of Contents<br />
1. Introduction .<br />
2. Dak1 Types.<br />
3. Scope. Extent. and Binding .<br />
4. Predicates ..<br />
5. Programming Constructs .<br />
6. Declarations .<br />
7. Sequences<br />
8. I.isis .<br />
9. Symhols<br />
10. Numbers<br />
11. Characters.<br />
12. Arrays.<br />
13. Strings.<br />
14. Hashing.<br />
15. Packages<br />
16. Defstruct<br />
17. The LOOP Iteration Macro<br />
18. The Flavor Facility<br />
19. Input. Output. and Streams<br />
20. Syntax. . .<br />
21. Debugging and Melering<br />
22. Errors. .. . .<br />
23. Environment Enquiries<br />
24. Compilation. .<br />
25. Introduction to the STEVE editor .<br />
26. The Patch Facility.<br />
27. T<strong>al</strong>king to <strong>NIL</strong> ....... .<br />
28. Peripher<strong>al</strong> Utilities. . . . . .<br />
29. Foreign Language Interface.<br />
30. What Will Break ..<br />
<strong>Reference</strong>s. ..<br />
Concept Index. . .<br />
Message Index. . .<br />
Resource Index . •<br />
Variable and Constant Index. . .<br />
Function, Macro, and Speci<strong>al</strong> Form Index . .<br />
1<br />
3<br />
.11<br />
.16<br />
.22<br />
.41<br />
.48<br />
.56<br />
.65<br />
.71<br />
.94<br />
103<br />
112<br />
118<br />
121<br />
125<br />
144<br />
170<br />
179<br />
213<br />
220<br />
· 229<br />
232<br />
· 243<br />
· 249<br />
280<br />
· 287<br />
295<br />
· 298<br />
· 301<br />
· 307<br />
· 308<br />
· 310<br />
· 311<br />
312<br />
· 314<br />
23-DEC-83
T.lbJc of Contents<br />
ji<br />
<strong>NIL</strong> Manu •• 1<br />
Table of Contents<br />
1. Introduction. . .<br />
1.1 Conventions .. . . . . . . . . . . .<br />
2. I )<strong>al</strong>~1 Types . . .<br />
2.1 Numbers ....<br />
2.1.1 Rarillfl<strong>al</strong>s. . .<br />
2.1.2 "'loafing-point Numbers ..<br />
2.1.] Complex Numbers.<br />
2.2 Characters . . . .<br />
2.3 Symhols . . . . . • . .<br />
2.4 l.ists c:md Conscs . . .<br />
2.5 Armys and Sequences.<br />
2J) Structures. . . . . . .<br />
2.7 Functions .•.....<br />
2.8 Random .mern<strong>al</strong> Types. .<br />
2.8.1 Minisubrs •.•..•.<br />
2.8.2 Modules. . . . . . . .<br />
2.8.3 I nlernaJ Markers. . . .<br />
2.8.4 Unused Types. . . • .<br />
2.9 Coercion . • . . . • . • .<br />
3. Scope. Extent. and Binding •<br />
. . . . .<br />
. . . .- .<br />
. . . . .<br />
. ,. . . . .<br />
... 1<br />
. 1<br />
. 3<br />
. .•. 3<br />
. . 3<br />
· .. 4<br />
· .. s<br />
. . s<br />
· .. 6<br />
· 6<br />
· 7<br />
· 7<br />
. ...... 7<br />
· 8<br />
· 8<br />
· 8<br />
. . . . . . 8<br />
...... 9<br />
. ... 9<br />
. . . . . .<br />
. . . . .<br />
3.1 '..41mbda Application . . . . . . . . 11<br />
13<br />
4. Predicates. . • . . . • • • .<br />
4.1 Type Predicates ..... .<br />
4J.l Type Specifiers .... .<br />
4.1.2 Gcner<strong>al</strong> Type Predicates •.•<br />
4.1.3 Specific Type Predicates .•<br />
4.2 Equ<strong>al</strong>ity Predicates • • • • • .<br />
.- .<br />
· . . . .. . . .<br />
5. Programming Constructs . • • . . . • • •<br />
5.1 Compositions. • • • . .. • • • . • . • • • .<br />
5.2 Definition Fonns. • • • • . • • . • • • •<br />
5.2.1 Defining Functions. • . • • . . • • . •<br />
5.2.2 Defining Macros. • • • . . . • •<br />
5.2.3 Defining Variables. • . • •••••<br />
5.2.4 ControHing Ev<strong>al</strong>uation TIme. • . • . • • • . . •<br />
5.3 Binding and Assignment . . • • • . • • . • • • . •<br />
5.3.1 Dynamic<strong>al</strong>ly Binding Variable Variables ..•.•<br />
5.4 Condition<strong>al</strong>s . . . • . • . . • . • • . . • . . •<br />
5.5 Function Invocation. • • •<br />
5.6 Iteration Constructs. • • •<br />
5.6.1 Mapping Functions ..<br />
5.6.2 Othcr Iteration Forms •<br />
5.6.3 BJock and Tagbody. . .<br />
.<br />
. .<br />
. . . . . .<br />
. . . . . .<br />
· . . . . . . .<br />
· . . .. . . . .<br />
.'. .<br />
· . . . . . .<br />
· . . . . . . .<br />
· .. . .<br />
· . . . . · . . . . . . . . ... .<br />
. . . . . . .. . . . . . . .. . . . . . . . .<br />
.. . . . . . . . . . . . . . . . . . . . . .<br />
e. • • • • • • • e" • • • • • • • • • • • • • • •<br />
. . . . .<br />
. . . . . .<br />
. . . . . .<br />
16-<br />
16<br />
16<br />
18<br />
18<br />
20<br />
22<br />
22<br />
22<br />
22<br />
23<br />
24<br />
2S<br />
2S<br />
27<br />
28<br />
30<br />
31<br />
31<br />
32<br />
34<br />
23-DEC-8J
Nil. Manu<strong>al</strong><br />
iii<br />
Table of Contents<br />
5.7 Non-I.ocat Flow ufControI ..<br />
5.8 Multiple V<strong>al</strong>ues ....<br />
5.9 Gener<strong>al</strong>ized Variables<br />
5.10 Property Lists ...<br />
6. Declarations . . . . . . . .<br />
6.1 Loc<strong>al</strong> Declarations . .<br />
6.1.1 The Speci<strong>al</strong> Declaration . . .... .<br />
6.l.2 Declarations Affecting Vari~lble Bindings.<br />
6.1.3 Declarations Affecting Compilation Strategies . .<br />
6.2 Proclamations: Giuhat Dechlrations<br />
6.3 Declaring the Types of ronns. . .<br />
7. Sequences . . . . . . . . . .<br />
7.1 Accessing Sequences .... .<br />
7.2 Creating New Sequences .... .<br />
7.J Searching through Sequenccs .. .<br />
7.4 M iscelJaneolls Operations on Sequences.<br />
7.5 Iteration over Sequences ..... .<br />
7.6 Sorting Sequences . . . . . . .. . . . .<br />
8. Lists . . . . . . . . . . . . . . . . . . .<br />
8.1 Creating. Accessing, and Modifying List Structure.<br />
8.2 Substitution . . .<br />
8.' lJsine f .~sts as S~ts<br />
8.4 Association Lists . .<br />
9. Symbols ...... .<br />
9.1 The Property List ..<br />
. 9.2 Thc Print Name ..<br />
9.3 Creating Symbols ..<br />
9.4 The V<strong>al</strong>ue and Function Cells.<br />
9.5 Addition<strong>al</strong> Names . . .<br />
9.6 Symbol Concatcntation ..<br />
9.7 Intern<strong>al</strong> Routines. . • . .<br />
10. Numbers •.......<br />
10.1 Types. Contagion, Coercion. and Confusion.<br />
10.1.1 The Types . . . . . . . .<br />
10.1.2 Contagion and Coercion.<br />
10.1.3 Confusion ....... .<br />
10.2 Predicates on Numbers ..<br />
10.3 Comparisons on Numbers. .<br />
. 10.4 Arithm<strong>et</strong>ic Operations ...<br />
10.5 Irration<strong>al</strong> and Transcendent<strong>al</strong> Functions.<br />
10.5.1 Exponenti<strong>al</strong> and I.ogarithmic Functions ..<br />
10.5.2 Trigonom<strong>et</strong>ric and Related Functions. . .<br />
10.6 Numeric Type Conversions •........<br />
10.7 Integer Convcrsion and SpeciaJized Division. . .<br />
35<br />
36<br />
38<br />
39<br />
41<br />
41<br />
43<br />
44<br />
45<br />
46<br />
47<br />
48<br />
49<br />
50<br />
51<br />
52<br />
54<br />
55<br />
56<br />
56<br />
. ..... 60<br />
61<br />
63<br />
65<br />
65<br />
66<br />
66<br />
68<br />
69<br />
70<br />
70<br />
71<br />
71<br />
71<br />
72<br />
72<br />
73<br />
. .... 73<br />
74<br />
76<br />
76<br />
77<br />
78<br />
79<br />
23-DEC-83<br />
, .... , j
T~lble ofC(}ntcnt~<br />
iv<br />
N II. M~l1lwtl<br />
10.8 I.ogic<strong>al</strong> Operations on Numbers .<br />
]0.9 Byte Manipul~ti()n Functions.<br />
10.10 Random Numbers .....<br />
10.11 Fixnum-Only Arithm<strong>et</strong>ic ..<br />
10.11.1 Comparisons. ..... .<br />
10.11.2 Arithm<strong>et</strong>ic Operations ..<br />
10,11.3 Bits and Bytes. . .. . .<br />
10.11.4 'Inc Super-Primitives ..<br />
10.12 Double-Float-Oniy Arithm<strong>et</strong>ic ...<br />
10.13 Decomposition of Floating Point Numbers . .<br />
10.14 Implementation Constants<br />
11. Characters. . . . . . . . . . .'. . . . . .<br />
] 1.1 Pred icates on Ch.lractcrs. . . . . . .<br />
11.2 Ch
<strong>NIL</strong> Manu<strong>al</strong><br />
v<br />
Table of Contents<br />
16. Dcf.~truct . . . . . .<br />
16.1 Introduction .....<br />
16.2 A Simple Examplc<br />
16.3 Syntax of def.~truct<br />
16.4 Options to defstruct. .<br />
16.4.1 :type. . . . .<br />
16.4.2 :constructor .<br />
16.4.3 :<strong>al</strong>tcrant .<br />
16.4.4 :namcd..<br />
16.4.5 :prcdicatc<br />
16.4.6 :print ..<br />
16.4.7 :dcfault-pointcr<br />
16.4.8 :conc-name. .<br />
16.4.9 :inc1ude .... .<br />
16.4.10 :copier .... .<br />
16.4.11 :class-symboJ ..'<br />
16.4.12 :sfa-function<br />
16.4.13 :sfa-name ..<br />
16.4.14 :sizc-symbo1.<br />
16.4.15 :size-macro . .- .<br />
16.4.16 :initi<strong>al</strong>-offs<strong>et</strong><br />
16.4.17 : but-first . .<br />
16.4.18 :c<strong>al</strong>lablc-acccssors..<br />
i6.4J9 :evai-when ......... .<br />
16.4.20 :property .... .<br />
16.4.21 A Type Used As An Option .<br />
16.4.22 Other Options ..•.....<br />
16.5 The dcfstrucl-dcscriplion Structurc<br />
16.6 Extensions to dcfstruct . . . . . .<br />
16.6.1 A Simple Example ...... .<br />
16.6.2 Syntax of defstruct-definc-type .<br />
16.6.3 Options to defstruct-define-type.<br />
16.6.3.1 :cons . . . .<br />
16.6.3.2 :ref....<br />
16.6.3.3 :predjcate.<br />
16.6.3.4 :overhead.<br />
16.6.3.5 :named . •<br />
16.6.3.6 : keywords . .<br />
16.6.3.7 :defstruct-options • •<br />
16.6.3.8 :dcfstruct ..•...<br />
16.6.3.9 :copier . . . . . . .<br />
16.6.3.10 :implcmentations. .<br />
. .',.<br />
. : .<br />
. . '.<br />
· .. 125<br />
· . 125<br />
· .. 125<br />
· . 126<br />
· . 127<br />
· .. 127<br />
· 128<br />
· 129<br />
· .. 131<br />
· .. 131<br />
· 131<br />
.132<br />
.132<br />
· 133<br />
· .134<br />
· 134<br />
· 134<br />
· 135<br />
.135<br />
· .135<br />
.135<br />
.... 135<br />
. . . .. .136<br />
.136<br />
.136<br />
.136<br />
.137<br />
.137<br />
.138<br />
· . 138<br />
· .139<br />
· •. 139<br />
.139<br />
· ...•. 140<br />
· . 141<br />
.141<br />
· ••••• 141<br />
.142<br />
.142<br />
· .142<br />
· .143<br />
. .•. 143<br />
17. The LOOP Iteration Macro<br />
17.1 Introduction. . . . . . . .<br />
17.2 Clauses. . . . . . . .' . .<br />
17.2.1 Itcration-Driving Clauses ....<br />
· ..... 144<br />
· .144<br />
.145<br />
· .. 146<br />
23-DEC-83<br />
~.r~ ~ _ ~ ,,~~~C w' " •<br />
., -' - _ - ': .w ~ ~ -r' ~"" _ ~"_ ..-.<br />
, . ,<br />
-- - - ~<br />
~~. ~,,, ,'" ~ ~ .'
'I' •• hlc of C()ntcnt.~<br />
vi<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
17.2.2 Bindings .....<br />
17.2.3 Entr~mce and Exit.<br />
17.2.4 Side Effects.<br />
17.2.5 V<strong>al</strong>ues ..... .<br />
17 .2.6 Endtest.~ . . . . .<br />
17.2.7 Aggregated Boolean Tests.<br />
17.2.8 Condirion<strong>al</strong>il.ation . . ..<br />
17.2.9 Miscellaneous Other Clauses<br />
17 J I.oop Synonyms ..<br />
17.4 Data Types . . . • . . .<br />
17.5 Dcstructuring •.....<br />
17.6 'I'hc Itcrcllion Framework<br />
17.7 Iteration Paths. . . . . • , .<br />
17.7.1 Prc-Defined Paths ...<br />
17.7.1.1 The Interned-Symbols Path<br />
17.7.1.2 Seq uence Iteration. ... . . . .<br />
17.7.2 Defining Paths ....... .<br />
17.7.2.1 /\ 11 Example Path Definition .<br />
18. Thc rlavor Facility. . . . . . . • ..<br />
18.1 Introduction. . . . . . . . . . . . . • . . .<br />
18.1.1 Object-oriented Programming ......•.•.<br />
18.1.2 Objcct-oriented Programming Using flavors.. . .<br />
IR.2 System-nefincci M~AAges . ... . ..<br />
18.3 Message Defaults . . . . . ....<br />
19. Input. Output, and Streams.<br />
19.1 Standard Streams ....<br />
19.2 Strcam Creation and Operations ...... .<br />
19.3 Input Functions. • . •...<br />
19.3.1 Ascii Input. . 0 • 0 • • • • • 0 ••<br />
19.3.2 Binary Input . • • 0 • • • • • 0 ••<br />
19.4 Output Functions. . •.•..• 0 ••<br />
19.4.1 Ascii Output . . • . • • . • 0 • • • • ••<br />
19.4.2 Binary Output ....••..•..•..<br />
19.5 Fonnatted Output ....<br />
19.6 Format 0 • • • • 0 • • •<br />
19.6.1 The Operators • 0 0 •<br />
19.6.2 Defining your own ..<br />
. ..<br />
19.7 Qucrying the User 0 •• 0<br />
19.8 FHesystem Interface 0.' 0.' • • •••••<br />
19.8.1 Pathnarnes • . • • • . .. • • • • . • • . . . .<br />
19.8.1.1 Pathnarne Functions. '0 • • • •••••<br />
19.8.1.2 Merging and Defaulting •••••...••••<br />
19.8.2 Opening Files. . • . . • •.•••<br />
19.8.3 Other File Operations. . ..•.<br />
19.8.4 File Matching. • . • . . •<br />
· . 149<br />
· .. 150<br />
· . lSI<br />
· .. 151<br />
· 153<br />
· 154<br />
· 154<br />
· . 156<br />
· .. 157<br />
· 157<br />
· .. 158<br />
· 159<br />
· .. 161<br />
· . 162<br />
· 162<br />
· .. 163<br />
• }()4<br />
· .. 167<br />
· . 170<br />
· .. 170<br />
· .. 170<br />
· .. 171<br />
· 176<br />
· . 177<br />
· .. 179<br />
.179<br />
· .180<br />
. .•.. 183<br />
· . 183<br />
.184<br />
· 184<br />
· .. 185<br />
· .• 186<br />
· ..• 186<br />
• • 187<br />
· .. 188<br />
• • 194<br />
· . 197<br />
· .197<br />
· ... 198<br />
· •• 199<br />
· ..• 200<br />
· .. 202<br />
• .. 203<br />
• •• 204<br />
23-DEC-83
_...... L • ~<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
vii<br />
Table of Contents<br />
19.8.5 Loading files .................... .<br />
19.8.6 filc Attribute Lists ................ .<br />
19.8.7 Intcrn<strong>al</strong>s for VMS Record Management Scrvices .... .<br />
19.8.7.1 Data Stnlcturcs ...... .<br />
19.8.7.2 RMS and Related Hacking. ...... .<br />
19.9 Tcrmin<strong>al</strong>llO ............... .<br />
19.9.1 Modifying the Termin<strong>al</strong> Characteristics ..<br />
19.9.2 Making More Tennin<strong>al</strong> Streams<br />
. ~. .<br />
19.9.3 Display 'ITY Mcssages ..<br />
20. Syntax ........... .<br />
20.1 What the Reader Tolerates.<br />
20.1.1 Backquote . .<br />
20.2 'Inc Lisp Reader ... .<br />
20.2.1 Introduction ... .<br />
20.2.2 Reader Extensions.<br />
20.2.3 Readtable . . . '. .<br />
20.2.4 Alternative Syntax .<br />
21. Dcbugging and Mctering<br />
21.1 I-low of Control ....<br />
21.1.1 Tracing. . . . . . .<br />
21.1.2 Who does Wha~ and Where.<br />
21.2 Examining Objects . . . .<br />
21.3 Ucbug and Breakpoints . .<br />
21.4 M<strong>et</strong>ering ...... .<br />
21.4.1 Timing. . . . . .<br />
21.4.2 Function C<strong>al</strong>ling .<br />
21.5 System Management<br />
21.5.1 An example . • .<br />
21.5.2 "Source (Re)Compilation" ..<br />
21.5.3 Information in Modules<br />
21.5.4 Related Utilities .<br />
21.6 Verification . . • • • •<br />
22. Errors .....•...•<br />
23. Environment Enquiries<br />
23.1 The Host Environment . •<br />
23.2 Mac1isp-Compatihle Status Enquiries .<br />
23.3 Privileges. . . • .<br />
23.4 Memory Usage . . • . . .<br />
23.5 Time and Date . • • . . •<br />
23.5.1 The Main Functions • • •<br />
23.5.2 Printing Dates and Times.<br />
23.5.3 Namings. . . . . • . • •<br />
23.5.4 Timezones. . . . . . . .<br />
23.5.5 Miscellaneous Other Functions.<br />
· .204<br />
· .205<br />
.207<br />
· .207<br />
· .208<br />
.209<br />
· . 211<br />
· .211<br />
· .212<br />
. ...... 213<br />
· . 213<br />
· .216<br />
.217<br />
. .. 217<br />
· .218<br />
· .218<br />
· .219<br />
. 220<br />
· .220<br />
· .220<br />
.221<br />
· .222<br />
.222<br />
.223<br />
.223<br />
· .224<br />
· .226<br />
· . 226<br />
.227<br />
.228<br />
.228<br />
.228<br />
.229<br />
· 232<br />
.232<br />
• ......... 232<br />
· 233<br />
· 234<br />
.234<br />
.235<br />
.235<br />
• . 236<br />
.238<br />
.238<br />
23-DEC-83<br />
".... . ~<br />
• ~ - - - ~ ~ • • "... - j<br />
. .'<br />
. , . . - ' .<br />
• • _ _ _ •• ~_ o. • ~<br />
~ , • _ " • _. • • _ _ ". •<br />
'.<br />
• • •
Table of Contents<br />
viii<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
23.5.6 Variations in Daylight Savings Time. . . . . . .<br />
23.5.7 Intern<strong>al</strong> Conversions . '0 0 ........ 0 0 0<br />
23.5.8 Brain Damage . . 0<br />
23.6 Job/Process and System Infonnation. . . . •<br />
• • • • • • • • • • • • • " • • •<br />
24. Compilation . . . . . . . . . . . . . . • . . .<br />
24.1 Interaction Control. . . . • . . . . . . . . .. . . .<br />
24.2 Efficiency. Optimization, and Benchmarking .•.•<br />
.239<br />
... 240<br />
. .240<br />
.241<br />
.243<br />
. 246<br />
.246<br />
249<br />
25. Introduction to thc STEVE editor ..... • 0 • • • • •<br />
25.1 Introduction. . . . . • . • . .. . . . . . . . . 249<br />
25.2 Gctting Started • . . . . . . . . . . . . . . . 249<br />
25.3 Editing Files ... 0 • • • • • • • • 250<br />
25.4 Modifying the buffer. . • • . • . • . 254<br />
25.4.1 The Simplest Commands . . • . . . . . . . . . . 254<br />
25.4.2 Now that you know the Simplest Commands . • . . . . 255<br />
25.4.2.1 Numeric Arguments" .•.... • · • . . . . . . • . . . . .. 255<br />
25.4.2.2 Control-X. . . . . . • . • 0 0 • • • • ". • • • • • • • • • • • • • • • •<br />
25.4.2.3 Mcta-X and Control-M<strong>et</strong>a-X. . . . . . . . . . . . . .<br />
256<br />
. 256<br />
25.4.2.4 Marks and Regions. . . . . . . . . . . . . . . . . . . . . . . . . . 257<br />
25.4.2.5 KiUing and Un-kiJIing . • . . eo • .. • • • • • • • • • • 0 0 • • • • • • • • •<br />
25.4.2.6 List Oriented Commands. • . . • . · • • . . . . . . .<br />
257<br />
. 258<br />
25.4.2.7 *more* • . . . . • · . • . . • • . . . . . • . . . . . . . . . . . 258<br />
25.4.2.8 Aborts. . ." . . . • • • • • . • . . . . '. . • . . . . . . • . . • . . . . . 258<br />
25.5 Major Modes . . . . • . 0 • 0 • • • • • • • • • 0 • • • • • • • • 0 • 0 •<br />
25.6 Help and Self Documentation • • • . • . . • . . . .. • . • . • . . . . . . . .<br />
258<br />
. 259<br />
25.7 GJossaryofCommands • ..• • • • 0 • 00 0 • • •• 0 • • • • • • • • .260'<br />
25.7.1 Speci<strong>al</strong> Character Commands .... • .... 0 •••••• 0 ••• 0 • 261<br />
261<br />
25.7.2 Contro) CharaclerCommands ... 0 • • • • • • • • • • • • • • • • •<br />
25.7.3 M<strong>et</strong>a Key commands. . . . . . • . . . . • . • • . • • . . . . . . • 264<br />
25.7.4 Control-M<strong>et</strong>a Commands ..•. 0 •• • • • • • • • 0 • • • • • •• 0 266<br />
25.7.5 Control-X Commands. .•. • • · 0 • • • • • •••••••••••••••••• 268<br />
25.7.6 M<strong>et</strong>a-X Commands. . . 0 • • • • • • 0 • • • • • • • • • • • • • • • • • • • • • 271<br />
25.8 Extending the Editor. . • • • • . . • • • • . • . • . • • • • • • . • • • • . . . 0 • • • 274<br />
25.8.1 Editor Functions • 0 • • • • • • • • • • • • • • • • • 0 • • • • 0 • • • • • • • • 0 0 • • 274<br />
25.8.2 Editor Objects • . • • . • • • • • • • • • • • • • • • • 0 • • • • • • • 275<br />
25.8.3 Other Functions and Conventions. 0 • • • • • • • • • • • • • • 0 • 0 • • • • • 277<br />
26. The Patch Facility. • . • • • • • • • • • • • • • . • • • • • 0 • • • • • • • • • • 0 280<br />
26.1 User Functions . . . • • • • • • • • • . . • • • • • 0 • • • • • • • • • 0 • • • • • • • • • 281<br />
26.2 Patch System Infonnation • . . • • 0 • • • • • 0 • • • • • • • • • 0 • 0 • • 0 0 • • 282<br />
26.3 Adding Patches . . . . • • . • • • • • • • 0 • • • • • • • • • 0 • • • • • • • • 282<br />
26.4 Defining Patch Systems. • •• • • • • . • • • • '0 • • • • • • • • • • • • • .284<br />
27. T<strong>al</strong>king to <strong>NIL</strong> •• · • • · • • • • • • · • . • . • • • • • • • • • • • • . • • • . • . . • . 287<br />
27.1 Stanup • • •. • .• • • .• • • • • . • . . • • • • •••..• 0 • 0 • • • 287<br />
27.2 The Toplevel Loop. . • 0 • • • • • • • • • • • • • • • • • • • • • • • • • • 288<br />
27.3 Entering and Exiting <strong>NIL</strong> • . • • • · • • • . . • • • . • . . . . • • •. . . 288<br />
23-DEC-83
-<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
ix<br />
Table of Contents<br />
27.4 VMS .. 0 .. 0 ..•.• 0<br />
27.5 Inst<strong>al</strong>lation . . . . . 0 • • •<br />
27.6 How the <strong>NIL</strong> Control Works<br />
28. Peripher<strong>al</strong> Utilities. . . . .<br />
28.1 The Predicate Simplifier ...<br />
28.2 A Mini-MYCIN. 0 0 ••••<br />
28.3 Mac1isp Compatibility for Macsyma. .<br />
29. Foreign Language Interface ..<br />
29.1 Introduction. . . . . . . . .<br />
29.2 Kernel and System-Services 0<br />
29.3 VMS object files ...<br />
29.4 Data Conversion ..<br />
29.5 lower level routines .<br />
30. What Will Break ....<br />
30.1 What Broke Since Release 0.259. . .<br />
30.2 Future Changes. . 0 • 0 • 0 • 0<br />
30.2.1 Default floating-Point Fonnat .<br />
30.2.2 New Package facility .. 0 0 . 0 •<br />
30.2.3 Vector-push and Vector-push-extend 0 •<br />
30.2.4 Multiple V<strong>al</strong>ues .. 0 • 00 •• 0<br />
30.2.5 Variable Naming Conventions 0 0<br />
,0 ").6 Otlrhaee Col1~ction. .<br />
30.2.7 Error System. 0 •<br />
<strong>Reference</strong>s. 0<br />
Concept Index.<br />
Message Index.<br />
• • 0<br />
Resource Index . 0<br />
Variable and Constant Index. •<br />
Function. Macro. and Speci<strong>al</strong> Fonn Index • • •<br />
• 0 291<br />
0290<br />
o .293<br />
· . 295<br />
· .• 295<br />
• 0 • 296<br />
· .297<br />
· .298<br />
· • 298<br />
· 0298<br />
· .. 299<br />
• 0 299<br />
· . 300<br />
· • 301<br />
. ..... 301<br />
....• 303<br />
· . 303<br />
.303<br />
• 0 303<br />
. 303<br />
· .305<br />
.30S<br />
o 0 305<br />
o 0 307<br />
o 0 0 308<br />
• 0 0 310<br />
· •. 311<br />
o 0 • 312<br />
.•.• 314<br />
23-DEC-83
---------------------------------------------------------------------------------------
<strong>NIL</strong> Manu<strong>al</strong> 1 Introduction<br />
1. Introduction<br />
<strong>NIL</strong>. which stands for New Implementation of Lisp. is a di<strong>al</strong>ect of LISP which runs on the<br />
DEC VAX. <strong>NIL</strong> currently runs under the VMS operating system. It will likely be converted. to run<br />
under U~lX (TM) at some point, but there is no effon underway to do so right now.<br />
<strong>NIL</strong> is a di<strong>al</strong>ect of CO\1MON LIst). COMMOJ\ LISP is essenti<strong>al</strong>ly a form<strong>al</strong> specification of the<br />
LISP language such that programs which confonn to that specification may be transported without<br />
modification from one CO\1\10~ LISP implementation to another, and be expected to run<br />
compatibly. As of this writing. the CO\1\f0~ liSP manu<strong>al</strong> has just gone to press: this manu<strong>al</strong> has<br />
therefore den'loped into documentation of a subs<strong>et</strong> of C()\1\tO~ IISP facilities which are currently<br />
supported by :\11.. and a large number of ~II -specific things.<br />
This document schi/ophrenic<strong>al</strong>l, attempts to cover three areas. One is "primer"<br />
document.ation: those things which must be known for any programming to g<strong>et</strong> done. In this<br />
case. aucmpts arc made to point out what of these things are ('0\1\10:\ LISP compatible. Another<br />
is the s<strong>et</strong> of things which migl;~ he expec-ted to change incompatihl), du£' to (,0\1\10' liSP<br />
conversion. The third is those wllich are part of the :\11 core Virtu<strong>al</strong> lllac/till£'. as it is heing<br />
de\cloped more fonn<strong>al</strong>ly. These include. for example. functions like %string - replace. \\hkh are<br />
sUiLtble low-level primitives for a VAX (or other byte-machine. like perhaps an 1B\1-J70) to<br />
provide. Lastly, there are certain parts of ~IL which have undergone large amounts of recent<br />
development. and are fairly stable. and which· may provide function<strong>al</strong>ity for lIsers in various<br />
domains: the 1/0 system. for example. Much of the pro\'ided documentation will he of things<br />
witidt ,uc ub!'ll:clIciy iuw-ic\'ci: ~omelimes. this is (0 point out piaces where me implementatIon<br />
f<strong>al</strong>ls short of the design: often too. to document these t(lr those who may find it useful,<br />
debugging. or in perfonning implementation-dependent activities: and occasion<strong>al</strong>ly, to explicitly<br />
note how the implementation differs from the gener<strong>al</strong> and portable semantics (as in the case of<br />
numbers and eq).<br />
1.1 Conventions<br />
All otherwise unqu<strong>al</strong>ified ration<strong>al</strong> numbers in this manu<strong>al</strong> are in decim<strong>al</strong>, not oct<strong>al</strong> (as has<br />
been the practice in certain other manu<strong>al</strong>s. notably [9] and [12]). Speci<strong>al</strong> qu<strong>al</strong>ifying syntax for<br />
forcing the interpr<strong>et</strong>ation of ration<strong>al</strong> numbers in other radices is described in section 2.1, page 3.<br />
There are a couple conventions for the fonning names of functions and variables coming into<br />
use from within the COMMON USP community.<br />
Gener<strong>al</strong>ly. variables whose v<strong>al</strong>ues are speci<strong>al</strong> and which may be modified during the course<br />
of program operation have names which begin and end with an asterisk; for instance,<br />
-package-. Lexic<strong>al</strong> variables, and constants defined with defconstant (page 24), are nonn<strong>al</strong>ly<br />
named without these asterisks. For instance, <strong>NIL</strong> defines the constants pi and most-positivedouble-float.<br />
This is a convention only and does not affect the operation of the I'lL interpr<strong>et</strong>er<br />
or compiler; however. the possibility exists tJlat (in tJIC future) the compiler will lISC the presence<br />
or ahsence of such asterisks to choose a course of action if it encounters a free reference to an<br />
undeclared variable. (Speci<strong>al</strong> and lexic<strong>al</strong> variable reference is discussed in chapter 3, page 11.)<br />
MC:NII.MAN:INTRO 18<br />
23-DEC-S3<br />
.<br />
, - ~ -<br />
,"", '.. ' .':: : ~ ..,'-. - ,: -'< c' _ . .'
Cotl\'cnliot1s 2 Nil. Manu<strong>al</strong><br />
'n1e names of predicate functions in!\u, and CO:\fMON LISP are typic<strong>al</strong>ly fi)nned by suffixing<br />
the character t~p" to the end of a descriptive name. For instance.consp is a predicate which is<br />
true if its argument is a cons~ and lessp (which actuaUy is a MACUSP. not COMMON USP.<br />
function) compares numbers and (when given two arguments) r<strong>et</strong>urns t if the first is less than the<br />
second. If the name itself is hyphenated. then "-pit is suffixed: upper-case-p is a predicate<br />
which tells if a character is upper-case. If, however. the predicate name is fonncd by prefixing a<br />
speci<strong>al</strong>izing name to an existing predicate name, then the fin<strong>al</strong> t.p" would not have hyphenation<br />
added to it: string-Iessp is a predicate can be used to compare strings using a standard collating<br />
sequence. the name heing fimned by prefixing "string-" to 'tlessp". There are. of coursc. many<br />
exceptions to this. and this convention does nOl eliminate <strong>al</strong>l ambiguity. but it helps. A goud<br />
numher of ~II functions did not fi)Uow this convention in earlier versiul1sof. ~II: many of these<br />
h~l\'e heen fixed. mld the old names made synonymous with the new names for the time being.<br />
MC:NJLMAN;INTRO 18<br />
23-DFC-83
NIl. Manu<strong>al</strong> 3 I )ata Types<br />
2. Data Types<br />
This chapter provides an overview of some of the data types used in <strong>NIL</strong>. their uses. and<br />
their syntax (their prillted representatio1l). Those not strongly familiar with LISP should go over<br />
this lightly to g<strong>et</strong> some idea of the sorts of objects which <strong>NIL</strong> offers. and proceed to the next<br />
chapter: others might want to read it anyway. to see what <strong>NIL</strong> provides which may differ from<br />
other LISP di<strong>al</strong>ects. Most of the sections here have later chapters devoted to them. which give<br />
much more compl<strong>et</strong>e infonnation on the types. how they may be used. and the functions which<br />
can manipulate them. Also. more compl<strong>et</strong>e 'information on the syntax used for these types is<br />
presented in chapter 20. page 213.<br />
2.1 Numbers<br />
The I'll. (and COM\101' LISP) hierarchy of numeric,l) types looks like this:<br />
number<br />
rationa j<br />
intE:ger<br />
fixnum<br />
bigntJm<br />
ratio<br />
float<br />
short-float<br />
siiigle float<br />
double-float<br />
long-float<br />
complex<br />
Collectively. the non-complex numbers are referred to in <strong>NIL</strong> as the type non-complex-number:<br />
the tenn re<strong>al</strong> is not used because of potenti<strong>al</strong> confusion with floating-point. Note that there is no<br />
guarantee that the above types might not be further subdivided or grouped for the convenience of<br />
the implementation.<br />
2.1.1 Ration<strong>al</strong>s<br />
The integer data type is intended to represent mathematic<strong>al</strong> integers. There is no magnitude<br />
limit on them other than that imposed by memory or addressing limitations.<br />
In <strong>NIL</strong>. those integers which can be fit in a 30 bit field in twos-complement are fixnums.<br />
which are represented in such a way that no storage is consumed. For integers not in this range.<br />
bignums are used. Generic arithm<strong>et</strong>ic functions automatic<strong>al</strong>ly choose the appropriate<br />
representation.<br />
The printed representation of integers ordinarily uses decim<strong>al</strong> notation. option<strong>al</strong>1y preceeded<br />
by a sign character and option<strong>al</strong>ly followed by a decim<strong>al</strong> point. The sharpsign reader macro<br />
(section 20.t page 214) may be used to input ration<strong>al</strong> numbers in other radices; for instance.<br />
MC:<strong>NIL</strong>MAN;TYPES 36<br />
23-DEC-83
Numbers<br />
4 <strong>NIL</strong> MimuaJ<br />
259<br />
259.<br />
#0403<br />
#blOOOOOOl1<br />
; Thc integer 259<br />
; 'Inc integer 259<br />
; entered in {l<strong>et</strong>a!<br />
; entered in binary<br />
A ratio is the type used to represent non-integer ration<strong>al</strong> numbers. It consists logic<strong>al</strong>ly' of<br />
integer components which arc its numer<strong>al</strong>or and drlllJlltillolOr (which arc accessible by functions of<br />
the same names). °rbe exteTmd intcrf,lCc is defined such that a ratio will <strong>al</strong>ways appear to be in<br />
r{'duced fonn (wh<strong>et</strong>her or not it is). and the denominator will <strong>al</strong>w,.ys be positive. (CO\1\10~ I.ISI)<br />
sei'. it can't be I.cro, infinity freaks.) 'nlC ct.rithm<strong>et</strong>ic nmtincs which de<strong>al</strong> with ration<strong>al</strong> numbers<br />
tranpar{,lltly C(}f1\"{'rt b<strong>et</strong>ween r<strong>al</strong>ios. bignums. and fixnumsas aPllfOpria\c. Ratios itrC d{'notcd<br />
separating the numerator and the denominatory by a I: thus. the ratio three-h<strong>al</strong>ves is 3/2.<br />
2.1.2 Floating-point Nunlbers<br />
CO\1MO~ LISP <strong>al</strong>lows for four kinds of floating-point representations, which must me<strong>et</strong> the<br />
filltuwing critcria:<br />
Format ~inimum PreCision Minimum Exponent Size<br />
Short 13 bits 7 bits<br />
Single 24 bits 8 bits<br />
Double 50 bits 8 bits<br />
long 50 bits 8 bits<br />
Nn !lrovid~:111 nf these fnrmat~ with th(' f(ll1(lwing specs:<br />
Type Precision Exponent<br />
short-float 19 bits 8 bits<br />
single-float 24 bits 8 bits<br />
double-float 56 bits 8 bits<br />
long-float 113 bits 15 bits<br />
The long - float type requires microcodc support to avoid software emulation.<br />
Floating-point numbers in <strong>NIL</strong> are syntactic<strong>al</strong>ly distinguished from integers in that they must<br />
have a decim<strong>al</strong> point followed by at least one digit. (This is more rigid than the COMMON USP<br />
specification.) So. for instance, 10 and 10. are both the integer ten. but 10.0 is floating-point 10.<br />
The various fonn<strong>al</strong>s of floating-point number are syntactic<strong>al</strong>ly distinguished by the use of the<br />
character used in exponenti<strong>al</strong> notation. For example. 10.OdO is double-float ten; 10.050 is shortfloat<br />
tcn. 10.010 is long-fioat ten. and 10.0e0 is single-float ten. When exponenti<strong>al</strong> notation is<br />
not used. the type of float is d<strong>et</strong>ermined by the user-modifiable variable .read-default-floatformat.<br />
(page 72). COMMON USP specifics that the default type of float is single-float, both for<br />
readin and the v<strong>al</strong>ues of various irration<strong>al</strong> or tranccndcnt<strong>al</strong> mathematic<strong>al</strong> functions when they are<br />
given ration<strong>al</strong> arguments (c.g.. sqrt). However. in <strong>NIL</strong>. the default is currently double-float,<br />
because this <strong>NIL</strong> release is the first to supply any (onnat other than double-float. The default<br />
;"ill be changed in a future release.<br />
MC:NlI.MAN:TYPES 36<br />
23-()EC-83
Nil. Manu<strong>al</strong> 5 Characters<br />
2.1.3 Complex Numbers<br />
Complex numbers in <strong>NIL</strong> represent a point in the complex plane in cartesian coordinates.<br />
Their printed representation shows these coordinates:<br />
/lC (rea/part imagparg)<br />
The re<strong>al</strong> and imaginary parts may be extracted with the reaipart and imagpart functions.<br />
The re<strong>al</strong> and imaginary components of complex numbers must both be either ration<strong>al</strong><br />
numbers, or floating point numbers of the same floating-point fonnat.<br />
Ration<strong>al</strong> numbers and complex numbers with ration<strong>al</strong> components collecti\"el~ constitute the<br />
gaussian-ration<strong>al</strong> :\11 data typc. Many. but not <strong>al</strong>l. ration<strong>al</strong> number functions ha\'e heen<br />
extended to operate on gaussian ration<strong>al</strong>s in Nil. for instimce numerator. denominator. and<br />
mod. In order to provide what we c<strong>al</strong>l a seamless ex/ellsioll of the ration<strong>al</strong> numbers to the<br />
complex plane. a gaussian ration<strong>al</strong> with a zero imaginary part is not of type complex. but just<br />
the ration<strong>al</strong> number. This interconversion may be compared with that which interconverts b<strong>et</strong>ween<br />
fixnums and bignums a~ necessary. Gaus~ian ration<strong>al</strong>s which have integer components (i.e..<br />
integers. and complex nt.:.,nbers with integer components) are the Nil type gaUSSian-integer.<br />
which is of course a subtype of gaussian-ration<strong>al</strong>. Certain integer flmctions in :'\11. have been<br />
extended to operate on gaussian integers: these include gcd. oddp. and evenp. The gaussian<br />
ration<strong>al</strong> and gaussian integer extensions in 1\11. are not defined by CO\1\10~ l.lS}>. and should<br />
therefore be considered experiment<strong>al</strong> and potenti<strong>al</strong>ly subject to change. For this reason. feedback<br />
on their usage and utility is desired in order tJlat these extensions can be ev<strong>al</strong>uated.<br />
Complex numbers with floating point components <strong>al</strong>ways have components of the same<br />
floating-point format. Such a number is <strong>al</strong>ways of type complex. even if the imaginary part is.<br />
zero.<br />
2.2 Characters<br />
<strong>NIL</strong> provides a data type for representing characters. Characters are the things one<br />
manipulates when doing "character 1/0" on streams. They are the things one g<strong>et</strong>s out of, and<br />
puts into, strings. Having a separate data type <strong>al</strong>lows them to maintain their identity within the<br />
lisp (as opposed to being an interpr<strong>et</strong>ation placed on fixnums, for instance). Chapter 11 is<br />
devoted to this.<br />
Characters in <strong>NIL</strong> use # \ syntax for input and outpu~ as shown below. Note that if the<br />
character after the # \ stands <strong>al</strong>one. it is taken liter<strong>al</strong>ly. If it occurs after a prefix such as<br />
"control- n , then it will be treated like an ordinary token, so may need to have a preceding<br />
backslash to inhibit case translation or just to <strong>al</strong>low proper token parsing.<br />
'\a<br />
: Lowercase "a".<br />
'\A<br />
; Uppercase "a".<br />
'\Control-a<br />
: Uppercase "an, with the control bit.<br />
/I\M<strong>et</strong>a-\a<br />
: Lowercase "a", with the m<strong>et</strong>a bit.<br />
Some characters have names, which may be lIsed in place of the character itself:<br />
/I\Rubout<br />
;'nle "ruhout" or "del<strong>et</strong>e" character<br />
#\Hyper-Space<br />
: The "space" character with the hyper bit<br />
MC:NIl.Mt\N:TYP~S 36<br />
23-DEC-83
Symbols 6 Nil. Manu,,1<br />
Only a subs<strong>et</strong> of <strong>al</strong>l possible characters are a110wcd to be contained in strings. These comprise<br />
the string-char d.tta type. It hClppens that in <strong>NIL</strong> these are tJlose characters which have no font<br />
or· bits attributes (both are 0).<br />
2.3 Symbols<br />
Symbols are what are used as names in lisp_ They can name functions. and variables (the<br />
two uses of which are syntactic<strong>al</strong>1y distinguishable by the . LISP ev<strong>al</strong>uator). Symbols have a 110mI'.<br />
<strong>al</strong>so c<strong>al</strong>led the print /lome or p"ome. which is a string containing the chamcters used in the<br />
printed representation of the symbol. A symbol <strong>al</strong>so has a propert)' lisl or plis! associated with it.<br />
Thi~ is a list of ailefll,lting "indicators" 411ld "\·,tlues". <strong>al</strong>lowing one to sture unidirectiun<strong>al</strong><br />
associations on the symhol. A symhol <strong>al</strong>so has a package. which points to the "name spacc" it is<br />
associated with (chapter IS. page 121)~<br />
The symbol nil is speci<strong>al</strong>. It is used both to represent booleoll folse. and the empty Jist. Its<br />
<strong>al</strong>ternate printed representation is· O. the empty Jist It has the data type null. which is both a<br />
subtype of symbol and a .subt~l)e of list and is the only object of that type. ltli v<strong>al</strong>ue is not<br />
<strong>al</strong>lowed to be changed. OtherwIse. it is lreated the S{.lme as other symbols (it h.1S a property list<br />
<strong>et</strong>c.).<br />
The symbol t is used to represcnt boolean lruth. Its v<strong>al</strong>ue is <strong>al</strong>so not <strong>al</strong>lowed to be changed.<br />
Symbols arc often used as keywords. Because of the existence of multiple namespaces<br />
(packages). t11is might present a problem because two symbols read into different namcspaces<br />
might not be the same. This is solved by haying speci<strong>al</strong> kCYM'(}rd symbols. or just keywords for<br />
short. A symbol which is typed in preceded by a colon (and nothing else) is read into the<br />
namespace (package) for keywords. Thus. an symbols so designated are the same (they are eq).<br />
Keywords are self-ev<strong>al</strong>uating, and their v<strong>al</strong>ues are not <strong>al</strong>lowed to be modjficd~<br />
NotationaUy. tokens which cannot be interpr<strong>et</strong>ed as anything else are taken to be symbols.<br />
except that tokens consisting entirely of unslashified dots are supposed to cause a syntax error~<br />
Thus. , .Oe + 4 will read as a floating-point number. but , .Oe + 4a will read as a symbol. More<br />
compl<strong>et</strong>e d<strong>et</strong>ails on input syntax are in chapter 20. page 213.<br />
2.4 Lists and Conses<br />
A cons is the type which makes LISP what it is. In simpler lisps. it may be the only data<br />
type which can be used to associate more than one object A cons makes a binary association: it<br />
has two components. its car and its cdr, which are accessed by just those functions. It is thus<br />
the datastructure of choice for representing binary trees.<br />
A list. when considered to be a data-type, is the union of the types cons and nutt-that is.<br />
it is either a cons. or the symbol nit (the empty list). That is why the <strong>al</strong>ternate printed<br />
representation of nil is O. (See section 20.1. page 214 for exposition of the printed representations<br />
of cnnses and lists.)<br />
MC:NII.MAN:TYPES 36<br />
23"DEC-83<br />
, " ,;":. i -,~;~;' ,; ',< ,~',<br />
~ "."-<br />
"':<br />
,i "~"~~'~;: co;': -- ," ,',' < :'.,:,,"" ,,' ,•••
-<br />
<strong>NIL</strong> Manu<strong>al</strong> 7 Arrays and Sequences<br />
Often, a list is a conceptu<strong>al</strong> sequence which has a discr<strong>et</strong>e end. In this context. the cdr of<br />
the last cons of the list must be nil. In text (and error messages), the phrase "proper Jist" is<br />
used to distinguish b<strong>et</strong>ween just a cons (or nil) and an actu<strong>al</strong> list whose fin<strong>al</strong> cdr is nil. For<br />
instance. the cons<br />
(a . b)<br />
is of the type list. but if given as a list argument to the member function (page 61) would cause<br />
an error which would say that it was not a proper list.<br />
2.5 Arrays and Sequences<br />
Arrays in 'II. are a ,ery geneml type. One dimension<strong>al</strong> arrays are the type vector. Arrays<br />
can he speci<strong>al</strong>ized as to the types of elemenl'i they may contain. A one dimension<strong>al</strong> array (a<br />
vector) which can only contain "string characters" (see the string-char-p function. page 19) is a<br />
string. A one dimension<strong>al</strong> array which is <strong>al</strong>lowed to hold only objects of type bit (that is. the<br />
integers 0 or 1) is a bit vector. Arrays are discussed fully in chapter 12. page 103.<br />
The type sequence is th;! union of the types list and vector. There are a large number of<br />
Sfl/UfllCf jUllctiollS in 'II. which operate on hoth Jists and vectors, \'iewing either as just a<br />
sequence of ohjects. One therefore has a\'ailahle the same gener<strong>al</strong> sequence operations. to be used<br />
on whatever particular type of datastructure was chosen for the task at hand: they may be lists,<br />
to make adding. delcting. splicing. <strong>et</strong>c.. easy, or \'ectors of a particular type suitable for the<br />
application-strings. bit vectors, <strong>et</strong>c. The functions for operating on sequences are described in<br />
ch:lpter 7, page 4R.<br />
2.6 Structures<br />
<strong>NIL</strong> provides a structure or record definition facility. This is supplied hy the defstruct<br />
function (page 125). which is essenti<strong>al</strong>ly the same one used in both MACLlSP and LISP MACHINE<br />
LJSP. In ~IL. the nonn<strong>al</strong> way defstruct is used defines a type, and the structures creatcd can be<br />
distinguished with typep. Addition<strong>al</strong>ly, such types interface to the <strong>NIL</strong> flavor system, which may<br />
be used to give them m<strong>et</strong>hods for such things as how they should print and pr<strong>et</strong>ty·print<br />
2.7 Functions<br />
There are sever<strong>al</strong> different things which can be "functions" in <strong>NIL</strong>. Most basic<strong>al</strong>ly, there is<br />
the type compiled-function (<strong>al</strong>so known as subr). This corresponds to a function created by the<br />
<strong>NIL</strong> compiler. or part of the <strong>NIL</strong> kernel. It may <strong>al</strong>so be created "on the fly" for the purpose of<br />
interfacing compiled code to interpr<strong>et</strong>ed code; in <strong>NIL</strong>, function<strong>al</strong> ev<strong>al</strong>uation of an interpr<strong>et</strong>ed<br />
function will result in an object of type compiled -function.<br />
Function<strong>al</strong> objects which implement "environment transfer" (which is discussed in a later<br />
chapter) are of the type closure. The most commonly seen speci<strong>al</strong>ization of this type is that used<br />
in the interpr<strong>et</strong>er. the type interpr<strong>et</strong>er-closure.<br />
MC:<strong>NIL</strong>MAN:TYPES 36<br />
23-DEC-83<br />
", - - ' , ',' - " -,' -'" ' '-. ' '-::'. - . ~ , '<br />
'~:~>- -, ',:: .. ':' ' ... -~ '
Random Intern<strong>al</strong> Types 8 <strong>NIL</strong> Manu<strong>al</strong><br />
2.8 Random Intern<strong>al</strong> Types<br />
Here are some of the intern<strong>al</strong>1y used types in <strong>NIL</strong> . While they should gener<strong>al</strong>ly not be seen,<br />
they may pop up on occasion either themselves or as a result of errors.<br />
2.8.1 l\1inisubrs<br />
lbe minisubr type is somewhat gratuitous: it win be flushed as a separate type someday. and<br />
its type bits reused by som<strong>et</strong>hing more uscthl. A millisubr is a speci<strong>al</strong> rOlltine within the 1'11.<br />
k~rnel: Stich routines arc caned with the VAX JSB instn.ctioll. However. they tend to have<br />
various assuned<br />
2.8.2 Modules<br />
A module. as a type. is the structure used by Nil. to contain a collection of compiled<br />
functions and the constants and jat~lstructures they ·reference. When the cumpiler compiles a file.<br />
it produces a module. When the garbagecollcctor (haha) relocates things. it rehlC,ttcs the module<br />
as a hlnck. The use of the name module for this primilhe d<strong>al</strong>Hstnlcture is it bit pr<strong>et</strong>entious .. so it<br />
will probably be c<strong>al</strong>led som<strong>et</strong>hing like compiled-code-modufe in the future.<br />
2.8.3 Intern<strong>al</strong> Markers<br />
The type si:intern<strong>al</strong>-marker is used for variolls things in 1Ioi1L. none of which should<br />
ordinarily be visible to (or touched by) the user. Objects of this type are meant to be checked<br />
for by things like the debugger and garbage-collector (to. for instance. parse stack frames). and<br />
manipulating them out of context wiUconfusc tllese programs.<br />
These objects print out as #!<br />
#fAFM-31<br />
#fPC"MARKI<br />
#!DOUBLE-FLOAT-MARK!<br />
#!NULL-ARGI<br />
followed by the name followed by!. For instance,<br />
; Stack marker for 3-arg function<br />
; c<strong>al</strong>l frame<br />
; Next slot on stack is a PC<br />
: Next two stack entries are the<br />
; representation of a double-float<br />
; Stack slot is for an argument which<br />
has not y<strong>et</strong> been computed,in a<br />
: function caU frame.<br />
MC:Nll.MAN:TYPES 36
<strong>NIL</strong> Manu<strong>al</strong> 9 Coercion<br />
2.8.4 Unused Types<br />
There are a number of unused type codes in <strong>NIL</strong>. Certain intern<strong>al</strong> routines. upon<br />
encountering them. bomb out to the VMS debugger because your <strong>NIL</strong> is then undoubtedly lOSing<br />
its lunch.<br />
2.9 Coercion<br />
coerce o~;ecl Iype<br />
If ol~;ccl<br />
is <strong>al</strong>ready of the type 1),l'e. then it is simply r<strong>et</strong>urned: otherwise, it is COI1\ ened<br />
to be of that type.<br />
Only certain forms uf coercion are defined. coerce wiJI perform coercion of one sequence<br />
type to another: its capabilities in this regard are similar to those of concatenate (page<br />
50). Note. however. that concatenate will <strong>al</strong>ways r<strong>et</strong>urn a copy of the sequence.<br />
whereas coerce will only create a new one if object is not of the proper type <strong>al</strong>ready.<br />
coerce <strong>al</strong>so <strong>al</strong>lows some non-sequence coercion< with the following types:<br />
float<br />
Coerce the object to a floating point number. If object is <strong>al</strong>ready a float, It IS<br />
r<strong>et</strong>urned: otherwise. it is coerced to the default type of float (double-float). See<br />
float. page 78.<br />
short-float<br />
single-float<br />
double-float<br />
long-float<br />
Coerce the object to that particular type of floating point number. Again. this is<br />
similar in function<strong>al</strong>ity to what may be obtained by giving float a second<br />
argument.<br />
complex<br />
object. which must be a number. is coerced to a complex number. If it is<br />
<strong>al</strong>ready complex. it is r<strong>et</strong>urned. If it is ration<strong>al</strong>, it is <strong>al</strong>so r<strong>et</strong>urned; this is<br />
because complex numbers with ration<strong>al</strong> components and a lero imaginary part are<br />
automatic<strong>al</strong>ly reduced to ration<strong>al</strong>s. If, however. it is a floating-point number,<br />
then a complex number with object as its re<strong>al</strong> component and a floating-point zero<br />
of the same fonnat as object as its imaginary component, is r<strong>et</strong>urned.<br />
(complex float)<br />
(complex short-float)<br />
(complex single-float)<br />
(complex double-float)<br />
(complex long-float)<br />
Effectively, these are like coercing the number to complex, and then r<strong>et</strong>urning a<br />
complex number whose re<strong>al</strong>part and imagpart have been coerced to the specified<br />
floating point type.<br />
character .<br />
Conven object to a character. This coercion is only defined for integers (see intchar.<br />
page %). symbols one character long, and vectors whose dement-type is a<br />
subtype of character (i.e., character vectors and strings). Moreover, in the<br />
MC:NII.MAN:TYPES 36<br />
23-DEC-83
Coercion 10 Nil. Manu<strong>al</strong><br />
integer case. an error is sign<strong>al</strong>led if the coercion does not succeed (Le.. int-char<br />
would r<strong>et</strong>urn nil when given the integer abjl'l'I).<br />
Note that coerce docs not providc for cocrcion to ration<strong>al</strong> or integer types. This is<br />
because the issuc of what to do about truncation OT rounding is a· matter of. the intent;<br />
the functions ration<strong>al</strong> (page 78) and ration<strong>al</strong>ize (page 78) may be used to convert<br />
numhers into ration<strong>al</strong> numbers, and the functions floor, ceiling. truncate. and round<br />
(section 10.7, page 79) are useful fix converting both floating-point numbers and ratios to<br />
integers with various sons founding behaviour.<br />
coerce docs not accept .. 11 of the gener~ll fonllsof type that it shuuld: however. must the<br />
simple fOrm<strong>al</strong>s. and cert;linJy &111 tlwse th&l( arc listed clbo\'c. arc handled properly.<br />
When compiled. c<strong>al</strong>ls to coerce with a conswnt second argument arc changed by the<br />
compilcr into c<strong>al</strong>ls to a routinc specific to the task: a few of these, most notably the<br />
conversions to (non-complex) floating p()int, arc handled especi<strong>al</strong>ly efficiently.<br />
Thcre arc a number of nthcr functions which perform specific types of coercions.<br />
instance. string will cocrcca sy~nbol or a string to a string.<br />
For<br />
MC:<strong>NIL</strong>M!\N:TYPES 36<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 11 Scope. Extent, and Binding<br />
3. Scope, Extent, and Binding<br />
The <strong>NIL</strong> interpr<strong>et</strong>er uses lexic<strong>al</strong> seoping. What this means, simply. is that variable references<br />
which are "textu<strong>al</strong>ly within" the code which binds them. are vaHd. Those references which are<br />
not "textu<strong>al</strong>ly within" the binding form are not, and will (typic<strong>al</strong>ly) cause unbound-variable errors.<br />
Consider the definition<br />
(defun make-associations (keys single-v<strong>al</strong>ue)<br />
{mapcar "(lambda (key) (cons key single-v<strong>al</strong>ue» keys»<br />
which takes a list of keys. and r<strong>et</strong>urns an association list associating <strong>al</strong>l of those keys with the<br />
same single v<strong>al</strong>ue (perhaps for usc by assoc). The first argument to mapcar. the lambda<br />
expression. is technic<strong>al</strong>ly a function. (The #' construct is explained hclow.) It is. however.'<br />
textu<strong>al</strong>1y within the binding of the argument Single-v<strong>al</strong>ue. so that variable reference is lexic<strong>al</strong>.<br />
and that function works in Nil. as desired. Consider the <strong>al</strong>ternative form<br />
(defun make-associations (keys single-v<strong>al</strong>ue)<br />
(mapcar ,'make-one-association keys»<br />
(defun make-ane-association (key)<br />
(cons key single-v<strong>al</strong>ue»'<br />
which might appear to be equiva\ ~nt. The reference to single-v<strong>al</strong>ue in the definition of makeone-association<br />
is nol textu<strong>al</strong>ly within the binding of that variable. hence appears "free".<br />
Although this function (in the absence of extra geclarations. as described below) would function<br />
"properly" in the MACLISP or IlSP MACHINE LISP interpr<strong>et</strong>ers. it will not in 1'IL. It is interesting<br />
to note that (again without speci<strong>al</strong> declarative information) both the MACUSP and LISP MACHINE<br />
LISP compilers will treat the second example as an error (or at least produce incorrect code),<br />
because <strong>al</strong>though the interpr<strong>et</strong>ers do not enforce lexic<strong>al</strong> scoping niles, code is compiled that way.<br />
A short note may be in order on the # ' construct which appeared above. # ' is an<br />
abbreviation for (function ...), just as ' is an abbreviation for (quote ...).<br />
In MACI.ISP. the two<br />
are equiv<strong>al</strong>ent. Howe"er. in ~1I. (and to some extent in l.ISP MACHINE I.ISP too), use of this<br />
speci<strong>al</strong> form is necessary to cause the proper (function<strong>al</strong>) interpr<strong>et</strong>ation of the fonn being<br />
ev<strong>al</strong>uated. In fact. in the make-associations example. it is that speci<strong>al</strong> interpr<strong>et</strong>ation which<br />
makes the lexic<strong>al</strong> reference to single-v<strong>al</strong>ue "work". If quote was used instead of function, the<br />
example would not work as desired. function (or # ') need not just be used around lambda<br />
expressions. It may <strong>al</strong>so be used around function names (as in the second make-associations<br />
example). The effect of ev<strong>al</strong>uating (function name) is equiv<strong>al</strong>ent to what the interpr<strong>et</strong>er does<br />
when it "ev<strong>al</strong>uates" name in the function position of a list being ev<strong>al</strong>uated.<br />
<strong>NIL</strong> does not restrict one to using only lexic<strong>al</strong> seoping rules. It is possible to declare to <strong>NIL</strong><br />
that a variable is speci<strong>al</strong>, and should be able to be referenced by code not textu<strong>al</strong>ly within the<br />
binding construct Or. perhaps a variable should have a glob<strong>al</strong> top level v<strong>al</strong>ue and not be bound<br />
anywhere. or maybe even have a top level v<strong>al</strong>ue. and be bound in some places. This is the<br />
purpose of the speci<strong>al</strong> declaration, which <strong>NIL</strong> implements compatibly with COMMON LISP, and<br />
which is about the same as it is in USP MACHINE USP and MACUSP.<br />
Most of the time. speci<strong>al</strong> variables are declared to be speci<strong>al</strong> glob<strong>al</strong>ly. This means that the<br />
<strong>NIL</strong> interpr<strong>et</strong>er (and compiler) will <strong>al</strong>ways treat the variable as being speci<strong>al</strong>. even if there is no<br />
declaration for it at the place it is bound. As a matter of style. variables declared speci<strong>al</strong> are<br />
usu<strong>al</strong>ly given names which begin and end with the character • so that they can be visu<strong>al</strong>ly<br />
MC:<strong>NIL</strong>MAN:BIND 27<br />
23-DEC-83
Scope. Extent. and Hinding 12 Nil. Manu411<br />
distinguished from more "ordinary'· lexic<strong>al</strong>ly scoped variablcs.<br />
variable speci<strong>al</strong> is with defvar (p41ge 24). ror instance.<br />
(defvar -leaves-)<br />
(defun find-<strong>al</strong>I-leaves (tree)<br />
(l<strong>et</strong> (-leaves- nil»<br />
(find-<strong>al</strong>l-leaves-l tree)<br />
-leav.8s-<br />
) )<br />
(defun find-<strong>al</strong>l-leaves-l (tree)<br />
(cond «atom tree)<br />
; Empty sctofleaves<br />
; o rO\lcl over the tree<br />
; And r<strong>et</strong>urn the leaves found<br />
One way to glob<strong>al</strong>ly declare a<br />
(cond «not (memq tree -leaves-»<br />
(s<strong>et</strong>q -leaves- (cons tree -leaves-»»)<br />
(t (find-<strong>al</strong>l-1eaves-! (car tree»<br />
(find-<strong>al</strong>l-leaves-1 (cdr tree»»)<br />
There are more esoteric (or SCIIEMIHike) ways in which the above could have been perfunned.<br />
without the. usc of the speci<strong>al</strong> variable -Ieaves-. but the above is fairly straightforward. fairly<br />
effident. ,md will <strong>al</strong>so run (both k terpreled and -compiled) compatibly in MACUSP and !.lSI'<br />
MACHINE I.ISP.<br />
The above intuitive (or. if you prefer. hand-waving and vague) description can now be used<br />
to more fonn<strong>al</strong>ly define the tenns of scope and extellt which are used to describe the accessibility<br />
and lif<strong>et</strong>imes of things. of which variable bindings are one instance. The scope of som<strong>et</strong>hing tells<br />
where it may be v<strong>al</strong>idly referred to~ To say that som<strong>et</strong>hing has lexic<strong>al</strong> scope then means that it<br />
iHay UC U)CU cJllywiaclc ·'i.cxluaiiy'" within Lhc conSlfUct which "creatcs" the objcct (e.g.. the<br />
lambda-expression which binds a variable). Note that this docs not in itself imply that the<br />
reference becomes inv<strong>al</strong>id if that construct is exited. That dimension is the extelll of the object.<br />
which tens the lime during which the object (e.g.. variable binding) is v<strong>al</strong>id dynamic extent<br />
means that the object (reference) is only vaHd during the execution of the construct. illdefillite<br />
extellt means that there is no such limitation. Variable bindings in the <strong>NIL</strong> interpr<strong>et</strong>er (which are<br />
not speci<strong>al</strong>) have lexic<strong>al</strong> scope and indefinite· extent lbismeans upward funarg capability.<br />
indefinite scope means that there is no restriction on wbere a v<strong>al</strong>id reference may occur from.<br />
This is the case with speci<strong>al</strong> variables; the "free" references may be made from any piece of<br />
code. The bindings of such variables. however, have only dynamic extent; they become inv<strong>al</strong>id<br />
(are "unbound") when the binding construct is exited. This combination of scope and extent,<br />
which is quite common, is· referred to as dYllamic scope.<br />
Now, for the pragmatics. The current <strong>NIL</strong> compiler actu<strong>al</strong>ly only implements loc<strong>al</strong> scope<br />
instead of lexic<strong>al</strong> scope. Its capabilities lie only in dctennining when it is losing. In many cases,<br />
this· docs nOl matter because the constructs being used are expanded out into other construc~<br />
making the references loc<strong>al</strong>. This is what happens for mapcar, for instance: in the construct<br />
(l<strong>et</strong> «22 (computate»)<br />
(mapc #'(lambda (x) (mumblify x 22» some-list})<br />
the reference to zz within the lambda expression is a non-loc<strong>al</strong> (but lexic<strong>al</strong>) reference. That<br />
expression is recoded by the compiJer~ however. as an iteration without a separate function. in<br />
which the reference become loc<strong>al</strong>.<br />
MC:<strong>NIL</strong>MAN:BIND 27<br />
23-DEC-83
N II. Manu<strong>al</strong> 13 I.ambda Application<br />
reference This is actu<strong>al</strong>ly a moderately standard way to handle .lexic<strong>al</strong> variables: rewrite<br />
the f(lnn when possihle to CilUse the reference to become loc<strong>al</strong>. The MACI.lSP compiler<br />
docs this with the mapping functions: even if tJ1e open-code-map switch is turned off, if<br />
such a reference occurs it will expand out the iteration to <strong>al</strong>10w the loc<strong>al</strong> reference.<br />
Environment transfer is implemented with closures. A closure is essenti<strong>al</strong>ly an encapsulation<br />
of a function. and some ponion of a binding environment. The closures with which lexic<strong>al</strong><br />
environment transfer is perfonned in the interpr<strong>et</strong>er. interpr<strong>et</strong>er closures. bundle up the lexic<strong>al</strong><br />
environment as of tJ1e time of their creation. Thus.<br />
(s<strong>et</strong>q fn (l<strong>et</strong> «x 5» (function (lambda () x)})}<br />
=> #<br />
(func<strong>al</strong>1 fn)<br />
=> 5<br />
One may test fln" ~l closure in g.ener<strong>al</strong> with (typep x ·closure). or with the closurep predicate<br />
(page 19).<br />
Nn actu<strong>al</strong>ly has the capability for giving "dvnamic" variables iudefilli/(' extent. '1l1is can be<br />
used to implement old-tashioned closures as creaLj by tJ1e Lisp Machine closure function (which<br />
exists in 1'11.).<br />
In <strong>NIL</strong>. what has been said for variables as far as scope. extend. binding. and shadowing is<br />
concerned. is equ<strong>al</strong>ly true for fUllctions. Variable v<strong>al</strong>ue and function v<strong>al</strong>ue are handled in<br />
virtu<strong>al</strong>ly identic<strong>al</strong> fashions. The primary differences b<strong>et</strong>ween the two are that the interpr<strong>et</strong>er does<br />
new toplc"el specia1 variable v<strong>al</strong>ue when the variable is not glob<strong>al</strong>ly declared speci<strong>al</strong>), and the<br />
compiler makes its speci<strong>al</strong> assumption qui<strong>et</strong>ly.<br />
The design of the ~I1. binding mechanism is described by White in [13].<br />
3.1 Lambda Application<br />
Application of a lambda expression in <strong>NIL</strong> is much like that of LISP MACHINE LISP. A lambda<br />
expression is of the gener<strong>al</strong> fonn<br />
(1 ambda lambda-list {declaration}. {fonn}.)<br />
In the simplest case. lambda-lisl is a (possibly empty) list of variable names, which are the fonn<strong>al</strong><br />
param<strong>et</strong>ers to the lambda expression when it is treated as a function. There must be as many<br />
arguments to the lambda-expression as there are variables. Thus.<br />
«lambda (a b c) (list a be» 1 2 (+ 3 4»<br />
=> (1 2 7)<br />
TIle lambda-list may <strong>al</strong>so contain speci<strong>al</strong> symbols which begin with the character &. These are<br />
·often c<strong>al</strong>led lambda list keywords. but they arc "keywords'· only in the gener<strong>al</strong> sense. i.e.. they<br />
are not typed in with a preceding colon. They are typic<strong>al</strong>ly used to drive the matching of the<br />
fonn<strong>al</strong> param<strong>et</strong>ers (variables) in me lambda list with the v<strong>al</strong>ues they should be bound to. There<br />
are basic<strong>al</strong>ly just four such keywords, each of which is option<strong>al</strong>. and which should appear in the<br />
order they are shown in:<br />
&option<strong>al</strong><br />
'The items from the &option<strong>al</strong> to the next&-keyword (or end of the lambda-list) describe<br />
MC:<strong>NIL</strong>MAN:BIND 27<br />
23-DEC-83
1.4JJl1bda Application 14 <strong>NIL</strong> M4mu<strong>al</strong><br />
option<strong>al</strong> arguments to the function. F..ach such item may be of one of the following<br />
thrms:<br />
variable<br />
)f a corresponding argument is supplied. then variable wi1l be bound to that.<br />
Othcrwisc. it will be bound to nil.<br />
( variable)<br />
Samc as an is01ated variable.<br />
( variable inil-jonll)<br />
If there is a corresponding argument. then l'ariablc is bound to th<strong>al</strong>. If not. then<br />
inil-/iJrm is c"(lluated. and l'ariab/r buund to that result. Thc ev<strong>al</strong>uation of iltiljimJl<br />
is performed in ,til environment where <strong>al</strong>l of the \'4lriHhlcs in the lambda 1ist<br />
to the left of this one have been bound <strong>al</strong>reCldy.<br />
( roriob/(' il1il-}("-1I1 illil-p-"ar)<br />
Just like tJ1C ,previous fnnnat. Addition<strong>al</strong>ly. illit-p" var will be bound to t if there<br />
was an argument supplied. nil if not.<br />
& rest<br />
There must be exactly une item b<strong>et</strong>ween .;t 1 &rest keyword and the next &-keyword (or<br />
the end of the lambda-list). This variable is bound to a list of <strong>al</strong>l the remaining<br />
arguments to the function.<br />
&key<br />
TIle items b<strong>et</strong>ween &key and either &aux or the end of the lambda-list describe<br />
keyworded arguments to the function. "lbese are arguments which are passed by keyword<br />
rather than by position: when given, it must be preceded by the keywurdnaming which<br />
argument it is. The function flU is defined with the lambda list<br />
(sequence item &key (start 0) end)<br />
which means it takes two required arguments (sequence and item). and two keyworded<br />
arguments (slarl and end)_ lbe c<strong>al</strong>ls<br />
(fill sequence new-item :start start :end end)<br />
(fill sequence new-item:end end :start start)<br />
are effectively the same. An keyworded arguments are by default option<strong>al</strong>. The<br />
specification of a key worded argument in the lambda list is nonnaUy the same· as that of<br />
an option<strong>al</strong> argument; thu~ if no :start keyword and associated v<strong>al</strong>ue is specified in a<br />
c<strong>al</strong>l to fjIJ. the Slar! param<strong>et</strong>er defaults to 0, and for elld, the default is nil. The name<br />
of the variable is used to generate the keyword which flags that panicular param<strong>et</strong>er.<br />
AddilionaHy, with the non-atomic fonns of option<strong>al</strong> param<strong>et</strong>er specification. a list of the<br />
actu<strong>al</strong> keyword which should be used and the variable to bind the argument to may be<br />
used instead. For example, if it were desired that the keyword :start be used to flag the<br />
starting index, but that the fonn<strong>al</strong> param<strong>et</strong>er be named i, then the lambda-list could have<br />
been written as<br />
(sequence item &key «:start i) 0) end)<br />
It is important to nOle that if both &key and &rest arc given, then the list the &rest<br />
variable is bound to is the same list from_which the keyworded arguments are extracted.<br />
This is som<strong>et</strong>imes useful if the arguments are going to be passed en-mass to some other<br />
function using apply, or perh4fps to reconstruct the origin<strong>al</strong> arguments to the function in<br />
. order to sign<strong>al</strong> an error.<br />
&aux<br />
Bindings specified with &aux arc for auxiliary variables: they have no correspondence to<br />
the "argumcnts" givcn to the lambda expression. PIne only things which may follow &aux<br />
MC:<strong>NIL</strong>MAN:BIND 27<br />
23-J)EC-83
-<br />
<strong>NIL</strong> Manu<strong>al</strong> 15 Lambd
Prcdic4Jtes 16 Nil. Mamml<br />
4. Predicates<br />
4.1 Type Predicates<br />
4. J.I Type Specifiers<br />
A type specifier is an expression which may be used to exprcs.~ a data-type constraint.<br />
nil No object is of the type nit: nif is a subtype of aU types.<br />
t All objects arc of the type 1. For· instctncc.<br />
(make-array ·(10 10) :.element-type t)<br />
m~tkcs an 10xl0 ~lrmy which can huld objects of any type.<br />
tJt,c-name<br />
This is the most common fhnn of type specifier; just a type name. filr insumcc number.<br />
double-float. string. IJ1'('-llilmemay be .the name of 1 flavor defined with defflavor<br />
(page 173). the name of a stnJcture defined by defstruct {page 125) (assuming defstruct<br />
is not told to implement the stnlcturc in some other fashion). or one of the m,my <strong>NIL</strong><br />
types noted in various places in this document<br />
(not type-specijiery<br />
AU objects which are not of type type-specifier.<br />
Carto !s! !s2 ... IS!?)<br />
The intersection of the types corresponding to the given type spccifiers~<br />
(or lsi Is) •.. tsn)<br />
The union of the types corresponding to the given type sp~jfiers.<br />
(member x) xl ... XIl)<br />
This describes a type which is one of the objects xl, xl, ... xiz. Equ<strong>al</strong>ity is defined by<br />
eql (page 20).<br />
(satisfiesjUnclion-name)<br />
An object is a ttmember" of this type if junction-name r<strong>et</strong>urns a non-null v<strong>al</strong>ue when<br />
applied to it, otherwise it is not.<br />
. There are some more complex fonns which are used variously as synonyms for, and<br />
constraints on. more gener<strong>al</strong> types. For instance:<br />
(integer low high)<br />
An object is of this type if it is an integer b<strong>et</strong>ween low and high. low and high may be<br />
integers. in which case the boundary check is illclusive, lists of integers. in which case the<br />
boundary check is exclusive. or the atom ., which signifies infinity of the appropriate<br />
sign. Thus. (integer 0 .) is a type specifier for <strong>al</strong>l non-negative integers. and (integer<br />
(0) .) or (integer 1 .) for <strong>al</strong>l positive integers.<br />
(signed - byte size)<br />
(unsigned - byte size)<br />
An object is of these types if it can be r.cprcscnted in the appropriate fonn in twos-<br />
MC:<strong>NIL</strong>MAN:PRElJ 29<br />
23-DEC-83<br />
, .. ~ , - ~<br />
-,.:,:c ".,~> .. ); ". }': ..', J'-. : : " ',' ~<br />
,<br />
,.... .' ,". . ~.<br />
,
<strong>NIL</strong> Manua) 17 TYIK' Predicates<br />
complement notation in a field of the specified size. (Without a hidden-bit convention.)<br />
Thus. (signed -byte 3) is the same as (integer -4 3). ,1Ild (unsigned -byte 3) is the<br />
same as (integer 0 7).<br />
bit Either 0 or 1.<br />
(array element-type dimensions)<br />
An object is of this type if it is an array with "the same" clement type and dimensions as<br />
those specified. dimellsions may be the symbol • (or not supplied). which matches an<br />
array of any rank and dimensions. Otherwise. it should he a list: it then matches an<br />
array \vhose rank is the length of the list. The clements of the list may be either the<br />
symhol *. or a non-negative integer which is the size of the corresponding dimension.<br />
For instance. the dimensions Jist (3 4 5) refers to a 3x4x5 array, ,md (3 • 5) an array<br />
whose first dimension is 3., second is of any size. and third is 5.<br />
There arc two different contexts the type specifier can be used in. and they affect the<br />
interpr<strong>et</strong>ation of the eJemeIlJ-t)1Je. These arc<br />
declaratioll<br />
in which som<strong>et</strong>hing is being declared to take on v<strong>al</strong>ues of this ty)e (declarations<br />
arc discussed in chapter 6). What the type specifier says is that the type is the<br />
same as would be r<strong>et</strong>urned by make-array were it given an clement-type of<br />
element-type and dimensions conforming to dimensions.<br />
discrimination<br />
which is re<strong>al</strong>ly JUSt usc of the type specifier as a second argument to typep. In<br />
t,;is ,,,:;e, the questk,n being dskeJ is w'hcthcf i,he ubjed tJ\.:illg h:~ico i~ uf e.xac/iy<br />
this type.<br />
These two "questions" arc different because of the way make-array (page 103) interpr<strong>et</strong>s<br />
its element-type argument. which is fully discussed in section 12.2. page 104. Basic<strong>al</strong>ly.<br />
what you g<strong>et</strong> from make-array is an array whose clement-type is the closest speci<strong>al</strong>ization<br />
to the specified element-type which make-array can provide.<br />
Fin<strong>al</strong>ly. the elemelll-type can be *, which means any element type at <strong>al</strong>l. Thus, (array t<br />
dims) is a not a subtype of (array • dims). because the former only refers to arrays<br />
which can hold clements of any type, whereas the latter includes bit arrays, string-char<br />
arrays, <strong>et</strong>c.<br />
(simple-array elemel1l-typ~ dimensions)<br />
This is like (array element-type dimensions). but addition<strong>al</strong>ly states that the array has been<br />
created without any "fancy options"; see chapter 12, page 103.<br />
(vector elemenl-t}pe size)<br />
This is equiv<strong>al</strong>ent to (array element-type (size».<br />
MC:<strong>NIL</strong>MAN:PRED 29<br />
23-DEC-83
Type Predicates 18 <strong>NIL</strong> Mcamwl<br />
4.1.2 Gener<strong>al</strong> Type Predicates<br />
typep objecl &option<strong>al</strong> type-specifier<br />
If only one argument is supplied. this is (somewhat) like MACl.ISP typep, and r<strong>et</strong>urns the<br />
exact implementation type of object. In NIl.. this is usu<strong>al</strong>ly som<strong>et</strong>hing too specific to be<br />
worth looking at<br />
Otherwise. r<strong>et</strong>urns t jf object is of type type-specifier, nil otherwise. See thc description of<br />
type specifiers. abovc.<br />
sub typep (l1)l'-Spcc(fin'"' (l'l'l'-Spccijir,... 2<br />
subtypep attempts lo dClcnnine if I)1J('-sp('cijier-r is a subtype of ~l·l'c-spl'(·ijier-2. It<br />
r<strong>et</strong>urns two \'4tlues~ the sC(,(Jlld will he t if thc rchllion could h(' d<strong>et</strong>ermined. nil if il could<br />
not he. Thc first is t if the rehltion can be d<strong>et</strong>ermined and 1J'1'c-.VJccilier-' is in fil<strong>et</strong> a<br />
subtype of 1)1U'-lPCCijicr-2. nil otherwisc.<br />
In \,lL if the type spccifiers are atomic type names and Iype-spccijie,../ j'.: a subtype of<br />
I),}}('-specilier-l. then subtypep will probably succeed in d<strong>et</strong>ermining this. ~,I t),pc-spcdjie,..<br />
/ is 1101 41 subtype of I)'pr-spcdjicr-2. then subtypep may fail to be able to d<strong>et</strong>cmline the<br />
relation. because it may not know that panicular supcrtypcs are mutu<strong>al</strong>ly exclusive.<br />
For instance.<br />
(subtypep 'fixnum 'number) => {t. t}<br />
(subtypep 'character 'number) => {nil! t}<br />
(subtypep 'number 'fixnum) => {nil, t}<br />
(subtypep '(satisfies fixnump) 'number) => {nil. nil}<br />
4.1.3 Specific Type Predicates<br />
null object<br />
This r<strong>et</strong>urns t if object is nil. nil otherwise. Stylistic<strong>al</strong>ly. null is used to test for object<br />
being the· cmpty list, whereas not (page 28), which is function<strong>al</strong>Jy equiv<strong>al</strong>ent because of<br />
the empty-listlboo)ean-faJse du<strong>al</strong>ity of nif, is used to test for boolean f<strong>al</strong>seness. This is<br />
why constructs of thc fonn<br />
(i f (not (null x) 1 frob-non-nul/-x frob-null-x)<br />
are so prcv<strong>al</strong>ent.<br />
symbo lp object<br />
R<strong>et</strong>urns t if object is a symbol, nil otherwise.<br />
consp object<br />
R<strong>et</strong>urns t if object is a cons, nil otherwise. This is the same as (not (atom object».<br />
11 stp. object<br />
consp or nult<br />
MC:<strong>NIL</strong>MAN:PRED 29<br />
23-f)EC-83
<strong>NIL</strong> Manu<strong>al</strong><br />
19<br />
Type Predicates<br />
f1xnump object<br />
characterp object<br />
These test for the exact types fixnum and character.<br />
str1ng-char-p character<br />
Tells if character is a character which may be stored in a string. 'Ibis wiJ] be a type of<br />
sorts in COMMON LISP, such that a string is a vector with clements of type string -char.<br />
Note that string-char-p requires its argument to be a character. as opposed to just any<br />
object: it is not re<strong>al</strong>ly a gener<strong>al</strong> type prcdicate~<br />
In 'II., this is characters with bill' and fiJI/I of 0 (sec chapter 11).<br />
str1ngp object<br />
vectorp oNect<br />
Tell if ubject is a string or vector respectively.<br />
O~;(,CI 'string) and. (typep object 'vector).<br />
These arc equiv<strong>al</strong>ent to doing (typep<br />
numberp object<br />
f10atp object<br />
These are the same as (typep object 'number) and (typep object 'float) respectively.<br />
closurep object<br />
Tells if object is a closure.<br />
The following are supported for MACUSP compatibility:<br />
pa 1 rp object<br />
lbis is synonymous with consp. Once upon a time. the name for cons in <strong>NIL</strong> was pair,<br />
and the function pairp was inst<strong>al</strong>led in MAC1JSP. Now, <strong>NIL</strong> and COMMON US}> c<strong>al</strong>l a cons<br />
a cons.<br />
b1gp object<br />
(typep object 'bignum)<br />
11xp object<br />
Equiv<strong>al</strong>ent to integerp. i.e.. (typep object 'integer). This name should be avoided<br />
because of possible confusion with fixnump.<br />
flonump object<br />
This is the same as (typep object 'double-float). for historic<strong>al</strong> reasons, not the same as<br />
ffoatp. It is provided for MACLISP compatibility only.<br />
MC:NlI.MAN:PRPD 29<br />
23-DEC-83
EqlWfilY Predicates 20 Nil. Manu<strong>al</strong><br />
4.2 Equ<strong>al</strong>ity Predicates<br />
Note <strong>al</strong>so null (page 18) and not (page 28). for testing for nil.<br />
eq x y<br />
'Ibis tens jf x and J' are the exact same opjcct. Implemcntation<strong>al</strong>ly, this is truc if x and y<br />
arc the same "pointer". For instance.<br />
(s<strong>et</strong>q -foo-(con5 'a 'b» => (a. b)<br />
(eq -foo•• foo*) => t<br />
(s<strong>et</strong>q *bar- (cons 'a 'b» => (a. b)<br />
(eq -foo* -bar*) => nil<br />
Philosophic<strong>al</strong>ly. what this predic.lle S
<strong>NIL</strong> Manu<strong>al</strong> 21 Equ<strong>al</strong>ity Predicates<br />
equ<strong>al</strong>p x y<br />
This is a more "gener<strong>al</strong>" version of equ<strong>al</strong>. Numbers are considered to he equ<strong>al</strong>p if they<br />
are numeric<strong>al</strong>ly equ<strong>al</strong>; type conversion wil1 OCCllr if needed to pcrfonn the comparison<br />
(see =. pagc 73). Charactcrs are compared with char-equ<strong>al</strong> (page 95). so are considercd<br />
equ<strong>al</strong>p cven jf thcy differ in casco Conses arc equ<strong>al</strong>p if their respective cars and cdrs<br />
are equ<strong>al</strong>p. Arrays arc equafp jf they have the same rank and dimensions. and if their<br />
corrcsponding clemcnts are equ<strong>al</strong>p: thus. a string will be equ<strong>al</strong>p to a gcner<strong>al</strong> vector<br />
containing equ<strong>al</strong>p characters:<br />
(equ<strong>al</strong>p #(#\F #\0 #\0) "foO") => t<br />
equ<strong>al</strong>p. likc equ<strong>al</strong>. is imp1cmcnled reclIrsi\cly so may dk' on circu1ar structures.<br />
MC:<strong>NIL</strong>MAN:PRED 29<br />
23-DEC-83<br />
, ,. ", ',' ,'" ,:" • O'" ' ',,', :, ,': ',' ,: . " ' , '<br />
-, -<br />
--' '".; .;-.. ' :~~'~~:-. "',~:'".' ---,.'., ~,:, -: ;': ,-, - " '..:- .', -, ' ,
Programming Constructs 22 <strong>NIL</strong> Manu<strong>al</strong><br />
5. Progr<strong>al</strong>nnling Constructs<br />
The <strong>NIL</strong> speci<strong>al</strong> and top)evel fonns.<br />
5.1 Compositions<br />
progn {{onn}-<br />
progn ev<strong>al</strong>uates each of the fhnns~ and r<strong>et</strong>urns the v<strong>al</strong>ue of the last. It is. therefore. a<br />
way· (0 g<strong>et</strong> multiple expressions in a position where only one is caUedfhr.<br />
(progn) nil<br />
(progn jiJnll) jiJnl1<br />
and<br />
( pro 9 n fo n,,·/ jiJnn-2 .•. jiJnl1-11 )<br />
ev<strong>al</strong>uates ,111 of the fontls. r<strong>et</strong>urning the result of the ev<strong>al</strong>uation of [onn-n.<br />
Back in the olden days of LISP. mc.my ~peci<strong>al</strong> foons only <strong>al</strong>lowed a single expression<br />
where we now <strong>al</strong>low multiple expressions to be cv<strong>al</strong>uatcd in sequence; for instrlflce. in the<br />
consequent') of the cond speci<strong>al</strong> form (page 28). This often necessitated tJleexplicit lise<br />
of the progn speci<strong>al</strong> fonn in such places. and is where the tenn implicil prugll. which<br />
describes a situation where such multiple forms are <strong>al</strong>lowed. comes from.<br />
prog1 first-fonn {{onn}·<br />
prog1 ~v:lln;ltC'C\ fir'i/-fnrm. (\nd s~ve~ tht:' v~'lJe: then it cv<strong>al</strong>uat~ an of t.~e other fcrm~.<br />
but instcad of rcturning the v<strong>al</strong>ue of the last like progn docs. it r<strong>et</strong>urns the v<strong>al</strong>ue saved<br />
from the the ev<strong>al</strong>uation of jirst-[onll.<br />
prog2 first-Jonn second-fonn (tOmt)<br />
This is entirely equiv<strong>al</strong>ent (0<br />
( pro 9 n firsi-fonn (p r 0 9 1 second-fonn fonn. •• »<br />
In other words, it ev<strong>al</strong>uates <strong>al</strong>l of the fonns in order, and r<strong>et</strong>urns the v<strong>al</strong>ue (it saved) of<br />
the second.<br />
5.2 Definition Forms<br />
5.2.1 Defining Functions<br />
defun name lambda-list {declaration}- [documentatioll] {fOnn}-<br />
Defines name as a function, equiv<strong>al</strong>ent to a lambda expression formed using the lambda<br />
IisL declarations. and forms.<br />
For MACLJSP-Compatibility, the following idiosyncratic syntaxes are recognized speci<strong>al</strong>ly:<br />
(I) If lambda-lisl is the atom macro, then this is assumed to be a MACI.lsp-style<br />
macro definition. and is transfonned appropriately.<br />
(2) If lambdwlisl is a non-nuH atom, then this is considered to be a MACLISP lexpr<br />
definition. name will be defined as a function of a variable number of arguments,<br />
MC: N II.M /\ N: pca NS 81<br />
2J~DEC-83<br />
. '<br />
:,::': ,":_:.:"0·;~;\. '.- .. -:,;:;>.t:~:;.~c~.,;
Nil. Manu<strong>al</strong> 23 Dc·finilion Fonns<br />
and the symhol lambda-list hound to that number. The functions arg and s<strong>et</strong>arg<br />
may then he used (compatibly with MACI.ISP) to access the arguments.<br />
(3) If lambda-list is the atom fexpr. then this is assumed to be a MACLlsp-style fexpr<br />
definition. and an attempt is made to turn it into a Nil, speci<strong>al</strong> fonn. Note. of<br />
course. that due to ev<strong>al</strong>uator semantics this will usu<strong>al</strong>ly not work (caBs to. ev<strong>al</strong><br />
will. for instance. utilize a new lexic<strong>al</strong> contour).<br />
In principle. name is a gener<strong>al</strong> function specifier ("function-spcc") as is done in LISP<br />
MACIII'F IISP. However. these hm'c not been put into ~I1. y<strong>et</strong>. so one addition<strong>al</strong><br />
idiosyncratic syntax (<strong>al</strong>so MACI.ISP compatible) is recognized: lI<strong>al</strong>llC may be a list of the<br />
form (namc I'ropl1amc). in which case the function is placed on the propn(]mc properly of<br />
namc. That is. one can do som<strong>et</strong>hing like<br />
(defun (faa hack) (x y)<br />
(list (* (sinh x) (cos y» (* (cosh x) (sin y»»<br />
with the result that<br />
{func<strong>al</strong>l. (g<strong>et</strong> 'foo 'hack) x y)<br />
will invoke a compiled function to perfonn that computation.<br />
5.2.2 Defining l\lacros<br />
A LISP macro differs from an ordinary function in that the code of the macro is run, not' to<br />
obtain a v<strong>al</strong>ue for the fonn. but rather to obtain a new fonn to be used in place of the origin<strong>al</strong><br />
form. 1n 'lSP. thiC\ iC\ nnt (innp thr(lneh ~ny stf!mz~ and miracu101..!s string-processing and<br />
substitution. but by USP code itself: LISP program code is just LISP data. which can be<br />
manipulated and constructed by ordinary LISP programs. When a macro c<strong>al</strong>l is encountered by a<br />
USP compiler. the code for the macro is run then and there. during the compilation. to construct<br />
the new fonn which must be compiled instead. For that reason. LISP macros. while gener<strong>al</strong> LISP<br />
functions, should not depend on their dynamic environment (<strong>al</strong>though if properly arranged they<br />
may have glob<strong>al</strong> declarative or definition<strong>al</strong> information around).<br />
defmacro name pattenl {declarations}* {documentation}- Yonn}*<br />
This is the preferred way for macros to be defined. name is defined as a macro. When a<br />
c<strong>al</strong>l to name is encountered by the interpr<strong>et</strong>er or compiler, the list of arguments to name<br />
(specific<strong>al</strong>ly, the cdr of the c<strong>al</strong>ling form) is matched against p<strong>al</strong>tern; the fonns are then<br />
ev<strong>al</strong>uated in an environment where the variables specified by p<strong>al</strong>lern are bound to the<br />
components of the arguments which they match. and the resulting v<strong>al</strong>ue is used in place<br />
of the origin<strong>al</strong> fonn.<br />
p<strong>al</strong>lem is gener<strong>al</strong>1y a pattern of symbols and conses. but it may <strong>al</strong>so have in it,<br />
intennixed, &option<strong>al</strong>. & rest. and &body. (&body is treated just like &rest by<br />
defmacro pattern matching. However, it is supposed to be an indication to a code<br />
fonnatter (pr<strong>et</strong>ty-printer. or an editor) that the following forms are a "body" rather than<br />
just a sequence of more arguments.) The following defines foo as a macro to be<br />
synonymous with car:<br />
(defmacro foo (x)<br />
( 1 is t • car x»<br />
In <strong>NIL</strong>. the &mumble keywords need not be "top-level" within the pattern:<br />
MC:<strong>NIL</strong>MAN:PCONS 81<br />
23-DEC-83
I xfinition Fonns 24<br />
(defmacro with-output-to-string «var &option<strong>al</strong> string).<br />
&body form)<br />
... )<br />
Especi<strong>al</strong>ly useful fhr constnlcting code in the bodies of macros is the backquote reader<br />
macro. section 20.1.1. page 216.<br />
Eventu<strong>al</strong>ly. defmacro will be extcnded to support these addition<strong>al</strong> Jambda-list keywords:<br />
&key kcyspecl keyspec2 ...<br />
Pr<strong>et</strong>ty much like the ordinary lISC of &key in lmnhd,. lists (section 3.1. page 13).<br />
&whole l'l.1riablc<br />
Binds l'lIri41b/(' to the ma
<strong>NIL</strong> Manu<strong>al</strong> 25 Binding and Assignment<br />
5.2.4 Controlling Ev<strong>al</strong>uation Time<br />
Macros often need to r<strong>et</strong>urn multiple fonns to be processed as if they <strong>al</strong>l appeared<br />
independently at lOplevel. For instance. defvar and its variants could <strong>al</strong>l be trivi<strong>al</strong>ly implemented<br />
as macros (if they aren't <strong>al</strong>ready). In 1'11.. they may be r<strong>et</strong>urned within a progn speci<strong>al</strong> fonn.<br />
For instance. a simplified defparam<strong>et</strong>er, which did not handle documentation, could have- been<br />
written like this:<br />
(defmacro defparam<strong>et</strong>er (variable v<strong>al</strong>ue-form)<br />
t(progn (proclaim '(speci<strong>al</strong> ,variable»<br />
(s<strong>et</strong>q .variable .v<strong>al</strong>ue-form»)<br />
proclaim and declarations are described in chapler 6. p,lge 41. The \1:\( 'liSP hack where the first<br />
clement of the progn had to be the fllnn (quote compile) is not needed (but will work just fine).<br />
This behaviour and the speci<strong>al</strong> casing only applies to toplevel fonns.<br />
ev 81 -when kwd-list lfonn}"<br />
This is as if each of the forms appe~red at topleve1. but were only there to be processed<br />
at the times specified by kwd·/isl. The <strong>al</strong>lowable keywords for kwd-list are<br />
ev<strong>al</strong><br />
When the ev<strong>al</strong>-when fonn is ev<strong>al</strong>uated by the interpr<strong>et</strong>er.<br />
load<br />
When the forms of the ev<strong>al</strong>-whenare loaded compiled (they will be treated as if<br />
th~y were:- ~l?l?n at top!eve! by the compiler; c.g., defuns wi!! b~ cmnpH~d. ~tc.).<br />
compile<br />
The jonns will be ev<strong>al</strong>uated immediately when processed by the compiler. Note<br />
that ev<strong>al</strong>-when keywords arc 1101 symbols in the keyword package (that is, you<br />
don't type them in with a colon in front).<br />
Note that for historic<strong>al</strong> reasons, these "keywords" are only keywords in the gener<strong>al</strong><br />
sense-they are not symbols in the keyword package (typed in with a colon prefix).<br />
5.3 Binding and Assignment<br />
s<strong>et</strong>q {variable v<strong>al</strong>ue}-<br />
s<strong>et</strong>q changes the v<strong>al</strong>ues of variables.<br />
(s<strong>et</strong>q a (f) b (g»<br />
makes the v<strong>al</strong>ue of a be the result of ev<strong>al</strong>uating (t), then makes the v<strong>al</strong>ue of b be the<br />
result of ev<strong>al</strong>uating (9). The v<strong>al</strong>ue r<strong>et</strong>urned by s<strong>et</strong>q is the last v<strong>al</strong>ue stored/computed,<br />
which in this case is what b now will ev<strong>al</strong>uate to, and what (9) ev<strong>al</strong>uated to.<br />
The choice of wh<strong>et</strong>her to change the lexic<strong>al</strong> or dynamic v<strong>al</strong>ue of the variable which s<strong>et</strong>q<br />
makes is the same as that which would be made by the ev<strong>al</strong>uator in ev<strong>al</strong>uating the<br />
variable; and if there is no binding of the variable. s<strong>et</strong>q creates a glob<strong>al</strong> dynamic v<strong>al</strong>ue<br />
for it.<br />
MC:<strong>NIL</strong>MAN:PCONS 81<br />
23-DEC-83
Binding and ;\ssignment 26 Nil. Manued<br />
ps<strong>et</strong>q {variable v<strong>al</strong>ue}-<br />
ps<strong>et</strong>q is syntactic<strong>al</strong>ly like s<strong>et</strong>Q. but it updates the variables in par<strong>al</strong>lel. That is. an of the<br />
v<strong>al</strong>ues are computed. before any of the variables are side-effected. A common idiom<br />
which uses this is<br />
(ps<strong>et</strong>q x y y x)<br />
which exchanges the v<strong>al</strong>ues of x and y. .<br />
ps<strong>et</strong>Q <strong>al</strong>ways r<strong>et</strong>urns nil.<br />
l<strong>et</strong> ({\'{lriab/e v<strong>al</strong>ue}' {declaratiull}- {/bn,,}-<br />
l<strong>et</strong> ev<strong>al</strong>u<strong>al</strong>es <strong>al</strong>l of the nilu('s. and then binds illJ of the l'ariablr ., to the corresponding<br />
v<strong>al</strong>llc~. ;\11 of the "<strong>al</strong>ues arc cumputed b<strong>et</strong>l)re any of the bindings are perf(lIlned.<br />
(l<strong>et</strong> «a (f». (b (g)))<br />
funns. .. )<br />
ev<strong>al</strong>u3t.es (f) and (g), then binds a to the result from the ev<strong>al</strong>uation of (fl and bto the<br />
result of the ey<strong>al</strong>uation of (g). and then ev<strong>al</strong>uates <strong>al</strong>l of the forms: the v<strong>al</strong>ue of the last<br />
fimn is r<strong>et</strong>urned ,IS the v<strong>al</strong>ue of the l<strong>et</strong>.<br />
Various other constructs in ~I1. accept a list of lists of variables and v<strong>al</strong>ues syntactic<strong>al</strong>ly<br />
the same as that used by l<strong>et</strong>. This is Wh,lt is meant by the tenn lel/isl.<br />
In NIl.. l<strong>et</strong> will accept in place of a variable. a pattern used for deslTUc/urillg. The<br />
variables within the pattern arc bound to thc corresponding parte; of the v<strong>al</strong>ue. This is<br />
"imil~r to thp iJ'lf('rf.'l(,C' t(l d~strlJc!t!nng used by d~fmacro: see it. page :n. for mere<br />
infonnation on this pattcm·directed deslfucturing.<br />
Because COMMON US}> l<strong>et</strong> is not defined to suppon destructuring. it· is recommended that,<br />
if destructuring is used. it be hidden in a macro. This will make it both easier to read<br />
(an tllC extra parentheses needed to use l<strong>et</strong> with deslfucluring make it hard to read), and<br />
<strong>al</strong>so make it easier to change should l<strong>et</strong> eventu<strong>al</strong>ly be changed to 110/ support<br />
destructuring (at which time there will be a primitive provided which docs). For instancc 9<br />
the !"IL compiler defines the macro debind-args to destructure argument lists of fonns<br />
being compiled:<br />
(defmacro debind-args (arglist-pattern form &body body)<br />
-{l<strong>et</strong> «.arglist-pattern (cdr ,form») ,8body»<br />
Eventu<strong>al</strong>ly <strong>NIL</strong> will provide some speci<strong>al</strong> fonns and functions for g<strong>et</strong>ting at the<br />
destructuring and argument· list matching function<strong>al</strong>ity provided by defmacro.<br />
l<strong>et</strong>. ({(variable v<strong>al</strong>ue)}' {dec/or<strong>al</strong>ion}- {{onn}-<br />
Syntactic<strong>al</strong>1y, l<strong>et</strong>. is similar to J<strong>et</strong>. However. rather than binding the variables in par<strong>al</strong>lel.<br />
it binds them sequCllli<strong>al</strong>ly. That is. when each v<strong>al</strong>ue fonn is ev<strong>al</strong>uated. the corresponding<br />
variable is bound to that v<strong>al</strong>ue, and the following v<strong>al</strong>ues are ev<strong>al</strong>uated in that<br />
environment. For instance,<br />
(1 <strong>et</strong>. « a jomlJ) (b fonn2»<br />
compute}<br />
first ev<strong>al</strong>uates fonnl. and binds a to that v<strong>al</strong>ue. Then. it ev<strong>al</strong>uates jOnn2, and binds b<br />
,to thaI v<strong>al</strong>ue. Fin<strong>al</strong>ly. it ev<strong>al</strong>uates compute and r<strong>et</strong>urns that v<strong>al</strong>ue as the v<strong>al</strong>ue of the<br />
l<strong>et</strong>·.<br />
MC:NJI.M;\N:PCONS 81<br />
23-DEC-83
Nil" Manu<strong>al</strong> 27 Binding and Assignment<br />
5.3.1 DynamicaHy Binding Variable Variables<br />
The routines in this section may be used to bind variables which are not known at codewriting<br />
(or compile) time. They <strong>al</strong>l bind the speci<strong>al</strong> (dynamic) v<strong>al</strong>ue of the variable.<br />
There are four variations on how the variables may be bound. Which is used is a matter of<br />
which is best suited for the particular task at hand. Basic<strong>al</strong>ly, the variations <strong>al</strong>l involve how the<br />
v<strong>al</strong>ue is computed.<br />
progv varlis, v<strong>al</strong>lis, fonns ...<br />
progv binds each of the ,"ariahles in \,o"'is/ to the corresponding "<strong>al</strong>lies in r<strong>al</strong>lis'. If there<br />
arc too many v<strong>al</strong>ues in ml/isl. the extras are ignored. If there are too Icw. then the<br />
extra variables will he bound "unbound". P.ach of the forms is then ev<strong>al</strong>uated in an<br />
environment in which the variables arc so bound: they arc <strong>al</strong>l bound dynamic<strong>al</strong>ly.<br />
progv is defined by (,OM~10N-I.ISP.<br />
None of the following spechtl fmms are, however.<br />
The following three spedaJ fonns an take an a-list as a specification of what variables to bind<br />
to what v<strong>al</strong>ues. The car of each entry in the a-list is the variable to be bound. I f the 'cdr is nil<br />
(the entry has a length of 1). then the variable will be bound "unbound". Otherwise. tJle cadr<br />
(110/ the cdr) of the entry tens what v<strong>al</strong>ue the variable should be bound to: the exact<br />
interpr<strong>et</strong>ation varies with the speci<strong>al</strong> fonn in use. In <strong>al</strong>l cases. the bindings are pcrfonned<br />
sequenti<strong>al</strong>ly: each variable is bound to its v<strong>al</strong>ue before the v<strong>al</strong>ue for the next variable to be<br />
bound is d<strong>et</strong>cnnined.<br />
progw a-IiSl funns ...<br />
The second clement of each entry in a-list is a fonn to ev<strong>al</strong> to g<strong>et</strong> the v<strong>al</strong>ue to bind the<br />
variable to.<br />
progwq a-list fonns .••<br />
This is son of a trivi<strong>al</strong> speci<strong>al</strong>-case of progw. The second clement of each entry in a-lis/<br />
is the actu<strong>al</strong> v<strong>al</strong>ue to bind the variable to; no ev<strong>al</strong>uation is perfonned.<br />
progw1 a-list forms ...<br />
This junction may lIot y<strong>et</strong> be ill the existing <strong>NIL</strong>.<br />
This is a variant of progw more in keeping with a LISP implementation in which things<br />
g<strong>et</strong> compiled. The second element of each entry in a-list is a function to be c<strong>al</strong>led on no<br />
arguments to d<strong>et</strong>ennine the v<strong>al</strong>ue to bind the variable to. This is much more practic<strong>al</strong><br />
than progw because it can eliminate a lot of interpr<strong>et</strong>er overhead.<br />
The typic<strong>al</strong> use of these speci<strong>al</strong> fonns is to provide a dynamic environment. the specification<br />
"of which may be augmented modularly, and hence might not be tot<strong>al</strong>ly known to the writer of<br />
the code which pcrfonns the binding. progw and its variants are usu<strong>al</strong>ly more convenient for this<br />
purpose than progv. because the specification of the environment is in a single datastructure.<br />
which might be kept around as the v<strong>al</strong>ue of a variable. Note however that progw. progwQ. and<br />
progwf are /lui defined by COMMO:"'-liSP. progw is defined by LISP MA(,II(~E LISP, but progwQ<br />
and progwf are not.<br />
~1C:<strong>NIL</strong>MAN:PCONS 81<br />
23-DEC-83
Condition<strong>al</strong>s 28 Nil. Manued<br />
5.4 Condition<strong>al</strong>s<br />
1 f predicate cOllsequel1l [else/omlJ<br />
not x<br />
if ev<strong>al</strong>uates predicate. If the result is not f<strong>al</strong>se (i.e.. nO( nil). then the result of the if is<br />
the rcsult of ev<strong>al</strong>uating cOlJsequent. Otherwisc. jf· else/onn is specified. the result of thc if<br />
is the result ofevaJuating else/onn. otherwise nil.<br />
not is used )ogic<strong>al</strong>1y (0 invert the scnsc. of a predicatc. That is. it is byconvCnlion used<br />
to test for the object representing boo/ran jill.')£'. Because of the emply-list/booJean-faJse<br />
du<strong>al</strong>ity of the symhol nit. iris function<strong>al</strong>ly equhHlcnt to nuft (page 18). which logic<strong>al</strong>ly<br />
checks fbr the CIIII'I)' /isl which is represented by thc type named nult Thus. one ottcn<br />
sees c()nstruct~ of the thml<br />
( i f (n 0 t (n u 1·1 1» ('()f1scqU(,111 r/sejiJn1l)<br />
because nuff is used to check for empty-listness (fbr instance. being m the end of an<br />
iter<strong>al</strong>iun down a list). and the not is used to invert the sense. so that the cOllsequcllt will<br />
be nm if there is in facl som<strong>et</strong>hing left to the list l.<br />
cond {(prctiicllir {collsequent}-»-<br />
GenemJ historic<strong>al</strong> condo Each predic<strong>al</strong>r to the cond is ev<strong>al</strong>uated. in order. If the result<br />
of an ev<strong>al</strong>uation is f<strong>al</strong>se. then the cond ev<strong>al</strong>uates the corresponding consequents in that<br />
"clausc", r<strong>et</strong>urning as its v<strong>al</strong>ue the vatuc(s) of the last one. unless there were no<br />
consequents. in which case the v<strong>al</strong>ue of the cond is the v<strong>al</strong>ue of the predicl1le ev<strong>al</strong>uation.<br />
\ ..... It... \,....~. ,<br />
I"",",. 1 .. 1 ,.1\<br />
(p2 c2)<br />
(t e»<br />
is equiv<strong>al</strong>ent to<br />
( if pI cl<br />
(if p2 cl e»<br />
however cond <strong>al</strong>10ws multiple consequents. and <strong>al</strong>so may more clearly show the selection<br />
by clearly listing the sequenti<strong>al</strong>ly processed tests.<br />
If a11 of the predicates are f<strong>al</strong>se. then cond r<strong>et</strong>urns nil.<br />
when predic<strong>al</strong>e-/onn {consequent-form}<br />
(when predicate-form<br />
consequent-J<br />
consequent-2<br />
cOllsequent-n)<br />
==><br />
(cond (predicate-form<br />
consequent-J<br />
consequent-]<br />
cOl1scquelll-n) )<br />
If predicQte-/onn ev<strong>al</strong>uates non-nuU. then the cOllsequl'llt-jOnns are eva1uated in order and<br />
the v<strong>al</strong>uc(s) of the last one r<strong>et</strong>urned as the v<strong>al</strong>ue of the when fonn: otherwise. the when<br />
fonn r<strong>et</strong>urns nit<br />
MC:NfLMAN:PCONS 81<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong><br />
29 Condition<strong>al</strong>s<br />
un les s predicate-fonn {collsequelll-jhml}·<br />
( un 1 e s s predicate-fonn<br />
consequent-I<br />
cOllsequent-2<br />
consequent-n)<br />
==><br />
(when (not predicate-Jon,,)<br />
c0l1sequclII-1<br />
COIlSl'quCllt-2<br />
c0l1sequel1t-11 )<br />
==><br />
(cond « not predicate)<br />
consequelll-I<br />
. cOllsequelll-2<br />
cotlsequent-n) )<br />
and {tOnn}·<br />
Ev<strong>al</strong>uates each fonn. and if any r<strong>et</strong>urns nil. and immediately r<strong>et</strong>urns nil without<br />
ev<strong>al</strong>uating any subsequent forms; otherwise, the result of the and is the v<strong>al</strong>ue(s) of the<br />
last foml. (and) = > t.<br />
or {fonn}·<br />
Ev<strong>al</strong>uates each fonl1, and if one r<strong>et</strong>urns a non-null result. that v<strong>al</strong>ue is r<strong>et</strong>urned by or .<br />
without ev<strong>al</strong>uating any of the following forms. (or) = > nil.<br />
or is supposed to r<strong>et</strong>urn exactly one v<strong>al</strong>ue, no matter how many were produced by the<br />
ev<strong>al</strong>uation of a form. except for the last fonl1 which is ev<strong>al</strong>uated tail-recursively (with<br />
respect to multiple v<strong>al</strong>ue propagation). It doesn't currently behave Quite this way.<br />
case keJfonn {(({key·}) {consequent}'}*<br />
A dispatch fonn utilizing the eql predicate. In gener<strong>al</strong>,<br />
(case keyform<br />
( (key-I-I key-I-2 .•. ) fonn-I-I form-I-2 .•• )<br />
( (key-2-1 key-2-2 .•. ) form-2-1 form-2-2 ••• )<br />
... )<br />
is essenti<strong>al</strong>ly the same as<br />
(l<strong>et</strong> «tern keyfonn»<br />
{cond « or (eql tern 'key-I-/) (eql tern 'kerl-2 ) .•. )<br />
/onn-i-I foml-I-] .•. )<br />
«or (eql tern 'key-]-/) (eql tern 'key-]-2) .•. )<br />
jOnn-2-1 /onn-2-2)<br />
... ) )<br />
Since the keys are constant. however. it is possible for the compiler to d<strong>et</strong>cnnine the<br />
cheapest way to perform the comparisons; see eql, page 20. In fact. if there are a<br />
moderate number of fixnum keys in a sm<strong>al</strong>l range. the <strong>NIL</strong> compiler may use the VAX<br />
CAS E instruction to perform the dispatching.<br />
MC:<strong>NIL</strong>MAN;PCONS 81<br />
23-DEC-83
Function I nvoc,ltion 30 <strong>NIL</strong> Manu<strong>al</strong><br />
In place of a list of keys. one may usc a single atomic key. Also. the symbols t and<br />
otherwise are speci<strong>al</strong>-cased and cause thaI "clause" to <strong>al</strong>ways be selected; no subsequent<br />
clauses will he examined. For example,<br />
(case (. 2 2) .<br />
(1 'one)<br />
(2 'two)<br />
(3 'three)<br />
(t 'many»<br />
=> many<br />
Nole that if one needs to lise nil. t. or otherwise as keys. they should he enclosed in a<br />
list: otherwise. nil wi11 be interpr<strong>et</strong>ed 4lS an empty list of keys. and t and otherwise as<br />
signifying the "ot.herwise" clause.<br />
This function is what selectq thought it would once be. and may be lIsed in place of<br />
MACI.IS., caseq.<br />
typecase ()l~;r(" {(/)1Jr-sprcijirr {limn},}--<br />
typeease examines each of its "clauses" in turn. If object is of the type specified by that<br />
I),pr-spcc{ficr (sec typep. page 18). then the ji,nlls in that clause arc e"<strong>al</strong>u4tted. and the<br />
v<strong>al</strong>ue of the last fonn is r<strong>et</strong>urned by typecase. If a 1)1JC-Spccijicr is one of the symbols t<br />
or otherwise. then that clause will <strong>al</strong>ways be selected. and <strong>al</strong>l subsequent clauses will be<br />
ignored.<br />
factoring out operations needed filf more th~lO oJleof the checks. The ;\IJ typecase docs<br />
not y<strong>et</strong> do any clever pointer';'lype dispatch, however.<br />
Remember that each "key" is a type specifier: it need not he just a type name. and it is<br />
definitely not a list of type names. To test for more than one type in one key, usc (or<br />
type! type) ... ).<br />
5.5 Function Invocation<br />
Often the function one desires to can is not constant: for instance. it may have been passed<br />
in as an argument (like the second argument to sort. page 55. or as a :test key worded argument<br />
to member. page 61. or som<strong>et</strong>hing obtained from a propeny list. hash table. or association .list).<br />
<strong>NIL</strong> does not suppon the old "function<strong>al</strong> variable" interpr<strong>et</strong>ation of a function<strong>al</strong> fonn; that is, in<br />
a fonn like (foo x y). the function c<strong>al</strong>led is never obtained from the v<strong>al</strong>ue of a variable foo.<br />
Instead. because the "name space" for functions and variables is compl<strong>et</strong>ely distinct, so speci<strong>al</strong><br />
functions are provided for invoking functions which are obtained by "norm<strong>al</strong>" ev<strong>al</strong>uation.<br />
tunea 11 fone/ion &rest orgs<br />
funeaU caUs junctioll on aU of the arguments in orgs. It is 1101 a speci<strong>al</strong> fonn; the<br />
junctiull is ev<strong>al</strong>uated in the regular filshion. and that v<strong>al</strong>ue should be a function. For<br />
instance. sort (page 55). which could be defined som<strong>et</strong>hing like<br />
(defun sort (sequence pred &k~y key) ... )<br />
could invoke its pred argument with som<strong>et</strong>hing like<br />
MC:NJI.MAN:PCONS 81<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 31 Iteration Constructs<br />
(func<strong>al</strong>l pred (elt sequence i) (elt sequence j»<br />
apply fullction &rcst args<br />
apply is somewhat like func<strong>al</strong>l. but the last of the args is a list of the remaining<br />
arguments to invoke /unctioll on. That is~ if apply is c<strong>al</strong>led like<br />
( app 1 y jil af a2 .•• <strong>al</strong>l list)<br />
then III will be invoked like<br />
(func<strong>al</strong>l In aJ a2 .•. <strong>al</strong>l el e2 ... em)<br />
where eJ c2 ... em are the clements of list.<br />
Often. the last argument tu apply is a list which is thc \'<strong>al</strong>uc of an &rest \ariab}e. 1 n<br />
~IL. this Jist may instead be a simple vector (it must be simple). as might be obtained by<br />
use of &restv instead of &rest.<br />
.Note that the ~1ACLISP apply function only acceptli two arguments. if you don't count the<br />
option<strong>al</strong> third argument which is an ev<strong>al</strong>uation environment.<br />
lexpr-func<strong>al</strong>1 jUllction & rest args<br />
Old name for what is now done hy apply. lexpr-func<strong>al</strong>l. unlike apply, is compatible<br />
with MACUSP.<br />
5.6 Iteration Constructs<br />
5.6.1 Mapping Functions<br />
mapc junction list &rest more-lists<br />
map 1 jullction list &rest more-lists<br />
mapcar jullction list &rcst more-lists<br />
map 11 s t junction lisl &rest more-lists<br />
mapcan function list &rest more-lists<br />
mapcon junction list &rest more-Iisls<br />
These arc the standard complement of USP mapping functions. which iterate down <strong>al</strong>l of<br />
the lists in par<strong>al</strong>lel. They accumulate results in three different ways, and apply jUnction in<br />
two different ways. In <strong>al</strong>l cases, if more than one list is supplied, they are stepped in<br />
par<strong>al</strong>lel and the iteration tenninates when the end of the shortest one is reach.<br />
mapc and mapl each r<strong>et</strong>urns its first argument as its· v<strong>al</strong>ue; that is, they are typic<strong>al</strong>ly for<br />
effect. mapc applies IUllctfgn to the cars of successive sublists, that is, to the elements of<br />
the lists. whereas mapl applies Iunction to the sublists themselves. Thus,<br />
(mapc #'print '(a be»<br />
prints<br />
a<br />
b<br />
e<br />
whereas<br />
(mapl #'print 9(a be»<br />
prints<br />
MC:<strong>NIL</strong>MAN:PCONS 81<br />
23-DEC-83
Ill'ration Constructs<br />
32 Nil. Manuul<br />
(a b c)<br />
(b c)<br />
(c)<br />
Both rcturn lisi. their first argument. Note that the function is not c<strong>al</strong>led on the nun list,<br />
evcn though thm might be thought of as a sublist. Random example where the r<strong>et</strong>urn<br />
v<strong>al</strong>ue is useful:<br />
(mapl "(lambda (subl)<br />
(rplacd subl (del<strong>et</strong>e (car subl) (cdr subl»»<br />
some-list)<br />
eliminatcs (dcstnlctively) <strong>al</strong>l duplicate element~ from some-list.<br />
mapl is what used tu be c<strong>al</strong>led map in MACI.lSI).·<br />
function (p4t£e 54).<br />
map is now a generic sequence<br />
mapcar and mapfist each r<strong>et</strong>urns a list of thercsull~ uf appJying JUl1eliol1 to tJlcir<br />
successive arguments: for map car. as with mapc. the arguments are the clements ofthc<br />
lists. and for maplist. as with mapf. they ar~ the sllblists themselves. For eXilmple:<br />
(mapcar #'(lambda (x y) (plus x y»<br />
• (1 2 3) • (9 10. 11»<br />
=> (10 1214)<br />
That could have been. written as<br />
(mapcar #'plus ... )<br />
mapcan :!nd mapccn "$p!ic~ tog~th~r" the results of applying ju;;Nivn to its succeSSive<br />
arguments. using (essenti<strong>al</strong>ly) nconc. One common usc of mapcan is to mapcar<br />
condition<strong>al</strong>ly:<br />
(mapcan #'(lambda (x) (and (pred x) (list (fx»»<br />
smne--Iist)<br />
is kind of like doing (mapcar # '/ some-list) having first del<strong>et</strong>ed those elements which do<br />
not satisfy pred.<br />
Because of the constrained nature of the iteration, mapcar, maplist. mapcan, and<br />
mapcon probably generate b<strong>et</strong>ter code than you (oreveD som<strong>et</strong>hing like the loop macro)<br />
could write for generating the r<strong>et</strong>urn v<strong>al</strong>ue.<br />
5.6.2 Other Iteration Forms<br />
dot 1mes (var count [end/onn]) {dec/aration}- {tag I fonn}-<br />
var is stepped from 0 (inclusive) to the v<strong>al</strong>ue of count (exclusive); for each v<strong>al</strong>ue, each of<br />
the /onns is ev<strong>al</strong>uated. When the iteration tenninates. the v<strong>al</strong>ue of end/onn is r<strong>et</strong>urned.<br />
The "body" of dotimes is a "tagbody" body (sec tagbody). Atomic tags may be inscncd<br />
among the forms and jumped to with go (page 34), to produce strange and wondrous<br />
unstructured code.<br />
AdditionaHy. dotimes establishes an implicit block named nil around the dotimes fonn<br />
(sec block): one may thus use r<strong>et</strong>urn (or r<strong>et</strong>urn-from with a block nrune of nil) to exit<br />
and r<strong>et</strong>urn a vaJuc(s) from the dotimes. without running exit/ann. block and tagbody<br />
are described in section 5.6.3, page 34.<br />
MC:<strong>NIL</strong>MAN:PCONS 81
<strong>NIL</strong> Manu<strong>al</strong> 33 Iteration Constructs<br />
dolist (var list [cndfimn]) {declaration}* {tag I jiJnn}*<br />
Similar to dotimes. hut steps var through the clements of list. the way mapc (page 31)<br />
d\)es.<br />
dovector (var vCClor) {declar<strong>al</strong>ion)· {tag I fonn)·<br />
Similar to dolist. but for vectors. dovector will work on any type of vector: its' name<br />
and existence dates from the early days of <strong>NIL</strong> when <strong>al</strong>l vectors were simple vectors. If<br />
vcctor is going to be of some known speci<strong>al</strong>ized type. one might be able to g<strong>et</strong> b<strong>et</strong>ter<br />
code hy llscing one of the speci<strong>al</strong>ized loop constnu:L4iavailable in NIl.. as discussed in<br />
section 17.7.1.2. page 163.<br />
do ({var [inil [s/cp]])' {cndlcst {el1lljiJnl1}*) {declar<strong>al</strong>iol1}· {lag I form}·<br />
do is a more gener<strong>al</strong> iteration constnlCt. The specified variables arc bound in par<strong>al</strong>lel (as<br />
by l<strong>et</strong>. page 26) to the v<strong>al</strong>ues of the corresponding initi<strong>al</strong> v<strong>al</strong>ues. These are their v<strong>al</strong>ues<br />
,for the first iteration. For <strong>al</strong>l subsequent iterations. the variables which have step forms<br />
specified are <strong>al</strong>l s<strong>et</strong> in par<strong>al</strong>lel to the v<strong>al</strong>ues of those step forms. (That is. the v<strong>al</strong>ues of<br />
<strong>al</strong>l of the step forms are computed b~fore <strong>al</strong>lY of the assignments have been made.)<br />
On each iteration. elldlest is ev<strong>al</strong>uated. If the result is not nil. then the iteration<br />
terminates and e\'<strong>al</strong>u~tes the elld/onus as an implicit progn (r<strong>et</strong>urning nil if there arc no<br />
elldfonns). Otherwise, the "body" of the do is interpr<strong>et</strong>ed as by tagbody (page 34).<br />
Thus.<br />
( do ( ... ) (n i 1) tagbody ... )<br />
( do (...) (t ... ) tag body . . . )<br />
will never g<strong>et</strong> around to interpr<strong>et</strong>ing the forms in tagbody.<br />
do establishes an implicit block named nil around the entire do fonn: see section 5.6.3.<br />
page 34.<br />
As a speci<strong>al</strong> hack for MACLISP code. if endrest is not specified (and hence no endfonus<br />
could be specified). then the body of the do is interpr<strong>et</strong>ed exactly once. and nil r<strong>et</strong>urned;<br />
that is. the do should have been written as prog (page 35), except that MACLISP prog<br />
docs not accept initi<strong>al</strong> v<strong>al</strong>ues for the variables.<br />
do.<br />
The MACLISP "old style do" is <strong>al</strong>so supponcd in <strong>NIL</strong>. This takes the fonn<br />
( do var inil step elldtest tagbody ••• )<br />
and is equiv<strong>al</strong>ent to<br />
(do « var init step» (endtest)<br />
tagbody • .. )<br />
New code should not use this fonnat.<br />
Speci<strong>al</strong>fonn<br />
({(var [illil [step]])} -> {endtest {endfoml) -> {declaration)· {tag I fonn}·<br />
Ihis is like do, except that the variables are bound to their initi<strong>al</strong> v<strong>al</strong>ues sequenti<strong>al</strong>ly (like<br />
l<strong>et</strong>- (page 26) rather than J<strong>et</strong>). and the steps are <strong>al</strong>so performed sequenti<strong>al</strong>ly (like s<strong>et</strong>q<br />
rather than ps<strong>et</strong>q).<br />
MC:<strong>NIL</strong>MAN;PCONS 81<br />
23-DEC-83
Iteration Constructs 34 <strong>NIL</strong> Manu<strong>al</strong><br />
See "Iso the loop macro, page 144. loop is a "programmahle iteration facility". which <strong>al</strong>lows<br />
one to combine various sorts of iterations (such as those provided by dotimes and dovector) with<br />
vilrious sorts of result accumuhttion (such as those provided by mapcar. mapcan. every. some.<br />
and other things such as summing and counting). Because it is complicated. it is documented<br />
fully in Ch4tptcr 17. page 144. An earlier version of that chapter appeared as [51. which is<br />
expected to be re.vised· similarly.<br />
5.6.3 Block and Tagbody<br />
block Clnd tagbody tog<strong>et</strong>her implement the flow-of-control function<strong>al</strong>ity pf()\'idcd hy standard<br />
prog. prog could have been implcmcnted as a milCro in terms uf these and l<strong>et</strong>. and in fil<strong>et</strong> is<br />
descrihed in that filshion by COMMON LISP.<br />
block nome {declar<strong>al</strong>ion}- ljorm}*<br />
block· ev<strong>al</strong>uates the jiJrms. If a lcxicaJly apparent r<strong>et</strong>urn-from is ev<strong>al</strong>uated with a tag of<br />
lIome (or l1ame is nil arid a r<strong>et</strong>urn is ev<strong>al</strong>uated). then the vaJue(s) of the form given to<br />
r<strong>et</strong>urn or r<strong>et</strong>urn-from arc r<strong>et</strong>urned as the \"<strong>al</strong>ue of the block form. Otherwise'. the block<br />
filrm r<strong>et</strong>urns the v<strong>al</strong>uc(s)uf the ev<strong>al</strong>umion of the lClst fonll.<br />
Note that the argument to r<strong>et</strong>urn or r<strong>et</strong>urn-from is ev<strong>al</strong>uated in the environment in<br />
which it occurs, 1101 the environment where the block was established.<br />
r<strong>et</strong>urn fonn<br />
Ev<strong>al</strong>uates jbnl1 , and r<strong>et</strong>urns the v<strong>al</strong>ue(s) it r<strong>et</strong>urns from the nearest lexic.llly apparent<br />
block with a name of nil. Many speci<strong>al</strong> forms implicitly establish blocks named nil. such<br />
as prog. do. do list. dotimes, dovector, and (usu<strong>al</strong>ly) loop.<br />
Note that this differs subtly from LISP MACIIINFl.JSP. In LlSI' MA(,IU~F. I.JSP. r<strong>et</strong>urn<br />
r<strong>et</strong>urns from the innermost prog (Le.. block) which is 1101 named t. In <strong>NIL</strong> (and COMMON<br />
LISP), a r<strong>et</strong>urn to a block name of nil only matches a block name of nil, and the block<br />
name t is not distinguished in any way.<br />
r<strong>et</strong>urn-from name form<br />
Ev<strong>al</strong>uates fonn, and r<strong>et</strong>urns the v<strong>al</strong>ue(s) it r<strong>et</strong>urns from the nearest lexic<strong>al</strong>ly apparent<br />
block with a name of name. name is not ev<strong>al</strong>uated.<br />
tagbody {tag J form}-<br />
The body of a tagbody is examined sequenti<strong>al</strong>ly. If a fonn is atomic. then it is a tag and<br />
is ignored, otherwise it is ev<strong>al</strong>uated. If during the ev<strong>al</strong>uation a lexica11y apparent c<strong>al</strong>l to<br />
go is ev<strong>al</strong>uated with an argument of one of the tags. then control is r<strong>et</strong>urned to that<br />
point within the tagbody fonn. which resumes its interpr<strong>et</strong>ation. If the interpr<strong>et</strong>ation<br />
reaches the end of the tagbody. the result is nit<br />
MC:NII.MAN:PCONS81<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 35 Non-Loc<strong>al</strong>l-"hl\\ of Control<br />
It is important to note that the name matching of block/r<strong>et</strong>urn-from and tagbody/go is<br />
lexic<strong>al</strong>. For instance.<br />
(defun f (x)<br />
(block foobar<br />
(g #'(lambda (x) (r<strong>et</strong>urn-from foobar x» x»)<br />
(defun 9 (fn x)<br />
(list (block foobar<br />
(func<strong>al</strong>l fn x»»<br />
(f 'faa) => faa<br />
not (faa). The 7\11_ compiler cannot handle this example. however. Also. the named hlock only<br />
has l~rll<strong>al</strong>l1i(' e.rlclIl: if an attempt is made to r<strong>et</strong>urn (0 a lexic<strong>al</strong>ly apparent block construct which<br />
has been exited. the interpr<strong>et</strong>er will complain.<br />
prog I'or/ist {dcdar<strong>al</strong>ion)* {lag I form}*<br />
_Swndard prog. l'arlisl may be a list of variables. or a list of lists of variables and their<br />
initi<strong>al</strong> v<strong>al</strong>ues. They will be bound in par<strong>al</strong>lel. prog can be built from the above<br />
primitives:<br />
( 1 e t varUs!<br />
Ihe dec/a rations<br />
(block nil<br />
(tagbody the lags <strong>al</strong>ldfonlls) ) )<br />
For compatibility with LISP MACHINE LISP. if the first "argument" to prog is a non-null<br />
"tuill. then th~t is uscd as thc jjam~ lif the blo~k.. wiih tlic \l<strong>al</strong> ii!)l ruiiuwiJJ~.<br />
prog. \Iar/ist {declaratioll}* {lag I Jon,,}*<br />
Like prog. but binds the variables sequenti<strong>al</strong>ly rather than in par<strong>al</strong>lel. i.e.. like using l<strong>et</strong>.<br />
(page 26) rather than l<strong>et</strong>.<br />
5.7 N on-Loc<strong>al</strong> Flow of Control<br />
catch tag {{ann}*<br />
COMMON USP catch. lag is ev<strong>al</strong>uated and the result saved. Then. if during the<br />
ev<strong>al</strong>uation of the fonus. if a throw to that tag (as tested for by eq) occurs, the catch<br />
fonn so named will r<strong>et</strong>urn the v<strong>al</strong>ues given to the throw. The tag so named has dynamic<br />
extent.<br />
The tag to catch is <strong>al</strong>lowed to be any LISP object. This means that one can generate a<br />
guaranteed unique tag by (for instance) (ncons nil). or by using a datastructure which is<br />
somehow associated with the control point of the catch. This is. in fact. how the <strong>NIL</strong><br />
interpr<strong>et</strong>er implements the block and tag body constructs; it uses the datastructures in<br />
which it stores its control-flow infonn~ltion as tags to catch.<br />
Note that this is incompatible with the standard MACI.ISP catch function documented in<br />
the 1974 manu<strong>al</strong> ([9]). However. PDPIO MACUSP has been bitching and moaning about<br />
use of catch for some year or more now. advising the use of .catch instead (which is<br />
equiv<strong>al</strong>ent to <strong>NIL</strong>'s catch).<br />
MC:<strong>NIL</strong>MAN:PCONS 81<br />
23-DEC-83
Multiple V<strong>al</strong>ues 36 Nil. Manu<strong>al</strong><br />
throw lag ibnn<br />
Itlg and ji>nl1 are ev<strong>al</strong>uated. Control is r<strong>et</strong>urned from the nearest catch established with a<br />
tag eq to the v<strong>al</strong>ue of tag. and that catch then r<strong>et</strong>urns <strong>al</strong>l the v<strong>al</strong>ues produced by fonn.<br />
speci<strong>al</strong> form because of mUltiple v<strong>al</strong>ue passb.lck. of course that doesn't work reliably y<strong>et</strong>.. ..<br />
Note that this is incompatible with the old-fashioned MACI.lSP throw function. However,<br />
in PDPlO MACI.JSP throw has been out of vogue for some time, supplanted by * throw.<br />
which has syntax and semantics identic<strong>al</strong> to this throw. and which is supported in 1'11 .•<br />
unw1nd-protectpmtcC(('ti-.l'onll {dCdllup-jonn)*<br />
prolcclcd-jimll is ey<strong>al</strong>mlted. and the result r<strong>et</strong>urned. Upon exi( the ('/eclllup-/CJnIlS arc<br />
ev<strong>al</strong>uated. No matter how the exit is achieved (throw. error. whatever).<br />
In principle. unwind-prote~t r<strong>et</strong>urns wh~ltever extra v<strong>al</strong>ues protected-jon" did. In the<br />
current 'implementation. this cannot be guaranteed bccnusc no state is saved around the<br />
ev<strong>al</strong>uation of the c/l'lIIlUp-/onlls.<br />
*catch tag {lbnll}*<br />
Old name fi1r what is now catch. Wi1l be supported ~md identic<strong>al</strong> to what catch is now<br />
indefinitely. for the sake of MACLISP programs. which use this name with identic<strong>al</strong> syntax.<br />
(Note however that MACLISP catch <strong>al</strong>lows lag to be a list of tags. which means it can't be<br />
just any object.)<br />
*throw tag jonn<br />
Old name for what is now throw. Will be supponed and identic<strong>al</strong> to wheat throw is now<br />
indefinitely. for the sake of MAOJSP programs. which use this name with identic<strong>al</strong> syntax.<br />
This seems to be an ordin
-<br />
<strong>NIL</strong> Manu<strong>al</strong> 37 Multiple V<strong>al</strong>ues<br />
v<strong>al</strong> ues -11 s t list<br />
R<strong>et</strong>urns as multiple v<strong>al</strong>ues <strong>al</strong>l the clements of list.<br />
v<strong>al</strong> ues -vector veclOr<br />
Because ~Il. makes such great usc of vectors. this is provided <strong>al</strong>so; it r<strong>et</strong>urns a11 the<br />
elements of vector as multiple v<strong>al</strong>ues.<br />
For example. in Nil. v<strong>al</strong>ues is defined by<br />
{defun v<strong>al</strong>ues (&restv vee)<br />
(v<strong>al</strong>ues-vector vee»<br />
Of course. the ~ll compiler will open-compile a caB to v<strong>al</strong>ues.<br />
mul t 1p 1 e-v<strong>al</strong> ue variables v<strong>al</strong>ues-foml<br />
The variables in variables. which must be a list of variables. are s<strong>et</strong> to the corresponding<br />
!11U1liplc v<strong>al</strong>ues r<strong>et</strong>urned by the ev<strong>al</strong>uation of v<strong>al</strong>ues-funn. Extra v<strong>al</strong>ues are ignored: if too<br />
few v<strong>al</strong>ues are r<strong>et</strong>urned. the extra variables are s<strong>et</strong> to nil.<br />
multiple-v<strong>al</strong>ue <strong>al</strong>ways r<strong>et</strong>urns exactly' one v<strong>al</strong>ue. the v<strong>al</strong>ue of the first v<strong>al</strong>ue r<strong>et</strong>urned by<br />
,'<strong>al</strong>ues-fun1l (or nil if none were r<strong>et</strong>urned).<br />
In <strong>NIL</strong>. as in USP MACHINE USP. one may use nil in place of a variable to cause the<br />
corresponding v<strong>al</strong>ue to be ignored. This is specific<strong>al</strong>ly dis<strong>al</strong>lowed by COMMON l.ISP. and<br />
should not be used. The preferred way to handle this uses multiple-v<strong>al</strong>ue-bind, below.<br />
The name of this will be changed to multipte-v<strong>al</strong>ue-s<strong>et</strong>q by COMMON LlSP ...<br />
mul t 1 ple-v<strong>al</strong> ue-b1 nd variables v<strong>al</strong>ues-fonn {declaration}* {{onn}*<br />
Somewhat like multiple-v<strong>al</strong>ue. except the variables in variables are bound to the v<strong>al</strong>ues<br />
produced by v<strong>al</strong>ues-form. and each of the fonns ev<strong>al</strong>uated in that environment.<br />
Note that. <strong>al</strong>though in <strong>NIL</strong> nil may be used as a placeholder in variables for a v<strong>al</strong>ue<br />
which will not be used, it may not in COMMON LISP. The preferred way to ignore a<br />
v<strong>al</strong>ue is to use a name for it, and deClare that name to be ignored; for instance.<br />
(multiple-v<strong>al</strong>ue-bind (quo rem) (%bignum-quotient-norm x y)<br />
{declare (ignore quo»<br />
(hack-about-with rem»<br />
This addition<strong>al</strong>ly provides the benefit of having the v<strong>al</strong>ue "documented" by vinue of<br />
being associated with a named variable.<br />
mult1ple-v<strong>al</strong>ue-l1st jOnn<br />
fonn is ev<strong>al</strong>uated. and <strong>al</strong>l of the v<strong>al</strong>ues it produces are r<strong>et</strong>urned as a list. For example:<br />
(multiple-v<strong>al</strong>ue-list (v<strong>al</strong>ues 1 2» => (1 2)<br />
(multiple-v<strong>al</strong>ue-list (v<strong>al</strong>ues» => nil<br />
mult1ple-v<strong>al</strong>ue-progl first-fon" {fOnn}*<br />
.This is likc progl (page 22). but r<strong>et</strong>urns <strong>al</strong>l of the v<strong>al</strong>ues produced by the ev<strong>al</strong>uation of<br />
firsl-jonn. progl is supposed to r<strong>et</strong>urn only the first v<strong>al</strong>ue, never the other v<strong>al</strong>ues;<br />
however. in the current multiple v<strong>al</strong>ue implementation <strong>NIL</strong> uses, this cannot be depcnded<br />
on.<br />
MC:<strong>NIL</strong>MAN;PCONS 81<br />
23-DEC-83
Gener<strong>al</strong>ized Variables 38 <strong>NIL</strong> Manu<strong>al</strong><br />
5.9 (.ener<strong>al</strong>izcd Variables<br />
S 8 t f {pI lice v<strong>al</strong>ue} ...<br />
s<strong>et</strong>f is sort of a gener<strong>al</strong>ized s<strong>et</strong>Q. Essenti(ll1y. a s<strong>et</strong>f fonn expands into the code needed<br />
to store each v<strong>al</strong>ue into each plac(,. For example. just as<br />
(s<strong>et</strong>q x 3)<br />
stores 3 intox.<br />
(s<strong>et</strong>' (car 1) 5)<br />
stures 5 inw the car of the vaJue of J. As with s<strong>et</strong>q. multiple p141ce/v<strong>al</strong>ue pairs ,Ire<br />
handled sequenti<strong>al</strong>ly.<br />
s<strong>et</strong>f <strong>al</strong>ways r<strong>et</strong>urns the hlst v,due stored.<br />
s<strong>et</strong>f works on variahles. aU dcfincd car/cdr functions. array and scquence accessing<br />
functions (aref. elt. vref. char. bit). g<strong>et</strong>. various attribute accessors (symbol-plist..<br />
symbol-v<strong>al</strong>ue. symbol-function. <strong>et</strong>c.). and <strong>al</strong>l accessors defined by either defstruct or<br />
defffavor. In fact. it is the canonic<strong>al</strong> (and the only fonn<strong>al</strong>ly defined) way to modify slots<br />
of structures defined with defstruct. It <strong>al</strong>so operates on a number of low-level <strong>NIL</strong><br />
primitives. including nibble. g<strong>et</strong>-a-byte. and g<strong>et</strong>-a-byte-2c.<br />
s<strong>et</strong>f <strong>al</strong>so operatcs on certain other fonns whose "inversions" are not strictly side-effecting,<br />
by pcrfonning the s<strong>et</strong>f on an argument of the function (which must be v<strong>al</strong>id as a place to<br />
s<strong>et</strong>f). Thesc include Idb and load;..byte. For instance, the side-cffect perfonncd by<br />
{~ptf (lt1h hyflJspec place) ."<strong>al</strong>}<br />
is the samc as<br />
(s<strong>et</strong> f place ( dpb \I<strong>al</strong> bYlespcc place»<br />
<strong>al</strong>though· the r<strong>et</strong>urn v<strong>al</strong>ue should be different.<br />
The s<strong>et</strong>' mcthodology is even more helpful when the logic<strong>al</strong> operation being perfonncd on<br />
the place is "read-modify-writc". This means that the place needs to only be specified once in the<br />
form.<br />
As of this writin& the COM~ON LISP compatible s<strong>et</strong>f has not y<strong>et</strong> been insta11ed in <strong>NIL</strong>, so<br />
not <strong>al</strong>l of the following macros may be in the <strong>NIL</strong> when it is released. This pertains to incf,<br />
decf, shiftt, and rotatef. and anything having to do with how one might define such a macro.<br />
s<strong>et</strong>f. push. and pop have been in <strong>NIL</strong> for some time <strong>al</strong>ready.<br />
pus h item place<br />
Approximately<br />
(s<strong>et</strong> f place (cons item place»<br />
except that order of ev<strong>al</strong>uation is preserved, and the forms of place are ev<strong>al</strong>uated only<br />
once.<br />
pop place<br />
Approximately<br />
(p rag 1 (car place) (s<strong>et</strong>f place (cdr place»<br />
but the fonns in place are ev<strong>al</strong>uated only oncc. In otherwords, pop treats the contents of<br />
place as a list stack~ it r<strong>et</strong>urns the top of the stack and pops it<br />
MC:<strong>NIL</strong>MAN;PCONS 81<br />
23~DEC-83
NIl. Manu<strong>al</strong><br />
39<br />
Property I -ists<br />
1 nct placc &option<strong>al</strong> (drlta I)<br />
S<strong>et</strong>s placc to plaer plus della.<br />
dect place &option<strong>al</strong> (della I)<br />
S<strong>et</strong>s plac(' to place minus delta.<br />
shittf place! place) ... placell fonn<br />
( s h i f t f place jbnl1)<br />
is just like using s<strong>et</strong>f.<br />
(shi ftf place!· place) /i,nl1)<br />
stores the v<strong>al</strong>uc of placel into pluce!. and then the v<strong>al</strong>ue of form into place2.<br />
rotat<strong>et</strong> placel placc) ... placcll<br />
rotatef "roUltes" the v<strong>al</strong>ue of the places. '111e v,llue of place} is stored into placc/.<br />
place] into place) <strong>et</strong>c., and placcl into placen. <strong>al</strong>l in par<strong>al</strong>lel.<br />
5.10 Property Lists<br />
A properly list is a list of even length. of <strong>al</strong>ternating indicators and v<strong>al</strong>ues. 'Illis is. of course.<br />
the same datastructure which is the property list of a symbol. Note that this is not the same as a<br />
disembodicd property list. which has odd length. COMMO!' LISP has gener<strong>al</strong>ized the property list<br />
mechanism so that is attached neither specific<strong>al</strong>ly to symbols or disembodied property lists, but<br />
rather interfaces to gener<strong>al</strong>ized variables.<br />
Note: as of this writing. the CO\1MON l.ISP compatible s<strong>et</strong>f. on which both remf and s<strong>et</strong>f on<br />
g<strong>et</strong>f are dependent. has not been inst<strong>al</strong>led in <strong>NIL</strong>. As a result. there is a chance they might not<br />
appear in this release.<br />
g<strong>et</strong>t place indicator &optionat default<br />
g<strong>et</strong>f f<strong>et</strong>ches the v<strong>al</strong>ue under the indicator indicator from the property list which place<br />
ev<strong>al</strong>uates to. If no such indicator exists, then default is r<strong>et</strong>urned. The standard MACLISP<br />
g<strong>et</strong> function could have been written as<br />
(defun g<strong>et</strong> (x indicator)<br />
(typecase x<br />
(symbol (g<strong>et</strong>f (symbol-plist x) indicator»<br />
(cons (g<strong>et</strong>f (cdr x) indicator»<br />
(t error»)<br />
It is not re<strong>al</strong>ly necessary for place to actu<strong>al</strong>ly be a gener<strong>al</strong>ized variable. However, g<strong>et</strong>f<br />
may be used with s<strong>et</strong>f (and <strong>al</strong>l such similar constructs). in which case place obviously<br />
must be such a thing. MACLISP putprop could have been written as<br />
(defun putprop (x v<strong>al</strong>ue indicator)<br />
(typecase x<br />
(symbol (s<strong>et</strong>f (g<strong>et</strong>f (symbol-plist x) indicator) v<strong>al</strong>ue»<br />
(cons (s<strong>et</strong>f (g<strong>et</strong>f (cdr x) indicator) v<strong>al</strong>ue»<br />
(t error»)<br />
MC:<strong>NIL</strong>MAN:PCONS 81<br />
23-DEC-83<br />
- --<br />
" '",', i" , "" ,:;.~:>;~.({~/;,: • ' , " '
.Jo _ • .... ' _ ~<br />
Propeny loists 40 <strong>NIL</strong> Manu<strong>al</strong><br />
'111(' utility of g<strong>et</strong>f is that it may be used to manipulate "property 1isl~" stored in p14lCCS<br />
other lhan symbols or the cdr of a cons. One might. fi)r instance. define a structure<br />
with defstruct (page 125) which has one SIOl used to hoJda property list:<br />
(defstruct (frobozz :named :conc-name)<br />
initi<strong>al</strong>-data<br />
plist<br />
(hyperspace~shift-co~nt O})<br />
Then. items in the "property list" may be accessed by<br />
( ge t f (f robozz-p 1 is t /robozz) illdi('i1Ior)<br />
and s<strong>et</strong> by<br />
(s<strong>et</strong> f (g<strong>et</strong> f (frobozz-p 1 is t /mb()zz) iJllJictltor) Ilafue)<br />
One may <strong>al</strong>so do such things as<br />
(incf (g<strong>et</strong>f (frobozz-plist jrobozz) indicator»<br />
to increment a v<strong>al</strong>ue stored on tlle propcnyJisL<br />
remf plac£' indicator<br />
remf removes an indicator/v<strong>al</strong>ue pair from the property list in place. In order to do so.<br />
place must be a gener<strong>al</strong>ized variable usable with self remf r<strong>et</strong>urns nil if there was no<br />
such pair for indicator, t otherwise.<br />
g<strong>et</strong>-propert 1es place names<br />
g<strong>et</strong>-properties <strong>al</strong>lows one to search for a s<strong>et</strong> of properties, It looks down the property<br />
list in place: when an indicator is found which· is in the list names, then it r<strong>et</strong>urns three<br />
Vu!uC3: u'Jc ·.."luc under that IndkaLui. iIi\:: indk'ilUi. and th~ suhIi~i uf i.h~ 1.IIUV\:1 i.y ii~i.<br />
beginning with the indic<strong>al</strong>Of. (Thu~ the car of that sublist is the indicator. and the cadr<br />
the v<strong>al</strong>ue. This last v<strong>al</strong>ue is what is r<strong>et</strong>urned by the MACLlSP g<strong>et</strong> I function. page 69.) ]f<br />
none of the indicators specified in names are found, then <strong>al</strong>1 three v<strong>al</strong>ues g~t-properties<br />
r<strong>et</strong>urns arc nil.<br />
Not only can g<strong>et</strong> - properties be used for searching for more than one indicator at once,<br />
but the third v<strong>al</strong>ue r<strong>et</strong>urned can be fed back to g<strong>et</strong>-properties to continue searching<br />
from that (or some later) point in the propeny list<br />
Note <strong>al</strong>so the property-list function g<strong>et</strong> (page 65) and remprop (page 65).<br />
MC:<strong>NIL</strong>~1AN:PCONS 81<br />
23-DEC-83<br />
" ,<br />
',-~", :" _ " r, ::.. -.' ' -', ::, _" "~,," ,-, "'" .-'::' .", :: ,';..:",,: ':;, ,,,,., ,', ,",;:: " • -~' "'~'"<br />
, .
<strong>NIL</strong> Manu<strong>al</strong> 41 I )eclarations<br />
6. Declarations<br />
In LISP. there is only one declaration that affects program semantics (and is thus the only one<br />
needed to make tJlem run correctly): the speci<strong>al</strong> declaration. All other declarations are for the<br />
purpose of providing extra information abollt the program-this infonnation may be for the<br />
compiler. for a code an<strong>al</strong>yzer, or just as documentation for humans. The assertions made by<br />
declarations may be tested by the l.ISJ> interpr<strong>et</strong>er or compiler in order to find program errors,<br />
and may be used to direct compilation strategies, so incorrect declarulions are illeg<strong>al</strong> and may<br />
cause erroneous results.<br />
6.1 Loc<strong>al</strong> Declarations<br />
The norm<strong>al</strong> declaration mechanism associates the declaration information with a particular<br />
context established by some speci<strong>al</strong> form or construct. This is what happens with a lambdaexpression.<br />
for instance. which is "described" as<br />
«(lambda lambda-list {declaration}. {jbn,,}.)<br />
{lonn}. )<br />
A dec/aration is either a fonn<br />
(dec 1 are {dec/-spec..})<br />
or a form which is a macro c<strong>al</strong>l which expands into such a declare form. Declarations are<br />
handled speci<strong>al</strong>ly by the forms they are within; it is an error for them to occur in other contexts.<br />
even though this may not be d<strong>et</strong>ected. The various speci<strong>al</strong> forms which accept declarations show<br />
"'w'here thGSC dcduiutiGns muy 4ippcar in their descriptions in this mam.i.iL Typk<strong>al</strong>ly, this is just<br />
preceding any "body" forms. as in the above examples. A dec/-spec is a list. the car of which<br />
must be a symbol which is recognized as naming some declaration; the possible symbols, and<br />
what they mean. are shown a bit below.<br />
Individu<strong>al</strong> declarations f<strong>al</strong>l into two categories: those which affect variable bindings, and those<br />
which do not. Those which do~ associate with bindings perfonned by the speci<strong>al</strong> construct they<br />
are associated with. For instance, both<br />
(lambda (a b c) (declare (type long-float e» .•. )<br />
(l<strong>et</strong> «a (f})(b (g» (c (h»)<br />
(declare (type long-float c»<br />
... )<br />
say that the variable c is being bound to som<strong>et</strong>hing of type long -float, and that that particular<br />
"instantiation" of c will <strong>al</strong>ways have a long-float as its v<strong>al</strong>ue. The declaration in effect "attaches"<br />
to the binding of the variable; only that particular binding is affected. The declaration in<br />
(l<strong>et</strong> «x (f»)<br />
(declare (type x Single-float»<br />
(l<strong>et</strong> «x (cons x y») ••• }<br />
... }<br />
only affects the outer binding of x, and makes no statement about the inner binding.<br />
declaration in<br />
The<br />
MC:<strong>NIL</strong>MAN;DCLS 31<br />
23-DEC-83<br />
~~ - . . . .....
Lo(<strong>al</strong> I )cciClfations 42 <strong>NIL</strong> Manu<strong>al</strong><br />
(l<strong>et</strong> «x (f»)<br />
(declare (type simple-vector v»<br />
· .. )<br />
is in error. because there is no variable v bcing bound in the construct the declare is associated<br />
with. l<strong>et</strong>.<br />
The other c~Jteg()ry of declaration is thepervasi\'t' declar<strong>al</strong>iOfl. which does not· associate with<br />
variable bindings. These have lexic<strong>al</strong> scope. delimited by the form the declaration occurs in. This<br />
sort of de clara lion is in effcct for (111 parts of the spcciul lbnn: this indudcssuch things as thnns<br />
which arc ev<strong>al</strong>uated to obtain v<strong>al</strong>ues for variables being hound. even if those forms arc not<br />
strictly part of the ttbody" of the spcci<strong>al</strong> «lnn. For inSi«Ulce. the optimize dccliJration in<br />
(l<strong>et</strong> «x (r») -<br />
(declare (type x single-float) (optimize (speed 3»)<br />
(l<strong>et</strong> «x (eons x y»))<br />
(mapc "(lambda (z) ... ) x)<br />
· .. )<br />
· .. )<br />
~s ttin effect" everywhere within the outer l<strong>et</strong>. unless it were to be loc<strong>al</strong>ly shadowed by another<br />
·.>ptimize declaration hidden in one of the fonns represented by the elipses. The fonn (f) to<br />
which the x in the outer l<strong>et</strong> is being bound. is affected by that declaration. On the other han
<strong>NIL</strong> Manu<strong>al</strong> 43 I.oc<strong>al</strong> I )ec larations<br />
6.1.1 The Speci<strong>al</strong> Declaration<br />
(speci<strong>al</strong> va,../ va,..] '"<br />
va,../l)<br />
The speci<strong>al</strong> declaration differs from <strong>al</strong>l other declarations in two ways:<br />
• It is the only declaration which affects program semantics. and<br />
• it is the only declaration which can both "attach to" variable bindings. and <strong>al</strong>so be a<br />
pervasive declaration.<br />
This du<strong>al</strong>ity is partly for convenience. but <strong>al</strong>so follows from what this declaration docs.<br />
For those variables in the speci<strong>al</strong> declaration which are being bound hy the speci<strong>al</strong> form the<br />
declaration is associated with. for instance x in<br />
(l<strong>et</strong> «x (f»)<br />
(declare (speci<strong>al</strong>.x y»<br />
fonus. .. )<br />
the declaration is an immedi<strong>al</strong>e. or variable-binding declaration. It says that the speci<strong>al</strong> v<strong>al</strong>ue of<br />
x should be bound. so that x has dynamic rather than lexic<strong>al</strong> scope. As a consequence of this.<br />
unshadowed references to x within the forms. will refer to the speci<strong>al</strong> v<strong>al</strong>ue of x-the one it was<br />
bound to. which is no doubt what is desired. This docs not affect bindings which arc not so<br />
declared: in<br />
(l<strong>et</strong> «x «f»)<br />
(declare (speci<strong>al</strong> x y»<br />
( 1 e t « x (g») ; x number 3<br />
. .. x ... ) ; x number 4<br />
... )<br />
the inner binding of x is a lexic<strong>al</strong>. rather than speci<strong>al</strong>. binding. because there is no speci<strong>al</strong><br />
declaration for it. This binding shadows the outer (speci<strong>al</strong>) binding of x. with the result that<br />
reference to x within that inner l<strong>et</strong> refers to the lexic<strong>al</strong> v<strong>al</strong>ue. which gives what (9) ev<strong>al</strong>uated to.<br />
This. then. is <strong>al</strong>l re<strong>al</strong>ly the same as how the type declaratitlO associated. as was described above.<br />
If. however. there are variables being declared speci<strong>al</strong> for which there no bindings. then the<br />
speci<strong>al</strong> declaration for them is a pervasive declaration, which affects their reference (it will stin not<br />
affect inner bindings). For instance. in both<br />
and<br />
(l<strong>et</strong> «x (f»)<br />
(declare (speci<strong>al</strong> x y»<br />
• .. y ..• )<br />
(l<strong>et</strong> «x (f»)<br />
(declare (speci<strong>al</strong> x y»<br />
(l<strong>et</strong> «x (9»)<br />
• •• x •••<br />
. ~. y ••. »<br />
the reference to y amidst the elipses is a speci<strong>al</strong> reference. due to the speCi<strong>al</strong> declaration for y.<br />
Note that by contrast the reference to x b<strong>et</strong>ween elipses is lexic<strong>al</strong> because of the shadowing effect<br />
of that inner lexic<strong>al</strong> binding.<br />
The example function find-<strong>al</strong>l-leaves from chapter 3. on page 12 (q.v.), can be rewritten as<br />
~IC:<strong>NIL</strong>M"N;DCLS 31<br />
23-DEC-83
Loc<strong>al</strong> Declarations 44<br />
<strong>NIL</strong> Manua1<br />
(defun find-<strong>al</strong>l-1eaves (tree)<br />
( 1 e t «. 1 e a v e s • nil» ; Empty s<strong>et</strong> ofleaves<br />
(declare (speci<strong>al</strong> .leaves.»<br />
(fi nd-a 11-1 eaves-l tree) ; Grovel over the tree<br />
.leaves-<br />
;And r<strong>et</strong>urn the leaves found<br />
} }<br />
(defun find-<strong>al</strong>l-leaves-l (tree)<br />
(declare (speci<strong>al</strong> .leaves-»<br />
(cond «atom tree)<br />
(cond «not (memq tree .leaves-})<br />
(s<strong>et</strong>q .leaves- (cons tree .leaves-»}»<br />
(t (find-<strong>al</strong>l-leaves-l (car tree»<br />
(find~<strong>al</strong>l-leaves-l (cdr tree»}»<br />
to demonstrate the common uses· (If the speciat declaration. The declaration in find - <strong>al</strong>l -leaves is<br />
an immediate declaration; it causes -leaves. to be dynamic<strong>al</strong>ly bound. In find-aU-leaves-1. it<br />
is a pervasive declaration which says that the references to .Ieaves. within that function are<br />
references to the speci<strong>al</strong> v<strong>al</strong>ue of -leaves.. It" hilppens that in find-<strong>al</strong>l-leaves-1. both the<br />
interpr<strong>et</strong>er and compiler would figure out that the references to .Ieaves. would have to be<br />
speciaJ references because they arc "free" references (there is no lexic<strong>al</strong>ly apparent binding).<br />
however the compiler would issue a warning about this. So. that declaration serves to teU the<br />
compiler, the interpr<strong>et</strong>er. and a reader of the code, that the references to .Ieaves. in find-aUtrees<br />
-1 are deliberately speci<strong>al</strong>.<br />
6.1.2 Declarations Affecting Variable Bindings<br />
Here arc the other declarations <strong>NIL</strong> accepts which associate with variables. being bound. It is<br />
an error for a variable to be specified in one of them. when it is not being bound by the<br />
construct the declaration is, associated with.<br />
(i gnore VQ,../ va,...2 ••• va,..n)<br />
This says that the specified variables. <strong>al</strong>though bound by the associated construct, are not actu<strong>al</strong>ly<br />
used. Its purpose is to tell the <strong>NIL</strong> compiler that you are aware that you wiU not ever reference<br />
the v<strong>al</strong>ues of those variables; otherwise, it might warn you that the variable is never referenced.<br />
One common use for this declaration . is for arguments to functions which are given, but<br />
(possibly because of an early Slate of development) not used. For instance,<br />
(defun program-d<strong>et</strong>erministic-p (program)<br />
(declare (ignore program»<br />
nil)<br />
which defines a function which takes a program as an argument, and r<strong>et</strong>urns t if it can be<br />
d<strong>et</strong>ennined that is d<strong>et</strong>cnninistic and it is, nit otherwise. The other common use is with speci<strong>al</strong><br />
binding constructs where som<strong>et</strong>hing must· be specified pOSition<strong>al</strong>ly, but what is obtained from that<br />
position is not needed. For instance,<br />
(defun mod (x y)<br />
(multiple-v<strong>al</strong>ue-bind (quo rem) (floor x y)<br />
(declare (ignore quo})<br />
rem) )<br />
which is how mod could" be defined; see page 81-mod is defined to be the second v<strong>al</strong>ue<br />
MC:<strong>NIL</strong>MAN:DCLS 31<br />
23-DEC-83<br />
- "<br />
.. _ ,_ C",<br />
., or ~ , ~ •<br />
• " ~,<br />
~. ~, ",."<br />
-" - .' - .". :. ." -;. .:,' • " • ' - .' > - - , "-" '", "'"' " ~,
_'<br />
.-,,:'<br />
- .' 0 ':'. ~;".<br />
y ''- • _ ,- _". •<br />
<strong>NIL</strong> Manu<strong>al</strong> 45 Loc<strong>al</strong> Declarations<br />
r<strong>et</strong>urned by the COMMON USP floor function.<br />
In the current <strong>NIL</strong> compiler. a variable declared with ignore but actu<strong>al</strong>ly referenced. will<br />
probably °not be d<strong>et</strong>ected. and will produce (erroneous) code just as if the variable had never<br />
been bound<br />
(type type var-I var-2 .•• var-n)<br />
(type var-I var-2 •.. var-n )<br />
These declare that the specified variables are of the type type. For the first fonn. type may be<br />
o<br />
any v<strong>al</strong>id type specifier (see section 4.1.1. page 16). For the second. only certain type specifiers<br />
which are symbols will be recognized: in the current <strong>NIL</strong> compiler. only fixnum is recognized.<br />
(The symbols flonum and notype are rccognized for MACLISP compatibility.)<br />
The current <strong>NIL</strong> compiler simply recognizes this declaration and throws it away.<br />
6.1.3 Declarations Affecting ~ompilation Strategies<br />
These de(' lrations make no statements about the program, so (in the absence of compiler<br />
bugs!) can have no effect other than efficiency on programs which are correct.<br />
(optimize (qu<strong>al</strong>ity-/ v<strong>al</strong>ue-I) (qu<strong>al</strong>ity-2 v<strong>al</strong>ue-2) ••• )<br />
The optimize declaration is used to ten the compiler how it should go about making decisions<br />
when it compiles code, in" a fairly gener<strong>al</strong> way; there are four different qu<strong>al</strong>ities which may be<br />
specified. Each may take on a v<strong>al</strong>ue which is an integer from 0 to 3 (inclusive); 0 says that that<br />
aspect should be discounted compl<strong>et</strong>ely. and 3· says that it is very important. The default v<strong>al</strong>ue<br />
for each is 1. The qu<strong>al</strong>ities are:<br />
speed<br />
Speed is of the essence. The compiler should try harder to make the code run faster.<br />
Obviously. doing so is going to have to trade off against at least one of the other<br />
following qu<strong>al</strong>ities-if it did not, then the compiler wouldn't have to make a choice.<br />
space<br />
This qu<strong>al</strong>ity attempts to quantify for the compiler how important compactness of code is.<br />
saf<strong>et</strong>y<br />
This attempts to quantify to the compiler how important the "saf<strong>et</strong>y" of the code is. The<br />
exact meaning of this is somewhat hazy; the <strong>NIL</strong> compiler takes it to mean that operations<br />
should d<strong>et</strong>ect erroneous inputs and situations when possible. or barring that, at least do<br />
things so that they might be less likely to trash your environment irrevocably in such a<br />
situation.<br />
compilation-speed<br />
The speed of compilation. In the <strong>NIL</strong> compiler, specifying a higher v<strong>al</strong>ue for this qu<strong>al</strong>ity<br />
will make it do a bit less in the way of minor or speci<strong>al</strong>-case optimizations which do not<br />
affect program operation <strong>al</strong>l that much, individu<strong>al</strong>ly.<br />
What the <strong>NIL</strong> compiler does for the various v<strong>al</strong>ues of these qu<strong>al</strong>ities is discussed in section 24.2,<br />
page 246.<br />
MC:<strong>NIL</strong>MAN;DCLS 31<br />
, .-. --<br />
-. • • < <<br />
. . ~ ~,' ~~ -' ~ . ~ ~ _ .<br />
• • _ ~ ~'_ .... - ,.. > ~ _ ~.;o _ '. r _<br />
"_
Proci&un.lliUlls: Glob4t1 I >edarations 46<br />
Nil. Manu<strong>al</strong><br />
( i n 1 i ne jUllc/iowl JUIlC/iOIl-2 ••• )<br />
(notinline jUllction-1 jUllctioll-) ••• )<br />
Theintine declaration says that the compi1er should attempt to code cans to the named functions<br />
'·in Hne"-that is. essenti<strong>al</strong>ly codc the body of thc function in placc of the c<strong>al</strong>l to the function.<br />
The notinline declaration says that this should not be done. Becausc the SIL compiler nonna11y<br />
in line-codes anything it knows how to. the inline declaration is re<strong>al</strong>ly only useful in <strong>NIL</strong> to<br />
shadow a notinline declaration.<br />
There arc a couplc· reasons why one might specify that a function not be coded inline. First.<br />
things like trace (page 220) c~m only '·trace" the function c<strong>al</strong>t if there actu,dly is a function c<strong>al</strong>l.<br />
S~cond. inlinc compilation. while il does not <strong>al</strong>ways eliminate error checking, sum<strong>et</strong>imes<br />
aggravates dehugging hy causing an error to be sign<strong>al</strong>led other than where it w(}uld ha\'c been in<br />
the interpr<strong>et</strong>ed code. ur (worse y<strong>et</strong>) causes some other error to happen.<br />
The compiJer is free to ignore the inline declaration: if it docs not know how to inline a<br />
function. it simply cannot do so. However. anything declared notinline will be compiled as a<br />
function c<strong>al</strong>l. It is an erfor to specify this for a specia1 fonn. e.g.. condo and it is prubably<br />
meaningless and ~I'! addition an error to do so for a macro~<br />
It is important to note that many functions in !\IL provide an intennediate possibility b<strong>et</strong>ween<br />
compl<strong>et</strong>e open-compilation without error checking. and c<strong>al</strong>ling the regular function: there is a<br />
large body of speci<strong>al</strong> subroutines in the <strong>NIL</strong> kernel which have caHing sequences optimized for<br />
how the compiler can compile c<strong>al</strong>ls to them. but which do error checking. This means that. for<br />
c<strong>al</strong>L cllthough one docs lose trace "lpabiJity. and the visibility of the function can on the stack<br />
when it is examined with the debugger. Wh<strong>et</strong>her such routines code as these "minisubr" c<strong>al</strong>ls or<br />
are compl<strong>et</strong>ely coded inline without error checking (where that is possible) is gener<strong>al</strong>1y controned<br />
by the optimize declaration. The d<strong>et</strong>ailed low· level specifics of this are discussed in section 24.2.<br />
page 246.<br />
6.2 Proclamations: Glob<strong>al</strong> Declarations<br />
Often one wants to make . declarations "glob<strong>al</strong>ly". For instance. to assert that a panicular<br />
variable is· <strong>al</strong>ways speci<strong>al</strong>, to s<strong>et</strong> an optimization param<strong>et</strong>er for the compilation of entire file. <strong>et</strong>c.<br />
The function proclaim is used for this.<br />
procl aim &rcst del-specs<br />
Each del-spec is a declaration specification (just like for decfare-see the beginning of the<br />
previous section). However. it is put into force "glob<strong>al</strong>ly". Many of the decJarations one<br />
may m.ake with proclaim are similar to those onc might loc<strong>al</strong>ly declare with declare,<br />
. however their semantics arc different because of their glob<strong>al</strong> nature. They are listed<br />
below.<br />
Note: it seems the CO\1MON LISP proclaim only takes one dd-spec argument?<br />
It is imponant to nole that proclaim subsumes previous usage of declare which was not in a<br />
speci<strong>al</strong> position (as described in the previous section). While declare in <strong>NIL</strong> is still accepted in<br />
ttabnonn<strong>al</strong>" positions (and might continue to be indefinitely for MACUSP compatibility), usc of<br />
MC:NII.MAN:DCLS 31<br />
" . - ~.... ~ , ~~<br />
, ,<br />
, '. :',' '. .~:... -. • , '-. ~', ' : . - .' • , -.' -', " >~.' ,,-"'"' ~ -.. .• ,. ~,; "-'.- ,-~
Nil. Manu<strong>al</strong> 47 Declaring tlle Types of Fonns<br />
proclaim is recommended to emphasize the nature of the declaration.<br />
proclaim ev<strong>al</strong>uates its argument.<br />
Also. remember that<br />
The ~IL compiler will recognize caIls to proclaim at top-level within a file. and. if the<br />
argument to it is constant (Le., it is quoted). put that declaration in force for the remainder of<br />
the compilation, in addition to outputting it to' the file: that it, it is as if it g<strong>et</strong>s wrapped by<br />
(ev<strong>al</strong>-when (ev<strong>al</strong> compile load) ... ) (see ev<strong>al</strong>-when, page 25).<br />
(speci<strong>al</strong> l'a~1 var-2 .•. \lar-Il)<br />
A speci<strong>al</strong> proclamation not only glob<strong>al</strong>ly declares that <strong>al</strong>l of the named variables should be<br />
referenccd speci<strong>al</strong>. but <strong>al</strong>so that <strong>al</strong>l bindings should be speci<strong>al</strong>. Howc\cr. one nonn~ll1y uscs<br />
defvar (pagc 24) without an initi<strong>al</strong>ization fonn to glob<strong>al</strong>ly dcchtfC a variahle speci<strong>al</strong>. or. whcn<br />
giving an initi<strong>al</strong>ization. uses defvar or defparam<strong>et</strong>er.<br />
(type type vor-l var-2 •.• \'or-Il)<br />
Syntactic<strong>al</strong>ly. this is the same as the rcgular type dcclaration. Howcvcr. the type information is<br />
associatcd with the speci<strong>al</strong> \'<strong>al</strong>l!~s of the variables. not with lcxic<strong>al</strong>ly bound variah1es of thc same<br />
names. so this is typic<strong>al</strong>ly p;~'red with a speci<strong>al</strong> proclamation. or with defvar (pagc 24),<br />
defparam<strong>et</strong>er (page 24). or defconstant (page 24).<br />
~Il..<br />
of course, ignores this right now.<br />
6.3 Declarin2 the Types of Forms<br />
Often one might want to associate type infonnation with a fonn. wherc there is no variable '<br />
being bound. The the speci<strong>al</strong> form <strong>al</strong>lows one to do this.<br />
the type-specifier [onn<br />
the declares that the v<strong>al</strong>ue r<strong>et</strong>urned by the ev<strong>al</strong>uation [oml is of the type type-specifier.<br />
Were the compiler to do nifty things with type constraining. use of this could greatly<br />
enhance its ability to optimize: currently. the compiler gener<strong>al</strong>ly throws away the type<br />
information. with the exception of a rare misguided speci<strong>al</strong>-form which explicitly looks for<br />
a the form. The <strong>NIL</strong> interpr<strong>et</strong>er. however. does verify that the r<strong>et</strong>urned v<strong>al</strong>ue is of the<br />
specified type.<br />
The type-specifier may be any v<strong>al</strong>id type specifier. and <strong>al</strong>so may be of the fonn<br />
(v<strong>al</strong>ues ~pespe~l QP~pe~2 ... ~pespe~n)<br />
in which case the r<strong>et</strong>urned v<strong>al</strong>ues must be of the specified types.<br />
MC:<strong>NIL</strong>MAN:DCLS 31<br />
23-DEC-83
Sequences 48 NII~ Manu<strong>al</strong><br />
7. Sequences<br />
A sequence is considered to be either a list or 'a vector (which is by definition a onedimension<strong>al</strong><br />
array). <strong>NIL</strong> supports a number of operations on sequences, which may be applied<br />
equiv<strong>al</strong>ently to lists. vectors. strings. and bit-vectors.<br />
Many sequence function take start and end arguments to delimit some subpart of the sequence<br />
being operated on. As a gener<strong>al</strong> rule. the slart is inclusil'f.'. and the end is exclusive: thus the<br />
length of the subsequence is thc difference of the elld and the starl. The start typic<strong>al</strong>ly defaults<br />
to O. and the end to the length of the sequence. Also.' the end. where it is an option<strong>al</strong><br />
~.rgurnent. may be explicitly specified as nil. ,md will sti1l def4111lt to' the length of the sequence.<br />
Thus.<br />
( fin d ile111 sequellce)<br />
searches the entire sequence.<br />
(fi nd ilem sequell('(' : start 5)<br />
and<br />
( fin d ilel11 sequence :! ~:-. art 5 : end nil)<br />
search from clement numher 5 onward.<br />
(find ilem sequ('lIc(' :end 5)<br />
checks the first five clements, and<br />
(find ile111 sequence :start 5 :end 10)<br />
searches the subsequence (which has a length of 5) which consists of the clements with indices 5,<br />
6, 7, 8. and 9~<br />
Functions which operate on two sequences gener<strong>al</strong>ly take the start and' end for each of the<br />
sequences separately: these are kcyworded arguments named :staru and :end1 to specify the<br />
subsequence of the first sequencc. and :start2 and :end2 to specify the subsequence of the second<br />
scqucnce. See, for insL1ncc. replace (page 52).<br />
Many sequence functions (and many other functions) pcrfonn comparisons of various sorts.<br />
For instance. find searches for an item in a sequence. (find item sequence) looks for an· element<br />
of sequence which is eql to item, and r<strong>et</strong>urns that element. The particular test used may be<br />
customized: a different test function may be spccified by use of the :test key worded argument, as<br />
in<br />
(find item sequence :test #'equ<strong>al</strong>)<br />
which uses equ<strong>al</strong> rather than eql. The sense of the test can be reversed by using :test-not<br />
instead of :test:<br />
(find item sequence :test-not #'equ<strong>al</strong>)<br />
r<strong>et</strong>urns the first clement of sequence which is not· equ<strong>al</strong> to item.<br />
Often. what one wants to compare against is not each element of the sequence. but some<br />
subpart of each clement For this, rather than composing a new :test function. one may specify<br />
a:key function. For instance,<br />
(fi nd ilem sequence : key # tear)<br />
will r<strong>et</strong>urn the first clement of sequence whose car is eql to item. This may <strong>al</strong>so be used with<br />
:test or :test-not. Note that the key function is only applied to clements extracted from<br />
sequences. ncver to things like the item argument to find.<br />
MC:NII.MAN;SEQUEN 19<br />
2J-DEC-83<br />
~ • '- _' ~ • _ ...... :- .-,o;.~ ~. • ~,-<br />
, ~ "- " ~ ~ - - ~ . -<br />
__ . ,.,>._. , " ".;';,,"";:"".' _"";~;~:.,~:.-,~,, , .... ,.:,_ .. -:.:. ,.-. -~'~ ... ~~~.-~J.>~. '-'':''''::'~' , .... , .. - '.' """.:_.:';,
2<br />
fi .-<br />
Nil. Manu<strong>al</strong> 49 A"e~sing Sequences<br />
Another c1ass of functions do "searching" by means of a unary predicate. These functions<br />
invariably come in pairs: one in which the test is satisfied if the test function r<strong>et</strong>urns a non-nil<br />
v<strong>al</strong>ue. and one in which the test is satisfied if the test function r<strong>et</strong>urns nil: for instance.<br />
position-if and position-if-not. and assoc-if and assoc-if-not. Often these functions <strong>al</strong>so take<br />
a :key keyworded argument <strong>al</strong>so: if that is specified. then that function is applied to the datum<br />
being tested and the result given to the test function. For the sequence functions. the datum is<br />
the clement of the sequence being examined.<br />
Fin<strong>al</strong>1y. for things which go grovelling through sequences sequenti<strong>al</strong>ly. one may specify the<br />
direction by usc of the :from-end keyworded argument. which if not nil means that the result<br />
will he as if the subsequence was processed from the higher to tower indices. rather than from<br />
lower to higher. Unless explicitly specified f()f a particular function. it may nul be depended on<br />
that the sequence is actu<strong>al</strong>1~ processed in that order. only tll<strong>al</strong> the end result is the same: for this<br />
reason. it is gener<strong>al</strong>ly a bad idea if the comparison or key functions have any side effects. or<br />
depend on the ordering of the clements on which they arc c<strong>al</strong>led.<br />
7.1 Accessing Sequences<br />
81 t sequence index<br />
This is the gener<strong>al</strong> sequence access function. It r<strong>et</strong>urns the indexth clement of sequence:<br />
the index is taken to be 7.ero-origined. This will work gener<strong>al</strong>ly on lists. vectors. strings<br />
(which are by definition vectors anyway). <strong>et</strong>c. One may modify an clement of a sequence<br />
hy 11sing s<strong>et</strong>f For inst~T'!("e.<br />
(s<strong>et</strong>q V (make-vector 10»<br />
=> #(nil nil nil nil nil nil nil nil nil nil)<br />
(s<strong>et</strong>f (e1t v 6) 'fool<br />
=> foo<br />
And now,<br />
v => #(ni1 nil nil nil n11foo nil nil nil nil)<br />
It is an error for index to be negative, or not less than the length of sequence as defined<br />
by length. This' means that it is an error to index p~ss the end of a list (in this elt<br />
differs from nth. page 57). and <strong>al</strong>so in its treatment of vectors with fill pointers (the fill<br />
. pointcr defines the length-to access anywhere within such a vector, use aref (page 103».<br />
1 ength sequence<br />
R<strong>et</strong>urns the length 'of sequence. If sequence is a vector with a fill pointer, the fill pointer<br />
is r<strong>et</strong>urned. In NI~ length will d<strong>et</strong>ect a circular list. and sign<strong>al</strong> an error; in other<br />
imp1ementations. it may fail to tenninate-contrast the definition of list-length, page 59.<br />
If sequence is a list. it is an error for it to not terminatc in nil-in this, length differs<br />
from previous implementations of <strong>NIL</strong>.<br />
MC:<strong>NIL</strong>MAN;SEQUEN 19
Creating New Sequences 50 Nil. Manu<strong>al</strong><br />
7.2 Creating New Sequences<br />
Many functions which create sequences take an argument which is the type of sequence to be<br />
created: it is typic<strong>al</strong>ly caHed the result-type, or perhaps just the type. This may be, in gener<strong>al</strong>. a<br />
type specifier suitable for use with typep, but must of course be a subtype of sequence-that is,<br />
a SUbtype of list or vector. The type of sequence created will be the most specific type of<br />
sequence which is a subtype of that specified type. At this time. the ~IL sequence code has not<br />
been integrated with the 1'11. array type code. so it is possible that complicated type specifications<br />
will not work. The filllowing typcs wi11 <strong>al</strong>ways work: list. string. simple-string. bit-vector.<br />
simple-bit-vector. simple-vector, and vector. vector. which is rcaH), an ahbreviation for the<br />
type specifier (array • (.». i.e.. a one-dinlcnsiomlt array of unspecifiedc1emem-type. will create a<br />
vector of clement-type 1. i.e.. a gener<strong>al</strong> '"ector.<br />
m<strong>al</strong> f •••••• "<br />
Creates a sequence of type reSull-/.lpe (as might be given to make-sequence). and stores<br />
in it the concatenation of aU the clements of sequences. For instance.<br />
(concatenate 'string "foo" "bar" ~baz")<br />
=> "foobarbaz"<br />
(concatenate 'list "foo" "bar" '(1 2»<br />
=> ('\f '\0 '\0 '\b '\a #\r 1 2)<br />
subseq sequence start &option<strong>al</strong> end<br />
R<strong>et</strong>urns a sequence of the same gener<strong>al</strong> type as sequence, containing clements from start<br />
up to (but not including) end.<br />
(Subseq "faa on you" 4) => "on you"<br />
(subseq "faa on you" 4 6) => "on"<br />
(subseq "faa on you" .4 3) => is an error<br />
(subseq tea b c d) 1 3) => (b c)<br />
Note that the result of subseq never shares with the origin<strong>al</strong> sequence. Thus. (subseQ<br />
lisl 5) is not the same as (nthcdr 5 list). In fact. subseq would sign<strong>al</strong> an error in this<br />
case if the list did not have at least 5 elements.<br />
The result of subseq wi11 <strong>al</strong>ways be a simple sequence; if, for instance, sequence is an<br />
adjustable array of element-type string -char and has a fill pointer. the result will just be<br />
a simple string.<br />
MC:NII.MAN:SEQUEN 19<br />
23"DEC-83<br />
~ ~ ~ ~, r-\~ ~<br />
, "<br />
.. , ~ - " ~<br />
~ \- ¥ ....,<br />
• :~,"<br />
"<br />
"" • : ' " ';',," --:~<br />
.-:<br />
,,' " ' .. ~",:..:.:;'. ". '., - - , ' " : - , - '", • - - , •• '~ -<br />
- >
<strong>NIL</strong> Manu<strong>al</strong> 51 Searching through Sequcnccs<br />
copy-seq sequence<br />
Copics thc sequcnce sequence. This might be neccssaryif the rcsult is going to he<br />
modified. for instance. 'Inc result of copy-seq will <strong>al</strong>ways be a simple sequence. as<br />
described undcr subseq.<br />
See <strong>al</strong>so thc map function, page 54. which produces a sequence of the results of applying a<br />
function to the corresponding clements of some input sequences.<br />
7.3 Searching through Sequences<br />
fin d i/{'m SClI1U'I1U' &kcy from-end slar! elld leSI lesl-not kcy<br />
find searches through the specified subsequence of sequencc until it finds an clement which<br />
satisfies the specified comparison ,lgainst item. in which case it r<strong>et</strong>urns th<strong>al</strong> clement: if no<br />
,match is found. find r<strong>et</strong>urns nil. If a non-null from-end argument is specified, then the<br />
result (if there is a match) will be the "rightmost" clement which matches ilem, otherwise<br />
it will be the "leftmost".<br />
fi nd-1f Icsl sequcl1ce &key from-end Slarf cnd key<br />
fin d - 1 f - not lesl scquence &key from-end sian elld key<br />
find - if r<strong>et</strong>urns an clement of the specifed subsequence of sequence which satisfies the<br />
function ICSI. or nil if no such clement is found. If a key argument is specified, then lesl<br />
is c<strong>al</strong>led on the result of c<strong>al</strong>ling key on an clement of the sequence: otherwise. lesl is<br />
c<strong>al</strong>led on the element directly. If a non-null from-Pl1d argument i~ ~pccifiec1, thpn rhp<br />
result will be the rightmost such clement within the subsequence: otherwise. it will be the<br />
leftmost.<br />
find -if-not is similar. but succeeds if the result of c<strong>al</strong>ling test is nil.<br />
pos 1 t 1 on item sequence &key from-end start end test test-not key<br />
If there is an clement of the specified subsequence of sequence which matches item<br />
according to the specified test, then position r<strong>et</strong>urns its index (the index within sequence.<br />
not within the subsequence); otherwise. position r<strong>et</strong>urns nil. If a non-null from-end<br />
argument is specified. then the result is the index of the lefunost element satisfying the<br />
test; otherwise. it is the index of the righunost such element.<br />
pos it ion-if test sequence &key from-end start end key<br />
position-if-not test sequence &key from-end start end key<br />
pOSition-if r<strong>et</strong>urns the index of an element within the specified subsequence which<br />
satisfies the test function lest. If key is specified, it is a function c<strong>al</strong>led on the element of<br />
the sequence. and that result is given to test instead of the clement itself. If a non-null<br />
from-end argument is specified. then the index will be of the rightmost such clement:<br />
otherwise. of the leftmost. If no such clement is found in the subsequence, nil is<br />
r<strong>et</strong>urned. As with position and <strong>al</strong>l similar functions, the index is the index within<br />
sequence. not within the subsequence.<br />
position-if-not is similar, but succeeds if the result of c<strong>al</strong>ling test is nil.<br />
MC:NII.MAN:SEQUEN 19<br />
23-DEC-83
. Qig~ .. h4iWJJllU. • .i a LJ 71<br />
Misccllmlcous Opcratiuns on Sequences 52 Nil. M411lu<strong>al</strong><br />
count ilem sequence &key from-end Slarl elld I('SI tl'SI-Il(J/ key<br />
count rcturns the count of clements within the specified subsequence of sequence which<br />
satisfy the specified comparison against item. The test function may depend on the order<br />
in which the clcments arc processed: if a non-null from-end argument is specified .. then<br />
the clements will be processed from right, to left (Le.•<br />
decreasing· indices); otherwise. from<br />
left to right (increasing indices). As usu<strong>al</strong>, the first argument to the test is item. and the<br />
second is the clement of sequence if no key is specified, otherwise the result of c<strong>al</strong>ling key<br />
on the elemenl<br />
count-1 f Irsl srqucl1ce &key from-cnd Slar! end key<br />
count-if-not Irsl srqurll('(' &key Ji-om-clld slart elld key<br />
count-if rcturns the count of tile element~ of suhscquence which S4uisfy thc unilry<br />
predicate lesl. If no kcy is specificd. lest is caned on tile cIement~ of the subsequence;<br />
otherwisc. it is c<strong>al</strong>led on the result of applying key to ench clement If a non-null fromclid<br />
argument is specified. tilen tile c1ement'i are processed from right to left (decreasing<br />
indices), otherwise from left to right.<br />
count-if-not is similar. but reverses the sense of lesl.<br />
7.4 l\liscellaneous Operations on Sequences<br />
reverse sequence<br />
R<strong>et</strong>urns a copy of sequence. with the clement, in the op!,ositc order_<br />
nreverse sequence<br />
Reverses sequence, destructively; it does not create a copy. Note that if sequence is a list.<br />
one should <strong>al</strong>ways use the r<strong>et</strong>urn v<strong>al</strong>ue of nreverse: that is. do som<strong>et</strong>hing like<br />
(s<strong>et</strong>q 1 (nreverse 1»<br />
rather than just<br />
(nreverse 1)<br />
This is in genera] true for <strong>al</strong>l destructive list operations. such as sort and delQ. The<br />
reason is that <strong>al</strong>though the cons cells of the input list are reused. the pointer r<strong>et</strong>urned is<br />
not necessarily the same as the origin<strong>al</strong>ftfirst tt cons of the lisL<br />
fill sequence element &key start end<br />
Replaces the elements of sequence with element, from start (default 0) up to end (default<br />
length of the sequence).<br />
(s<strong>et</strong>q a '(0 1 2 3 4 5 6»<br />
(fill a nil :start 2 :end 4)<br />
=> (0 1 nil nil 4 5 6)<br />
And now,<br />
a => (0 1 nil nil 4 5 6)<br />
rep 1 ace sequence! scquencel &key starl! end! s1art2 endl<br />
Replaces the clements of the specified subsequence of sequence} by the elements of. the<br />
specified subsequence ofsequelice2.<br />
MC:NII.MAN:SEQUEN 19<br />
23-DEC-83<br />
. ~ , ' -<br />
.' > ":: " ' , :'.:: :., . ..: ,~>.::,.;' .",: :,""c..'" ,'" "" "
Iteration over Sequences 54<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
substitute-1f nrw lrsl spquellce &key from-end Slart end key ('ou",<br />
substitute-if-not new lest sequence &key j;om-end slart end key COUIlI<br />
Similar. by extension.<br />
nsubst1tute new old sequence &1cey /rom-elld slart end test les/-not key count<br />
The destructive version of substitute; sequence is modified.<br />
nsubstitute-1f new lest scquence &key /rom-e1ld start end key counl<br />
nsubs t 1 tute-1f-not new test sequellce &kcy /rom-el.ld start end key count<br />
Similar.<br />
7.5 Iteration over Sequences<br />
The fi)lIowi,ng functions iterate a user-specified function over one or more sequences in various<br />
ways.<br />
map rcsu/t-typc junctioll &rest sequellt~es<br />
'111is is the gener<strong>al</strong> sequence mapping function. Nute that this is different from the<br />
MAC'l.ISP and LISP MACHINE LISP map function. which is renamed to mapl by COMMON<br />
USP.<br />
The result is a new sequence of type result-type (see section 7.2. page 50). containing the<br />
results of applying jUliction to the clements of sequences. There must be at least one<br />
srqllenee specified: junction g<strong>et</strong>s as many arguments as there are sequences-first it g<strong>et</strong>s<br />
c<strong>al</strong>led on <strong>al</strong>l of the first (index 0) clements. then on ,,11 the second clements. <strong>et</strong>c. The<br />
iteration tenninates when the end of any of the sequences is reached. so the result will<br />
have the same length as the shortest input sequence.<br />
(map 'list #'cons "abc" '(a bed e f»<br />
=> (#\a . a) (#\b • b) (#\c • c»<br />
If result-type is list. and the input sequences are <strong>al</strong>l lists. then this is effectively the same<br />
as mapcar (page 31).<br />
some predicate &rest sequences<br />
some applies the function predicate to the corresponding elements of sequences (of which<br />
there must be at least one), in order. If the result of some application is not nil, then<br />
some immediately tenninates the iteration and r<strong>et</strong>urns that v<strong>al</strong>ue; if <strong>al</strong>l the applications<br />
r<strong>et</strong>urned nil. some r<strong>et</strong>urns nil.<br />
The predicate may depend on being c<strong>al</strong>led on the elements of the sequences in order.<br />
Only as many elements as there are in the shortest sequence are processed.<br />
The effect of this may <strong>al</strong>so be obtained by use of the thereis clause in the loop macro<br />
(page 144).<br />
MC:<strong>NIL</strong>MAN:SEQUEN 19<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 53 Miscellaneous Operations on Sequences<br />
(s<strong>et</strong>q v (make-sequence 'vector 10»<br />
=> #(nil nil nil nil nil nil nil nil nil nil)<br />
(replace v '(1 2 3 4 5 6»<br />
=> #(1 2 3 4 5 6 nil nil nil nil)<br />
v => #(1 2 3 4 5 6 nil nil nil nil)<br />
The number of elements transfercd is the minimum of the lengths of the two<br />
subsequences, i.e.,<br />
(min (- end! startl) (- end2 start2»<br />
remove ilrl11 srquence &key /rom-end slart elld leSI tesl-lIol key COUllt<br />
remove r<strong>et</strong>urns a copy of srquem'c of Ule S.lI11C gener<strong>al</strong> type. except that clements within<br />
Ule specified suhsequence which match ilem according to the specified test arc not copied.<br />
If Ule COUllt argument is -specified. then it should he a non-negative integer which limit'!<br />
the numher of matching element~ which g<strong>et</strong> "ignored": jf it is not specified. <strong>al</strong>l matching<br />
-clements within the specified subsequence wHl be missing from ule result. The from-end<br />
flag is only re<strong>al</strong>ly meaningful if a COUIlI is specified: if a non-null from-end is specified.<br />
then the rightmost COUIII c1ement~ of the specified subsl~quence will be missing from the<br />
resul~ otherwise the leftmost.<br />
remove-if tesl sequence &key /rom-end slarl elld key count<br />
remove-if-not tesl sequence &key /rom-end slarl end key COUllt<br />
Like <strong>al</strong>l similar extensions.<br />
de 1 <strong>et</strong>e f!rn: ~rqur::('[' &kcy from-end start end test lest iwi key COUiii<br />
'J11is is the destructive version of remove. q. v.: it will attempt to use sequellce to<br />
construct its resu It The result mayor may not be eq to sequence. and sequence mayor<br />
may not be actu<strong>al</strong>ly modified to produce the result: <strong>NIL</strong> will attempt to do this the "best<br />
way" it can. For this reason. del<strong>et</strong>e should ullly be used for v<strong>al</strong>ue, never strictly for<br />
effect.<br />
del<strong>et</strong>e will succeed in side-effecting sequence to produce its result jf sequence is (1) a list,<br />
(2) an adjustable vector of any type, or (3) a vector with a fin pointer. The result is still<br />
not guaranteed to be eq . to sequence.<br />
de 18 t 8 -1 f lesl sequence &k ey from-end slart end key count<br />
del<strong>et</strong>e-if-not les/ sequence &kcy /rom-end start end key count<br />
Similar, by extension.<br />
subst 1 tute new old sequence &key from-end slart end lesl test-not key count<br />
substitute r<strong>et</strong>urns a new sequence in which the elements within the specified subsequence<br />
matching old according to the specified test have new substituted. While substitute does<br />
not modify sequence, the result may share with sequellce; in particular, if sequence is a<br />
list, the result may share a tail.<br />
If a count argumcnt is specified. then this is a non-negative integer which limits the<br />
number of substitutions madc. In this case. specifying a non-null from-end argument<br />
causes the rightmost COUIlI clements matching old to undergo substitulion. otherwise the<br />
leftmost.<br />
MC:<strong>NIL</strong>MAN;SEQUEN 19<br />
23-DEC-83
<strong>NIL</strong> Manua} 55 Sorting Sequences<br />
every predicate &rest sequences<br />
l.ike some. but r<strong>et</strong>urns t if thc result of applying predicate to the clements of sequences is<br />
ncvcr nil: if some app1ication of predicate is nil. then every terminatcs immediately and<br />
rcturns nil.<br />
The effect of this may <strong>al</strong>so be obtained by use of the <strong>al</strong>ways clause in the loop macro<br />
(page 144).<br />
not any pr('dicate & rest sequences<br />
R<strong>et</strong>urns t if the rcsult of applying the function predicate to the corrcsponding clements of<br />
scqU(,IIC(,S is <strong>al</strong>w,lYs nil: if the result of that application is not nil. then notany<br />
immediately tenninates thc itcration and r<strong>et</strong>urns nil.<br />
The cffect of this may <strong>al</strong>so be obtaincd by usc of the never clause in the loop macro<br />
(pagc 144).<br />
notevery predicate &rcst sequences<br />
If the result of some application of predicate to the corresponding clements of sequences is<br />
nil. then notevery tenllinates its iteration and r<strong>et</strong>urns t: otherwise. it r<strong>et</strong>urns nil.<br />
7.6 Sorting Sequences<br />
sort sequence predicate &k~y key<br />
This is the (,OMM01' LISP sort function: when it is used without a key. it is MACI.lSP<br />
compatible.<br />
sequence is destructively sorted according to thc predicate predicate. which receives two<br />
arguments and should r<strong>et</strong>urn a non-null v<strong>al</strong>ue only if its first argument is strictly less than<br />
its second argument. If key is spccified. then it is a function of one clement which is<br />
applied to the sequence element before being passed on to the predicate.<br />
For MACLISP compatibility, if sequence is a list. then the sort is stable; equiva1ent pairs of<br />
items (those where the two keys are neither strictly less than each other) remain in their<br />
origin<strong>al</strong> order. When sequence is a vector, a quicksort <strong>al</strong>gorithm is used.<br />
sortcar sequence predicate<br />
This is provided for MACLISP compatibility. It is just like<br />
( so r t sequence predicate : key II' c'a r )<br />
stab le-sort sequence predicate &kcy key<br />
Like sort. but guarantees that the sort will be stable (sec sort). If sequence is a vector,<br />
thcn a bubble sort is used.<br />
MC:NII.MAN:SEQUEN 19<br />
23-DEC-83
Lists<br />
8. Lists<br />
Note <strong>al</strong>so consp (page 18). listp (page 18).<br />
S6<br />
Nil. Manu<strong>al</strong><br />
8.1 Creating, Accessing, andl\1odifying List Structure<br />
car COilS<br />
cdr cons<br />
c ...• r cons<br />
'II dcfincsaJt compositions of car ,md cdr up to four levels deep; Illr insk1nce. (cddar<br />
COilS) is equiv<strong>al</strong>ent to (cdr (cdr (car elms»).<br />
Actu<strong>al</strong>ly. COilS may be either a cons or nil: the car and cdr of nil arc <strong>al</strong>wa)'s nil.<br />
Nonn<strong>al</strong>ly in <strong>NIL</strong> car. cdr. and their compositions compile into speci<strong>al</strong> subroutine cans<br />
into the !'Il. kernel which do error check~ng. but arc much faster than function ca11ing.<br />
Directing the compiler to produce faster code by usc of the Sf eed qu<strong>al</strong>ity in the optimize<br />
declaration will cause <strong>al</strong>l of these accesses to be compl<strong>et</strong>ely inHne coded, witht}lu<br />
checking: sec section 24.2. page 246. (In <strong>NIL</strong>. car and cdr each Like only one<br />
instruction. )<br />
AlI of these functions may be used with s<strong>et</strong>f in order to update the panicular component<br />
of cons.<br />
rp laca ('OilS new-car<br />
rplacd cons new-cdr<br />
rplaca modifies the car of COilS to be flew-car, and r<strong>et</strong>urns cons: rplaca modifies the<br />
cdr. Sec <strong>al</strong>so s<strong>et</strong>f (section 5.9, page 38) which can be used to update any of the above<br />
car I cdr references.<br />
These functions, and the use of s<strong>et</strong>f with car, cdr. and mends. are norm<strong>al</strong>ly coded by<br />
the <strong>NIL</strong> compiler as speci<strong>al</strong> subroutine caUs into the <strong>NIL</strong> kernel which do argument<br />
checking. but are faster than function c<strong>al</strong>ls. Use of the speed qu<strong>al</strong>ity with the optimize<br />
declaration may override this; see section 24.2, page 246.<br />
f1 rst list<br />
second lisl'<br />
th 1 rd lisl<br />
fourth lisl<br />
fifth lisl<br />
sixth Iisl<br />
seventh lisl<br />
eighth lisl<br />
ninth lisl<br />
tenth lisl<br />
car, cadr, ctc. lbese may <strong>al</strong>l be used with s<strong>et</strong>f.<br />
MC:NII.MAN:LIST 37<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 57 Creating. Accessing, and Modifying Lisl. ..<br />
Note that the names of these functions use one-origin indexing:<br />
(third x) (nth 2 x)<br />
rest list<br />
cdr. This may be used with s<strong>et</strong>f.<br />
nth index list<br />
R<strong>et</strong>urns the illdextl1 clement of list. zero origined. Note <strong>al</strong>so tl1at this takes its arguments<br />
in a different order than 'elt (and other more speci<strong>al</strong>ized sequence accessors).<br />
If illt/ex is not less than 111e length of lisl. nth r<strong>et</strong>urns nil by an<strong>al</strong>ogy to car and cdr. In<br />
111is it <strong>al</strong>so differs from elt.<br />
nthcdr mimes list<br />
, Relurl1S list after mimes cdrs have been taken on it.<br />
Note <strong>al</strong>so tl1e t reader-macro (section 20.1.1. page 216). which is convenient for creating list<br />
structure in template form. especi<strong>al</strong>ly if large portions of it are constant. and push (page 38) and<br />
pop (page 38) which can be lIsed lO maintain a list in FIFO fonn in an arbitrary s<strong>et</strong>fable place.<br />
cons x y<br />
Makes a cons whose car is x. and whose cdr is y.<br />
ncons x<br />
Equiv<strong>al</strong>ent to (cons x nil).<br />
xcons x y<br />
"Exchanged" cons. Equiv<strong>al</strong>ent to (cons y x). This function is not nonn<strong>al</strong>ly used~ it is<br />
inherited from MACLISP. where its existence is mainly for me benefit of me compiler in<br />
rewriting c<strong>al</strong>ls to list into c<strong>al</strong>ls it could chain tog<strong>et</strong>her the computations of b<strong>et</strong>ter:<br />
(list x y z)<br />
==> (xcons (xeons (ncons z) y) x)<br />
11 s t &rcst elements<br />
R<strong>et</strong>urns a freshly created list of its arguments.<br />
(list) => nil<br />
(list 'x) => (x)<br />
(list 'x 'y) => (x y)<br />
11 st. first-thing &rest other-things<br />
Sort of like list. but the last argument to list. is used as the cdr of the fin<strong>al</strong> cons.<br />
instead of nil. Alternatively. it may be thought of as many nested conses:<br />
(list- 'a) => a<br />
(list. 'a 'b) => (a. b)<br />
(list. 'a 'b 'e) => (a b . e)<br />
(list- fa 'b nil) => (a b)<br />
MC:<strong>NIL</strong>MAN:LIST 37<br />
23-DEC-83
Creating, Accessing. and Modifying List .• 58 Nil. Manu<strong>al</strong><br />
make-l1 st size-of list &key il1i1i<strong>al</strong>-elemelll<br />
Creates a list of nils size-offisl lung. whose clemcnl~<br />
nil).<br />
arc inili<strong>al</strong>-elemeflf (which defaults to<br />
append &rcst lisls<br />
(append x y) r<strong>et</strong>urns a list which has first <strong>al</strong>l of the elements of x, fol1owed by <strong>al</strong>l of<br />
the clements of y; for instance.<br />
(append '(a b) '(x y» => (a b x y)<br />
The subpart of this list (in the example. the cddr) is the origin<strong>al</strong> last argument to<br />
append: append never copies its last argument.<br />
(append x )' z)<br />
==> (append x (append y z»<br />
When given une argument, append r<strong>et</strong>urns that argument: with no arguments, it r<strong>et</strong>urns<br />
nil.<br />
If just copying a list is desired, it is stylistic<strong>al</strong>ly b<strong>et</strong>ter to usc (copy-list /is/) (page 59)<br />
rather than (append list nit).<br />
revappend list I Iisl!<br />
This is like (append (reverse lisll) !ist!). but is more effident because it only has to<br />
make one pass over listl.<br />
last Iisl<br />
RNllrn, rhl' l~~t (,one; of lis, (!!!H th~ last e!('m~nt!). un!~ss lis! i~ nil. in ',I,'hkh c~ze it<br />
r<strong>et</strong>urns nil. In r\1L. last de<strong>al</strong>s properly with a non-nun last cdr of /isl. The only noncons<br />
it will accept as an argument howcyer is nil.<br />
(last '(1 2 3 4 5» => (5)<br />
(last '(a b . e)} => (b. c)<br />
(last nil) => nil<br />
nco n c &rest lists<br />
Joins tog<strong>et</strong>her <strong>al</strong>l of the lists by destructively modifying them. Specific<strong>al</strong>ly, for each of<br />
the lists which is not nil~ the fin<strong>al</strong> cons (as might be r<strong>et</strong>urned· by last) is modified by<br />
rpJacd to be the next list<br />
(s<strong>et</strong>q 11 '(a b»<br />
(s<strong>et</strong>q 12 '(x .v»<br />
(ncone 11 12) => (a b x y)<br />
and now,<br />
11 => (a b x y)<br />
One should be careful. however, about using ncone strictly for. effect (i.e., not using the<br />
r<strong>et</strong>urned v<strong>al</strong>ue), because if the first list is nil (the empty list) the desired side-effect will<br />
not occur.<br />
nreconc listl list2<br />
'Ibis is like (ncone (nreverse Jisll) lisI2), but can be faster because it only has to make<br />
one pass over lisil.<br />
~1C:NII.MAN:LIST 37<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 59 Creating. Accessing. and Modifying List ...<br />
list-length list<br />
list-length r<strong>et</strong>urns the length of the list lisl. If list is circular. then list-length r<strong>et</strong>urns<br />
nil--in this it differs from length, which in r\lL will sign<strong>al</strong> an error but in other COMMON<br />
LISP implementations may fail to terminate.<br />
It is an error for Iisl to not tenninate with nil (assuming it is not circular). In this, listlength<br />
differs from its implementation in previous releases of <strong>NIL</strong>.<br />
copy-l1 s t list<br />
Copies the top-level cnnses of list. This may be used to replace the common idiom<br />
(append lis/ (»<br />
and. addition<strong>al</strong>ly. handles a non-null last cdr of lis/ gracefully.<br />
copy-<strong>al</strong>ist a-lisl<br />
Like copy-list. and addition<strong>al</strong>ly. each top-level clement of a-list which is a cons has that<br />
first cons copied <strong>al</strong>so (1101 tJle entire top-level of the a-list cntry).<br />
Note that this function name contains "<strong>al</strong>ist", a term which is spelled "a-list" everywhere<br />
else now.<br />
This replaces the LISP MACHINE LISP function copy<strong>al</strong>ist, which exists identic<strong>al</strong>ly in <strong>NIL</strong>.<br />
copy-tree tree<br />
R<strong>et</strong>urns a copy of tree. Recurses through both the car and the cdr. tcrminating at nonconses.<br />
That is. only conses are copied. This replaces the old MAC'l.lSP idiom<br />
(subst nil nil "eel<br />
which has been changed incompatibly by COMMON LISP (page 60).<br />
This function is thc COMMON I.ISP equiv<strong>al</strong>ent of the LISP<br />
function, which is defined in <strong>NIL</strong> as a synonym for copy-tree.<br />
MACHINE LISP copytree<br />
butlast list &option<strong>al</strong> (n/)<br />
This r<strong>et</strong>urns a copy of lisl, but without the last n elements. If the length of the list is<br />
less than or equ<strong>al</strong> to n, nil is r<strong>et</strong>urned.<br />
(butlast '(1 2 3» => (1 2)<br />
(butlast '(1 2 3) 2) => (1)<br />
(butlast '(I» => nil<br />
(but1ast nil) => nil<br />
nbut 1 ast list &option<strong>al</strong> (n I)<br />
Destructive version of butlast: the last n elements of list are "spliced out", by rplacd.<br />
nbutlast should be used for v<strong>al</strong>ue. however, because if the length of the list is less than<br />
or equ<strong>al</strong> to n, nil is r<strong>et</strong>urned and no "splicing" is perfonned.<br />
ta 11 P sublist list<br />
tailp r<strong>et</strong>urns t if sublist is a sublist of list. nil otherwise. What this means is that after<br />
taking some numbcr of cdrs of list (possibly l.cro), one gcts to a list eq to list.<br />
MC:<strong>NIL</strong>MAN:LIST 37
Substitution 60 <strong>NIL</strong> Manu<strong>al</strong><br />
1 d 1 ft list sublist<br />
If (taiJp sublisl list) is tnJe,ldiffC"1ist differencc") r<strong>et</strong>urns a list of the clements of lisl up<br />
to but not including sublist. This is the same as .<br />
( nbut 1 as t list (1 ength sublist})<br />
If (tailp sublist list) is f<strong>al</strong>se. Idiff simply r<strong>et</strong>urns a copy of list.<br />
8.2 Substitution<br />
These functions arc extensions of the subst and subJis functions which are defined by<br />
\1:\('1 ISP and liSP MAClIl~F IJSP. NOle LI),ll LIley by dcfhult usc eql to lest for equ<strong>al</strong>ity; Lllis is<br />
incompatible with MACI.1SJl mld an e,lrly release of Nil.. in which subst used equ<strong>al</strong> but sublis<br />
lIsed eq (but only worked on symbuls). A different tcst may be specified by usc of the :test<br />
keywordcd arg~lment: this is a predicate of two arguments used to test "cQu<strong>al</strong>ity". )f it is more<br />
convenient, the sense of the predicate may be reversed by usc of the :test-not keyword.<br />
Note <strong>al</strong>so thatthcse functions only descend through list structure ('·trees")~<br />
inside of vcctors. arrays. or other structures.<br />
they do not 100k<br />
subst new old tree &key test lest-not" key<br />
R cturnsa copy of tree. with n('w. substituted when a of the tree matches old according to<br />
the test.<br />
This is incompatible with MACUSP subst. in that the result is 1101 guaranteed to <strong>al</strong>ways<br />
copy even if substitution is not perfonned. TheMACUsp idiom (subst nil nil lrer) is<br />
replaced by the copy-tree function (page 59). Be on the lookout for the use of this<br />
idiom in old code. for it can cause obscure bugs when uncopied structure is modified.<br />
The Nil. compiler will warn about usc of this idiom and turn the subst into a ~1n to<br />
copy-tree if (1) there are no keyworded arguments supplied (2) Ilewand old arc constants<br />
d<strong>et</strong>erminable at compile-time and (3) their v<strong>al</strong>ues are eql. The runtime function cannot<br />
d<strong>et</strong>ect this idiom.<br />
nsubst new old tree &key lest lesl-.nol key<br />
Like subst •. but does not copy: the new components are destructively stored in tree.<br />
However, this should be used for v<strong>al</strong>uc, for if tree matches old.- the result is new but no<br />
bashing of list structure is done.<br />
sub 11 s ~list tree &kcy lest lest-llot key<br />
Like subst. but performs substitution for sever<strong>al</strong> things. at once. a-lisl is an association<br />
list of the· objects to match. and their replacements. For example,<br />
(sublis '«yes. no) (t . nil» '(t gener<strong>al</strong>ly means yes»<br />
=>(n11 gener<strong>al</strong>ly means no)<br />
sublis. remember, looks at cars and cdrs equiv<strong>al</strong>ently. If we attempt to invert the above<br />
example. we g<strong>et</strong><br />
(sublis '(no. yes) (nil. t» '(nil gener<strong>al</strong>ly means no»<br />
=> (t gener<strong>al</strong>ly means yes . t)<br />
MC:NI1.MAN:LIST 37<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 61 Using I ,ists as S<strong>et</strong>s<br />
nsub 11 s a-list tree &key test test-not key<br />
I.ike sublis. but destructive. See <strong>al</strong>so nsubst.<br />
8.3 Using Lists as S<strong>et</strong>s<br />
One common use of lists is as s<strong>et</strong>s of objects~<br />
of functions for doing this.<br />
<strong>NIL</strong> (and COMMON LISP) provide a complement<br />
All of the functions take similar arguments. Nonn<strong>al</strong>Iy. they use eql as their predicate. so that<br />
they work on numbers properly <strong>al</strong>so. If this is not suitable for the purpose. then a predicate may<br />
be specified by gh'ing it as the :test kcyworded argument. For instance.<br />
(union '«a b) (b) (e» '«d) (e) (a b) (b» :test "equ<strong>al</strong>)<br />
=> «a b) (b) (e) (d) (e})<br />
The scns~ of the predicate can be reversed by using :test-not instead of :test.<br />
Som<strong>et</strong>imes the c1ements of the s<strong>et</strong> arc d~lt41S1ructures of some sort. and one desires to only<br />
compare one part of the datastructure. but not write a predicate to compare things. If thc :key<br />
kcyworded argument is used. then that is a function which will be applied to each clement as it<br />
is tested. and the results of that will be given to the equ<strong>al</strong>ity predicate, rather than the elements<br />
themselves. for example,<br />
(union '«a) (b) (e» '«d) (e) (a) (b)) :key 'tcar}<br />
=> «a) (b) (c) (d) (e»<br />
The :key-specified function is only applied to elemenL~ extracted from lists, never to sin81~ ilpm<br />
arguments givcn to any of these functions (such as member. below). The ordering of the result<br />
may not be depended on; neither may the result if either of the inputs contains duplicate<br />
clements (as defined by the predicate). nor the particular choice of clement (that is. the one from<br />
the first list or the one from the second I~st). Thus.<br />
(union '«a) (b x) (c}) '«d) (e) (e) (b y» :key "car)<br />
might r<strong>et</strong>urn either of the s<strong>et</strong>s<br />
«a) (b x) (c) Cd) (e»<br />
or<br />
«a) (b y) (c) (d) (e»<br />
since they are equiv<strong>al</strong>ent according to the test criteria.<br />
member item list &key test test-not key<br />
If item is a member of list according to the specified test (which defaults to # 'eql). then<br />
member r<strong>et</strong>urns the sublist whose car satisfied the test. Otherwise. nil is r<strong>et</strong>urned. The<br />
other functions in this section (Ire implemented in terms of this. Note that if a function is<br />
specified with :key, it is only applied to items of list. not to item.<br />
Note that the default predicate for member. # 'eqJ. is incompatible with MACLISP member.<br />
This provides consistency with an other similar functions.<br />
memq item list<br />
This is member with a test of # 'eq. memq is not defined by COMMOl' USP, but is<br />
inherited from MACIJSP. It is speci<strong>al</strong>ly handled by the <strong>NIL</strong> compHer.<br />
MC:<strong>NIL</strong>MAN:I.IST 37<br />
23-DEC-83
• _ .,<br />
Using Lists (is S<strong>et</strong>s<br />
un ion lisll lis/2 &key<br />
s<strong>et</strong>-difference Ii.'ill lisl} ,&kcy lesl leSI-no/ key<br />
} are used to constructthc result.<br />
Rcturns the s<strong>et</strong> diffcrence of lisl! and lisl} (a list of the elcments of lisil which arc not<br />
present in lisl2. according to the predicate).<br />
ns<strong>et</strong>-difference list! lisI2 &'key leSI leSI-I1o/ key<br />
IJcstructi\,c s<strong>et</strong>-difference: the result is constructed from the conses of lisil and/or lisl!.<br />
s<strong>et</strong>-exclus ive-or lisll lis12 &key leSI lest-nol key<br />
R<strong>et</strong>urns a list of the clements which occur in eithcr lis" or lis/}. bill not both. according<br />
to the predicate.<br />
ns<strong>et</strong>-exclusive-or listl list2 &key leSI /esl-1101<br />
Destructive s<strong>et</strong>-exclusive-or: the result is constructed from the conses of lisil and/or.<br />
list2.<br />
subs<strong>et</strong>p Iisll lisl2 &key lesl IttSI-110/ key<br />
R<strong>et</strong>urns t if lisil is a SUbs<strong>et</strong> of (bUt not necessarily a proper subs<strong>et</strong> of) lisa. nil otherwise.<br />
adjoi n item lis/ &key leSI lesl-not key<br />
If ilem is a member of lisl according to the specified test, this just r<strong>et</strong>urns lisl: otherwise.<br />
it conscs ilem onto the front of list. and r<strong>et</strong>urns th<strong>al</strong> adjoin could have been defined as<br />
(defun adjoin (item list &rest keyworded-args<br />
&key test test-not key)<br />
(if (apply #'member item list keyworded-args)<br />
list<br />
(cons item list»)<br />
which <strong>al</strong>so shows the utility of the &rest keyword combined with &key.<br />
key<br />
MC:<strong>NIL</strong>MAN:I.IST 37<br />
23-DEC-S3<br />
-. . .<br />
. ..' . .:,..::,"'
<strong>NIL</strong> Manu<strong>al</strong> 63 Association I -ists<br />
8.4 Association Lists<br />
Association lists arc an abstraction built from lists which arc useful in many cases. An<br />
association lisl (or a-list, som<strong>et</strong>imes misspelled <strong>al</strong>isl in this document), is a list.. <strong>al</strong>l clements of<br />
which are conses: the car of each cons is the key, and the cdr of each cons is the data<br />
associated with that key. Association list~ differ slightly from just lists used as sequences utilizing<br />
a key of car (or cdr): if an entry in an association list is the atom nil, then it will be ignored<br />
tot<strong>al</strong>ly. Functions which de<strong>al</strong> with more gener<strong>al</strong> sequences or lists. such as member, find, and<br />
position. would blindly apply the supplied key (e.g.. car) to nil. and try matching this against<br />
the item being searched for.<br />
There are two common ways in which aSSOCiation lists are used. For one. what is being<br />
constructed is basic<strong>al</strong>ly just a lilb1e with entries of a single key. In this. the entries in the a-list<br />
are cnnses of the key and the data associated with the key. and one uses assoc with an<br />
appropriate test to do the lookup: the data of the key may be replaced by using rplacd on the<br />
result of the assoc. assuming assoc did not r<strong>et</strong>urn nil. There are two potenti<strong>al</strong> disadvantages<br />
with this approach. First, the lookup is linear. so the lookup time grows linearly with the length<br />
of the tahle. How much this matters depends on the efficiency of the equ<strong>al</strong>ity predicate in usc:<br />
eq is extremely fast. and eql is fairly fast, so this could matter a fair amount if they arc the<br />
predicates in usc. Second. because a-lists arc constnlcted out of C(lnses. they can be scattered <strong>al</strong>l<br />
over \'inu<strong>al</strong> memory and cause poor paging performance: it is possihle for each cons in an a-list<br />
to lie on a different page. If entries are only rarely added to or removed from the table (entire<br />
entries. not just update of the car or cdr of an a-list entry), it might be reasonable to ensure<br />
ta'iut th\: a liSi lk5 ira fairly cuntiguous virtud] Hi(;Jii\ii) b,)' \.:oJ.'yiug it wilil l;(JIJY-i2ii~i (page 59)<br />
when som<strong>et</strong>hing is added to it. Some rough guesses. with a test of eq: if the a-list has over 50.<br />
entries, it is probably b<strong>et</strong>ter to use a hash table. For 70 or 80. a hash table is vinu<strong>al</strong>1y<br />
guaranteed to be b<strong>et</strong>ter, unless most of the lookups wi1l succeed, and find entries near to the<br />
front. For b<strong>et</strong>ween 5 and 10 entries. an a-list is <strong>al</strong>most undoubtedly best. and can he optimized<br />
by copying with copy-<strong>al</strong>ist. For v<strong>al</strong>ues b<strong>et</strong>ween 10 and 50. the decision on which to use<br />
requires b<strong>al</strong>ancing additions and del<strong>et</strong>ions against wasting time (and creating garbage) using copy<strong>al</strong>ist.<br />
Probably it is best to only do the copying with copy-<strong>al</strong>ist for tables which are not updated<br />
in th,e "norm<strong>al</strong> course of program running", i.e., which might only be updated when new files are<br />
loaded.<br />
The other common use of a-lists is where the implicit ordering of a list comes into play. One<br />
entry in the association list might have the same key' as another which occurs "later" in the a-list;<br />
since association lists are <strong>al</strong>ways searched in left-to-right order, the first occurence will shadow any<br />
other occurences. A simple LISP lexic<strong>al</strong> interpr<strong>et</strong>er might use an association list to hold the lexic<strong>al</strong><br />
variable bindings, for instance. "Binding" pushes the new variable/v<strong>al</strong>ue pair on the front of the<br />
"environment" a-list. and "unbinding" pops the entry off. For this son of use, hash tables do<br />
not present an <strong>al</strong>ternative without some hairy hacking of "contexts".<br />
A third possible use of an a-list is for two-way associations; that is, the car and cdr may<br />
both be viewed as keys used to look. up the other: one uses assoc to find the entry by the car<br />
key, and rassoc to find the entry by the cdr key. Hash tables do not provide this son of<br />
service: if a-list lookup time is prohibitive in a particular case. the <strong>al</strong>ternative is to usc two hash<br />
tables.<br />
MC:NJI.MAN;I.IST 37<br />
23-DEC-83
Association l.ists 64 <strong>NIL</strong> Manu<strong>al</strong><br />
as soc item a-lisl &key lesl lesl-nol<br />
Searches a-lisl for an entry whose car matches ilem according to the specified test. I f one<br />
is found. that cons is r<strong>et</strong>urned; otherwise nil is r<strong>et</strong>urned. If a non-null result is r<strong>et</strong>urned,<br />
the datum of it may be modified by use of rplacd.<br />
Note <strong>al</strong>so that since the default test is # 'eql, this is incompatible with MACLISP assoc.<br />
To r<strong>et</strong>ain the same effect. one must· use<br />
(assoc item a-list :test "equ<strong>al</strong>)<br />
or simply assq (below). Of course. often the choice of assoc in MACTISP is because item<br />
is a number, so equ<strong>al</strong> is not needed in Nil becausc eql compares numhcrs correctly.<br />
ras soc il(,l11 a-/isl &key lesl lesl-l1ot key<br />
l.ike assoc, except that item is matched against each datum in a-lisl. rather than each<br />
key.<br />
assq item a-lisl<br />
This is inherited from MACl.lSP and <strong>al</strong>so .is defined by I.1SP MAClllt\F 1 JSP: it is 1101<br />
defined by CO\1~ON I.ISP. It is identic<strong>al</strong> to<br />
(assoc ilC111 a-Jisl : test #'eq)<br />
Compilation of assqdocs ·1101 produce any different code than the above fonn. so the<br />
choice b<strong>et</strong>ween the two is b<strong>et</strong>ween COMMON LISP compatibility and verbosity in the source<br />
code.<br />
r"~~q<br />
i'I'''' n-If~!<br />
'111is is inherited from LISP MACHINE LISP; it is not defined by COMMOT' LISP.<br />
same as<br />
(rassoc item a-list :test I'eq)<br />
Sec assq (above) for more qu<strong>al</strong>ifications.<br />
It is the<br />
aeons key datum a-liSI<br />
This is the same as<br />
{cons (cons key datum) a-lis/)<br />
but shows the intent b<strong>et</strong>ter.<br />
pa 1 rl1 s keys data &option<strong>al</strong> a-Iist<br />
R<strong>et</strong>urns an a-list made by associating keys and d<strong>al</strong>a and adding them to the front of a-iisl<br />
(which defaults to nil). keys and data must be lists of the same length.<br />
(pairlis '(foo bar) '("Foo" "Bar") '«baz . "Baz"»)<br />
=> ( (foo . "Foo") (bar . "Bar") (baz . "8az"»<br />
The result will share structure with a-list (that is. (tailp a-list paiTIi~result) is 0, so<br />
modifications to the associations in the r<strong>et</strong>urned result will atfectthose assocations in a-list<br />
<strong>al</strong>so.<br />
MC:NII.MAN;I.IST 37<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 65 Symbols<br />
9. Synlbols<br />
9.1 The Property List<br />
See <strong>al</strong>so section 5.10, page 39, which de<strong>al</strong>s with property lists in a more gener<strong>al</strong> way.<br />
symbo 1 - P 11 s t symbol<br />
R<strong>et</strong>urns the property list of symbol. Unlike the MACLISP pUst function. this only works<br />
on symbols. not disembodied property lists.<br />
symbol- pHst J11~ly he used with s<strong>et</strong>f to change the property list of a symhoL This is<br />
gener<strong>al</strong>ly not rec()mmcnd~dpraclicc. however. because doing so might c<strong>al</strong>lsc properties<br />
essenti<strong>al</strong> to tllC ~Jl. system to be lost.<br />
g<strong>et</strong> sJ'Il1bul indicator<br />
Standard MAC'I.ISI) ·g<strong>et</strong>. The v<strong>al</strong>ue stored under indica/or on the property list of symbol is<br />
r<strong>et</strong>urned: if tllere is no such v<strong>al</strong>ue. nil is r<strong>et</strong>urned. As in MACUSP. symbol may <strong>al</strong>so be a<br />
disemhodied property list. Unlike in MAC'I.lSP. g<strong>et</strong> docs not arhirrarily check the type and<br />
then r<strong>et</strong>urn nil if it is ncitller a symbol nor a list; in :-';11. one g<strong>et</strong>s an error for an inv<strong>al</strong>id<br />
type.<br />
For both MACLISP compatibility and convenience. g<strong>et</strong> is not going to disappear in tlle<br />
future.<br />
putprop s),mbol v<strong>al</strong>ue indicator<br />
Standard MACLISP putprop. If symbol <strong>al</strong>ready has an indica/or property. tllis replaces it<br />
with v<strong>al</strong>ue. otherwise puts a new one. As in MACLlSP, symbol may <strong>al</strong>so be a disembodied<br />
property list<br />
COMMO~ LISP does not define putprop: rather. one uses s<strong>et</strong>f with g<strong>et</strong>f (page 39).<br />
putprop is not going to be flushed from <strong>NIL</strong>, however. Note <strong>al</strong>so that putprop takes its<br />
arguments in a different order from the "standard s<strong>et</strong>f order" in which the v<strong>al</strong>ue being<br />
s.tored comes last<br />
remprop symbol indicator<br />
Standard MACUSP remprop. If symbol has an indica/or propcrty, then that is removed by<br />
being spliced out of the property Jist. and tlle subHst of tllc property list whose car is the<br />
v<strong>al</strong>ue (being removed) is r<strong>et</strong>urned. If there is no such property, nil is r<strong>et</strong>urned. For<br />
instance, if one does<br />
(putprop 'kitty 'yu~shiang 'flavor)<br />
then<br />
(remprop 'kitty 'flavor)<br />
= > ( y u - s h ian 9 and maybe some subllsl 0/ the property list)<br />
. See <strong>al</strong>so the remf macro, page 40 .. for removing properties from property lists stored in<br />
arbitrary places.<br />
MC:<strong>NIL</strong>MAN;SYMBOL 30<br />
23-DEC-83<br />
'.<br />
'<br />
; ~ ---- . ~ ~<br />
. - ~ ~ - .<br />
, ". ,', ~~< .'. . ~ '. "-,'.::,'" .. " ,- - . ~, . ' "'". ..." ..".. '. .. "",', .; "
The Prill( Name<br />
66<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
Note: COMMON USP docs not define the actu<strong>al</strong> v<strong>al</strong>ue r<strong>et</strong>urned by remprop. only that it<br />
will be null if the property was not found, non-null if it was. The v<strong>al</strong>ue r<strong>et</strong>urned by <strong>NIL</strong><br />
remprop is compatible with MACLISP. and wilJ be r<strong>et</strong>ained fi)r that compatibility.<br />
9.2 The Print Name<br />
symbol-name symbol<br />
R<strong>et</strong>urns the name of symbol. which is a string.<br />
Note that a string which is a symbol name should never be modified: ncitJler should the<br />
name of a symbol be changed.<br />
In ~II .•<br />
the name Of.'l symbol will <strong>al</strong>ways be a simple string.<br />
The mime of a symhol has variously been c<strong>al</strong>Jed a prilll 1Iame and a pname. tenns which<br />
are being phased out but· stiU pervade the <strong>NIL</strong> implementation.<br />
samepnamep s)'1171<br />
sym2<br />
R<strong>et</strong>urns t if syml and sym2 have equ<strong>al</strong> print names. Case is significant. syml and s)'1112<br />
may be strings too. Either (or both) of the symbols may be specified as strings instead~<br />
samepnamep is reany just a MACLISP function. It is obsol<strong>et</strong>ed by string = (page 113).<br />
because the string comparison functions in SIL will accept symbols and perfonn the<br />
comparison on their namcs.<br />
9.3 Creating Symbols<br />
make-symbol pname<br />
Makes a new uninterned symbol whose print-name is the string pname. It will have no<br />
v<strong>al</strong>ue or function bindings. no package, and an empty propeny list<br />
That the print-name (as r<strong>et</strong>urned by symbol-print-name) of the r<strong>et</strong>urned symbol will be<br />
eq to p"ame should not be depended upon.<br />
copy-symbol sym &option<strong>al</strong> coprprops<br />
If copy-props is nil. then this is the same as (make-symbol (symbol-name S)'111»; that is<br />
t<br />
it r<strong>et</strong>urns a virgin symbol with the same print-name as sym. If Coprprops is not nil then<br />
t<br />
the v<strong>al</strong>ue and function definition and propeny-Jist and package of sym wiJI be copied to<br />
the new symbol.<br />
Actu<strong>al</strong>ly. the current dynamic bindings (v<strong>al</strong>ue and function) of sym are copied to the new<br />
glob<strong>al</strong> dynamic bindings of the new symbol.<br />
,<br />
copy-symbol with a nun copy-props argument is a reasonable way to generate a unique<br />
symhol which is somewhat mnemonic <strong>al</strong>though not compl<strong>et</strong>cJy visu<strong>al</strong>ly unique. The <strong>NIL</strong><br />
compiler copics symbols like if-f<strong>al</strong>se to generate tags. for instance: no new print name is<br />
created. just the basic symbol structure. on which· properties can be placed. If the symbol<br />
is to be used as a variable in macro expansions, however. it may be b<strong>et</strong>ter to use<br />
MC: N I LM 1\ N :SYM BOL 30<br />
23-DEC-83<br />
. . - . -<br />
, -' . .. . . . - - .' - '<br />
> .>.>, .. ". >' ••.. " .. "J'~>: .; .• 'i}/:'~ "1:'...,',,) >":, ~";>"
<strong>NIL</strong> Manu<strong>al</strong> 67 Creating Symhols<br />
gentemp (below).<br />
gensym &option<strong>al</strong> x<br />
Standard inherited-from-MACLISP gensym. gensym creates new uninterned symbols. The<br />
print name of the symbol is constructed by prepending a single character prefix' to the<br />
decim<strong>al</strong> representation of a counter which g<strong>et</strong>s incremented every time gensym is c<strong>al</strong>led.<br />
The name has been around for so long that automatic<strong>al</strong>1y generated names arc commonly<br />
refered to as geIlSYI1lS, and the act of doing so as gl'flsyming.<br />
(gensym) r<strong>et</strong>urns such a constructed symbol.<br />
(gensym lI<strong>al</strong>ll£» s<strong>et</strong>s the prefix to he n<strong>al</strong>ll£>. which must be a string or a svmhol. and<br />
then makes a gensym. (In ~1AC1.lSP. only the first character of name is used: in NIl.. the<br />
entire name is.)<br />
(gensym illteger) s<strong>et</strong>s the counter to i11leger, and then makes a gensym. illIeger must<br />
not be negative.<br />
gentemp &option<strong>al</strong> prefix package<br />
gensym creates a symbol in a manner similar to gensym. but interns it in package<br />
(which defaults to the current package). Addition<strong>al</strong>ly, gentemp guarantees that the<br />
symbol is unique by continuing to increment its intern<strong>al</strong> counter until it succeeds in<br />
constructing a symbol which has nol <strong>al</strong>ready been interned in package.<br />
Unlike gensym. the prefix argument to gentemp is not "sticky": that is. it does not<br />
default to the last one supplied. If it is not supplied, it defaults to t. Also, there is no<br />
provision for res<strong>et</strong>ting the intern<strong>al</strong> counter.<br />
Use this for creating variables for usc in macro expansions. because the symbol can be<br />
typed in .. Also, gentemp will leave some infonnation around so that code an<strong>al</strong>yzers or<br />
the compiler can see that the variable is a generated variable so may . be optimized away<br />
without loss of debugging infonnation. (Nonn<strong>al</strong>1y such a test would be that the symbol is<br />
not interned. i.e .. it was created by gensym or copy-symbol. lbis does not work for<br />
gentemp because gentemp interns the symbol so it can be typed in for debugging.) In<br />
1'11... gentemp-crcatcd symbols are flagged by having a non-null si:gentemp-marker<br />
property.<br />
symbol-package symbol<br />
This r<strong>et</strong>urns the "home package" of symbol, or nil if symbol does not have one (it is not<br />
interned).<br />
MC:<strong>NIL</strong>MAN:SYMBOL 30<br />
23-DEC-83<br />
. .... ...• ~ ,.
a<br />
The V<strong>al</strong>ue and FunctiunCeHs 68 Nil. Manu<strong>al</strong><br />
9.4 The V<strong>al</strong>ue and Function Cells<br />
See <strong>al</strong>so chapter 3. page 11 k)r discussion about scope. extent. and binding. and chapter 3.<br />
page 11 for a description of the <strong>NIL</strong> intern<strong>al</strong> mechanism for performing variable and function<br />
binding.<br />
Speci<strong>al</strong> implementation qu<strong>al</strong>ification: because of the hairy v<strong>al</strong>ue cell mechanism in <strong>NIL</strong>. v<strong>al</strong>ue<br />
cells arc not just <strong>al</strong>located in the heap. so (due to lack of code to do some relocation right now)<br />
there is an assembly-timc timi~ltjon on how many may he cremed. Thus, generating symbols and<br />
using the v<strong>al</strong>uc cells to store things may not work as . well as you expected (an error complaining<br />
NEW_SLINK wants to grow the SLINK occurs). This limil4ltioll is nol a function of the<br />
mechanism but rather of the Im:k of garb.lge-collccior. however.<br />
symbo l-V8 1 ue symbol<br />
R<strong>et</strong>urns the current dynamic (speci<strong>al</strong>) vaJucof symbol.<br />
symbol-v<strong>al</strong>ue may be used with s<strong>et</strong>f.<br />
boundp symbol<br />
R<strong>et</strong>urns t if symbol has a defined dynamic (speci<strong>al</strong>) v<strong>al</strong>ue, nil otherwise. Note that<br />
(s<strong>et</strong>q *foo* 1) => 1<br />
(l<strong>et</strong> «.foo. 3»<br />
(declare (speci<strong>al</strong> .foo.»<br />
(makunbound '.foo*)<br />
(boundp '*foo*»<br />
=> nil<br />
=> 1<br />
makunbound symbol<br />
"Undefines" the current dynamic v<strong>al</strong>ue of symbol.<br />
An error is sign<strong>al</strong>led if symbol is a constant (as defined by defconstant).<br />
symbol-function symbol<br />
R<strong>et</strong>urns the current dynamic (speci<strong>al</strong>) function v<strong>al</strong>ue of symbol. The result of symbolfunction<br />
on a symbol defined as a macro or speci<strong>al</strong> fonn is undefined in COMMON LISP.<br />
In <strong>NIL</strong>. speci<strong>al</strong> fonn definitions are not stored here, but other kinds of function<br />
definitions are.<br />
symbol-function may be used with s<strong>et</strong>f.<br />
fboundp symbol<br />
R<strong>et</strong>urns t if symbol has a defined dynamic function v<strong>al</strong>ue, nil otherwise. (Like boundp.)<br />
fmakunbound symbol<br />
An<strong>al</strong>ogous to· makunbound.<br />
MC:<strong>NIL</strong>MAN;SYMBOL 30<br />
23-DEC-83
••<br />
Nil. Manu<strong>al</strong> 69 Addition<strong>al</strong> Names<br />
9.5 Addition<strong>al</strong> Names<br />
Some other MACLlSP-compatibJe. LISP MACJlJI':E LIsP-compatible, and older <strong>NIL</strong>-compatible<br />
names.<br />
symev<strong>al</strong> symbol<br />
Same as symbol-v<strong>al</strong>ue, page 68.<br />
s<strong>et</strong> symbol v<strong>al</strong>ue .<br />
Same as (s<strong>et</strong>f (symbol-v<strong>al</strong>ue symbol) v<strong>al</strong>ue).<br />
fsymev<strong>al</strong> symbol<br />
Same as symbol-function. page 68.<br />
fs<strong>et</strong> ,symbol fUllc/ion<br />
Same as (s<strong>et</strong>f (symbol-function symbol) function).<br />
~ u t - P name symbol<br />
Same as symbol-name. page 66.<br />
P 11 st symbol<br />
Same as symbol-pJist. page 65. Note that this is not exactly the same as the MACLISP<br />
plist function (maybe it should be made to be?). The MACUSP plist function "works" on<br />
disembodied property lists (specific<strong>al</strong>ly. it takes the cdr of a list) - this is sort of an<br />
artifact of the MACLISP implementation.<br />
s<strong>et</strong>p 11 st symbol new-plisl<br />
The same as (s<strong>et</strong>f (symbol-plist· symbol) new-pUst).<br />
qu<strong>al</strong>ifications hold as for plist.<br />
The same MACLlSP-compatibility<br />
g<strong>et</strong> 1 symbol indicator-list<br />
Standard MACLISP g<strong>et</strong>f. R<strong>et</strong>urns the subpart of the property list of symbol beginning with<br />
the first indicator found in the list indicator-Ust, or nil if none was found. As in<br />
MACLlSP, symbol may <strong>al</strong>so be a disembodied property list. Essenti<strong>al</strong>ly, this is the third<br />
v<strong>al</strong>ue r<strong>et</strong>urned by<br />
(g<strong>et</strong>-properties<br />
(if (symbolp symbol) (symbol-plist symbol) (cdr symbol»<br />
indicator-list)<br />
copysymbol symbol &option<strong>al</strong> copy-props<br />
MACLISP name for copy-symbol (page 66). Note that in MACUSP, however, copy-props<br />
is a required argument.<br />
~1C:<strong>NIL</strong>MAN:SYMROL 30<br />
23-DEC-83
Symbol COllc<strong>al</strong>cnt<strong>al</strong>ion<br />
9.6 Symbol Concatentation<br />
70<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
'Ibc following routines are not defined· by COMMON IJSP. but arc fairly useful in lIteir own<br />
right by macros <strong>et</strong>c.<br />
symbo 1 conc &rest frobs<br />
symbolconc r<strong>et</strong>urns a new symbol (interned in lite current package) whose name is lite<br />
concatenation of lite names of frobs. Typic<strong>al</strong>ly. each frob is a symbol. however<br />
symbolconc <strong>al</strong>so <strong>al</strong>lows it to be a fixnum (in which case its dccim.1I printed<br />
represcntation is usro). a sIring. or a character (which must be convertihle 10 a string.<br />
i.c .. satisty string-char-p).<br />
sf: package- symbo 1 conc /'f.J('kagr-sp('C' &rcs( frobs<br />
Simii
--<br />
._-_.-..<br />
-_._----------------------<br />
N II. Manu<strong>al</strong> 71 Numbers<br />
10. Numbers<br />
10.1 Types" Contagion, Coercion, and Confusion<br />
10.1.1 The Types<br />
Nn. provides sever<strong>al</strong> different representations for numbers. It provides integers. of essenti<strong>al</strong>ly<br />
unlimited precision. and floating-point. There is <strong>al</strong>so the ratio data type. for representing noninteger<br />
ration<strong>al</strong> numhers. The complex daw type has heen added. but may not y<strong>et</strong> be<br />
trustworthy for anything other than simple arithm<strong>et</strong>ic operations. and has not y<strong>et</strong> been speci<strong>al</strong>ized<br />
to a point where any significant "crunch" might be performed on it.<br />
<strong>NIL</strong> integers arc currently of two kinds. There arc jixllulIlS and bignulIls . . Fixl1ums have 30<br />
hits of precision. inc1uding the sign. and arc represented without cnnsing (i.e.. no memory<br />
consumption). Integers which reqL'ire more ~an 30 bits to represent are implemented as bignums.<br />
lJigllUII1S arc an extended data-type. and can grow to any size, limited only by whate\er system<br />
param<strong>et</strong>er happens to be limiting the growth of your NIl .• and your patience.<br />
There arc four primitive floating-point fonnats supported in <strong>NIL</strong>, as described in section 2.1,<br />
page 3. These are<br />
short-float<br />
This is implemented as a single-float (VAX f _ f loa t format) with some of the fraction<br />
bits tnmcated. so that it can fit into a !\IL pointer without any memory consumption. An<br />
operations on this type essenti<strong>al</strong>ly convert it to a single-float to perform the operation. and<br />
then pack it back (truncating some of the fraction bits) when it is r<strong>et</strong>urned. 5 of the<br />
fraction bil~ g<strong>et</strong> truncated. leaving 19. or about 5 decim<strong>al</strong> digits of precision. Because the<br />
exponent is the same as for single-float. it has close to the same range. however.<br />
single-float<br />
This corresponds to the VAX f _ float format; this provides 24 bits of precision (about 7<br />
decim<strong>al</strong> digits), and a range of about 2.ge-39 to l.7e+ 38.<br />
double - float<br />
This utilizes the VAX d_float format. which has 56 bits of precision (about 16 decim<strong>al</strong><br />
digits). The exponent fonnat is identic<strong>al</strong> to that of single-float, so the range _ is<br />
essenti<strong>al</strong>ly the same.<br />
long-float<br />
This utilizes the VAX h_float fonnat. This has a whopping 113 bits of precision (33<br />
decim<strong>al</strong> digits), and binary exponent range from -16383 to + 16383. This is a range of<br />
about 8.4e-4933 to 5.ge+4931. Because the machine instructions which operate on this<br />
format of float are not supponed by <strong>al</strong>l VAX hardware. <strong>NIL</strong> makes use of a VMs-supplied<br />
condition handler to cause emulation of the missing instructions. As a compromise. it <strong>al</strong>so<br />
tries to avoid such instructions when it can (for instance, just for data movement).<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83
Types. Contagion. Coercion, and Confusion 72 <strong>NIL</strong> Manu<strong>al</strong><br />
10.1.2 Contagion and Coercion<br />
Most of the <strong>NIL</strong> arithm<strong>et</strong>ic functions are gelleric. rlbat is.. they accept numbers of any type<br />
(subject to the semantics of the functiun. of course). and automatic<strong>al</strong>ly "coerce" as necessary<br />
when there are mixed types. Coercion is mainly a function of the floating-point types. For<br />
instance. division of integcrs might yie1d a ratio:<br />
(I 2 3) => 2/3<br />
Howcver. ration<strong>al</strong> numbcrs are <strong>al</strong>ways ·'norm<strong>al</strong>izcd". and automatic<strong>al</strong>ly "convert" back to intcgers:<br />
(+ 1/3 2/3) => 1<br />
When a flo,ning-point numher mcct~ an integer or a floating~ptlint numbcr uf a "shorter" type.<br />
the latter is cOIn crtcd autumatic<strong>al</strong>ly to thc format of thc .ftlftTIer bcfore thc operation procccds:<br />
(. 2 2.0s0) => ~.OsD<br />
(. 2 2.0dO 2.050) => 8.0dO<br />
Such coinagiolls convcrsion is ncvcr performed in the othcr direction: floating point numbcrs arc<br />
ne\cr COll\'crtcd to integers just because the rcsult might bc intcgr<strong>al</strong>. for cxamplc. or ttl a shortcr<br />
forr< at of float.<br />
Complex numbers in Nil. are restricted to having components which are either both ration<strong>al</strong>.<br />
or both floats of the same format. A complex number with ration<strong>al</strong> components will automatic<strong>al</strong>ly<br />
be converted back to a ration<strong>al</strong> (non-complex) number if the result of a computation gives a zero<br />
imaginary part. This never occurs if the components are· floats:<br />
(. Nc(O 1) Nc(O I)} => -1<br />
(. Nc(O.O 1.0) Nc(O.O 1.0» => Nc(-I.O 0.0)<br />
J 0.1.3 Confusion<br />
As was described in section 2.1. page 3. the fonnat of a floating-point number may be<br />
selected by use of a particular character as the exponent specifier. 'Ibus; 2.0s0 is short-float,<br />
2.0fO is single-float. 2.OdO is double-float, and 2.010 is long-float. COMMON uSPspecifies<br />
that the default fonnat is Single-float. 'Ibis is the fonnat which is used when a floating-point<br />
number is read in. and either no exponent character is used, or one of e is used (e.g., 2.5gel 0).<br />
This is <strong>al</strong>so the format specified as being r<strong>et</strong>urned by exponenti<strong>al</strong>. transcendent<strong>al</strong>, or irration<strong>al</strong><br />
functions when given ration<strong>al</strong> inputs. <strong>NIL</strong> has historic<strong>al</strong>ly had a default (in fact, it used to be the<br />
only) format of double-float. Becausc single-float (and shon and long) are <strong>al</strong>l quite new to <strong>NIL</strong>,<br />
the default format is still double -float. That is. currently<br />
(typep 2.59 'double-float) => t<br />
(typep (log 3/4) 'double-float) -> t<br />
However. Ihis will be changed. The <strong>NIL</strong> reader/printer combination has been twiddlcd somewhat<br />
so that while the default fonnat chosen by read is double-float, the printer will <strong>al</strong>ways print<br />
the exponent character which will force the fonnaL<br />
*read-default-tloat-tormat-<br />
Variable<br />
This variable (which is defined by COMMON USP) names the type of float which read<br />
should create when it encounters one which does not specify the format. It should have<br />
as its v<strong>al</strong>ue short-float. single-float. double-float. or long-float. The COMMON LISP<br />
default for this. is single-float.<br />
MC:NII.MAN;NUMBER 70<br />
23-DEC-83
a<br />
. .<br />
.... .. , ~(::ll;'~.:~j;i~~:~ ... ·3iL,·~L·;:~~iti~:';' .<br />
<strong>NIL</strong> Manu<strong>al</strong> 73 Predicates on Numbers<br />
As a speci<strong>al</strong> interim hack. !'Il. <strong>al</strong>lows this variable to have nil as its v<strong>al</strong>ue. This is taken<br />
to mean (to the reader) to produce double-float by default. but (to the printer) to not<br />
usc an "unspecified" fonnat on output. That is. with .read-default-float-format* being<br />
nil. the prir~ter will never produce "1.0", but rather "1.OdO".<br />
It is strongly recommended that explicit usc ()f coercion (using the float function, page 78) be<br />
made wherever the type of the result might matter. when using functions which must convcrt into<br />
floating-point befi)rc procceding. This includes things like log sin. and sqrt. Note <strong>al</strong>so that<br />
certain operations on complex numhers with ration<strong>al</strong> components. such as abs. implicitly usc<br />
these other functions: for instancc.<br />
(abs #c(3 4)) => 5.0dO<br />
10.2 Predicates on Nunlbers<br />
Note <strong>al</strong>so the type predicates numberp. bignump. integerp. fixnump. floatp. ratiop.<br />
ration<strong>al</strong>p. and complexp.<br />
zerop number<br />
R<strong>et</strong>urns t if number is intcger, floating-point. or complcx lero. nil otherwise.<br />
P 1 usp nOll-complex-number<br />
m1 nusp non-complex-number<br />
R<strong>et</strong>urn t if non-complex-number is of the appropriate sign. nil otherwise.<br />
oddp integer<br />
evenp integer<br />
R<strong>et</strong>urn t if integer is odd (even), nil otherwise.<br />
In <strong>NIL</strong> (but 1101 COMMON USP), oddp and evenp have been extended to gaussian integers.<br />
evenp is defined as divisibility by 1 + i. and oddp as being not evenp. This definition<br />
has the propeny that exactly h<strong>al</strong>f of the gaussian integers are odd and h<strong>al</strong>f are even.<br />
While there is a remote possibility that this definition will be changed, I consider it very<br />
unlikely.<br />
10.3 Comparisons on Numbers<br />
• number &rest more-numbers<br />
/- number &rest more-numbers<br />
< number &rest more-numbers<br />
> number &rest more-numbe1'$<br />
- number &rest more-numbers<br />
Thcse functions each take one or more arguments. If the scqucnce of arguments satisfies<br />
a cenain condition:<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83
Arithm<strong>et</strong>ic Operiltions 74 <strong>NIL</strong> Manu<strong>al</strong><br />
= an the same<br />
I = aU different<br />
< monotonic<strong>al</strong>ly increasing<br />
> monotonic<strong>al</strong>ly decreasing<br />
= monotonicaJIy nonincreasing<br />
then the predicate is· true, and otherwise is f<strong>al</strong>se.<br />
Complex numhers arc only acceptable as arguments to = and / =: the others require<br />
their arguments to be non-complex.<br />
These functions <strong>al</strong>so h4t\"e fixJlum-only and duuble-fioat-only versions.<br />
greaterp 1111111/<br />
I1UlII} & rest more-lJumbers<br />
.1 as s p IIUfIiI ,lIum2 &rest more-l1umbers<br />
These are implemented as synonyms of < and >. and exist for MACI.ISP compatibility.<br />
ma.': number &rest more-llumbers<br />
m1 a I1l1l11be,. &rest morc-numbers<br />
Generic max/min. Works on any non-complex numbers. Note <strong>al</strong>so the existence of<br />
max& and min& (page 87), which only work on fixnums, and max$ and min$ (page 91),<br />
which only work ondouble-ftoats.<br />
10.4 Arithm<strong>et</strong>ic Operations<br />
+ & rest numbers<br />
plus & rest numbers<br />
R<strong>et</strong>urns the sum of <strong>al</strong>l of the numbers. pcrfilrming type coercion as appropriate. If there<br />
are no numbers. 0 is r<strong>et</strong>urned. The name plus is r<strong>et</strong>ained for MACLlSP compatibility.<br />
Note <strong>al</strong>so the fixnum-only + &, and double-float-only + $.<br />
1+<br />
addl number<br />
( P 1 us number 1)<br />
The nameaddl is r<strong>et</strong>ained primarily for MACLISP compatibility.<br />
- number &rcst numbers<br />
With one argument. - r<strong>et</strong>urns the negative of that argument. With more than one<br />
argumcn~ it subtracts <strong>al</strong>l of the others from the first. Type coercion is performed as<br />
necessary. Note <strong>al</strong>so the fixnum-only -a. and double-float-only -$ functions.<br />
d1 fference number &rest numbers<br />
When given more than one argument. difference subtracts from the first argument <strong>al</strong>l the<br />
others. and r<strong>et</strong>urns lhe result \Vhen given one argument. difference r<strong>et</strong>urns it. This is<br />
noteworthy because it is compatible with the MACLISP difference function. and it is<br />
illcompatible with - above.<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83
»<br />
Nil, Manu<strong>al</strong><br />
75<br />
Arithmctic Operations<br />
1- llumber<br />
sub 1 number<br />
(- number 1)<br />
'Inc name sub1 is r<strong>et</strong>ained for MACLISP compatibility.<br />
m1 nus number<br />
This is the same as (- number): the name is r<strong>et</strong>ained for MACI.ISP compatibility.<br />
• & rest numbers<br />
t 1mes &rest numbers<br />
Rcturns the product of <strong>al</strong>l of the numbcrs. coercing as appropriate. The identity filr this<br />
opcr,ltion is 1. The name times is r<strong>et</strong>aincd ftlr \1Al'I.ISP compatibility.<br />
I I11lIl1ber &rest numbers<br />
This is the generic ration<strong>al</strong>izing division function. With one argument. / reciprocates the<br />
argument: with more than one. it divides the first by <strong>al</strong>l the others. and r<strong>et</strong>urns the<br />
resull. / will r<strong>et</strong>urn a ratio if the mathe1T!:\tic<strong>al</strong> quotient of two integers is not an eX:lct<br />
integer: truncming integer division is pel f(lnned by the ~1AC'l.lSP compatible quotient<br />
function. and variolls sorts of truncation and rounding (not limitcd to fio,lting-point<br />
input"') arc provided by the floor. ceiling. truncate. and round functions (section 10.7,<br />
page 79).<br />
quot 1 ent number &rest more-numbers<br />
Tn'" i" th(' MA.C'f ISP-('('mpatib!r quotient fun~tion. Wh~n g!ven more th.;!n ~~ne ~rgmnent.<br />
quotient divides the first hy <strong>al</strong>l the others. and r<strong>et</strong>urns the result. With one argument,<br />
r<strong>et</strong>urns that argument.<br />
If quotient is given integer arguments. it perfonns truncating division (see truncate. page<br />
79). However, if any of the arguments are ratios. it will instead do ration<strong>al</strong> division, like<br />
I.<br />
conjugate number<br />
R<strong>et</strong>urns the complex conjugate of number, which is number itself if number is not<br />
complex.<br />
gcd &rest integers<br />
R<strong>et</strong>urns the greatest common divisor of the integers. With no arguments. ged r<strong>et</strong>urns O.<br />
In <strong>NIL</strong>. ged works on <strong>al</strong>l gaussian integers. The result will <strong>al</strong>ways lie within the first<br />
quadrant, or <strong>al</strong>ong the positive re<strong>al</strong> axis.<br />
1 cm integer &rcst more-integers<br />
R<strong>et</strong>urns the least common multiple of the integers.<br />
Like gcd. lem in <strong>NIL</strong> works on <strong>al</strong>l gaussian integers.<br />
MC:NII.MAN:NUMBER 70<br />
23-DEC-83<br />
~:.
I rration<strong>al</strong> and Transcendent<strong>al</strong> Functions 76 NII~ Manu<strong>al</strong><br />
10.5 Irration,l1 and Transcendent<strong>al</strong> Functions<br />
Remember that the functions in this scction which must perfbnn their operations in floating ..<br />
point. will convert ration<strong>al</strong> numbers to double-float currently. but to single-float in the future.<br />
pi<br />
Const<strong>al</strong>lt<br />
The v<strong>al</strong>ue of this constant is pi. in the. longest floating-point fonnat available; in NJ~ this<br />
is a long-float. To use a shoner fonnat of pl. for instance double-float. one should use<br />
som<strong>et</strong>hing like one of the fonns<br />
(+ (float pi O.OdO) n)<br />
( + (c 0 ere e pi' do u b 1 e-flo at) II}<br />
to an)id hm'jng the v<strong>al</strong>ue of pi cause coercion to 'long-float in your cumputatiuns. Uses<br />
of both coerce and float like the above will be optimized by the compilerc into the<br />
appropriilte v<strong>al</strong>ue.<br />
I f other similar constants arc added to <strong>NIL</strong>. thcy <strong>al</strong>so will be in 10ng-fl()~1t<br />
should be treated similarly.<br />
fimnat. and<br />
10.5.1 Exponenti<strong>al</strong> and Logarithmic Functions<br />
8XP number<br />
R<strong>et</strong>urns e raised to the power number. where e is the base of the natur<strong>al</strong> logarithms. If<br />
lIumber is a float. the answer is computed and r<strong>et</strong>urned in the same fonnat: if it is<br />
ration<strong>al</strong>. it is first convcrtcd to double-float.<br />
exp t base-number power-number<br />
R<strong>et</strong>urns base-number raised to the power power-Ilumber. If base-number is a ration<strong>al</strong><br />
numher and the power-number is an integer. the c<strong>al</strong>culation will be exact and the result<br />
will be a ration<strong>al</strong> number. Otherwise. the c<strong>al</strong>culation devolves into fioating-point. and will<br />
use a logarithmic computation if power-number is not an integer.<br />
log number &option<strong>al</strong> base<br />
R<strong>et</strong>urns the logarithm of number in the base base. which defaults to e, the base of the<br />
natur<strong>al</strong> logarithms. lbe rules of contagious coercion apply here: number and base are<br />
converted to the largest format of the two, unless both are ration<strong>al</strong>. in which case they<br />
are converted to double-float.<br />
It is an error if number is zero, unless base is zero. in which case the log is taken to be<br />
zero.<br />
sqrt number<br />
R<strong>et</strong>urns the principaJ square root of number. If number is ration<strong>al</strong>, it is converted to a<br />
double-float first; sqrt in <strong>NIL</strong> never produces a ration<strong>al</strong> number even if number might<br />
have a ration<strong>al</strong> square root. even though this is not dis<strong>al</strong>lowed by COMMON USP.<br />
If number is a negative non-'complcx number. a complex number is r<strong>et</strong>urned.<br />
MC:NII.MAN;NUMBER 70<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 77 Irration<strong>al</strong> and Transcendent<strong>al</strong> Functions<br />
1sqrt integer<br />
Integer square-root: the argumentmllst be a non-negative integer. and t11e result is the<br />
greatest integer less than or equ<strong>al</strong> to the exact positive square root of the argument.<br />
10.5.2 Trigonom<strong>et</strong>ric and Related Functions<br />
abs number<br />
R<strong>et</strong>urns the absolute v<strong>al</strong>ue of the argul!1ent. which may be any type of number.<br />
When applied to the complex plane. abs r<strong>et</strong>urns the disL4mce of t11e point from the<br />
origin. which is<br />
(sqrt (+ (expt rea/pari 2) (expt imagpart 2»).<br />
Thus. for complex numbers. the result will <strong>al</strong>ways he floating-point hecause t11ere is a<br />
$qrt hidden away in the computation. Applications which require only cOll1paring<br />
distances from the origin may use t11e aho,"e f(lrm without the sqrt operation~ this is<br />
done. for instance. hy the intern<strong>al</strong> code for ged of complex integers.<br />
s 1 9 n um number<br />
By definition.<br />
(signum x) - (if (zerop x) x (I x (abs x»)<br />
signum of an ration<strong>al</strong> number will r<strong>et</strong>urn -1, O. or 1 according to wh<strong>et</strong>her the number<br />
is negative. zero. or positive. For a floating-point number. the result will be a floatingpoint<br />
number of the same fonnat with. one of the mentioned three vllhles_<br />
signum of a complex number is a complex number of the same phase but with unit<br />
magnitude. As a result. it will <strong>al</strong>ways be a complex number with floating-point<br />
components (see the discussion under abs, above).<br />
sin radians<br />
cos radians<br />
tan radians<br />
Standard trig functions. The number radians will be convened to a double-float if it is<br />
ration<strong>al</strong>. These accept complex arguments.<br />
asin number<br />
acos Ilumber<br />
asin r<strong>et</strong>urns the arcsine of the argument, and acos the arccosine. The result is in<br />
radians. number will be converted to a double-float first if it is ration<strong>al</strong>; it may <strong>al</strong>so be<br />
complex.<br />
Note that (asin -5), for instance, results in a complex answer.<br />
atan y &option<strong>al</strong> x<br />
Fairly standard arctangent<br />
With one argument (which may be complex). the arctangent is r<strong>et</strong>urned: for a noncomplex<br />
argument. the result is b<strong>et</strong>ween -fl/2 and '!T12 (exclusive). More gener<strong>al</strong>ly. the<br />
following definition is used:<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83
Numeric Type Conversions 78 NIl. Manu<strong>al</strong><br />
atan(z) = -j.log( (l+i-z)-sqrt( 1/(I+z"2»)<br />
With two arguments. neither may be complex. . '111c arclangent of y / x is r<strong>et</strong>urned. and<br />
the signs of y and x arc used to derive quadrant information. Also. x may be zero as<br />
long as y is not lero. TIle result will be b<strong>et</strong>ween -." (exclusive) and 11 (inclusive).<br />
s 1 n h number<br />
cosh number<br />
tanh lIumber<br />
Hyperoolic·sine. cosine. and tangent. number m4ty be complex.<br />
as 1 nh IIlImber<br />
aeash Ilumber<br />
atanh lIumbi'r<br />
Etc.<br />
10.6 Numeric Type Conversions<br />
float Ilumba &optionaI other<br />
If olher is not supplied, then if number is a float of any type. it is r<strong>et</strong>urned: otherwise, it<br />
is con\'crted to a float of the default fonnat. which is currently double-float. but will be<br />
single-float in the future.<br />
If ollirr is supplied. then it must bea floating-point number. Ilumber is convened to a<br />
float of the same type. Thus.<br />
(float iTob o.orO)<br />
causes explicit conversion of frob to a single-float. Note that this will conven to a shoner<br />
fi)nn41t <strong>al</strong>so.<br />
The <strong>NIL</strong> compiler contrives to recognize the cases where float is given a constant ()ther<br />
argument. and caU speci<strong>al</strong> efficient routines for convening to the given type.<br />
rat 1ona1 number<br />
11lis converts number to . a ration<strong>al</strong> number. If it is <strong>al</strong>ready ration<strong>al</strong>. it is r<strong>et</strong>urned.<br />
Otherwise, a ration<strong>al</strong> number is computed corresponding to the precise representation of<br />
the number. For instance,<br />
(ration<strong>al</strong> (float 7/11 D.OsO» => 333637/524288<br />
It is <strong>al</strong>ways the case that for a floating-point number f,<br />
(= (float (ration<strong>al</strong> 1) 1) J) => t<br />
ration<strong>al</strong>ize number<br />
]f number is ration<strong>al</strong>, it is r<strong>et</strong>urned. Otherwise, the floating-point representation is taken<br />
to be an approximation of a ration<strong>al</strong> number, and that ration<strong>al</strong> number is r<strong>et</strong>urned. For<br />
instance.<br />
(ration<strong>al</strong>ize (float 7/11 O.OsO» => 7/11<br />
ration<strong>al</strong>ize is not the most efficient coercion routine around ...<br />
MC:NH.MAN:NUMBER 70<br />
23-DEC-83
•<br />
<strong>NIL</strong> Manu<strong>al</strong> 19 Integer Conversion and Speci<strong>al</strong>ized Division<br />
comp lex rea/parI &option<strong>al</strong> (imagpart 0)<br />
This constructs a complex number with re<strong>al</strong> part of rea/parI, and imaginary part of<br />
imagparl. If rca/parI is ration<strong>al</strong> and imagparl is either (integer) 0 or not supplied, then<br />
the result is just rca/pari. because complex numbers with ration<strong>al</strong> components and a zero<br />
imaginary part automatic<strong>al</strong>ly turn back. into ration<strong>al</strong> (non-complex) numbers. If either<br />
argument is floating-point. then both components will be converted to the longest floating<br />
point fnnnat of the two. For instance,<br />
(complex 5 3)<br />
(complex 1/5 3.0dO)<br />
(complex 2.510 0.750)<br />
(complex 2)<br />
(complex 2.0)<br />
=><br />
=><br />
=><br />
=><br />
=><br />
IIc(5 3)<br />
IIc(0.2dO 3.0dO)<br />
#c(2.510 0.710)<br />
2<br />
IIc(2.0 0.0)<br />
10.7 Integer Conversion and Speci<strong>al</strong>ized Division<br />
truncate /lumber &option<strong>al</strong> divisor<br />
t100r number &optionaJ divisor<br />
ce 111 ng /lumber &oplion.ll divisor<br />
round number &option<strong>al</strong> divisor<br />
These functions serve two similar purposes. They may be used to convert from a fioatingpoint<br />
number to an integer in various useful ways, and they can <strong>al</strong>so perfonn<br />
division/remainder operations similarly.<br />
If only one argument is given. it is converted to an integer by the appropriate m<strong>et</strong>hod:<br />
by truncation for truncate, by rounding towards negative infinity for floor, by rounding<br />
towards positive infinity for ceiling. or by rounding towards the nearest integer for round.<br />
(The <strong>NIL</strong>. and (,OMMO~ LISP round will round an exact h<strong>al</strong>f by rounding towards the even<br />
integer: in this it may differ from rounding in other languages.) Two v<strong>al</strong>ues are r<strong>et</strong>unled:<br />
the first is the result of the conversion, and the second is the remainder for the operation.<br />
If number is an integer. then the first v<strong>al</strong>ue is that integer and the second is O. If it is a<br />
ratio. then the second will <strong>al</strong>so be a ratio, and if it is a float, then the second will bea<br />
float of the same fonnat. For example,<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-I)EC-83
Integer Conversion and Speci<strong>al</strong>ized Division so <strong>NIL</strong> Manu<strong>al</strong><br />
(truncate 2.5) => {2, D.5}<br />
(truncate 5/2) => {Z. lIZ}<br />
(truncate -Z.5) => {-2. -O.5}<br />
(truncate -5/2) => {-Z, -lIZ}<br />
(ceiling 2.5) => {3. -0.5}<br />
(ceiling 5/2) => {3, -I/2}<br />
(ceiling -2.5) => {-Z, -O.5}<br />
(ceiling -5/2) => {-2, -1/2}<br />
(floor 2.5) => {2.·0.5}<br />
(floor 5/2) => {2. 1/2}<br />
(floor -Z.5) => {-3. 0.5}<br />
(floor ,-5/2) => {-3. lIZ}<br />
(round 2.5) => {2. 0.5}<br />
(round -Z.5) => {-Z, -O.5}<br />
(round Z.6) => {3. -O.4}<br />
(round -2.6) => {-3, 0.4)<br />
(round 3.5) =>' {4. -0.5)<br />
(round -3.5) => {-4, O.5}<br />
If the divisor argument is given .. the first v<strong>al</strong>ue is the result of integer conversion of the<br />
result of dividing /lumber by divisor, after the appropriate type of rounding or truncation<br />
is performed. The second v<strong>al</strong>ue is the remainder for that division after the<br />
rounding/truncation. That is. if the v<strong>al</strong>ues arc q and r. then<br />
{:; nUlI/otlr (T i- q divisor) r) j => t<br />
For instance~<br />
(truncate 5 2)<br />
(truncate -5 2)<br />
(truncate 5 -2)<br />
(truncate -5 -2)<br />
(floor 5 2)<br />
(floor -5 2)<br />
(floor 5 -2)<br />
(floor -5 -2)<br />
=><br />
=><br />
=><br />
-><br />
=><br />
-><br />
-><br />
=><br />
{2,<br />
{-2.<br />
{-2.<br />
{2.<br />
{2.<br />
{-3.<br />
{-3 t<br />
{2,<br />
I}<br />
-I}<br />
I}<br />
-I}<br />
I}<br />
I}<br />
-I}<br />
-I}<br />
What this means is. if truncate is given two integer arguments. then the two v<strong>al</strong>ues are<br />
the quotient and remainder. as obtained by those functions. If floor is given two integer<br />
arguments. then the second v<strong>al</strong>ue is the standard mod (page 81).<br />
rem number divisor<br />
When rem is given integer arguments. it is identic<strong>al</strong> to the MACLISP remainder function.<br />
More gener<strong>al</strong>Jy. however. it perfonns the truncate operation on its two arguments, and<br />
r<strong>et</strong>urns the second v<strong>al</strong>ue from that as its v<strong>al</strong>ue.<br />
rema 1 n de r number divisor<br />
This is identic<strong>al</strong> to rem. The name is r<strong>et</strong>ained for MAClISP compatihility: if number and<br />
dil'isor arc both integers (which is aU the MACl.ISP remainder function accept~). then the<br />
op~r<strong>al</strong>ion is the same.<br />
MC:NII.MAN:NUMBER 70<br />
23-DEC-83
Nil. Manu<strong>al</strong> 81 l.ogicaJ Operations on N urn hers<br />
One slight discrepency exists with the MACl.ISP remainder function: in MAC"I lSI>'<br />
remainder wiJ] accept a Jil'isor argument of 0 and r<strong>et</strong>urn number. This is incompatible<br />
with the definition of rem (and <strong>al</strong>so with fixnum open-compilation of remainder in<br />
MACl.ISJ>!) because of the implicit division involved-in <strong>NIL</strong>, a divisor of 0 results in a<br />
division-by-zero error.<br />
mod number divisor<br />
When Ilumber and divisor are both integers, then mod is the stmdard "modulus" function.<br />
More gener<strong>al</strong>ly. mod perf0l111S the floor operation on its two arguments, and r<strong>et</strong>urns the<br />
second v<strong>al</strong>ue from that as its v<strong>al</strong>ue.<br />
Note that by \'irtue of its definition in terms of floor which is a kind of division. a<br />
divisor of zero results in a division-by-zero error.<br />
ffloor Ilumber &option<strong>al</strong> divisor<br />
ftruncate Ilumber &option<strong>al</strong> divisor<br />
fee 111 ng I1wllber &option<strong>al</strong> divisor<br />
fround Ilumber &option<strong>al</strong> divisor<br />
These functions behavc just like floor. truncate. ceiling, and round. except that the first<br />
v<strong>al</strong>ue r<strong>et</strong>urned is converted to a float if it is not. While this is fairly useless for ration<strong>al</strong><br />
arguments. it can rcsult in some efficiency gain for arguments of type float. Note that if<br />
both arguments are ration<strong>al</strong>. only the first v<strong>al</strong>ue will be a double-float, not the second.<br />
10.8 Logic<strong>al</strong> Operations on Nuntbers<br />
The logic<strong>al</strong> operations in this section treat integers as if they were represented in two'scomplement<br />
notation.<br />
One common use of integers in this manner is as s<strong>et</strong>s; each bit which is "on" (is 1) in the<br />
integer represents the presence of a particular item in the s<strong>et</strong>. If the integer is negative. then it is<br />
an infinite s<strong>et</strong>. because the sign is vinu<strong>al</strong>ly extended to infinity. The presence of a particular item<br />
in a s<strong>et</strong> can be tested for with logbitp; one refers to the item by its lero-origined bit index.<br />
Other s<strong>et</strong> operations can be perfonned with the various boolean functions: log and performs<br />
intersection, logior performs union, logxor performs s<strong>et</strong>-exclusive-or, and logandc2 performs<br />
s<strong>et</strong>-difference. A new s<strong>et</strong> with an item represented by bit-index index added can be constructed<br />
by a form like<br />
(dpb 1 (byte 1 index) integer)<br />
10gb1tp index integer<br />
logbitp is true if the bit in integer whose index is index (that is, its weight is (expt 2<br />
index» is a one-bit; otherwise, it is f<strong>al</strong>se.<br />
1 og 1 0 r &rest integers<br />
logxor &rest illtegers<br />
10gand &rest illtegers<br />
logeqv &rest integers<br />
These r<strong>et</strong>urn the bit-wise logic<strong>al</strong> inclusive or, exclusive or, and, or equiv<strong>al</strong>ence (<strong>al</strong>so<br />
known as exclusive 110r) of their arguments. ]f no arguments are given, the results are 0<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83
I #ogic<strong>al</strong> Opcrations on Numbers 82 <strong>NIL</strong> Manu<strong>al</strong><br />
for logior and logxor. and -1 f()r log and and logeqv. which are the identities for those<br />
operations, Notc <strong>al</strong>so t.he fixllum-unly versions of these. logior&. logxor&. logand&. and<br />
logeQv& (page 88).<br />
lognand integerl illteger}<br />
lognor il/legerl integer2<br />
logandcl integerl integer}<br />
logandc2 il1Iegerl integer]<br />
logorc1 ilJlrgt'rl integerl<br />
1 ogorc2 iIlTt!~crl integer2<br />
Th~se are the other six n()n·trivi~fl bit-wise logic<strong>al</strong> operations on two arguments. Bec~luse<br />
they arc not commutative or associative. they take exactly two arguments rather than any<br />
number.<br />
The "cl lt and "c2" in some of the above names should be read as "having complemented<br />
argument 1 (ur 2)": for instance. logorc1 is the logic<strong>al</strong> or of the logic<strong>al</strong> complement of<br />
illtcgerl. with ituegerl.<br />
logandc1 and logandc2 are often used as bit-deuring functions. Howe\er. the ordering<br />
given to such names as bit-clear or logelr is often confusing (and historic<strong>al</strong>ly. has b~n<br />
incompatible from one macro-package to another), togandc1 r<strong>et</strong>urns inTeger2 with aU bits<br />
which are on in illlegerl. cleared; logandc2 r<strong>et</strong>urns integerl. after dearing any bits<br />
which are s<strong>et</strong> in illIeger2.<br />
boo 1 e up inlegerl illteger2<br />
'Jbe function boo'e takes an operation op and two integers. and r<strong>et</strong>unlS an integer<br />
produced by perfonning the logic<strong>al</strong> operation specified by op on the two integers.<br />
There are sixteen variables (the names of which are listed below) which have the boolean<br />
functions as their v<strong>al</strong>ues; the boolean functions are represented as fixnums from 0 to IS<br />
(inclusive).<br />
The <strong>NIL</strong> implementation of boole defines the boolean functions such that they map into<br />
the standard "truth table" used in MACUSP. lbat is, if the binary representation of op is<br />
abed. then the truth table for the boolean operation is<br />
y<br />
101<br />
x<br />
o I a c<br />
I<br />
1 I b d<br />
For example, the boolean function 4 has binary representation 0100. This shows that the<br />
result will have a bit s<strong>et</strong> only when the corresponding bit of integer] is 1 and integer2 is<br />
O. This is the logandc2 operation. New code, . especi<strong>al</strong>ly that intended to b<strong>et</strong>ransponed<br />
b<strong>et</strong>ween COMMON LISI) implementations. should nel'er rely on this-this coincidence is<br />
provided 01111' for M:\CLlSI' compatibility.<br />
MC:<strong>NIL</strong>MAN;NUMRER 70<br />
23-DEC-83
...<br />
Nil. Manu<strong>al</strong> 83 I.ogic<strong>al</strong> Operations on Numbers<br />
Also for !\.1ACI.lSP compatibility. when Nil. boole receives more than three arguments. it<br />
goes from left to right. thus:<br />
(boole k x y z) (boole k (boole k x y) z)<br />
In certain cases it may accept less than three arguments. Again. new code should not rely<br />
on this behaviour.<br />
lognot inleger<br />
R<strong>et</strong>urns the bit-wise logic<strong>al</strong> 1101 of its argument. Every bit of the result is the complement<br />
of the corresponding bit in the argument.<br />
1 ogtes t illlcgcr/ int('g('r]<br />
logtest is a predicate which is true if any of the bits designated hy the l's in ilJlrgerl arc<br />
l's in integer 2.<br />
(logtest x y) (not (zerop (logand x y»))<br />
except that it can be done more efficiently. because it docs not have to actu<strong>al</strong>ly compute<br />
the logand.<br />
ash intrger coUIll<br />
Shifts in/('gcr arithmctic<strong>al</strong>ly left by COUllt bit positions if COUllt is posltl\'e. or right -COUIlI<br />
bit positions if cOUll1 is ncgative. The sign of the result is <strong>al</strong>ways the same as the sign of<br />
integer.<br />
The actu<strong>al</strong> implementation of ash works on. and will produce. bignums. There is <strong>al</strong>so an<br />
A~hR n.1nftion which de<strong>al</strong>s (In!y with fixnums.<br />
In practice. COUllt is only <strong>al</strong>lowed to be a fixnum ...<br />
logcount i11leger<br />
If integer is non-negative. logcount r<strong>et</strong>urns the number of "1" bits on in its twoscomplement<br />
representation. If it is negative, then the number of "0" bits in that<br />
representation is r<strong>et</strong>urned; this is then the same as the count of "Itt bits in the logic<strong>al</strong><br />
complement of it<br />
integer-length integer<br />
integer-length r<strong>et</strong>urns the zero·origined index of the sign bit of the field needed to<br />
represent integer in twos-complement notation. That is, any integer i may be represented<br />
in twos-complement notation in a field (1 + (integer-length i» long. If integer is non·<br />
negative, then it may be represented in unsigned binary fonn in a field (integer-length<br />
integer) long. For instance,<br />
(integer-length 5) => 3<br />
because the binary representation of 5 is ... 0101.<br />
The following two functions are provided for MACLISP compatibility. They both do some<br />
semblance of manipulation of the binary representation of integers. However, the results of these<br />
functions are defined in tenns of the absolute v<strong>al</strong>ue of the integer they are examining-because in<br />
Nil. integers are oriented towards manipulation of their twos·complement representation. these<br />
routines may not be panicularly efficient on negative integers.<br />
MC:NI1.MAN:NUMBER 70<br />
23-DEC-83
t<br />
Byte Manipulation Functions 84 Nil. Manu<strong>al</strong><br />
haulong integer<br />
R<strong>et</strong>urns the number uf signific,mt bit~ in lheabsolule v<strong>al</strong>ue of illteger. The precise<br />
computltion performed is ceilillg(1og2(abs(illteger)+ 1».<br />
For example:<br />
(haulong 0) => 0<br />
(haulong 3) => 2<br />
(haulong 4) => 3<br />
(haulong -7) => 3<br />
haulong is provided ft'r MAfTISP c(}m~~ttibility:<br />
prefer~nce.<br />
. integer-length should be used in<br />
ha 1 part integer COUIlI<br />
This function exists primarily for MACI.lSP cumpatibility. Its function<strong>al</strong>ity is subsumed by<br />
the byte manipulation functions Idb and dpb. which are described in the following<br />
section ..<br />
haipart r<strong>et</strong>urns the high COUIlI bits of the binary representation of the absolute v<strong>al</strong>ue of<br />
integer. or the low -('mlllt bil~ if COUII( is negative.<br />
10.9 Byte l\1anipulation Functions<br />
There are various functions in <strong>NIL</strong> and CO!\'1 MO~ LISP to de<strong>al</strong> with arbitrary-width contiguous<br />
fields of bite; within integers. These functions are not restricted to operations on fixnums. but<br />
rather de<strong>al</strong> with the twos-complement representation of arbitrarily large integers.<br />
Most of these functions use an object c<strong>al</strong>led a byte specifier. This object is used to refer to a<br />
field within an integer. which is dctennined by the size of the field. and the' positioll of the field<br />
within an integer. Both of these must be non-negative integers.<br />
byte size position<br />
byte constructs a byte specifier. You may not depend on the fonnat of the object<br />
r<strong>et</strong>urned. only that it wi]) be acceptable for usc as a byte specifier by the fonowing<br />
functions; in particular. the type of the object r<strong>et</strong>urned by byte may not be distinct. In<br />
gener<strong>al</strong>. the restrictions on the magnitude of size and posilion are implementation<br />
. dependent. In <strong>NIL</strong>, they may be any non-negative fixnums. Byte specifiers in which the<br />
size and position will both fit in an unsigned field 15 bits long (that is. they are both<br />
integers from 0 to 32767 inclusive) are represented more efficiently than others.<br />
byte - size bylespec<br />
byte-pos it ion bylespec<br />
byte-size r<strong>et</strong>urns the size "component" of bylespec, and byte-position r<strong>et</strong>urns the<br />
position "component".<br />
MC:NIl.MAN;NUMBER 70<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 85 Byte Manipulation Functions<br />
1 db bytespec ill1eger<br />
by/{'sl'('c specifics a field of integer to be extracted. That field extracted from the twoscomplement<br />
binary representation of illlegrr is r<strong>et</strong>urned as a non-negative integer. For<br />
instance. the low three bits can be extracted using the byte specifier constructed by (byte<br />
3 0):<br />
(ldb (byte 3 0) 15) => 7 :15is ... OlllIll in binary<br />
( 1 db (byte 3 0) 14) => 6 ; 14 is ... 011Ill0 in binary<br />
( 1 db (byte 3 0) -3) => 5 ;-4 is ...1111101 in binary<br />
The third group of three bilS can he extracted lIsing tJ1C byte specifier (byte 3 6):<br />
(ldb (byte 3 G) 15) => 0 :15is ... OOOOlll111inbinary<br />
(ldb (byte 3 6) 63) => 7 :6Jis ... Olllll1111inhinary<br />
(ldb (byte 3 6) -3) => 7 ;-3is ...lll1111101 in binary<br />
Idb may be used with s<strong>et</strong>f (page 38). if the fonn illfeger is a \'aJid 1'1£1('r argument to<br />
's<strong>et</strong>f. Rather than modifying the integer itself. doing s<strong>et</strong>f on a Idb fonn will "nest" like<br />
( s<strong>et</strong> f (1 db bytcspcc i11lrger) newbyte)<br />
==><br />
(Sf.:c,;,f integer (dpb newbyte bytespec integer»<br />
ldb-test bytespec integer<br />
( 1 db - te S t bytespec integer)<br />
(not (zerop (ldb bylespec integer»)<br />
While a Idb -test can in gener<strong>al</strong> be . done more efficiently than the second filnn.<br />
pr\ibat1y i5 not dl.HK ~f'Cddliy y<strong>et</strong> ii} j~iL<br />
it<br />
dpb newbyte bytespec integer<br />
dpb is sort of the inverse of Idb. It r<strong>et</strong>urns an integer with the same binary<br />
representation as illtrgrr. except that the field referred to by by1rspec is replaced by the<br />
twos-complement binary represention of newbyte.<br />
(dpb 3 (byte 3 0) 0) => 3<br />
(dpb 7 (byte 3 0) 0) => 7<br />
(dpb 0 (byte 3 0) -1) => -8<br />
mask-field bycespec integer<br />
This does not seem to be in yell<br />
mask -field r<strong>et</strong>urns an integer whose binary representation is an zeros, except in the field<br />
referred to by bylespec, which has the same bits as that field in integer. That is,<br />
(mas k -f i e 1 d bytespec integer)<br />
<br />
( d P b (1 db bytespec integer) bytespec 0)<br />
<br />
(ash (1 db bytespec integer) (byte-pos ; ti on bytespec»<br />
If the integer is being used as the representation of a s<strong>et</strong> (section 10.8. page 81). then<br />
mask-field could be considered to be perfonning an intersection operation on the s<strong>et</strong><br />
represented by integer. and the s<strong>et</strong> of <strong>al</strong>l objects whose bit positions correspond to the<br />
positions within the fic1d specified by bytespec.<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
2J-DEC-83
R~andom Numbers<br />
86 <strong>NIL</strong> Manu<strong>al</strong><br />
de pos 1 t - f 1 e1 d 1I(' •...t~",e<br />
This docs 110/ SCt'lIt 10 be ill ),el?<br />
by/t'sp('c integer<br />
This is the "inverse" of mask-fieJd. deposit-byte r<strong>et</strong>urns an integer which is the same<br />
as inlcgcr, except that the field referred toby bylespec is contains instead the bYlespec<br />
field of IJfwbyle. That is. it is like<br />
(dpb (1 db bytespec newbyle) bylespec integer)<br />
10.10 Random Numbers<br />
random &option<strong>al</strong> modulus random-sl<strong>al</strong>e<br />
I f no modulus argument is given. then this is compatible with the MAC'I.ISP. random<br />
function of no arguments: it r<strong>et</strong>urns a number mndomly distributed over the range of <strong>al</strong>l<br />
fixnums. (CO\fMO;\ J IS}> docs not define random nfnn argumenL~.) Otherwise. the<br />
answer r<strong>et</strong>urned by random is n number of the ~lme type evenly distributed b<strong>et</strong>ween zero<br />
(inclusive) and modulus (exclusive).<br />
If random-sl<strong>al</strong>c is supplied. it must be an object of type random-state: tIlis is what<br />
holds the SUIte of the random number generator. If it is not supplied. then the glob<strong>al</strong><br />
random number SL'lte (the v<strong>al</strong>ue of *random-state.) is used.<br />
The random number r<strong>et</strong>urned is random over tta11 its bits": random-sl<strong>al</strong>e is used to<br />
compute a sequence of random bilS which are used· to construct the result. For a floatingpoint<br />
number. this is used as tile significand (fraction) of a constnlcted number which is<br />
sc411cd to the appropriate range: filr an integer. a sequence of bit'i is constructed<br />
approximately 10 bilS longer than that needed for the resul~ and then a modulus<br />
operation performed.<br />
*random-state*<br />
Variable<br />
This holds the glob<strong>al</strong> random state used by default by random. One may. for instance,<br />
lambda-bind this variable to a new object of type random-state to save and restore the<br />
state of the random number generator.<br />
make-random-state &option<strong>al</strong> slate<br />
This creates a new random-state object If sl<strong>al</strong>e is nil or not suppJied. then a copy of<br />
the current v<strong>al</strong>ue of *random-state* is r<strong>et</strong>urned. Ifs/<strong>al</strong>e is t. then a new random-state<br />
is r<strong>et</strong>urned. seeded from the time. Otherwise, Slate should be a random-state; its state<br />
is copied.<br />
When <strong>NIL</strong> is first loaded up. the random-st<strong>al</strong>e object in .random-state* is <strong>al</strong>ways in the<br />
same state. It may be seeded from the current time by doing<br />
(s<strong>et</strong>q .random-state. (make-random-state t»<br />
jf . that is necessary for applications. There is, however.. no offici<strong>al</strong>1y defined way to g<strong>et</strong> a<br />
"known" random-state from which the same sequence of pseudo-random numbers may be<br />
generated. other than copying one withmake-random-state and saving it. If this is found to be<br />
necessary (for instance to reproducibly debug a program which uses the random number<br />
generator). the fonn<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 87 Fixnum-Onty Arithm<strong>et</strong>ic<br />
(si:make-random-state-intern<strong>al</strong>)<br />
wilt create a new random-state the same as the one i'\IL starts up with.<br />
For MAC'USP compatibility, the random option to the status and sstatus macros is supported.<br />
(status random) r<strong>et</strong>urns a copy of thc current v<strong>al</strong>ue of .random-state-: (sstatus random<br />
random-st<strong>al</strong>e) restores .random-state- to a copy of that. Onc may <strong>al</strong>so reseed by doing (sstatus<br />
random integer).<br />
10.11 Fixnum-Only Arithm<strong>et</strong>ic<br />
Currently. the :'\11. compiler does not make any usc of lype declarations to help it decide to<br />
inline-code arithm<strong>et</strong>ic routines. Primarily for this reason. !'IL provides a full complement of<br />
fixllum-only and double-fioat-only arithm<strong>et</strong>ic rOlltines. which will be in1ine-coded by the compiler<br />
(when possible and reasonable) into fairly efficient code.<br />
In Nil., as in MACIISP. the tot<strong>al</strong>ly open-~ompi1ed fixnum-only routines behave "as the machine<br />
docs": that is. overflow is gener<strong>al</strong>ly not d<strong>et</strong>ected. Note that thc VAX hardware d<strong>et</strong>ects division by<br />
zero. howcver. and those routines not compiled as machine instructions. sllch as "&. may d<strong>et</strong>ect<br />
overflow and signa1 an crror.<br />
10.11.1 Comparisons<br />
-!r number &rcsl more-numbers<br />
1-& number &rest more-numbers<br />
& number &rest morc-numbers<br />
< -& number &rest mcire-llumbers<br />
>-& number &rest more-numbers·<br />
Fixnum-only versions of the =. 1=.
Fixnum-Only Arithm<strong>et</strong>ic 88<br />
.& &rest fixllums<br />
Fixnum-only multiplication.<br />
1& fixllum &rest more-jixIlulIls<br />
Fixnum-only division. With one ,lrgument. reciprocates. which seems singularly useless to<br />
me~ since this is truncating division. reciprocation is an error if the argument is lero~ one<br />
if it is one, otherwise zero.<br />
\& jixlluml jixIlum2<br />
Fixnum-only remainder. Although there is no CO\4MON I.ISP \ function to make the<br />
fixllum-only (as inherited from MACI.JSP) \ function change incompatihly. the name of \<br />
is heing changed to \& for consistency. Note that this function mllst nonn<strong>al</strong>ly he typed<br />
in as \ \&. bec<strong>al</strong>lse \ is the "quoting" character in NH_<br />
1+& ji.'Jmum<br />
1-& jixllum<br />
Fixnum-only "I + and 1 -.<br />
ab $& jixflum<br />
Fixnum-only abs.<br />
s1gnum& jixnum<br />
Fixnum-only signum.<br />
"& jixllum I jixIlum2<br />
Fixnum-only expt. It is an error for the result to exceed the range representable by a '<br />
fixnum.<br />
10.11.3 Bits and Bytes<br />
logand& &rest fixnums<br />
logior& &rest jixnums<br />
logxor& &rcst jixnum<br />
logeqv& &rcst jixnums<br />
lognand& fixnuml jixnum2<br />
lognor& jixllumJ fixnum2<br />
logandcl& jixn:JmJ jixnum2<br />
logandc2& jixllumJ jixIZum2<br />
logorcl& jixllumJ fixnum2<br />
logorc2& jixnumJ fixnum2<br />
Fixnum-only boolean functions<br />
boo 18& op jixnuml jixnum2<br />
Fixnum-only boole.<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83<br />
. . ;. , .' ~<br />
~ . . ~ .~ ... ~ ~~<br />
'~. ': " ~, : ,',,'" ,',,-."" . ."'.. '~'" "':" :,'::', '. '.~. .'~::"" '.,~", . ',.<br />
' .~'
<strong>NIL</strong> Manu<strong>al</strong> 89 Fixnum-Only Arithm<strong>et</strong>ic<br />
lognot& fixllum<br />
Fixnum-only lognot.<br />
logtest& fixl1uml fixIlum2<br />
Fixtlum-only logtest.<br />
logb1tp& index fixllum<br />
Fixnum-only logbitp. 'Ibis is defined for an index larger than the number of bits in a<br />
fixnum: however. inc/ex must he a fixnum.<br />
as h& fixl1um COUllt<br />
Fixnllm-only ash. Shifting hy a positive C()ulll may shift hil~ into the sign pOSItIOn, tJ1US<br />
changing me sign of the result (and losing bits). It is an error if COUll I is not of type<br />
(signed-byte 8). tJ,at is, b<strong>et</strong>ween -128 and 127 inclusive.<br />
logcount& fixllum<br />
Not y<strong>et</strong> in?<br />
haulong& jixl1ulll<br />
Not inHne-coded. but provided for compl<strong>et</strong>eness (sec. perhaps. %fixnum-haulong. (noty<strong>et</strong>-written».<br />
Maybe this should he diked. since haulong should dispatch just as rapidly.<br />
1 db& bytcspcc fixllum<br />
Fixnum-only Idb. This is not strictly a version of generic Idb which takes a fixnum<br />
second argument. but ramer a version of low-level fixnum byte-extraction which takes a<br />
gener<strong>al</strong> bytespec as an argument: it is an error for the byte to extend outside of the<br />
fixnum (for the position plus the size of the bytespec to be greater than 30).<br />
dpb& ncwby/e by/espcc fixllum<br />
As Idb& is to Idb. so dpb& is to dpb. Other Idb& restrictions apply.<br />
s<strong>et</strong> -1 db& bylespec jixnum newbyte<br />
Maybe this shouldn't be here, but it is in case s<strong>et</strong>f g<strong>et</strong>s used on Idb&.<br />
Back in the olden days when there were few thoughts about integers greater than 34359738367<br />
(or som<strong>et</strong>hing like that), the byte-specifier to Idb and its friends used to be designated as ppss.<br />
The interpr<strong>et</strong>ation of this is that. if you consider ppss to be a 4-digit oct~l number, the number<br />
(oct<strong>al</strong>) pp tells the position of the byte being referenced, and the ss the size. In order that a byte<br />
specifier not be so restricted in the size of the "byte" it is referencing (since the pp can be<br />
upwards-compatibly extended to the left but the ss cannot). <strong>NIL</strong> has incompatibly abandoned that<br />
fonnat. So that code which uses this old fonnat may be trivi<strong>al</strong>ly converted. however, the old<br />
function<strong>al</strong>ity may be obtained with the %Idb and %dpb functions. below.<br />
Xl db ppss jixnum<br />
Extracts the byte defined by ppss (as described above) from fixllum. It is an error if the<br />
byte so referenced lies outside of the fixnum (that is, the size plus the position is greater<br />
than 30).<br />
MC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83
I )ouhle-Float-Only Arithm<strong>et</strong>ic 90 <strong>NIL</strong> Manu<strong>al</strong><br />
%dpb v<strong>al</strong> PI'SS fi"lIlU1l1<br />
R<strong>et</strong>urns a fixnum which is firnulI1 with the byte defined hy ppSS replaced by the fixnum<br />
v<strong>al</strong> (truncated as necessary). It is an error if the byte so referenced lies olltside of the<br />
fixnum (that is. the size plus tJ1C position is greater tJlan 30).<br />
10.11.4 The Super-Primitives<br />
G<strong>et</strong>ting closer still to thc hardware ...<br />
load-byte fixIIU1I1 POSiliol1 sizl'<br />
This is thc primitive f'1I eXlract-a-byte-from-a-fixnum function. In the style of many ~II.<br />
primitivcs. and in the style of the VAX byte-extracting instructions, it takcs arguments of<br />
position and size (different ordering from the byte function). It is an error for the byte<br />
dcscrib~d by posi/ioll and size to lie out of hounds of the intern<strong>al</strong> reprcsentation of a<br />
fixnum (30 bits).<br />
depos i t-byte jiXIIUII1 P(}SIlIOII size llewbYIe<br />
Modifics tJ1C byte. as per load-byte. Note argument ordering is different from dpb in<br />
that I1l'wbyle comes last 'Ibis is to make it convenient fbr s<strong>et</strong>f to usc.<br />
sys :Xf1xnurn-plus-w1th-overflow-trapp1ng x y overflow-code ...<br />
sys: Xf1xnum-d1 fference-w1 th-overfl ow-trapping<br />
Speci<strong>al</strong>/onn<br />
x y O\'erflow-code .•.<br />
sys :Xf1xnum-t1mes-w1th-overflow-trapp1ng x Y Ol'crflow-code ...<br />
sys : Xf 1xnum- as h -wi th-oYerflow-trapp 1 ng x )' ovclfloM/.codc ...<br />
lbese are speci<strong>al</strong> fonns which primarily exist for the benefit of implementing generic<br />
arithm<strong>et</strong>ic functions. The appropriate binary operation on x and y, inJine-coded. is<br />
pcrfonned: jf afterwards mere has been no o\'erflow, that result is r<strong>et</strong>urned. Otherwise,<br />
ol'erflo~code is run, and the resultant v<strong>al</strong>ue r<strong>et</strong>urned.<br />
Only the compiler knows how to use these right now.<br />
10.12 Double-Float-Only Arithm<strong>et</strong>ic<br />
<strong>NIL</strong> provides some functions (like those in MACLISP) which operate only on double-floats. It is<br />
unlikely that corresponding functions wi]) be provided for other floating-point types when thcy are<br />
added, however; inJine-codcd arithm<strong>et</strong>ic on such numbers will be handlcd by declarations to the<br />
compiler eventu<strong>al</strong>ly.<br />
+$ &rest double-floats<br />
• $ &rest double-floats<br />
-$ double-float &rcst more-double-floats<br />
IS double-float & rest more-double-floats<br />
1+$ double-floQt<br />
1-$ double-flo<strong>al</strong><br />
Double-float-only stuff. Essenti<strong>al</strong>ly this is maclisp-compatible.<br />
MC:<strong>NIL</strong>MAN;NUMHER 70<br />
23-DEC-83
•<br />
<strong>NIL</strong> Manu<strong>al</strong> 91 Decompusition of Flo<strong>al</strong>ingPoint Numbers<br />
abs$ double-float<br />
l)ouble-Hoat-onty abs.<br />
max$ &rest double-floats<br />
mi n$ &rest duuble-floots<br />
... s double-float jixl1um<br />
The double-fimlt only exponentiation function.<br />
10.13 Decomposition of Floating Point Numbers<br />
All of the following routines are defined by CO\IMON LISP. The basic premise is that a<br />
floating point numheris represented by some number of digits in a base b. multiplied by b to<br />
some exponent. with a sign. In <strong>NIL</strong> on the VAX. b is of c()urse2 for the primithc floating-point<br />
data types. so the exponent is a binary exponent.<br />
float-radix float<br />
This r<strong>et</strong>urns the radix b of float. For the I'll. prllnltlve float daL1 types (short-float.<br />
single-float. double-float. and long-float). it <strong>al</strong>ways r<strong>et</strong>urns 2.<br />
decode-float float<br />
This function r<strong>et</strong>urns three v<strong>al</strong>ues:<br />
(I) 'Ibc sigllijic<strong>al</strong>ld of flo<strong>al</strong>. This is· a number b<strong>et</strong>ween 1/ b (inclusive) and 1<br />
(exclusive). which represents the bits of .POOI. The sole exception is for zero. for<br />
which the r<strong>et</strong>urned significand is l.ern (of the ~1me floating-point type as floa!).<br />
(2) The exponent of float. This is· an integer which. jf used to sc<strong>al</strong>e thc significand<br />
(using sc<strong>al</strong>e-float. bclow), will produce a number with the same absolute v<strong>al</strong>ue<br />
as float.<br />
(3) The sign of float; this is either 1.0 or -1.0, in the same floating-point fonnat as<br />
float.<br />
Thus.<br />
(multiple-v<strong>al</strong>ue-bind (significand exponent sign)<br />
(decode-float float)<br />
{= float (* (sc<strong>al</strong>e-float significand exponent) sign»)<br />
=> t<br />
sc<strong>al</strong>e-float float integer<br />
This is like doing<br />
(. float (expt b integer»<br />
where b is the radix of float. It is done, of course. somewhat more efficiently and<br />
without danger of any son of intennediate overflow or underflow if the fin<strong>al</strong> rcsultcan be<br />
represented. It is an error if the fin<strong>al</strong> result cannot be represented; sc<strong>al</strong>e-float will sign<strong>al</strong><br />
an error. (In a future <strong>NIL</strong> with a smaner compiler and type declarations, however, it may<br />
be the case that open-compilation of this function will not sign<strong>al</strong> an error.)<br />
1n05e familiar with the PDPIO MACLISP fsc function will recognize this as being somewhat<br />
of the same thing, <strong>al</strong>though it is not subject to the kludges that fsc is (partly because the<br />
VAX docs not represent unnonn<strong>al</strong>ized floating point numbel'$} ..<br />
MC:<strong>NIL</strong>MAN;NUMRER 70<br />
23-DEC-83
,; ~:..-<br />
Implementation Constants 92 Nil. Manu<strong>al</strong><br />
float-sign float &option<strong>al</strong> other<br />
If other is not supplied. then this r<strong>et</strong>urns the sign of float. 1;0 or -1.0. in the same<br />
fonnat as float. This is the same as the third v<strong>al</strong>ue r<strong>et</strong>urned by decode-float.<br />
If <strong>al</strong>her is supplied. then the effcct is of transfering the sign of flo<strong>al</strong> to other; the result<br />
will be of the same floating-point format and absolute v<strong>al</strong>ue as oliler. but have the same<br />
sign as flo<strong>al</strong>.<br />
float-digits flo<strong>al</strong><br />
This r<strong>et</strong>urns the number of base b digits in the representation of flaa/. In ~II.. this is a<br />
conswnt for any particular one of the primitive floating-point lypes. Specific<strong>al</strong>ly. shortfloat<br />
has 19. single-float has 24. double-float has 56, and long-float has 128.<br />
float-precision flo<strong>al</strong><br />
This (he said while looking the other way) is the same as float-digits except that it<br />
r<strong>et</strong>urns 0 for zero.<br />
1ntagar-decoda-float float<br />
This r<strong>et</strong>urns three v<strong>al</strong>ues. like decode-float. The difference is that the significand is<br />
r<strong>et</strong>urned as an integer, and the exponent differs accordingly. The magnitude of the<br />
integer is such that it is b<strong>et</strong>ween "2"p (exclusive), and 2 .... (p-1) (inclusive), wherep is the<br />
precision of float (as would be r<strong>et</strong>urned by float-precision). If the float radix is 2 as it is<br />
for the <strong>NIL</strong> primitive floating types. then the integer will have the same number of bits<br />
(intAgAr-IAnnth l';le(' 8) ~~ the rr{'d~ilJn. Again. an ~xccption for zero exists: the first<br />
v<strong>al</strong>ue will then be O.<br />
10.14 Implementation Constants<br />
most-positive-f1xnum<br />
Cons~nt<br />
most-negat1ve-fixnum<br />
Constant<br />
lbese have as their v<strong>al</strong>ues the most positive and negative fixnums representable in <strong>NIL</strong>;<br />
integers of the same sign but greater magnitudes have to be represented as bignums.<br />
Because <strong>NIL</strong> uses twos-complement representation for fixnums, the absolute v<strong>al</strong>ue of<br />
most-negative-fixnum is one greater than most-positive-fixnum.<br />
most-pos it iva-short-float<br />
Constant<br />
most-pos it ive-s1 ngle-float<br />
Conslant<br />
most-pos it i ve-doubla-fl oat<br />
Constant<br />
most-pos it iva-long-float<br />
Constant<br />
These have as their v<strong>al</strong>ues the most positive numbers of the corresponding fonnats which<br />
can be represented.<br />
most-negat i ve-short-fl oat<br />
Constant<br />
most-negat 1ve-si ngle-float<br />
ConstGnt<br />
most-nagat iva-double-fl oat<br />
'Constanl<br />
most-nagat iva-long-float<br />
COllslant<br />
lbcse have as their v<strong>al</strong>ues the most negative numbers of the corresponding fonnats which<br />
can be represented.<br />
MC:<strong>NIL</strong>MAN;NUM8ER 70<br />
23-DEC-83<br />
.. t -,.-c,... ~ • .... ......... ".4...... •<br />
~~» ~ ~~-: ~-~~~~ ?- ~ ~. ~<br />
"- ~ - ... ~ .'"
as<br />
NIl. Manu<strong>al</strong> 93 Implementation Constant')<br />
18ast-pos 1 t 1ve-short-float COllsl<strong>al</strong>l1<br />
1 east-pos 1 t 1 ve-s 1 ng1 e-f1 oat C0I1Sl<strong>al</strong>l1<br />
1 east-pos 1 t 1 ve-doubl e-float COllsl<strong>al</strong>l1<br />
least-pos it ive-long-float<br />
COllsl<strong>al</strong>l1<br />
These have as their \'<strong>al</strong>ues the sm<strong>al</strong>lest numbers of the corresponding fonnats that can be<br />
represented. which are still positive.<br />
least-negative-short-float<br />
least-negative-single-float<br />
least-negative-double-float<br />
least-negative-long-float<br />
These have as their\'<strong>al</strong>ues<br />
corresponding fonnats.<br />
COIISlanl<br />
COllsl<strong>al</strong>l1<br />
COIlSltlnl<br />
COllsl<strong>al</strong>l1<br />
the most positive negati\'e numbers representable in the<br />
short-float-epsilon<br />
single-float-epsilon<br />
double-float-eps1l~n<br />
long-float-epsilon<br />
These have as their v<strong>al</strong>ues the sm<strong>al</strong>lest positive numbers which.<br />
corresponding fannat. produce a different answer.<br />
COI1Slanl<br />
COllsl<strong>al</strong>l1<br />
ConSlant<br />
COllslanl<br />
when added to 1.0 of thr<br />
short-float-negat1ve-eps11on<br />
single-float-negat1ve-eps11on<br />
dQuble~flo<strong>et</strong>-neg~t1ve-ep~1'on<br />
long-float-negative-eps11on<br />
These arc broKen and wrong.<br />
Constant<br />
('onstanl<br />
r_ .... _"' .........<br />
\,.. VIl.lIU'"<br />
COllslanl<br />
tvtC:<strong>NIL</strong>MAN:NUMBER 70<br />
23-DEC-83<br />
, , ~ ~ -<br />
. ,', . , :... .' :', . ';c ,-(: ',,: .> ,:;:~~~;;~~>',:-_: r~:'-, ":-, ....:;..:.
Characters 94 <strong>NIL</strong> Manu<strong>al</strong><br />
11. Characters<br />
In <strong>NIL</strong>. characters are represented as a separate data type. This provides multiple benefits;<br />
among them. the object maintains some semantic identity when it appears in code (it is obvious<br />
that it is a "character"). and since it does maintain its identity as a character. the read/print/read<br />
"fixed-point" is capable of functioning across differing LISP implementations that intern<strong>al</strong>ly utilize<br />
different character s<strong>et</strong>s (e.g.• ASC'II VS. EBCDIC).<br />
Characters in <strong>NIL</strong> have three different attributes: their code. their bils. and their [0111. 'Ibe<br />
code defines the basic ("root") chamcter. The bit"i are used as modifiers. Typic<strong>al</strong>1y. an input<br />
processor (such as the editor, or even the prescan for the tople\'c1 Lisp read-ev<strong>al</strong>-print loop) will<br />
treat a character without any bits as "ordinary" and assume it is part of the text being typed in.<br />
but treat a character with some bits, as being a command. Four of the speci<strong>al</strong> bits are named:<br />
they are control, m<strong>et</strong>a. super. and hyper. The font of the character defines how certain things<br />
about the character arc defined: for instance. equating characters of different fonts (char-equ<strong>al</strong>).<br />
wh<strong>et</strong>her a character is upper or lower case. <strong>al</strong>phab<strong>et</strong>ic. or a digit (upper-case-p <strong>et</strong>c.). and how<br />
to do case conversion (char-upcase). While NIl.' docs not y<strong>et</strong> rc<strong>al</strong>ly define "fonts", there is a<br />
mechanism for how such definitions can interface to the low-level character manipulation<br />
primitives which utilize such things (section 11.7. page 100).<br />
<strong>NIL</strong> character objects are immediate-pointer structures; they require no storage. Most of the<br />
routines which construct, dissect. and compare characters are open-coded by the compiler.<br />
Thc ~~lL character sct ha5 not y~t b~cn ck,iil~d up with respect tu -the cUllru~iulI UCLWCCIl Uu:<br />
ASCII control characters and the characters it uses with the control bit See section 11.6. page 99.<br />
char-code-l1m1 t<br />
Constant<br />
char-font-l1m1t<br />
Constant<br />
char-b1 ts-l1m1t<br />
Constant<br />
These variables have as their v<strong>al</strong>ues the upper exclusive limits on those attributes of<br />
characters. The v<strong>al</strong>ues should not be changed. It happens that, in the VAX<br />
implementation, <strong>al</strong>l three are 256 so that each quantity will fit into an g"bit byte.<br />
11.1 Predicates on Characters<br />
standard-char-p character<br />
This r<strong>et</strong>urns t if character is one of the "standard" ASCII characters. These are an the<br />
ordinary graphic characters (<strong>al</strong>phanumerics and punctuation characters). plus Space and<br />
R<strong>et</strong>urn. Only characters with 0 font and bits attributes can be standard.<br />
graph 1 c-char-p character<br />
R<strong>et</strong>urns t if character is a graphic (printing) character; that is. it has a single glyph<br />
representation. No character with non-zero bits attribute is graphic. Wh<strong>et</strong>her or not a<br />
character is graphic depends on its font<br />
MC:<strong>NIL</strong>MAN;CHAR 33
<strong>NIL</strong> Manu<strong>al</strong><br />
95 Predicates on Characters<br />
<strong>al</strong>pha-char-p character<br />
upper-case-p character<br />
lowe r - ca s e - p character<br />
both-case-p character<br />
a1 phanumer 1 cp character<br />
Predicates on character objects. All arc nil for characters with any bits; ()thcrwisc~<br />
depend on the font.<br />
thcy<br />
char- character &rest more-characters<br />
char( character &rest more-characters<br />
char(- character &rest more-characters<br />
char> character &rest more-characters<br />
ch a r> - character &rest more-characters<br />
charI- character &rest more-characters<br />
These routines collate or compare characters. The comparison is depcndent on the bits,<br />
fon4 and case of the characters. Each routine r<strong>et</strong>urns t if <strong>al</strong>l pairwise combinations of its<br />
arguments satisfy the appropriate predicate~ nil otherwise; if a single argument is givcn,<br />
the result is t.<br />
char = is the primitiv~ function for tclling if the characters are "thc same charactcr"-that<br />
is, if their code, bjts. and font arc <strong>al</strong>l the samc. It is what is used by eql and equ<strong>al</strong> for<br />
comparing characters. char / = r<strong>et</strong>urns. t if none of the pairs of characters are char = .<br />
ch~r =, =d cn:lr) cc!mtc t'1c eh~rnctcrs ~eeording to some unspecified<br />
collating sequence. What is guaranteed is that the upper-case<strong>al</strong>phab<strong>et</strong>ics, the lower-case<br />
<strong>al</strong>phab<strong>et</strong>ics, and the digits will not bc intcrspersed within thc coUating sequence, and,<br />
within each of these s<strong>et</strong>s, they follow the obvious coUating order.<br />
char-equ<strong>al</strong> character &rest more-characters<br />
char-l essp character &rest more-characters<br />
char-greaterp character &rest more-characters<br />
c h a r - no t -1 e ssp characler &rest mor~characters<br />
char-not-greaterp character &rest more-characters<br />
These routines compare characters independently of font, bits. and case. This does not<br />
mean that only the code portion of the characters is compared, but rather a fontdependent<br />
canonicaHzation is performed on the characters before they are compared.<br />
Thus, for two characters in different fonts, it is possible for them . to not be char-equ<strong>al</strong><br />
even if they have the same code (one might be a "greek" character and the other<br />
"roman"), and conversely it is possible for them to be the same even with different codes<br />
(one might be upper-case and the other lower-case).<br />
MC:<strong>NIL</strong>MAN;CHAR 33<br />
23-DEC-83
Ch4lmcter Construction and Selection 96 <strong>NIL</strong> Manu<strong>al</strong><br />
11.2 Character Construction and Selection<br />
character jrobozz<br />
Coerces jrobozz to a character. It may be a character. a fixnum. in which case char-int<br />
is applied. or a string. symbol. or character vector of length 1. in which case that single<br />
character is r<strong>et</strong>urned. This is what is used· by the coerce function (page 9).<br />
char-code character<br />
char-bits character<br />
char-font character<br />
These three functions extract those attributes (as fixnums).<br />
by the compiler. and accept only character objccts.<br />
AI) are efficiently open-coded<br />
code-char code &option<strong>al</strong> (bils 0) (font 0)<br />
Creates. a character with code, bits, and font of code. bils. and font. unless that is not<br />
possible in the implementation. in which case nil is r<strong>et</strong>urned. In other words. it is an<br />
error for code. bils. or fonl to not be. non-negative integers, however they need not be<br />
less than char-code-limit, char-bits-limit. and char-font-limit respectively.<br />
maKe-char char &option<strong>al</strong> (bitsO) (jontO)<br />
Creates a character with code of the the code of char. and with bits and font of bils and<br />
jont. unless that is not possible in the implementation, in which case nil is r<strong>et</strong>urned.<br />
make-char could have been defined as<br />
(dp.flln maIcA-r.har {t::"~r &option<strong>al</strong> (bits 0) (font 0»<br />
(code-char (char-code char) bits font»<br />
11.3 Character Conversions<br />
char-upcase char<br />
char-downcase char<br />
Upper- or Jower-casify char, preserving the font and bits attributes of it. Note in<br />
particular that these functions just r<strong>et</strong>urn char if it has a non-zero bits attribute, because<br />
such a character is not <strong>al</strong>phab<strong>et</strong>ic and hence not subject to having its case changed.<br />
char-i nt char<br />
R<strong>et</strong>urns a non-negative integer (in <strong>NIL</strong>. this will be a fixnum) encoding of the character<br />
char. If the bits and font of char are 0, this is the same as char-code. This is useful<br />
for hashing. and certain charactcr-fixnum conversions such as those needed for the<br />
MACLISP tyi function are defined in tenns of char-int.<br />
1nt-char integer<br />
If there is some character c for which (char-int c) equ<strong>al</strong>s integer, that character is<br />
r<strong>et</strong>urned; otherwise. nil is r<strong>et</strong>urned.<br />
~1C:NII.MAN:CHAR 33<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 97 Intern<strong>al</strong> Error Checking Routines<br />
char-name char<br />
R<strong>et</strong>urns the name of the character char, if it has one. Supposedly. <strong>al</strong>l characters which<br />
have zero font and bit4i attributes and which are non .. graphic (see graphic-char-p) have<br />
names.<br />
In <strong>NIL</strong>. the name of a character is by convention a symbol in the keyword package.<br />
name-char sym<br />
The argument S)'111 must be a symbol. If the symbol is the name of a character object.<br />
that object is r<strong>et</strong>urned: otherwise nil is r<strong>et</strong>urned.<br />
In !'II. character name symhols arc symbols in the keyword p4lCk~lge.<br />
d1git-char-p digit &oplion<strong>al</strong> (radix 10)<br />
digit-char-p is a semi-predicate. If digit, which must be a chanlcler, is a digit in radix<br />
radix. then the weight of thm digit is r<strong>et</strong>urned. otherwise nil is r<strong>et</strong>urned. By definition. a<br />
character with non-zero bits is not a digit. so for that digit-char-p will <strong>al</strong>ways r<strong>et</strong>urn nil.<br />
digit-char u'£'iglrl &optionaJ (radix 10) (fimf()<br />
I f it is possible to construct a chilracter with the given bits and font which has the weight<br />
weigh! in radix radix ~ then such a character isr<strong>et</strong>urncd. otherwise nil is rcturned. weight<br />
must be a \ <strong>al</strong>id weight for thc radix (a non-negativc integer less th,m radix). Note the<br />
similarity to make-char (page 96) <strong>al</strong>so.<br />
(digit-char 5) => #\5<br />
(digit-char 10) =~ nil<br />
(digit-char 10 25) => #\A<br />
Note that unlike make-char, digit-char does not take a bils argument. This is because<br />
a character with a non-lero bits attribute is by definition not a digit.<br />
11.4 Intern<strong>al</strong> Error Checking Routines<br />
The following may be of use to uscrs writing their own routines for dc<strong>al</strong>ing with characters.<br />
(They should eventu<strong>al</strong>ly be supplanted by more gener<strong>al</strong> type-checking macros, which will probably<br />
turn into c<strong>al</strong>ls to these routines ... )<br />
s1: requ1 re-character character<br />
Error.;checks that character is in fact a character. This is what is c<strong>al</strong>led by (for example)<br />
the interpr<strong>et</strong>ed version of char-code.<br />
s 1: requ1 re-character-f1xnum integer<br />
Error-checks that illteger is in fact an integer for which there is a character representation:<br />
that is, on whichint-char would r<strong>et</strong>urn a character. All such intcgers in <strong>NIL</strong> happen to<br />
be non-negative fixnums.<br />
MC:NII.MAN:CHAR 33<br />
23-DEC-83
I.ow-I.evel I nterf~lces 98 Nil. Manu<strong>al</strong><br />
11.5 LOl\'·Level Interfaces<br />
Xint-char fixllum<br />
Non-check version of jnt-char. It is an error for fixllum to not be the integer encoding<br />
of a v<strong>al</strong>id character object. as would be r<strong>et</strong>urned by char-int.<br />
The following four routines define digitness in the <strong>NIL</strong> character s<strong>et</strong>. at a low level. These<br />
routines do 1101 depend on the fillli of the character (if they take a character as an input); rather,<br />
they dcfine thc basic conversions for the "standard" ~IJ. character s<strong>et</strong> (~II"S interpr<strong>et</strong>ation of<br />
ASCII).<br />
% v a 11 d - dig 1 t - r ad 1 x - p radix<br />
This defincs the v<strong>al</strong>id rangc of radices which %digit;..char-in-radix opcratcs on. The<br />
radix must he a fixnum.<br />
%d1 g1 t-char-1 n - radix -p char radix<br />
Primili\'c predicatc for testing whcther thc charactcr ohject char is a digit character in the<br />
fixnum radix radix (which must be a v<strong>al</strong>id numeric radix).<br />
%digit-char-to-we1ght dwr<br />
For any char which satisfies %digit-char-in-radix-p, this will r<strong>et</strong>urn the weight of that<br />
digit.<br />
%d1g1t-we1ght-to-char weiRhl<br />
This inverts %digit-char-to-weight.<br />
The fonowing two routines perfonn low-level case mapping for the <strong>NIL</strong> character s<strong>et</strong><br />
%char-upcase-code code<br />
%char-downcase-code code<br />
These routines perform low-level case mapping for the <strong>NIL</strong> character s<strong>et</strong> code must be a<br />
v<strong>al</strong>id character code; the r<strong>et</strong>urned v<strong>al</strong>ue is a character with 0 bits and font attributes.<br />
For example. if <strong>NIL</strong> did not provide low-level support for multiple fonts,<br />
(char-equ<strong>al</strong> el e2)<br />
would be the same as<br />
(char= (%char-upcase-code (char-code el»<br />
(%char-upcase-code (char-code el»)<br />
The actu<strong>al</strong> definition of char-equ<strong>al</strong> is somewhat different in that the translation and<br />
canonic<strong>al</strong>ization of the characters depends on their font<br />
MC:NII.MAN:CBAR 33<br />
2J-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 99 The N II. Character S<strong>et</strong><br />
11.6 The NI L Character S<strong>et</strong><br />
As can be seen. the format of character objects in <strong>NIL</strong> provides for a basic eight-bit root<br />
charactcr (defined by the code). which can then have both bils and fOllt attributes added to it.<br />
However. the 1/0 devices l':ILmust de<strong>al</strong> with only handle (at most) eight-bit characters-often<br />
only scven.<br />
In principle, !\Il wilt utilize an eight-bit character s<strong>et</strong>; h<strong>al</strong>f of these witl be graphic characters<br />
(the norm<strong>al</strong> ASCII graphics. plus speci<strong>al</strong> symbols), and the other h<strong>al</strong>f reserved. foonat effectors<br />
(such as line feed. backspace), and speci<strong>al</strong> commands for things like the editor and debugger<br />
(Aborl. Resume. C/eor".\'cr{'cll. that kind uf tJ'ling). All oftJ'lcse chamc(ers will then he ahlc to<br />
have bils mld jiml <strong>al</strong>lribu(es added.<br />
To de<strong>al</strong> with tJlis on (for instance) an urdinary seven-bit ASCII tennin<strong>al</strong>. 'II will haye to do<br />
mrce thil)gs in the future. These are not done now. but are noted because they have bearing un<br />
me representation of character objects and input from devices.<br />
I Turn ordinary ASCII con£rol charilcters into the ~II \ersion of the control character. For<br />
instance. the :\sell character with code of 1. which is what you g<strong>et</strong> when typin~ ('amm/<br />
A on a standard ASCII keyboard. will turn inw tJ1e character A (uppercase 1\) with the<br />
COlltrol bit s<strong>et</strong>.<br />
2 Provide "prefix" character-Je\"el commands in variolls places in order U14lt other chanlctcrs<br />
with bits may be entered (this is what is done in the editor). For instance. in the current<br />
inpl1f rnl('('~"()r t'4;
Primili\'e Fonl I }cfinitions 100 <strong>NIL</strong> Manu<strong>al</strong><br />
$ s<strong>et</strong> term/eightbit<br />
to (>Ct,.) Now we have a seven-bit character. If the seven-bit code is less than 32. and if it is not<br />
one of the codes for Backspace. Tab. Lill efeed. or R<strong>et</strong>urn (8. 9. 10. and 13 respective1y). then<br />
add 64 to it. and s<strong>et</strong> the {olllro/ bit. Adding 64 fonns the corresponding uppercase-<strong>al</strong>phab<strong>et</strong>ic or<br />
punctuation character. Thus. 1 turns into {o1llro/-A (65 plus Control). and 135 turns' into<br />
{vlllrv/-Afela-G (135 = 128 + 7. = A.Jela + CQllIro/ + 73 which is G).<br />
11.7 Primitive Font Definitions<br />
Thi\ section d<strong>et</strong>ails how "fonts" are described at a low level in \11, in order to be interfaced<br />
to the character primiti\'es described in this chapter. The contents of this section can he s,,'c1y<br />
ignored by anyone who isn't going to try to define fonts and interf~lce them to !':IL.<br />
first. remer:tber that the code portion of a character is exactly 8 bits.<br />
There are sever<strong>al</strong> ttattributes" of a font which we need to encode in such a way that certain<br />
operations become trh': <strong>al</strong>. They are these:<br />
C(}Il\'crsioll 10 Ul'l'Cl case<br />
('ol1\'crsieJl/ 10 !owe,..case<br />
These want to be done rapidly<br />
Icsling/or ('crlain <strong>al</strong>fribulcs<br />
the predicates upper-case'-p. graphic-char-p. both~case-p. <strong>et</strong>c.<br />
cOIllParison of charactcrs of d~(rere11l fOil IS<br />
Two go<strong>al</strong>s are desired here. It may be desirable for two characters in different fonts with<br />
the same code to 1101 be char-equ<strong>al</strong>. because they represent different things. It might<br />
<strong>al</strong>so be desirable for two characters in different fonts with different codes to be charequ<strong>al</strong>-one<br />
might be p. the other P.<br />
gelling H'ciglils of digits<br />
obtaining digit characters from weights<br />
For efficiency. <strong>al</strong>l of these go<strong>al</strong>s are implemented through table lookup. There are sever<strong>al</strong><br />
speci<strong>al</strong> variables whose v<strong>al</strong>ues are simple vectors which contain one entry for each possible font<br />
(256 entries in each vector). In the initi<strong>al</strong> <strong>NIL</strong> environment. <strong>al</strong>l of the entries of each vector are<br />
initi<strong>al</strong>ized to the same thing.·<br />
Before these tables g<strong>et</strong> listed, there are a couple of conventions which must be explained first<br />
The first is what is caned intern<strong>al</strong>ly a translation table for characters. 1bis is just a simple-string<br />
or simple-bit-vector 256 bytes (2048 bits) )ong~ for doing code-to-code translation. For instance,<br />
translation to upper-case for a particular font utilizes such a table. The <strong>NIL</strong> primitives are defined<br />
such that it docs not matter wh<strong>et</strong>her this datastructure is a simple-bit-vector or a simple-string.<br />
Another such datastructure is a sy1l1ax table. This is the same as a translation ciblc~ but each<br />
byte within the table is treated instead as a bit-mask with one bit s<strong>et</strong> for each attribute about the<br />
code being defined. Both of these concepts will be abstracted away from characters in a' future<br />
~JL<br />
1be attributes about a font we define arc these:<br />
uppr,..casc IransT<strong>al</strong>ion lable<br />
lowe,.case tr<strong>al</strong>lsl<strong>al</strong>ioll/able<br />
MC:NlI.MAN:CHAR 33<br />
23-DEC-83<br />
" .<br />
, . _', _ -. -' , .' • ~ c " ' ~ - , • '," - ,
<strong>NIL</strong> Manu<strong>al</strong> 101 Primitivc Font Definitions<br />
Etch font has one of each of these. ehar-upease works by r<strong>et</strong>urning a new character of<br />
the same font. with a code which is the result of extracting the byte from the upper-case<br />
translation table at the code index. (If the character has non-zero bits it is just r<strong>et</strong>urned<br />
however.)<br />
syntax table<br />
A syntax table (as described above) with syntax bits for the character primitives graphieehar-p.<br />
upper-ease-po lower-ease-p. both-ease-po <strong>al</strong>phanumeriep. and <strong>al</strong>phaehar-p.<br />
Constants for these bits are defined below.<br />
digit weight table<br />
This is a simple vector 256 long with one entry for each character code. All entries are<br />
fixnul11s. Those entries corresponding. to characters which cannot ever he interpr<strong>et</strong>ed as<br />
digits should he -1: <strong>al</strong>l others should have the weight of the digit.<br />
digil cliar lable .<br />
This is a simple-string (it must 1101 be a simple-bit-vector) used for conversion from a digit<br />
. weight to thc corresponding character. The length of the string is the maximum radix<br />
which 'can be handled in that font. and <strong>al</strong>l entries in-b<strong>et</strong>ween must be v<strong>al</strong>id. For<br />
iT: tance. in the standard such table. the entry at index 9 is the character 9. and the<br />
entry at index 12 is the character C.<br />
the 1)]J('Jilce<br />
The fonnat of this object is not defined: the typefaces of different fonts are compared<br />
with eq by such predicates as char-equ<strong>al</strong>. This is discussed later.<br />
Iypeface cGl1ol1ic<strong>al</strong>izatiolltable<br />
This is a simp]e vector 256 long. which is used to produce a canonic<strong>al</strong>il.ation of a<br />
character within a typeface. The eiemenlli ot the vector are tlxllurns. When two characters<br />
of the same typeface are compared. the code of each character is used as an index into<br />
this table (there is one per font. remember), and that result is used for the comparison.<br />
This <strong>al</strong>lows a typeface to have. among sever<strong>al</strong> fonts. more than 256 characters.<br />
s 1: nata-pr 1m1 t 1 va-fan t font-number &key upper-ease-translations syl1lax-table<br />
lower-case-translations typeface backwards-reference digit-weight-table<br />
digi I-chaT'" table t),peface-c<strong>al</strong>lonic<strong>al</strong>ization<br />
This assigns <strong>al</strong>l of the infonnation described above to the font fOllt-number. Appropriate<br />
defaults are assigned for those entries which are nil.<br />
The following constants define syntax bits used in the syntax table used. For each, the uSv_tt<br />
constant has as its v<strong>al</strong>ue the position of the bit within the field (byte), and the "Sm_tt constant a<br />
mask for testing the bit (with logtest&~ for instance) or s<strong>et</strong>ting it (with logior&).<br />
s1: charsyntax$v_graph1c Constant<br />
s 1: charsyntax$m_graph 1 c<br />
Constant<br />
This hit tells if the character is graphic; that is. if it should satisfy graphie-char-p.<br />
s1: charsyntax$v_uppar _case Conslant<br />
S 1: charsyntax$m_upper _case<br />
Constanl<br />
This bit tells if the character is upper case (should satisfy upper-case-p).<br />
MC:<strong>NIL</strong>MAN:CHAR 33<br />
23-DEC-83
Primitive Fonl Definitions<br />
102<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
s1:charsyntax$v_lower_case<br />
s1:charsyntax$m_lower_case<br />
This tells if the character is lower case.<br />
{OIlSlant<br />
ConSl<strong>al</strong>lt<br />
s1:charsyntax$v_both_caS8<br />
s1:charsyntax$m_both_case .<br />
This tells if the character satisfies both-case-p (page 95).<br />
s1:charsyntax$v_d1g1t<br />
s1:char5yntax$m_d1g1t<br />
This teBs if the chamcter is Cl (decim<strong>al</strong>) digit chamcter.<br />
COllstanl<br />
Constant<br />
COllslOllt<br />
COils/<strong>al</strong>ii<br />
s1 : charsyntax$v_standard<br />
('011.';/(1111<br />
51: charsyntax$m_standard COIiSIGllt<br />
This lells if thc character, were it if font O. is a s~1ndard char (standard-char-p. page<br />
94).<br />
s1: charsyntax$v_<strong>al</strong>pba COllsttlnt<br />
51: charsyntax$m_<strong>al</strong>pba COllsl<strong>al</strong>l1<br />
This tells if the chamcter is <strong>al</strong>phab<strong>et</strong>ic. If the chiJracter is either upper or lowef case.<br />
then it must have this bit s<strong>et</strong> <strong>al</strong>so. It is hypothctic<strong>al</strong>ly possihle. however. for a character<br />
to be <strong>al</strong>phab<strong>et</strong>ic but neither upper Of lower case.<br />
Character comparison <strong>al</strong>a char-equ<strong>al</strong>. char~lessp. <strong>et</strong>c .. i~performed itS follows. w~ :lSSllme<br />
thJt it is possible to group characters into logic<strong>al</strong> "typefaces": canonic<strong>al</strong>il.ations within a typefllce<br />
are v<strong>al</strong>id. and comparisons of characters of different typefaces are not. Each font has associated<br />
with it one such typeface. and the assumption. is that many different fonts map to just a few<br />
typefaces. When two characters are compared. if their typefaces are the same. then the codes of<br />
the characters are translated into fixnums by obtaining the eod<strong>et</strong>h clements of the typeface<br />
canonic<strong>al</strong>ization tables, and the results compared in the appropriate manner (= for char-equ<strong>al</strong>, <<br />
for char-Iessp, <strong>et</strong>c.). If the typefaces arc ·different. then the characters are not equ<strong>al</strong>; for<br />
ordering, they are compared in a manner consistent with char
<strong>NIL</strong> Manu<strong>al</strong> 103 !\ITays<br />
12. Arrays<br />
Arrays in I'll _ encompass a large number of varied objects which share certain features and<br />
aspects of usage. <strong>NIL</strong> arrays may range in rank (number of dimensions) from 0 to about 250. All<br />
array indices in <strong>NIL</strong> are zero origined. One-dimension<strong>al</strong> arrays are veClors. are of the type vector,<br />
and may be used by the various sequence functions (in chapter 7). Restrictions on the types of<br />
the clements of an array (its elemenl IJpe) can result in speci<strong>al</strong> storage and access strategies. The<br />
data in multidimension<strong>al</strong> arrays is <strong>al</strong>ways stored in row-major order; this is compatible with<br />
MACI.ISP. <strong>al</strong>though nonn<strong>al</strong>ly it docs not matter-.<br />
12.1 Array Creation,! Access,! and Attributes<br />
make - ar r 8y dimcllsilills &key el(,1I1(,III-I)1)C displaced-Io displa('('d-ind('x-ojfs('/ <strong>al</strong>fius/able<br />
jill-poil1lcr<br />
This is the gener<strong>al</strong> array creation function. dimensions may be an integer. in which case<br />
the rank of the created array will he_ one (it will he a vector). or a list of integers which<br />
are the sizes of the correspondhq dimensions of the array.<br />
The array wi11 be created to hold objects of type ('/('melll-I)1)C. If this is not supplied. t is<br />
assumed. and the created array will be able to hold any lisp objects. The most common<br />
types. aside from t. are bit (which creates a bit-array). and string-char (which creates a<br />
string-char-array). The speci<strong>al</strong> types which Jl'IL supports. and their consequences. arc<br />
tii~"lIcc(\ti ..........-.-..,.......- ............ in c",.,inn _....".... 1"" "--;-4 "''tnt> 11\.1<br />
.t'~C" .&.v ••<br />
If jill-poilller is not null. then the array must be one-dimension<strong>al</strong> (a vector). It will be<br />
created with a fill pointer initi<strong>al</strong>ized to jill-pointer. which must be b<strong>et</strong>ween zero and the<br />
size of the array (inclusive). Fill pointers arc discussed in section 12.3. page 105.<br />
Nonn<strong>al</strong>ly, the size of an array may not be changed (other than by modification of its fill<br />
pointer if it has one). This <strong>al</strong>lows the implementation some leeway to provide for more<br />
efficient access and storage. However, if adjustable is specified and not nil, then the array<br />
will be created in such a way that its size (and its displacement attributes) can be<br />
modified later by adjust-array. Modification of array size and attributes is discussed in<br />
section 12.5. page 107.<br />
The displaced-to and displaced-index-offs<strong>et</strong> arguments control array displacement; that is<br />
where one array can "point into" another. This is discussed in section 12.4. page 107.<br />
are' array &rest indices<br />
R<strong>et</strong>urns the element of array addressed by the indices. The number of indices must<br />
match the rank of the array, and each index must lie b<strong>et</strong>ween zero (inclusive) and the<br />
size of the corresponding dimension of the array (exclusive).<br />
If the array is one dimension<strong>al</strong> (Le .• a vector) and has a fin pointer. the fill pointer is 110t<br />
used to decide the range of the array which may be v<strong>al</strong>idly referenced: aref may be used<br />
to access <strong>al</strong>l clements of such an array. In this, it differs from elt (page 49).<br />
MC:<strong>NIL</strong>MAN;ARRAY 36<br />
23-I)FC-83
Array Element Types 104 <strong>NIL</strong> Manu
-------------------------------<br />
<strong>NIL</strong> Manu<strong>al</strong> 105 FiJI Pointers<br />
string-char<br />
The array can only hold characters which satisfy the predicate string-char-p (page 19).<br />
A one-dimension<strong>al</strong> array of this clement-type is of type string. A string that is not<br />
adjustable, not displaced, and has no fin pointer is of the type simple-string: this is<br />
implemented more efficiently than a more gener<strong>al</strong> string~ and can be efficiently accessed<br />
with the schar function (page 114). Chapter 13 is devoted to strings.<br />
character<br />
The array can hold only characters (but they may be any type of characters). This<br />
provides no advantage over the clement-type t in the current implementation: in a later<br />
'II., vectors of clement-type character will he acceptahle to the string function~ (chapter<br />
13).<br />
(unsigned-byte 8)<br />
(signed-byte 8)<br />
(unsigned-byte 16)<br />
(signed-byte 16)<br />
Store those integers which arc representable in tl··~<br />
respective fields.<br />
double-float<br />
The double-floats arc stored p,lCked in machine representation. Until lhe' compiler has<br />
sufficient power to speciaJly handle accesses to arrays of this type, there is no particular<br />
benefit to their usc. because a generic array reference to a dl.luhle-float array will have to<br />
cons the number to r<strong>et</strong>urn it.<br />
t Au aIT"y \if dement-type t ean h\ild any lisp (}bjc~t. If sli~h dB eli"d), i~ um:-Jilm:lJ~iullai.<br />
not adjustable. not displaced. and has no fill pointer. then it is a simple vector (of the<br />
type simple-vector). Such a vector is especi<strong>al</strong>ly efficient, and may be accessed with the<br />
svref function (page 109).<br />
12.3 Fin Pointers<br />
The :fill-pointer option to make-array <strong>al</strong>lows one to create a vector of varying length. It is<br />
only applicable to one-dimension<strong>al</strong> arrays. The fill pointer of a vector is an integer which may<br />
range from 0 to the size of the vector. 1t is used as the length of the vector; the v<strong>al</strong>ue of the fill<br />
pointer will be r<strong>et</strong>urned by length (page 49). and used as the length by <strong>al</strong>l sequence and string<br />
functions: in fact, by everything except for aref (and its variants such as char and bit). The<br />
contents of the array at and beyond the fill pointer are still considered v<strong>al</strong>id;· they just are not<br />
considered when the array is viewed as a sequence.<br />
A string with a fill pointer is reputed to be similar to a PL/I varying string. <strong>al</strong>though such a<br />
comparison is beyond the re<strong>al</strong>m of this author's knowledge.<br />
To find the actu<strong>al</strong> <strong>al</strong>located length of a vector which has a fill pointer, use array-dimension<br />
with a dimension number of O. array-dimension <strong>al</strong>ways r<strong>et</strong>urns the <strong>al</strong>10catcd length.<br />
f\·1C:NII.MAN:ARRA Y 36<br />
23-DEC-83<br />
... - ~...
Fill Pointers 106 <strong>NIL</strong> Manu<strong>al</strong><br />
array-has-f111-pofnter-p array<br />
This r<strong>et</strong>urns t jf array has a fill pointer (implying that it is a vector). nil otherwise. It is<br />
an error for array to not be an array.<br />
fill-poi ntar vector<br />
This r<strong>et</strong>urns the fill pointer of vector, which must bea vector with a fill pointer. " lnis<br />
may be used with s<strong>et</strong>f.<br />
vector-push \JeClor object<br />
reClor must be a vector with a fiU pointer. If the fiU pointer is a vaJid index into the<br />
\ector (that is. its \".llue is J~ss than the <strong>al</strong>located length of the ,"ector). then vector-push<br />
SlOres (}/~i('('1 into thilt slot. incr~l1lents the fill poi Iller. .md re(Urns the origin<strong>al</strong><br />
(linincremented) fill pointer (which address~s where the uhject was stored). If the filt<br />
pointer is the same as the <strong>al</strong>loc<strong>al</strong>ed length (the only other v<strong>al</strong>id situation). then vectorpush<br />
r<strong>et</strong>urns nil.<br />
Note that the argument order to vector-push differs from that of the push macro (page<br />
38). This will be incompatibly chmlged in the future. at which time ver.tor-push will<br />
contrive to figure out which argument is which from their types.<br />
vector-push-extand vector object &option<strong>al</strong> extension<br />
This is like vector-push. but whereas vector-push will r<strong>et</strong>urn nil if the vector is "fun",<br />
vector-push-extend will instead can adjust-array to incre,lse the si7e of V('Clor in order<br />
thilt if miehr no the:- pnli;h. Thu~, it nl?\'l~~ rt:tt!r!l~ niL If ~X{!>f?!f(lf? is 5upp1i{'d and not nU.<br />
then that is the amount by which the size of \'eclor is incremented by adjust~array, if<br />
necessary; otherwise. some random guess based on the current sizcis used.<br />
In order for adjust-array to succeed in increasing the size of veclor. l'l'clor must have<br />
been cre<strong>al</strong>ed with the :adjustable option to make-array; see section 12.5, page 107.<br />
The ordering of the arguments vector and object will be reversed in the future; see<br />
vector-push, above.<br />
vector-pop vector<br />
This is the inverse of vee/or-push. The fill pointer of vector is decremented, and the<br />
object addressed by that index is r<strong>et</strong>urned. The fill pointer must not <strong>al</strong>ready be zero.<br />
res<strong>et</strong>-fill-pointer vector &option<strong>al</strong> (illdexO)<br />
Res<strong>et</strong>s the fin pointer of veclor, which must have one. If index is not specified, 0 is<br />
assumed.<br />
This function is obsol<strong>et</strong>ed by the use of fiU"pointer with s<strong>et</strong>f.<br />
One common use of vectors with fill pointers is as buffeTS. For example. the <strong>NIL</strong> compiler<br />
lIses a vector with a fin pointer for anocating a tahle of v<strong>al</strong>ue cell indices to be referenced by the<br />
code it is compiling. It creates a vector with make-array. specifying that the array is adjustable,<br />
mld gi\ ing it an initi<strong>al</strong> fill pointer of O. Then. it uses vector-push-extend to add Cl new entry,<br />
and the v<strong>al</strong>ue thm r<strong>et</strong>urns is the index into this table. vector-push -extend takes care of<br />
increasing the size of the vector jf the initi<strong>al</strong> guess as to its size was too sm<strong>al</strong>l.<br />
MC~NII.M;\N:ARRAY 36
N II. Manu<strong>al</strong> 107 Displaced Arrays<br />
This same technique can be used for generating text. jf the vector is a string (that is. makearray<br />
was given string-char as the :element-type keyword). This is how some string<br />
accumulating primitives work.<br />
With vector-pop, vectors with fill pointers can <strong>al</strong>so be used as stacks.<br />
12.4 Displaced Arrays<br />
Arrays may be created which do not have data of their own. but in fact "share" data with<br />
some other array. These arc displacrt/ arrays. The lIses for displaced arrays \·<strong>al</strong>'}'. One might<br />
want to access the clements of a multi-dimension<strong>al</strong> array as if it were a \ ector: this could he<br />
done by<br />
(make-array size :displaced-to other-array)<br />
which r<strong>et</strong>urns a vector which will "ccess the clements of Oilier-array in row-major-order. With<br />
displacement. a displaced index offs<strong>et</strong> may <strong>al</strong>so be specified. Conceptu<strong>al</strong>ly, when an array is<br />
accessed. a single index is computed from the indices and dimensions of the array: this is the<br />
index into the row-major-order data. This iildex then has the displaced-index-offs<strong>et</strong> added to it.<br />
to gel the index into the data for the array being displaced to.<br />
Another potenti<strong>al</strong> use for displaced arrays is to reference some "substructure" of an array<br />
which implicitly has some ·'structure". This causes modification of the displaced array to modify<br />
the referenced subpart of the origin<strong>al</strong> array. In genera1. however. it is not appropriate to use<br />
array displacement as a substitute for a subseq operation (page 50): it is intended fi1f cases<br />
where modification of one must implicitly nl0dify the other. <strong>al</strong>though if the subsequence is large<br />
it may be worthwhile.<br />
Efficiency note; displaced arrays which are displaced to non-adjustable arrays access at just<br />
about the same speed as nonn<strong>al</strong> arrays (not counting those which are especi<strong>al</strong>ly efficient. namely<br />
simple vectors, simple strings, and simple bit vectors). Arrays displaced to adjustable arrays are a<br />
touch slower. At this time. the l':IL compiler does not know how to inline code any non-vector<br />
array access, however, so aref (or use of it with s<strong>et</strong>f) will produce gener<strong>al</strong> function c<strong>al</strong>l unless<br />
there is exactly one index.<br />
12.5 Modifying Array Sizes and Characteristics<br />
Nonn<strong>al</strong>ly, an array may not have the size of its dimensions or other attributes changed once<br />
it is created (other than modification of its fill pointer; section 12.3, page 105). If a non-null<br />
:adjustable option is given to make-array, however, the array will be created such that this is<br />
possible.<br />
·adjust-array array dimensions &key displaced-to displaced-index-offs<strong>et</strong> element-type<br />
jill-pointer<br />
adjust-array interpr<strong>et</strong>s dimellsio11s just as make-array docs. The array is modified to<br />
have the new dimensions; however. its rank may not be changed.<br />
If jill-pointer is specified. then array must have origin<strong>al</strong>ly been created with a fill pointer:<br />
the v<strong>al</strong>ue of ftll-poilller is used as the new one.<br />
MC:NII MAN:ARRAY 36
..<br />
Speci<strong>al</strong> Vectur Primitives 108 Nil. Manu<strong>al</strong><br />
The remaining options wi11 not be d<strong>et</strong>ailed at this time. adjust-array currently only<br />
works on one-dimension<strong>al</strong> arrays. so <strong>al</strong>though not gener<strong>al</strong>ly useful y<strong>et</strong>. it has enough to<br />
keep vector-push-extend happy.<br />
12.6 Speci<strong>al</strong> Vector Primitives<br />
These functions arc around in <strong>NIL</strong> for historic<strong>al</strong> reasons. They should gener<strong>al</strong>1y not be used<br />
in new code. for reasons which will become clear from reading the descriptions. They arc<br />
documented because they arc used aU over the place in Nil. itself still. and vref in particular is<br />
generated intern<strong>al</strong> hy the compiler from the usc of aref.<br />
vref }'('('lOr index<br />
'111is is absolu(('(J' idflllic<strong>al</strong> to aref when aref is given a vector and a single index. ar<strong>et</strong> is<br />
tJle preferred function to usc in code~ the <strong>NIL</strong> compiler compiles aref· of it single index as<br />
a c<strong>al</strong>l to this intern<strong>al</strong> vector-referencing subroutine.<br />
Because this is the same as aref on a one-dimension<strong>al</strong> array. It IS Ultcresting to note tJlat<br />
(for a vector with a fill pointer) vref does not usc the vector-length to check if the index<br />
is in range.<br />
vector-l ength vector<br />
For historic<strong>al</strong> reasons, this is the same as length but only accepts a vector as an<br />
argument. If the vcctor has a fin pointer. this is not the same as (array-dimension<br />
l'ector 0). which is the quantity used by vref for boundscheckjng.<br />
12.7 Simple Vectors<br />
Vectors of elcment-type t which are not adjustable and have no fill pointer are implemented<br />
as the primitive data type simple-vector. (This was c<strong>al</strong>led simple-gener<strong>al</strong>-vector in the<br />
'previous <strong>NIL</strong> release. Do 1101 misinterpr<strong>et</strong> the name. simple-vector to mean one encompassing<br />
vectors of other clement types.) This type is extensively used in <strong>NIL</strong> as a building block for more<br />
complicated datastructurcs in <strong>NIL</strong>. including less· simple arrays. There arc speci<strong>al</strong> routines for<br />
creating and manipulating them, which are coded cfficiently by the <strong>NIL</strong> compiler.<br />
Vectors of this type may be checked for with typep, of course.<br />
lIlake-vector size &key initi<strong>al</strong>-contellts initi<strong>al</strong>-element<br />
Makes a vector of element-type t. size long. Because no complicated array options can be<br />
specified, this will <strong>al</strong>ways be a simple vector.<br />
This may be caned make-simple-vector in the future, but the name make-vector will<br />
be preserved indefinitely.<br />
MC:NII.MAN:ARRA Y 36
pa<br />
<strong>NIL</strong> Manu<strong>al</strong> 109<br />
Bit Arrays<br />
vector &rcst elemellls<br />
This makes a simple vector whose clements are initi<strong>al</strong>ized to elements. That is.<br />
(vector 123) => #(123)<br />
svref simple-vee/or index<br />
<strong>Reference</strong>s a simple vector. This routine, is entirely open-coded by the compiler, with no<br />
error checking; to r<strong>et</strong>ain nmtime type and bounds checking. aref must be used.<br />
svref may be used with s<strong>et</strong>f.<br />
This function used to be c<strong>al</strong>led sgvref: th41t name is still around.<br />
simple-vector-length vcelvr<br />
. R<strong>et</strong>urns the length of the simple vector "ector.<br />
, This used to be c,.1Jed simpJe-gener<strong>al</strong>-vector-length (yow!): that name is still around.<br />
12.8 Bit Arrays<br />
Arrays which contain only bits. which can be used to represent boolean true and f<strong>al</strong>se, are<br />
useful in various applications. There arc sever<strong>al</strong> functions which perform boolean operations on<br />
arrays of this clement type.<br />
Bit arrays may be more or iess appropnate ior a panlcuiar apphcatlon than integers used to<br />
represent a sequence of bits. Bit arrays (or bit-vectors) may be side-effected: integers may not.<br />
Integers however may be used to represent infinite s<strong>et</strong>s. because they are vinu<strong>al</strong>ly extended with<br />
their sign: see <strong>al</strong>so section 10.S. page Sl. Bit arrays, of course, may be multi-dimension<strong>al</strong>.<br />
bit bit-array &rest subscripts<br />
Just like aref (page 103), but only works on arrays of clement-type bit.<br />
s<strong>et</strong>f may be used with bit.<br />
s b 1 t bit-array &rcst subscripts<br />
This is just like bit, but is only for use on simple bit arrays. This can result in much<br />
more efficient code, especi<strong>al</strong>ly if the bit-array is one-dimension<strong>al</strong>.<br />
s<strong>et</strong>f may be used with sbit.<br />
b 1 t - an d bit-array-] bit-array ..] &option<strong>al</strong> resu/t-bit"orroy<br />
bit-ior bit-array-] bit-array-] &option<strong>al</strong> result-bit-array<br />
b 1 t - xo r bit-array-] bit-array ..] &option<strong>al</strong> result-bit-array<br />
b1 t-eqv bit-array-] bit-array-] &option<strong>al</strong> resu/t-bit-array<br />
bit-nand bit-array-l bit-array-] &optionaJ result-bit-orray<br />
bit-nor bit-array-i bit-arra"v-] &option<strong>al</strong> result-bit-array<br />
bit-andc1 bil-arrl1y-i bil-array-2 &option<strong>al</strong> result-bit-array<br />
bit-andeZ bit-array-I bit-array-] &option<strong>al</strong> result-bit-array<br />
bit-orc1 bit-arruy-i bil-array-l &option<strong>al</strong> resull-bil-array<br />
bit-orcZ bit-array-l bil-array~] &option<strong>al</strong> result-bit-array<br />
MC:NII.MAN:ARRA Y 36<br />
23-DEC-83
Hit Arrays 110<br />
These cnmch tog<strong>et</strong>her bit-array-/ and bi/-arm)'" 2. pcrfonning the appropriate bitwise<br />
logic<strong>al</strong> operation. bi/-urray-} and bit-array"} must have the same rank and dimensions. If<br />
result-bit-array is nil or not specified. then the . result is a freshly created bit array of the<br />
same rank and dimensions. If it is t. then the resuJlc; are stored in bit-orrar I.<br />
Otherwise. it must be a bit array of the same rank and dimensions as the other two, and<br />
the results are stored intO it<br />
b 1 t - no t hi/-array &optionaJ r{'sult-hit-aml)'<br />
Perfonns a bitwise logic~l1 negation on the contents of bit-array. If rrsull-bil-arroyis nil or<br />
nOl specified. then the result is r<strong>et</strong>urned as a freshly created bit array of the same rank<br />
and dimensions as bit-array. If rrsu"-bil-a,.rt~l' is t. then hi/-array is side-effected with the<br />
n~~lIlts. Otherwise. ,.csul,-bihlrmy should be the a hit array of the same ranK ~md<br />
dimensions as bit-arr(l),. undwiU h<strong>al</strong>e the results stored into it.<br />
12.8.1 Simple Bit Vectors<br />
In '". a one-dimensiona1 hit array which is 'not adjus~lblc. nOl dispJaccd~ and has no fin<br />
pointcr. hi represented as the primithe t~ pesimple-bit-vector. which is reprcsented more<br />
efficiently than a more gener<strong>al</strong> bit array_ Simple bit vecturs are used as building blocks fur more<br />
complicated stmctures which contain binary data. such as the more complicated bit arrays. and<br />
even arrays of clement-type double-float. There are primitives for accessing variable length fields<br />
from them as (possibly sign-extended) fixnums. (but lIo/gener<strong>al</strong> integers. y<strong>et</strong>). and primitives for<br />
treating them il~ jf th~y w~r~ ~('qllen("~ of f'ight·hjrhyt~<br />
Once upon a time the name for this type was bits. This name still lingers in places. but is :<br />
heing replaced by simple-bit-vector.<br />
maKe-b1t-v8ctor size &key illiti<strong>al</strong>-element initi<strong>al</strong>-contents<br />
. Creatcs a simple-bit-vector size long. If neither initia/-element nor initia/-colltents are<br />
specified, the contents of the created bit-vector are undefined. 'The current implementation<br />
of l'IL storage <strong>al</strong>location requires that <strong>al</strong>l <strong>al</strong>located. datastructure be initi<strong>al</strong>ized, so in fact<br />
the bit-vector will <strong>al</strong>ways be initi<strong>al</strong>ized to zeros. but this could change in the future.<br />
If illiti<strong>al</strong>-elemelll is specified, it must be either 0 or 1. and the elements of the bit vector<br />
are initi<strong>al</strong>ized tothaL<br />
If initi<strong>al</strong>-contents is specified. then it should be a bit vector, and the created bit vector is<br />
initi<strong>al</strong>ized to the contents of illilia/-colltell/S. If initi<strong>al</strong>-colltellls is longer than size. the<br />
extra elements arc ignored: jf it is shaner, then the contents of the remaining elcmentsof<br />
the created bit vector arc undefined (just as they arc if neither :initi<strong>al</strong>"'element nor<br />
:initia1-contents are specified). It is an error to specify both illili<strong>al</strong>-elemtIl1I and initi<strong>al</strong>coiuenls.<br />
s1mple-b1t-vector .. length simple-hit-vPClor<br />
R<strong>et</strong>urns the length of simp/l""bit-ver;lor.<br />
MC:NII.MA'N:ARRAY 36<br />
23-DEC-83<br />
. ~ ..... ~ ~"<br />
~ .... ". '" .. ~ "'~ " ~ ,. r
•<br />
Nil. Manu<strong>al</strong> 111 Bit Arrays<br />
n 1 bb 1 e simple-bit-vector skip take<br />
R<strong>et</strong>unls the sequence of bits take long from simple-bit-vector. starting at skip. as a<br />
fixnum. take may range from zero to the number of bit~ representable in a fixnum (30)~<br />
however. if the last. the result will include the sign bit so may be unacceptable for<br />
certain applications. The result is zero-extended.<br />
s<strong>et</strong>f may be used with nibble to replace the field.<br />
n1bble-2c simplc-bit-veClOr skip lake<br />
l.ike nibble. hut the result is sign-extended. 'lbat is •. the result is interpr<strong>et</strong>ed as a signed<br />
hinary v<strong>al</strong>ue from the referenced field.<br />
s<strong>et</strong>f may he used with nibble-2c to replace the field.<br />
g<strong>et</strong>-a-byte simple-bit-vector byte-index<br />
Interpr<strong>et</strong>s simple-hit-vector as a sequence of type (unsigned -byte 8). and r<strong>et</strong>urns the byteindex<br />
th byte.<br />
s<strong>et</strong>f may he used with g<strong>et</strong>-a-byte.<br />
g<strong>et</strong> - a - byte-2c simple-bit-vector byte-index<br />
Interpr<strong>et</strong>s simple-bit-vector as a sequence of type (signed-byte 8). and r<strong>et</strong>urns the b)'/eindexth<br />
byte.<br />
s<strong>et</strong>f may be used with g<strong>et</strong>-a-byte-2c.<br />
\1C:NlI.MAN:ARRA Y 36
Strings 112 Nil. Manu<strong>al</strong><br />
. ]3. Strings<br />
Strings arc vcctors of characters which satisfy the prcdicate string-char-p(page 19).<br />
Although thc gcncric sequence and· array primitives operate on strings, there are two reasons for<br />
having addition<strong>al</strong> functions for strings. For Olle. it is convenient for atomic symbols to be used in<br />
pJace of strjngs~ symbols are not coerced to strings by sequence functions. but they are for most<br />
of the string functions. Additiona1Jy. many of the string functions which compare characters do so<br />
independcnt of the character case: the sequence functions are gener<strong>al</strong>ly based on thceql predicate<br />
(page 20). so are case dependent.<br />
FH'nlUaJly. the string functions will he gener<strong>al</strong>ized to handle arguments which are gener<strong>al</strong><br />
c.:h~tfa
.' ~;,<br />
<strong>NIL</strong> Manu<strong>al</strong> 113 String Comparison<br />
13.2 String Comparison<br />
When routines de<strong>al</strong> with boundaries within strings. there are two different conventions<br />
applied. Many functions take range arguments as the lower inclusive bound and the upper<br />
exclusive bound (gener<strong>al</strong>ly named start and end). These arguments conveniently default to 0 .and<br />
the length of the string (typic<strong>al</strong>ly). As a gener<strong>al</strong> rule. an upper exclusive bound may be explicitly<br />
specified as nil producing behavior as if it were mit specified; this is often necessary in order for<br />
following option<strong>al</strong> arguments to be spccified.<br />
The other commonty used substring convention is for a starting index and a count (gener<strong>al</strong>ly<br />
named start and ('OUllt) to be specified. (This convention is used primarily hy subprimithes. and<br />
old 'II functions. not (,0\1\10' LISP functions.) The suhstring in qucstion is that starling at the<br />
index. and proceeding for count characters. Hadng a specified count fun off the string is an<br />
error, and an explicit specification of a count of nil is not <strong>al</strong>lowed. Just about <strong>al</strong>l of the routines<br />
which s,til1 follow this subsequence convention are low-level 1'11. functions. in which the count is a<br />
required argument. so the question of how it defaults if not specified should not arise any more.<br />
Routincs using this convention som<strong>et</strong>imes n;lme these arguments skip and take rather than start<br />
and COUllt.<br />
string-equ<strong>al</strong> string! siring] &key (starl! 0) (sttlrt20) end! end2<br />
This r<strong>et</strong>urns t if the subsequence of sIring! from startl (inclusive) to end! (exclusive) is<br />
equ<strong>al</strong> (using case-independent character comparison. <strong>al</strong>a char-equ<strong>al</strong> (page 95» to the<br />
subsequence of string] from starf2 (inclusive) to end] (exclusive). The subsequences are<br />
St!~r~!!tccd to he uncqu:1! if t.."c ~!.!b$cqucncc lengths differ.<br />
As a speci<strong>al</strong> upwards-compatibility hack,<br />
arguments instead of keyword arguments.<br />
string-equ<strong>al</strong> will accept option<strong>al</strong> position<br />
string-nat-equ<strong>al</strong> stringl string2 &key (startIO) (start20) end/ end2<br />
The opposite of string-equ<strong>al</strong>. Similarly. the subsequences are guaranteed unequ<strong>al</strong> if their<br />
lengths differ.<br />
str1 ng-lessp stringl string2 &key (startl 0) (start20) end! endl<br />
str1ng-not-lessp string 1 string2 &key (starIIO) (slarI20) end! end2<br />
str1 ng-greaterp string! string2 &key (startl 0) (start] 0) endl end2<br />
str1ng-not-greaterp string 1 string2 &kcy (slartl 0) (slart20) endl end2<br />
Each of these r<strong>et</strong>urns t if the specified subsequences satisfy the specified ordering<br />
predicate. Basic<strong>al</strong>ly. the comparison is d<strong>et</strong>ermined by the first character in the<br />
subsequences which differs (see char-Iessp ctc.. page 95). unless the subsequences are<br />
equa~ in which case a shorter subsequence is t'less than".<br />
As a speci<strong>al</strong> upwards-compatibility hack, string-Iessp (but not the other functions) will<br />
accept its arguments position<strong>al</strong>ly rather than by-keyword.<br />
string- string 1 strillg} &kcy (slarIIO) (slort20) end! end}<br />
string/- .~tringl string} &key (startlO) (start) 0) endl end]<br />
str 1 ng< string I string} &kcy (start 10) (slart20) elldl end2<br />
string- slringi slring2 &key (startIO) (starI20) endl end2<br />
MC:<strong>NIL</strong>MAN:STRING 54<br />
23-DEC-83<br />
~ .. . ... -
Extracting Characters from Strings 114 NH. Manu<strong>al</strong><br />
str i ng> string! string] &key (slartl 0) (sta,,20) elldl elld2<br />
These functions are similar to those above, but do a case dependent character comparison;<br />
that is, they compare the characters like char:: <strong>et</strong>c. (page 95), rather than char-equ<strong>al</strong>.<br />
]3.3 Extracting Characters from Strings<br />
char Siring index<br />
R<strong>et</strong>urns the indexth character (zero-origined) of the string sIring. as a character object.<br />
sIring must be a string.<br />
Because sIring must hea string. the result uf char will <strong>al</strong>ways Stllisfy string-char-p (page<br />
19), with <strong>al</strong>l that that implies.<br />
schar simple-string index<br />
This is like char except that the string must be a simple string. This routine can be<br />
efliciently coded by the <strong>NIL</strong> compiler.<br />
Like char. schar may be used with s<strong>et</strong>f to store into the string.<br />
13.4 String Creation<br />
make-string length &key :initi<strong>al</strong>-efement<br />
Makes a string irl1gln iong. Since no compiicated array options may· be specI"ed. thIS wiJI<br />
<strong>al</strong>ways be a simple-string. initi<strong>al</strong>-elrment must be a character which satisfies stringchar-p;<br />
if it is specified. the r<strong>et</strong>urned string contains that charactcrin every element<br />
If initi<strong>al</strong>-element is 110t supplied. the contents of the r<strong>et</strong>urned string is undefined by<br />
CO\1MON USP. <strong>NIL</strong>. which abhors uniniti<strong>al</strong>ized memory. will initi<strong>al</strong>ize it to zeros (which<br />
happen to be, but may not <strong>al</strong>ways be, the character # \Null). If <strong>NIL</strong> were to be<br />
transported to another operating system with different virtu<strong>al</strong> memory facilities, then this<br />
could change incompatibly.<br />
string-length Siring<br />
R<strong>et</strong>urns the length of the string sIring. string must be a string; it is not coerced.<br />
For COMMON USP, this function is superceded by the generic length function (page 49).<br />
There shou1d be no noticeable efficiency difference b<strong>et</strong>ween length and string -length. Of<br />
course, string-length will complain if its argument is nota string, whereas length wilt<br />
accept any sequence, including nit<br />
str1ng-upcase Slrillg &.key (slartO) end<br />
stri ng-downcase SIring &1cey (start 0) end<br />
R<strong>et</strong>urns a copy of SIring with <strong>al</strong>l characters converted as by char-upcase (or chardowncase).<br />
If start and/or end arc supplied. then only the specified subsequence of the<br />
result is affected: the result <strong>al</strong>ways is the &1melength as SIring. That is. string-upcase<br />
could have been defined as<br />
MC:NfLMAN;STRJNG 54<br />
2.1-I)EC-83
· - ~"''''"<br />
-..w.t"""'_.....,..._______<br />
------~--------------'~-.--~---,----------------<br />
<strong>NIL</strong> Manu<strong>al</strong> 115 More String Functions<br />
(defun string-upcase (string &key (start 0) end)<br />
{nstring-upcase (copy-seq string) :start start :end end»<br />
If no characters of the string are affected by the conversion. one may not depend on<br />
wh<strong>et</strong>her the result is string itself or a copy of it; to guarantee a copy, use copy-seq and<br />
nstring-upcase. as in the above example.<br />
nstring-upcase siring &key (stanO) end<br />
nstri ng- downcase siring &key (slarlO) end<br />
These rOlltines destructively con\'crt <strong>al</strong>l of the characters in the specified suhsequcnce of<br />
slrill~ to upper- or lower-case. siring is r<strong>et</strong>urncd.<br />
string-trim character-bag string<br />
S tr 1 ng -1 eft -tr 1m character-bag string<br />
str i n9 - ri ght - tr 1 m character-bag string<br />
Thesc routines rcturn a substring of siring resulting from trimming the characters in thc<br />
"This is a test. "<br />
13.5 l\lore String Functions<br />
The functions in this section are not provided by COMMON USP, but are typic<strong>al</strong>ly inherited<br />
from LISP MACHI:\E LISP. and are heavily used in <strong>NIL</strong>. That is <strong>al</strong>so why they havc not y<strong>et</strong> been<br />
convcrted to takc kcyworded argumcnts (<strong>al</strong>though some of them may be in the future).<br />
str1 ng-append &rcst strings<br />
R<strong>et</strong>urns a string which is the concatenation of <strong>al</strong>l the strings. The arguments are coerced<br />
to strings using string; in this it differs from the generic sequence function concatenate<br />
(page 50), which will not accept symbols, but will accept sequences (of characters) other<br />
than strings.<br />
substring string start &option<strong>al</strong> end<br />
R<strong>et</strong>urns the substring of string (coerced to a string using string) from the index start up<br />
to but not including end. which defaults to thc length of string if nil or not specificd. If<br />
the specified subsequence is the entire string. one may not depcnd on wh<strong>et</strong>her the<br />
r<strong>et</strong>urned result is string itself, or a copy; to guarantee a copy. subseq (pagc 50) may be<br />
used-howcver. subseq neither restricts its input to strings nor coerces symbols to strings.<br />
string-reverse string<br />
str1ng-nreverse Siring<br />
These are pr<strong>et</strong>ty much superceded by reverse (page 52) and nreverse (page 52). Notc<br />
that for string - nreverse. Siring must be a rc<strong>al</strong> string bccause it is destructively reversed;<br />
string-reverse will accept a symbol and rcturn a string.<br />
MC:<strong>NIL</strong>MAN:STRING 54<br />
23-DEC-83
Implementation Suhprimitivcs 116<br />
N I J. M~Ulu<strong>al</strong><br />
s t r 1 n 9 - sa arc h -c h a r char sIring &optionaJ (from 0) 10<br />
string-reverse-search-char char string &option<strong>al</strong> from (tvO)<br />
str1ng-search-not-char char SIring &option<strong>al</strong> ({ramO) 10<br />
str1ng-revarsa"'s8arch-not-char char slrillg &option<strong>al</strong> from (toO)<br />
str1 ng-saarch-s<strong>et</strong> char-s<strong>et</strong> string &option<strong>al</strong> (from 0) 10<br />
str1ng-raverse-saarch-s<strong>et</strong> char-s<strong>et</strong> string &option<strong>al</strong> from (toO)<br />
string-search-not-s<strong>et</strong> cha,..s<strong>et</strong> string &option<strong>al</strong> (fromO) 10<br />
str1ng-reverse-saarch-not-s<strong>et</strong>('ha,..sl'l string &option<strong>al</strong> from (100)<br />
char-srt is coerced into a sequence of characters: it should be a string. or a list or vector<br />
of ohjects acceptable to character (page 96).<br />
str i ng-search key SIring &option<strong>al</strong> (from 0) to<br />
str 1 ng - reverse - search key SIring &option<strong>al</strong> from (/00)<br />
Ll6 Implementation Subprimitives<br />
Th~ roulines descrihed in thb section are very fllst routines pnmltlve'S which arc orienled<br />
toward~ being open-compiled. As such. the}' perfonn very few nic<strong>et</strong>ies Jikeargumelll d<strong>et</strong>~lUlting.<br />
The versions available in the interpr<strong>et</strong>er probably will do some error checking~ but don't count on<br />
it. These are the Sluff' of which higher-level routines are made. '111ose which lake string<br />
arguments only accept simple strings.<br />
%s tr1 ng- cons length jill-character<br />
Creates a primitive string length long. filled with the character jill-character, C<strong>al</strong>ls to<br />
make-string will compile into c<strong>al</strong>ls to this. if possible. so one should not go out of the<br />
way to use this,<br />
%str1 ng-posqcharacter string index count<br />
This searches through string starting at index and proceeding for count characters for the<br />
character character. If it is found. then the index at which it occurs is r<strong>et</strong>urned;<br />
otherwise nil is r<strong>et</strong>urned. This primitive only looks at the code attribute of character.<br />
ignoring the rest<br />
%str1ng-eqv string! string] index! index} count<br />
Rcturnst if the substrings of string I and string2 defined by index!, index2. and count<br />
arc string = -that is, the same, with case being significant.<br />
%str1ng-replace destination source deslillation-index source-index counl<br />
This transfers COUllt characters from the simple-string source to the simple string<br />
des/ination, starting at the given indices.<br />
%str1 ng-trans 1 ate destillation source tr<strong>al</strong>lsl<strong>al</strong>ion-table destination-index source-index counl .<br />
This is a slightly hairier version of %string-replace, Instead of the characters being<br />
transferred liter<strong>al</strong>ly. the code of each character taken· from the string source is used as an<br />
index in the string tr<strong>al</strong>lslation-table to obtain the code to store instead. For example,<br />
string - upcase could be defined<br />
MC:NII.MAN:STRING 54<br />
23-DEC-83
Nil. Manu<strong>al</strong> 117 Imp1cmcnt~lion Subprimitives<br />
(defun string-upcase (string<br />
&aux (len (string-length string»))<br />
(%string-translate<br />
(make-string len) string *:character-upcase-table<br />
o 0 len»<br />
where *:character-upcase-table has as its v<strong>al</strong>ue a string char-code-limit long whose<br />
ith character is the uppercase version of the character with code i. Note that this<br />
definition of string-upcase is not correct if the input sIring is not a simple-string. and<br />
note <strong>al</strong>so how this relates to how string-char-p is defined.<br />
String hashing in ~IL<br />
is ultimately performed by the eRe instruction.<br />
%str1ng-hash sIring erc-tab/e slar! ('(JUllI<br />
This performs a hash comput..1tion on the substring of SIring starting at character starT and<br />
proceeding for cowll characters. ere-table must be a simple bit vector 512 bit.; (16 \'AX<br />
]ongwords) long: it should contain the hash polynomi<strong>al</strong> for usc by the eRC instruction.<br />
Sever<strong>al</strong> hash polynomi<strong>al</strong> tables arc pf(l\'ided (they arc listed below). The hash<br />
computation is initi<strong>al</strong>ly -1: tllt.~ result is r<strong>et</strong>urned as a signed 'II fixl1um-that is. a 32-bit<br />
word with the lop two bits shifted otl'. Consult the VAX architecllIre manu<strong>al</strong>. or some<br />
other DEC documentation. to s<strong>et</strong> up other hash polynomi<strong>al</strong>s.<br />
For this to be properly useful for increment<strong>al</strong>ly generating CRe computations. this<br />
primitive will have to be changed to somehow input and output full 32-bit quantities;<br />
*:autod1n-11-hash-polynom1<strong>al</strong><br />
*:cc1tt-hash-polynom1<strong>al</strong><br />
*:crc-16-hash-polynomi<strong>al</strong><br />
This is the one <strong>NIL</strong> uses for doing intern and sxhash of strings.<br />
J;ariablc<br />
Variable<br />
Variable<br />
MC:<strong>NIL</strong>MAN:STRING 54<br />
23-DEC-83
-. • • • _': - " .~.<br />
• - - - '.' - • ," .:: • • .-' -- .'. - • •<br />
Hashing 118 Nil. Mamwl<br />
14. Hashing<br />
Nil. supports a COMMON JJSP compatible hash-table facility. This will eventu<strong>al</strong>ly include the<br />
ability to have a hash-table from which associations can be garbagc-conected.<br />
14.1 Hash Tables<br />
The following routines are COMMON I.ISP compatible:<br />
make-hash-table &key :test :rehash-threshold :rehash-size :size<br />
Cr{,~ltcs .. hash tahle. The tcs/ m,l}, be one of # 'eq.' # 'eql. or # 'equ<strong>al</strong>. <strong>NIL</strong><br />
,uJditionaHy provides some others it is able to perfonnsignific,mt optimizations on as<br />
primith'e (see hclow). Note t11m fi.lr 1'11. () usc some predicate it must know how to<br />
compute a hash code compatible with that predicate'snotion of equ<strong>al</strong>ity: thUS. not just<br />
any predicate is acceptable.<br />
g<strong>et</strong> hash kcy haslf"lable &option<strong>al</strong> dejault<br />
This r<strong>et</strong>urns two v<strong>al</strong>ucs. If there is an entry for key in hash-lab/e. then this r<strong>et</strong>urns as its<br />
v41lues the v<strong>al</strong>ue associated with key. and t. Otherwise. it r<strong>et</strong>urns default. and nit<br />
g<strong>et</strong>hash may be used with s<strong>et</strong>f to add an entry to (or replace an entry in) a· hash table.<br />
remhash key hash-table<br />
Removes the cntry associated with key from hash-Iable.<br />
cl rhash hash-fable<br />
Removes <strong>al</strong>1 entries from hash-lable.<br />
hash - tab 1 e - count hash-table<br />
R<strong>et</strong>urns the number of entries in hash-lable.<br />
14.1.1 Addition<strong>al</strong> Hash-Table Predicates<br />
<strong>NIL</strong> addition<strong>al</strong>ly offers the following predicates for hash-tables:<br />
string -equ<strong>al</strong><br />
string= '<br />
associating hashing routines with predicates, making this list extensible?<br />
MC:NII.MAN;HASH20<br />
23-DEC-83<br />
".;,. ..... ~ , - ~. I , ~<br />
. ~ -. .~: ~ - ~ ~ -, : : ~<br />
- .... I " • • _ ..<br />
. .". v. . " '. f' ~"<br />
•<br />
•
<strong>NIL</strong> Manu<strong>al</strong> 119 Hash Functions<br />
14.2 I lash Functions<br />
A hash function for equ<strong>al</strong>ity predicate (p xl. x2) is a function which r<strong>et</strong>urns the same v<strong>al</strong>ue<br />
for <strong>al</strong>l x which are equiv<strong>al</strong>ent according to p. "The standard LISP hashing function is sxhash.<br />
which is defined according to the equ<strong>al</strong> predicate. sxhash is inherited from MACUSP. and is<br />
defined by CO~1MON LISP and LISP MACHINE LISP;<br />
Other hash functions are defined by ~IL. for use with other equ<strong>al</strong>ity predicates. Usu<strong>al</strong>ly they<br />
are not needed. because tJley are impJied in me use of a hash table utilizing a particular equ<strong>al</strong>ity<br />
predicate. Ry convention. <strong>al</strong>l 'II. hashing functions r<strong>et</strong>urn a non-negative fixnum: it is a fixnum<br />
for ease of computation. and non-negative to make modulus operations more trivi<strong>al</strong>.<br />
sxhas h ()~;ecl<br />
This is tJle gener<strong>al</strong> J .ISP hashing function. hased on the predicate equ<strong>al</strong> (page 20). hit<br />
.r<strong>et</strong>urns a non-negative integer: in <strong>NIL</strong>, this will <strong>al</strong>ways be a fixnum. Two objects which<br />
are equ<strong>al</strong> should <strong>al</strong>ways sxhash to me same tJling. If tJ1is is not true. then any hash<br />
~1hles which use sxhash and equ<strong>al</strong> will break. Note that hecause !'II will have a<br />
relocating garbage collector, the hash of In object should never be a function of the<br />
address of anything.<br />
str i ng-equa l-hash string<br />
This function r<strong>et</strong>urns a non-negative fixnulTI such tJlat for <strong>al</strong>l strings which are stringequ<strong>al</strong>.<br />
tJleir hashes computed by this function will be equ<strong>al</strong>.<br />
str1ng a -hash Siring<br />
Similar; defined by the predicate string = (page 113).<br />
sys: sxhash-comb1 ne {hash} +<br />
This macro might be useful to writers of :sxhash m<strong>et</strong>hods or speci<strong>al</strong> hashing functions. It<br />
is a canonic<strong>al</strong> way to combine a fixed number of hash codes. For example, the sxhash<br />
of a cons docs<br />
(sys:sxhash-combine (sxhash (car x)} (sxhash (cdr x)})<br />
The hashes are rotated some fixed amount d<strong>et</strong>ennined by the number of arguments, and<br />
crunched tog<strong>et</strong>her in some canonic<strong>al</strong> fashion. (There may be a limitation on the number<br />
of arguments which are handled, but this will work for some moderate number of<br />
arguments.)<br />
14.3 Symbol Tables<br />
Although one can use packages to implement symbol tables. and this has been recommended<br />
in the past. it is now b<strong>et</strong>ter to use a hash table based on the appropriate predicate. and storing<br />
'an appropriate object as the v<strong>al</strong>ue. For example, if one had been using a package as a symbol<br />
table and then using the symbol after interning it. a hash table could be used using string-equ<strong>al</strong><br />
or string = as the predicate (as appropriate) and putting a symbol in as the v<strong>al</strong>uc. Dcpending on<br />
what the symbol is used for. it may be b<strong>et</strong>ter to use a defstruct-created object instead: attributes<br />
can be accessed fasler off of this than as properties on the pliSl of a symbol. Secondarily. there is<br />
a moderate space inefficiency to gener3ting lots of v<strong>al</strong>ue ceBs in Nil" so instead of generating<br />
symbols and using their v<strong>al</strong>ue cells to store things is <strong>al</strong>so b<strong>et</strong>ter to usc a speci<strong>al</strong>ized structure.<br />
~1C:NII.MAN:H"SH 20<br />
2J-DFC-83
Symbol Tables 120 Nil. M,lnu<strong>al</strong><br />
When the ~n. package system is redone. the intcrna1 portion of that which docs simple<br />
symbol-table hacking will be made· available fi)r applications where that is truly nceded.<br />
~1C;NJL~1.\~:HASH 20
<strong>NIL</strong> Manu~l 121 Packages<br />
15. Packages<br />
Skctchy. This is <strong>al</strong>l going to brcak. either as a result of COMMON LISP or compl<strong>et</strong>e<br />
rcimplcmcntation and redesign or both.<br />
understanding of simple obarrays/ob/isls and interning is assumed below<br />
The basic idca of packages is that if an programs in a large messy environment like <strong>NIL</strong> use<br />
the same name-sp
Packages 122 <strong>NIL</strong> Manu<strong>al</strong><br />
A little thought «thOllt the use of the sys and glob<strong>al</strong> p~lckages in the ahove description will<br />
show that they should nO( be ordin
<strong>NIL</strong> Manu<strong>al</strong> 123 Modules<br />
15.1 Modules<br />
CO!\1!\10~ LISP defines a fairly simple way in . which one may name modules. declare that they<br />
have been loaded, and cause them to be loaded if they have not been. While t11is is intended to<br />
be used as a part of the COMMON LISP package system. it is fairly independent and can be used<br />
without it. Here it is.<br />
In this sense. a module (not to be confused with the <strong>NIL</strong> data type module which will be<br />
renamed someday) is simply an independent subsystem which is treated as a unit. A module can<br />
come from one or more files: the' number is irrelevant other than to the loading process.<br />
CO\1\10,\ liSP modules arc referenced by name: functions which take a module name may he<br />
given either a string or a symhol. In the module name. case mailers. so. f()r instance. "LSS" is<br />
not the same module name as "Isb".<br />
• modul as.<br />
Variable<br />
This variable has as its v<strong>al</strong>ue a list of the names of <strong>al</strong>l the modules which have been<br />
provided (see be1
Modules 124<br />
NII~ Manu<strong>al</strong><br />
note-modu18-pathname module-1lome po/hllam!'<br />
This declares that in order to provide lIlodule-llame. p<strong>al</strong>/m<strong>al</strong>lle must be loaded. p<strong>al</strong>hllome<br />
may <strong>al</strong>so be a list of pathnames.<br />
Eventu<strong>al</strong>ly. higher-level ways of defining packages, systems. and modules wiU be defined.<br />
and use of note-modufe-pathname will be phased out.<br />
The only modules known about in advance by the <strong>NIL</strong> system right now LS8 and SIMP. Of<br />
course. as of this writing. the fc1cilitics documented in this. section haven °t even been inst<strong>al</strong>led y<strong>et</strong>.<br />
so there will probably be severa) tnoreshonly .<br />
...<br />
!\1C:NII.\1AN:PACKAG 17<br />
23-DEC-S3
<strong>NIL</strong> Manu<strong>al</strong> 125 Defstruct<br />
16. Defstruct<br />
) 6.1 Introduction<br />
This chapter is a modification of the description of defstruct appearing in the MacIisp<br />
Extensions Manu<strong>al</strong> [3]. There are three sorts of ~hangcs:<br />
(I) Del<strong>et</strong>ion of topics not applic~bJe) to <strong>NIL</strong>;<br />
(2) Del<strong>et</strong>ion of things which do not y<strong>et</strong> work in <strong>NIL</strong>;<br />
(3) Modifications of the defaults. as the <strong>NIL</strong> defstruct is intended to be upwards-compatible<br />
with the CO\1\HY\ IISP defstruct.<br />
For these reasons. some of Ule wording m~'y seem a bit strange. in that the origin<strong>al</strong> document is<br />
concerned with helping users write code compatible in differing l.isp implementations. defstruct<br />
is part of the ('0\1\10;\ I.ISJ> st4tndard (but not <strong>al</strong>l the parts of it). and the documentation on it<br />
will be fixed in the future. Any inaccuracies in this modification of it are purely the fault of<br />
GSB.<br />
The keywords which are used in defstruct arc <strong>al</strong>l interned in the keyword package. just like<br />
Olher keY\H)rds in :\11.. For compatibility with \tACI.ISP programs. howe":-f. defstruct \\-'ill accept<br />
UlOse 1101 in me keyword package. Convcrsely. the MAC'I.ISP def.~truct will check f(lr symbols<br />
which have a leading "." in their names. In !'IL. one should use the colons for stylistic<br />
consistcncy.<br />
16.2 A Simple Example<br />
defstruct<br />
defstruct i~ a macro defining macro. The best way to explain how it works is to show a<br />
sample c<strong>al</strong>l to defstruct. and thcn to show what macros are defincd and what each of<br />
them does.<br />
Sample c<strong>al</strong>l to defstruct:<br />
(defstruct (elephant (:type :list»<br />
color<br />
(size 17.)<br />
(name (gensym»)<br />
This fonn expands into a whole rat's nest of stuff, but the effect is to define five macros:<br />
elephant-color, elephant-size. elephant-name. make-elephant and <strong>al</strong>ter-elephant. Note that<br />
none of these symbols appeared in the origin<strong>al</strong> form, they were created by defstruct. The<br />
definitions of color. size and name are easy. they expand as follows:<br />
(elephant-color x) ==> (car x)<br />
(elephant-size x) ==> (cadr x)<br />
(elephant-name x) ==> (caddr x)<br />
You can see that defstruct has decided to implement an elephant as a list of uucc things~ its<br />
color, its size and its name. The expansion of make-elephant is somewhat harder to explain,<br />
l<strong>et</strong>'s look at a few cases:<br />
MC:<strong>NIL</strong>MAN;DEFSTR 91<br />
23-DEC-83
57 - -.- v 'to ,<br />
I<br />
Syntax of de fstruct 126<br />
Nil. Milfiu<strong>al</strong><br />
(make-elephant) ==> (list nil 17. (gensym»<br />
(make-elephant :color 'pink) ==> (list 'pink. 17. (gensym»<br />
(make-elephant :name 'fred :size 100)<br />
==> (list nil 100 'fred)<br />
As you can sec, make-elephant takes a "sctq-stylc" list of pan names and forms, and<br />
expands into a c<strong>al</strong>l to list that constructs such an elephant. . Note that the unspecified pans g<strong>et</strong><br />
defaulted to pieces of code specified in the origin<strong>al</strong> caU to defstruct. Note <strong>al</strong>so that the order of<br />
the sctq·style arguments is ignored in constructing the c<strong>al</strong>l to list. (In the example. 100 is<br />
ev<strong>al</strong>uated before 'fred even though 'fred came first in the make-elephant form.) Care should<br />
thus he taken in usjng code with side effects within the scope of a make-e1ephant. (This<br />
particular hehaviour will be "fixed" by (,O\1MO~ LISP. hut has not y<strong>et</strong> been worked into \11.)<br />
Fin<strong>al</strong>ly, wke note of the fact thai the (gensym) is ev<strong>al</strong>uated el'C'IJ' lime a new elephmltis creilled<br />
(unless you override it).<br />
The explanation of what <strong>al</strong>ter-elephant docs is delayed until section 16.4.3. page 129~<br />
So now you know how to construct a new elephant and how to examine the parts of an<br />
elcph.mt. but how do you ch.mgc the pare; of an <strong>al</strong>ready existing elephant? The answer is to use<br />
the s<strong>et</strong>f m,tcro (section 5.9 t page 38).<br />
_(s e t f (e 1 e p han t - n arne x) 'b i 11 ) = = > ( s<strong>et</strong> f (c add r x) , bill )<br />
which is what you want.<br />
A nt1 th!lt ~5 jU5t about an t"~rc -is t{' defstruct: you now know enough to use it in your cede.<br />
but if you want to know about <strong>al</strong>l its interesting features, then read on.<br />
16.3 Syntax of derstruct<br />
The gener<strong>al</strong> fonn of a defstruct fennis:<br />
(defstruct (name opt;o"..1 0pl;0n-2 ••• option-n)<br />
slot-description-I<br />
slot-description-2<br />
s/ol-descriplion-m)<br />
name must be a symbol. it is used- in constructing names (such as_ "make-elephant") and it is<br />
given a defstruct-description property of a structure that describes the structure compl<strong>et</strong>ely.<br />
Each oplion-i is either the atomic name of an option. or a Ust of the form (option-name arg •<br />
res/). Some options have defaults for arg; some will complain if they are present without ail<br />
argument: some options complain jf they are present with -an argument. The intcrpr<strong>et</strong>ationof rest<br />
is up to the option in question. but usu<strong>al</strong>ly it is expected to be nit<br />
Each SIOI-dcscriplioll-j is either the atomic name of a slot in the structure. or a list of the<br />
form (slot-Ilome illit-C'ode). or a list of byte field specifications. illil-code is used by constructor<br />
macros (such as make-<strong>et</strong>ephant) to initi~1ize slots not specified in the c<strong>al</strong>l to the constructor. If<br />
the illil .. code is not specified. then the slot is initi<strong>al</strong>ized to whatever is most convenient. (In the<br />
elephant example, since the structure was a list. nil was used. If _ the structure had been a<br />
MC:<strong>NIL</strong>MAN:DEFSl'R 91<br />
23-DEC-83
N II. Manu<strong>al</strong> 127 Options to defstruct<br />
fixnurn array. such slots would be fined with zeros.)<br />
A bytc field specification looks like: (field-name bytespec) or (field-name bylespec illit-code).<br />
Notc that since a byte field specification is <strong>al</strong>ways a list. a list of byte field specifications can<br />
never be confused with the other cases of a slot description. The byte field feature of defstruct<br />
may be undergoing change in !'I:II. due to the incompatible change of bytespec format (see section<br />
10.9. page 84). so is discouraged for the present·<br />
16.4 Options to defstruct<br />
The following sections document each of the options defstruct understands in d<strong>et</strong>ail.<br />
On the Lisp Machine and in ~II..<br />
package.<br />
an these defstruct options are interned on the keyword<br />
16.4.1 :type<br />
The :type option specifics what kind of lisp object defstruct is going to use to implement<br />
your structure. and how that implementation is going to be carried out. The :type option is<br />
illeg<strong>al</strong> without an argument. If the :type option is not specified. then defstruct will choose an<br />
appropriate default: in I'lL. defstruct will implement the structure as a vector-like object. which<br />
will be defined as a type whose name is the name given to defstruct. One can then check for<br />
objects ot thiS type with typep. (This dittcrs from the way defstruct currently operates in<br />
\1:\('I.ISI> and I.IS}> M:\C'IIINF LISP.) It is possible for the user to teach defstruct new ways to<br />
implement structures, the interested reader is referred to section 16.6, page 138, for more<br />
information. Many useful types have <strong>al</strong>ready been defined for the user. A table of these "built<br />
in" types follows.<br />
:Iist<br />
:named-list<br />
:tree<br />
:list.<br />
Uses a list This is the default in MULTICS MACUSP.<br />
Like :list, except the car of each instance of this structure will be the name<br />
symbol of the structure. This is the only "named" structure type defined on<br />
Multics and is the default named type there. (See the :named option documented<br />
in section 16.4.4, page 131.)<br />
Creates a binary tree out of conses with the slots as leaves. The theory is to<br />
reduce car-cdring to a minimum. The :include option (section 16.4.9, page 133)<br />
does not work with structures of this type.<br />
Similar to :list. but the 1ast slot in the structure wi11 be placed in the cdr of the<br />
fin<strong>al</strong> cons of the list. Somc people caB ohjects of this type ttdotted lists". 111C<br />
:include option (section 16.4.9. page 133) does not work with structures of this<br />
type.<br />
MC:NII.MJ\N:DEFSTR 91<br />
2J-I)EC-8J
Options to d<strong>et</strong>struct 128 <strong>NIL</strong> Manuill<br />
: array<br />
:sfa<br />
:vector<br />
Uses an array object (not a symbol with an array property). This is the default on<br />
Lisp Machines. Eventu<strong>al</strong>ly. many of the same hairy array options which defstruct<br />
supports on the Lisp Machine will be supported in <strong>NIL</strong>; at this time. however.<br />
<strong>NIL</strong> users are advised to just usc the default, or perhaps :vector.<br />
Uses an SFA. The constructor macros for this type accept the keywords :sfafunction<br />
and:sfa-name. Their arguments (ev<strong>al</strong>uated. of course) are used.<br />
respectivcly. as the function and the printed represenwtion of the SFA. See <strong>al</strong>so<br />
the :sfa-function (~cli(}n 16.4.12. page 134) and :sfa-name (section 16.4J3. page<br />
135) options. (SFAs ,tre clvailahle in ~n. for compatibility with PDP-IO \1 ACIISI).<br />
They should not nonn<strong>al</strong>ly be used. and HfC not documented in the 'II m~lJlu<strong>al</strong>.)<br />
Uses an vector. This will be a simple-vector.<br />
:nl\med - vector<br />
I -ike \ ector. ex,:cpt clement number 0 illways contains the n(lme symbol of the<br />
structure. Note thUl this is 110/ Ule default lIdmcd type in Nil .• :extend is.<br />
:extend<br />
'Ibis is the default named type in ~IL. Nonn<strong>al</strong>ly you don't need· to know that it<br />
h~~ thi" w~ird T1;l1T'!('. h~m,se thi5 has bc~n the d~f:m!! dcfS!!"uct typ~ if :namse is<br />
specified for a \\'hile. and it is now the def4Juh type period. See <strong>al</strong>so the :classsymbol<br />
option (section 16.4.11, page 134).<br />
) 6.4.2:constructor<br />
The :constructor option specifics. the name to be given to the constructor macro. Without an<br />
argumen~ or if the . option is not present. the name defaults to the concatenation of "make..·' with<br />
the name of the structure, If the option is given with an argument of nil. then no constructor is<br />
defined. Otherwise the argument is the name of the constructor to define. NonnaUy the syntaX<br />
of the constructor defstruct· defines is:<br />
( COIlSlTUClo~nQme<br />
keyword-J code-J<br />
keyword-2 codeo2<br />
keyword-n code-n)<br />
Each keyword- i must be the name of a slot in the structure. or one of the speci<strong>al</strong> keywords<br />
<strong>al</strong>lowed for the particular type of structure being constructed. . All of these keywords are symbols<br />
interned in the keyword package. <strong>al</strong>though for upwards-compatibility (this is new behaviour) that<br />
is not required. For each keyword that is the name of a slot. the constructor expands into code<br />
to make an instance of the structure using ('odr-i to initi<strong>al</strong>ize slot keyword-i. Unspecified slots<br />
default to the forms given in the origin<strong>al</strong> defstruct fonn. Of, if none was given there. to some<br />
convenient v<strong>al</strong>ue such as nil or O.<br />
MC:<strong>NIL</strong>MAN:DEFSTR 91<br />
23-DEC-83
dieTl' r "TrT'erl;"" . pm'l<br />
7'$tMr7' 'Teitmr<br />
<strong>NIL</strong> Manu<strong>al</strong> 129 Options to defstruct<br />
For keywords that are not names of slots. the use of the corresponding code varies. Usu<strong>al</strong>ly<br />
it controls some aspect of the insUlnce being constructed that is not otherwise constrained. The<br />
only one of these which is used in <strong>NIL</strong> is the :sfa-function option (section 16.4.12. page 134).<br />
If the :constructor optior is given as (:eonstru<strong>et</strong>or Ilame arglis!). then instead of making a<br />
keyword driven constructor. defstru<strong>et</strong> defines a ttfunction style" constructor. The arglist is used<br />
to describe what the arguments to the constructor will be. In the simplest case som<strong>et</strong>hing like<br />
(:constructor make-foo (a b e» defines make-foo to be a three argument constructor macro<br />
whose arguments are lIsed to initi<strong>al</strong>ize the SIOLIi named a. band c.<br />
In addition. the keywords &option<strong>al</strong>. &rest and &aux are recognized in the argument list.<br />
They work in the way you might expect. but there are a few fine points worthy of explan
W ·lrV"·<br />
•<br />
130<br />
made to be the v<strong>al</strong>lie of slot s!o/-llome-; of that structurc. lbe slots are an <strong>al</strong>tcrcdin par<strong>al</strong>le1<br />
<strong>al</strong>ief <strong>al</strong>l code has been ev<strong>al</strong>uated. (Thus you can usc an <strong>al</strong>terant macro to exchange the contents<br />
to two slots.) As for the kcywordcd constructor macro. the s!ot-Ilame-i should be symbols interned<br />
in the keyword package. <strong>al</strong>though (again) that is not required.<br />
Example:<br />
(defstruct (lisp~hacker<br />
(favorite~macro-package<br />
(unhappy? t)<br />
(number-of-friends 0»<br />
(:type :11st)<br />
:conc-name<br />
:defau1t-pointer<br />
:a1terant)<br />
nil)<br />
(s<strong>et</strong>q lisp-hacker (make-lisp-hacker»<br />
Now we can perfonn a transfonnation:<br />
(<strong>al</strong>ter-lisp-hacker lisp-hacker<br />
favorite-macr0-package 'defstruct<br />
number-of-fribnds 23.<br />
unhappy? nil)<br />
==> «lambda (G0009)<br />
« lambda (GOOI1 GOOIO)<br />
(s<strong>et</strong>f (car G0009) 'defstruct)<br />
ls<strong>et</strong>t (caaar uOOOY) uOOll)<br />
(s<strong>et</strong>f (cadr G0009) GOOIO»<br />
23.<br />
nil»<br />
lisp-hacker)<br />
Although it appears from this example that your fonns will be ev<strong>al</strong>uated in the order in<br />
which you wrote them~ this is not currently guaranteed.<br />
Alterant macros are particularly good at simultaneously modifying . sever<strong>al</strong> byte fields that are<br />
<strong>al</strong>located from the same word. They produce b<strong>et</strong>ter code than you can by simply writing<br />
consecutive s<strong>et</strong>fs. They <strong>al</strong>so produce bener code when modifying sever<strong>al</strong> slots of a structure that<br />
uses the :but-first option (section 16.4.17, page 135).<br />
For defstruct types whose accessors take more than one argument. <strong>al</strong>l of those arguments<br />
must be supplied to the <strong>al</strong>terant macro in place of just the usu<strong>al</strong> one. (Sec section 16.6.3.2, page<br />
140 for how accessors with more than one argument can come to be, there are no built-in<br />
defstruct types with this propcny.)<br />
MC:NII.MAN:DEFSTR 91<br />
23-DEC-83<br />
. - .<br />
- -<br />
. . -<br />
, ~ < • .. • ~ ~ ." ~ .. _ ....: - ~ , • ., ~ ...... _ ~.., ~ ~ , • J. • f
3 - -<br />
2<br />
~<br />
<strong>NIL</strong> Manu<strong>al</strong> 131 Option!'. to dcfstruct<br />
16.4.4 :named<br />
This option tells defstruct that you desire your structure to be a "named structure". In PDP-<br />
10 \1ACl.ISP this means you want your structure implemented with a :named-hunk, :named-list<br />
or :named-vector. On a Lisp Machine this indicates that you desire either a :named-array or a<br />
:named-array-Ieader or a :named-list. On Multics this indicates that you desire a :named-list.<br />
In ~IL this indicates that you desire a :extend. a :named-vector or a :named-list. defstruct<br />
bases its decision as to what named type to use on whatever v<strong>al</strong>ue you did or didn't give to the<br />
:type option: in <strong>NIL</strong>. the default named type is :extend. and :named is the default-the<br />
significance of this was explained in section 16.4.1. page 127. It is an error to usc this option<br />
with an argument.<br />
16.4.5 :predicate<br />
The :predicate option causes defstruct to generate a predicate to recognize instances of the<br />
stmcllIre. Natur<strong>al</strong>ly it nnh' works for some ~efstruct types. Currently it works for <strong>al</strong>l the named<br />
types as we11 as the types :sfa {PDP-tO \1ACUSf) and :\IL only) and :extend (:\11. only). The<br />
arg.ulllcnt to the :predicate option is the name of the predicate. I f it is present without an<br />
argument, then the name is formed by concatenating "_p" to the end of the name symbol of the<br />
stmcture. If the option is not present then no predicate is generated. Example:<br />
(defstruct (foo :named :predicate)<br />
foo-a<br />
foo-b)<br />
defines a single argument function. foo-p. that is true only of instances of tJlis stmcture.<br />
16.4.6 :print<br />
The :print option <strong>al</strong>10ws the user to control the printed representation of his structure in an<br />
implementation independent way:<br />
(defstruct (pair :named<br />
pair-first<br />
pair-second)<br />
(:print "{-S . -S}"<br />
(pair-first pair)<br />
(pair-second pair»)<br />
The arguments to the :print option are used as if they were arguments to the format function<br />
(page 187). except that the first argument (the stream) is omitted. They are ev<strong>al</strong>uated in an<br />
environment where the name symbol of the structure (pair in this case) is bound to the instance<br />
of the structure to be printed.<br />
This option presently only works on Lisp Machines and in <strong>NIL</strong>. using the defstruct types<br />
:named-array and :extend respectively. We hope to make it work in rDP-10 \1ACl.lSP for the<br />
:named-hunk type soon. In MULTICS MACLlSP. this option is ignored. Notice that if you just<br />
specify the :named option without giving an explicit :type option. each defstruct implementation<br />
will default to a named type that can control printing if at <strong>al</strong>l possible.<br />
MC:NII.MAN:DEFSTR 91<br />
23-DFC-83
Optiuns to defstruct 132 Nil. M.tnu<strong>al</strong><br />
16.4.7 :default-pointer<br />
Norm<strong>al</strong>ly the accessors are defined to be macros of exactly one argument. (They check!) But<br />
if the :default-pointer option -is present then they will accept zero or one argument. When used<br />
with one argument. they behave as before. but given no. arguments. they expand as if they had<br />
been c<strong>al</strong>led on the argument to the :default .;.pointer option. An example is probabJy caned for:<br />
(defstruct (room (:type :tree)<br />
(:default-pointer •• current~room •• )}<br />
(room-name 'y2)<br />
(room-contents-list nil»<br />
Now the accessors expand as follows:<br />
(room-name x)<br />
(room-name)<br />
==><br />
==><br />
(car x)<br />
(car •• current-room •• )<br />
If no argu~ent is given to the :default-pointer option. then the name of the stnJcture is<br />
used as the "default pointer". :default- pointer is most often used in this fashion.<br />
16.4.8 :conc"name<br />
Frequently <strong>al</strong>l the accessor macros of a· stnt<strong>et</strong>ure will want to have names that begin the same<br />
way: usu<strong>al</strong>ly with the name of the stnlcture followed by a dash. The :conc-name option Clllows<br />
the user to specify this prefix. Its argument should be a symbol whose print name will be<br />
concatenated onto the front of the slot names when forming the accessor macro names. If the<br />
argument is not given. then the name of the structure fbl10wed by a dash is used. as it is if the<br />
:conc-name option is not prcscnL(This is different than it used to be!) If it is desired that the<br />
slot names. as specified. be used' as the accessor macros. then (:conc-name nil) may be used.<br />
An example illustrates a common use of the :conc-name option <strong>al</strong>ong with the :default-pointer<br />
option:<br />
(defstruct (location :default-pointer<br />
:conc-name)<br />
(x 0)<br />
(y 0)<br />
(z 0»<br />
Now if you say<br />
(s<strong>et</strong>q location (make-location x 1 y 34 z 5»<br />
it will be the case that<br />
(location-y)<br />
will r<strong>et</strong>urn 34. Note wen that the name of the slot ("ytt) and the name of the accessor macro for<br />
that slot ("location y") are different<br />
w<br />
MC:NII.MAN:DEFSTR 91<br />
- -, ,- - - . '- ' . -' ,- -, _:'" ' - - .: , ' -<br />
- -' " ~ ~~ -' '.' -~, ~~ '-~ '.':, " - ". ' ' - " --, ,<br />
-, ,- , - ~ :' -' , . ';: -,'. , - -. .
WoW'OM t<br />
<strong>NIL</strong> Manu<strong>al</strong> 133 Options to defstruct<br />
16.4.9 :include<br />
The :include option inserts the definition of its argument at the head of the new structure's<br />
definition. In other words. the first slots of the new structure are equiv<strong>al</strong>ent to (Le. have the<br />
same names as. have the same inits as. <strong>et</strong>c.) the slots of the argument to the :include option.<br />
The argument to the :include option must be the name of a previously defined structure of the<br />
same type as the new one. If no type is specified in the new structure, then it is defaulted to<br />
that of the included one. It is an error for the :include option to be present without an<br />
argument. Note that :include does not work on certain types of structures (e.g. structures of type<br />
:tree or :Iist.). Note <strong>al</strong>so that the :conc-name, :default-pointer. :but-first and :c<strong>al</strong>lableaccessors<br />
options only apply to the accessors defined in the current defstruct: no new accessors<br />
arc defined f(.lf the included slots.<br />
An example:<br />
,(defstruct (person (:type :list})<br />
name<br />
age<br />
sex)<br />
(defstruct (spaceman (:include person)<br />
(:conc-name nil)<br />
:defau1t-pointer)<br />
helm<strong>et</strong>-size<br />
(favGrit~-b~v~rag~ 'tang})<br />
Now we can make a spaceman like this:<br />
(s<strong>et</strong>q spaceman (make-spaceman :name 'buzz<br />
:age 45.<br />
:sex t<br />
:helm<strong>et</strong>-size 17.5»<br />
To find out interesting things about spacemen:<br />
(helm<strong>et</strong>-size)<br />
==> (cadddr spaceman)<br />
(person-name spaceman) ==> (car spaceman)<br />
(favorite-beverage x) =:> (car (cddddr x»<br />
As you can see the accessors defined for the person structure have names that start with<br />
"person-" and they only take one argument. The names of the accessors for the last two slots of<br />
the spaceman structure are the same as the slot names, but they <strong>al</strong>low their argument to be<br />
omitted. The accessors for the first three slots of the spaceman structure are the same as the<br />
accessors for the person structure.<br />
Often. when one structure includes another. the default initi<strong>al</strong> v<strong>al</strong>ues supplied by the included<br />
structure will be undesirable. These default initi<strong>al</strong> v<strong>al</strong>ues can be modified at the time of inclusion<br />
by giving the :include option as:<br />
(: include name new-init-] ••. new-fnil-n)<br />
Each Ilcw-fnit-i is either the name of an included slot or of the fonn (included-slot-name new-init).<br />
If it is just a slot name. then in the new structure (the one duing the including) that slot will<br />
have no initi<strong>al</strong> v<strong>al</strong>ue. If a new initi<strong>al</strong>" v<strong>al</strong>ue is given. then that code replaces the old initi<strong>al</strong> v<strong>al</strong>ue<br />
code for that slot in the new structure. The included structure is unmodified.<br />
MC:NII.MAN:DEFSTR 91<br />
23-DEC-83
Options to defstruct 134 <strong>NIL</strong> Manu<strong>al</strong><br />
16 .• 4.10 :copier<br />
This option causes defslruct to generate a single argument function that will copy instances of<br />
this structure. The argument to the :copier. option is the name of the copying function. If this<br />
option is present without <strong>al</strong>l argument. then the name is formed by concatenating "copy-" with<br />
the name of the structure.<br />
Example:<br />
(defstruct (coat-hanger (:type :list) :copier)<br />
current-clos<strong>et</strong><br />
wire-p)<br />
Gen(.~r'llcs a function ~Ipproximatcly like:<br />
(defun copy-coat-hanger (x)<br />
(list (car x) (cadr x»)<br />
16.4.11 :class .. symbol<br />
For use with tlle :extend defstruct type ~l\·ai1ahle only in :\11 (section Io.'U. page 128). this<br />
option <strong>al</strong>lows the lIser to control hem' the flavor definition is pcrfimlled. '( his option IIIWil be<br />
given a variable name as an argument: the v<strong>al</strong>ue of that variable is used as the flavor (class)<br />
object of the object which the defstruct-defined constructor will create. defstruct wi11 not define<br />
the flavor.<br />
This option W~)S origin<strong>al</strong>ly implemented for bootstrapping purposes. so that typed objects in<br />
!':Il. could be created before the flavor system was fully loaded. Pventu<strong>al</strong>ly it will be fully<br />
outmoded by extensions to the flavor system, which <strong>al</strong>ready has the capability of defining accessor<br />
macros for instance variables.<br />
16.4.12 :sfa-function<br />
Available in PDP-IO MACUSP and in <strong>NIL</strong>. this optionaUows the user to specify the function<br />
that will be used in structures of type :sfa. Its argument should be a piece of code that ev<strong>al</strong>uates<br />
to the desired function. Constructor macros for this type of structure will take :sfa-function as a<br />
keyword whose argument is <strong>al</strong>so the code to ev<strong>al</strong>uate to g<strong>et</strong> the function. overriding any supplied<br />
in the origin<strong>al</strong> defstruct form.<br />
If :sfa ,..function is not present anywhere, then the constructor will use the name-symbol of<br />
the· structure as the function.<br />
MC:<strong>NIL</strong>MAN:DFFSTR 91<br />
23-DEC-83
.. "' m -f' - .,.o. d' T T C "5 - W)'W"'mlttnr ltV f'g' .,<br />
<strong>NIL</strong> Manu<strong>al</strong> 135 Options to defstruct<br />
16.4.13 :sfa-name<br />
Available only in PDP-IO MACI.ISP and 1'0:11.. this option <strong>al</strong>lows the user to specify the object<br />
that will be used in the printed representation of structures of type :sfa. Its argument should be<br />
a piece of code that ev<strong>al</strong>uates to that object. Constructor macros for this type of structure will<br />
take :sfa-name as a keyword whose argument is <strong>al</strong>so the code to ev<strong>al</strong>uate to g<strong>et</strong> the object to<br />
usc, overriding any supplied in the origin<strong>al</strong> defstruct fotm.<br />
If :sfa-name is not present anywhere. then the constructor will use the name-symbol of the<br />
stnlcture as the function.<br />
16.4.14 :sizc-symbol<br />
The :size-symbol option <strong>al</strong>lows a user to specify a symbol v.hose v<strong>al</strong>ue will be the "size" of<br />
the stnicture. The exact meaning of this varies, but in gener<strong>al</strong> this number is the one you would<br />
need to know if you were going to <strong>al</strong>locate one of these structures yourself. The symbol will<br />
have this v<strong>al</strong>lie both at compi1e time and' at run time. If this option is present without an<br />
argument. then the name of the structure is concatenated with "-size" to produce the symhol.<br />
16.4.15 :size-macro<br />
Similar to :size-symbol. A macro of no arguments is defined that eXPands into the size of<br />
the structure. The name of this macro defaults as with :size-symbol.<br />
16.4.16 :initi<strong>al</strong>-orrs<strong>et</strong><br />
lbis option <strong>al</strong>lows you to tell defstruct to skip over a certain number of slots before it starts<br />
<strong>al</strong>locating the slots described in the body. This option requires an argument. which must be a<br />
fixnum, which is the number of slots you want defstruct to skip. To make use of this option<br />
requires that you have some t:'UTliliarity with how defstruct is implementing you structure,<br />
otherwise you will be unable to make use of the slots that defstruct has left unused.<br />
16.4.17 :but-first<br />
This option is best explained by example:<br />
(defstruct (head (:type :list)<br />
nose<br />
mouth<br />
eyes)<br />
(:conc-name nil)<br />
(:default-pointer person)<br />
(:but-first person-head»<br />
So now the accessors expand like this:<br />
(nose x) ==> (car (person-head x»<br />
(nose)<br />
==> (car (person-head person»<br />
MC:NII.MAN:DEFSTR 91<br />
2J-DEC-8J
, • ,~ ~. ~ ~ - • ~.: M •<br />
Options to def.~lruct 136 <strong>NIL</strong> Mmlllill<br />
The theory is that :but-firsfs argument will likely be an accessor from some other stnlcture.<br />
and it is never expected dl<strong>al</strong> this structure will be found outside of that slot of that other<br />
structure. (In the example I had in mind that thefe was a person structure which had a slot<br />
accessed by person~head.) It is an effor for the :but-first option to be used without an<br />
argument.<br />
16.4.18 :c<strong>al</strong>lablc-accessors<br />
This option controls wh<strong>et</strong>her the accessors defined by defstruct will work as "function<strong>al</strong><br />
ar!!Ullll'1l1S" (as the first argument to mapcar. for example). On the I.isp Machine and in ~II.<br />
m.:ccs~or\ arc GJllahlc hy dcfitUll. but inPI>P-W \iA(,IISP it is cxpenshe to milke this work, so<br />
the~ arc only caHahle if you ask for it. (Currently on Multks the feaLUre doesn't work at <strong>al</strong>l ..•)<br />
The argument to this option is nil to indicate that the feature should he turned off. and t to turn<br />
the feature on .. If the option is present with no argument. then the feature is turned on.<br />
16.4.19 :cl'<strong>al</strong>-when<br />
Norm<strong>al</strong>ly the macros defined by defstruct are defined at c\<strong>al</strong>-time. compile-time 4md at loadtime.<br />
This option <strong>al</strong>lows the user to control this behavior. (:ev<strong>al</strong>-when (evaJ compile»~ for<br />
example. will c<strong>al</strong>ise the macros to he defined only when the code is nmning interpr<strong>et</strong>ed and<br />
inside the compiler. no trace of defstruct wiJ] be found when running compiled code. (See ev<strong>al</strong>when.<br />
page 25.}<br />
Using the :ev<strong>al</strong>-when option is preferahle to wrapping an evaJ-when around a defstruct .<br />
fonn. since nested ev<strong>al</strong>-whens can interact in unexpected ways.<br />
16.4.20 :property<br />
For each structure defined . by defstruct, a propeny list is maintained for the recording of<br />
arbitrary propenies about that structure.<br />
The :property option can be used to give a defstruct an arbitrary propeny.· (:property<br />
properly-name v<strong>al</strong>ue) gives the defstruct a property-name propeny of v<strong>al</strong>ue. Neither argument is<br />
ev<strong>al</strong>uated. To access the propeny list. the user will have to look inside the defstruct-description<br />
structure himself, he is referred to section 16.5, page 137. for more information.<br />
16.4.21 A Type Uscd As An Option<br />
In addition to the options listed above, any currently defined type (a leg<strong>al</strong> argument to the<br />
:type option) can be used as a option. This is mostly for compatibility with the old Lisp Machine<br />
defstruct. It <strong>al</strong>lows you to say just type when you should be saying (:type type). Use of this<br />
feature in new code is discouraged. It is an error to give an argument to a type used as an<br />
option in this m,tnner.<br />
MC:NII.MAN:DEFSTR 91<br />
23·IJEC-S3<br />
, ,r • ~ ~ ~ • ~ _ ... ' ~;::. ~ _ . ~ ~ "t' ~ ~ ~ _<br />
, .' •• '
-<br />
NIl. Manu<strong>al</strong> 137 The defstruct-descriplion Structure<br />
16.4.22 Other Options<br />
Fin<strong>al</strong>ly, if an option isn't found among those listed above, defstruct checks the property list<br />
of the name of the option to see if it has a non-null :defstruct-option property. If is docs have<br />
such a property. then if the option was of the fonn (optiOlrname v<strong>al</strong>ue). it is treated just like<br />
(:property option-name v<strong>al</strong>ue). That is. the defstruct is given an option-name property of v<strong>al</strong>ue.<br />
If such an option is used without an argument. it is treated just like (:property op/ion-name t).<br />
That is. it is treated as if the argument was t.<br />
'Illis provides a primitive way for the user to define his own options to defstruct. Severa} of<br />
the options listed ahove are actu<strong>al</strong>ly imp1cmel1lcd using this mechanism.<br />
16.5 The defstruct-description Structure<br />
This section discusses the intern<strong>al</strong> structures used by defstruct that might be useful to<br />
programs that want to interface to defstruct nicely. The infonnation in this section is <strong>al</strong>so<br />
necessary for anyone who is thinking of defining his own structure types (section F.6, page 138).<br />
l.isp Machine and 'II programmers will find that the symbols found only in this section arc <strong>al</strong>l<br />
interned in the "systems-intern<strong>al</strong>s" package ("51" for short).<br />
Whenever the user defines a new structure using defstruct. defstruct creates an instance of<br />
the defstruct-description structure. This structure can be found as the defstruct-description<br />
property of the name of the structure: it contains such useful infonnation as the name of the<br />
structure. the number of slots in the stnlcture. <strong>et</strong>c.<br />
The defstruct-description structure is defined som<strong>et</strong>hing like this: (This is a bowdlerized<br />
version of the re<strong>al</strong> thing, I have left out a lot of things you don't need to know un1ess you are<br />
actu<strong>al</strong>ly reading the code.)<br />
(defstruct (defstruct-description<br />
(:default-pointer description)<br />
(:conc-name defstruct-description-»<br />
name<br />
size<br />
property-<strong>al</strong>ist<br />
slot-<strong>al</strong>ist)<br />
The name slot contains the symbol supplied by the user to be the name of his structure.<br />
som<strong>et</strong>hing like spaceship or phone-book-entry.<br />
The size slot contains the tot<strong>al</strong> number of slots in an instance of this kind of structure. This<br />
is not the same number as that obtained from the :size-symbol or :size-macro options to<br />
defstruct. A named structure. for example~ usu<strong>al</strong>ly uses up an extra location to store the name<br />
of the structure. so the :size-macro option will g<strong>et</strong> a number one larger than that stored in the<br />
defstruct description.<br />
Pille property-<strong>al</strong>ist slot contains an <strong>al</strong>ist with pairs of the fonn (properly-name. properly)<br />
containing properties placed there by the :property option to defstruct or by property names used<br />
as options to defstruct (see section 16.4.20, page 136. and section 16.4.22, page 137).<br />
MC:<strong>NIL</strong>MAN:DEFSTR 91<br />
23-DFC-83<br />
.<br />
.' . .•<br />
"<br />
.~.~~ .:.·':·::·.F·c· ........<br />
. ..•... .' .'
Extensions to defstruct 138 <strong>NIL</strong> Manu<strong>al</strong><br />
The sfot-aiist slot contains an <strong>al</strong>is( of pairs of the fimn (slot-name. slot-description). A slot·<br />
descripliol1 is an ins~lnce of the defstruct-slot-description structure. The defstruct-slotdescription<br />
structure is defined som<strong>et</strong>hing like this: (another bowdlerized defstruct)<br />
(defstruct (defstruct-slot-description<br />
(:default-pointer slot-description)<br />
(:conc-name defstruct-slot-description-»<br />
number<br />
ppss<br />
init-code<br />
ref-macro-name)<br />
The number slot contains the number of the location of this slot in an instance of the<br />
structure. l.ocations arc numhered starting with O. and continuing lip to one less than the size of<br />
the structure. The actu<strong>al</strong> location of Ule slot is d<strong>et</strong>ennined by the reference c(lnsing code<br />
associated with ule type of the structure. See scction16.6. page 138.<br />
The ppss slot contains the 'byte specifkr cod~ for this slot if this slot is ~ byte field of its<br />
Jocation. If this slot is the entire location. then the ppss slot contains nil.<br />
The init-code slot contains the initi<strong>al</strong>ization code supplied for this slot by the lIser in his<br />
defstruct form. If there is no initi<strong>al</strong>ization code for this slot then the init-code slot contains the<br />
symbol %%defstruct-empty%%.<br />
Thl' r~f-rn~('r(\-narn~ ~~(\t ('(\ntains th~ sym1)(\! lllat is d('fin('d as an nccessor t.~Jt references<br />
this ,slot.<br />
16.6 Extensions to defstruct<br />
da1struct-d<strong>et</strong>1ne-typ.<br />
The macro defstruct-define-typeean be used to teach defstructabout new types itean<br />
use to implement structures.<br />
16.6.1 A Simple Example<br />
L<strong>et</strong> us start by examining a sample c<strong>al</strong>l to defstruct-define-type. This is how the :list type<br />
of structure might have been· defined:<br />
{defstruct-define-type :11st<br />
(:cons (initi<strong>al</strong>ization-list description keyword-options)<br />
:list<br />
(cons -list initi<strong>al</strong>ization-list»<br />
(:ref (slot-number description argument)<br />
(list 'nth slot-number argument»)<br />
This is the minim<strong>al</strong> example. We have provided defstruct with two pieces of code. one for<br />
cnnsing up fonns to constnJct instances of the structure. the other to cons up fonns to reference<br />
various clements of the structure.<br />
1\1C:NII.MAN:DEFSTR 91<br />
23-DEC-83
".<br />
NIl. M~mll<strong>al</strong> 139 Extensions to defstruct<br />
From the example we can see that the constructor c
Extensions to defstruct 140 <strong>NIL</strong> Manu<strong>al</strong><br />
The symbol i"ils will be bound to the code that the C(}n~tnlctor conser should use to initi<strong>al</strong>ize<br />
the slots of the structure. The exact form of this argument is d<strong>et</strong>cnnincd by the symbol kind.<br />
There arc currently two kinds of initi<strong>al</strong>ization. There is the :Iist kind, where illilS is bound to a<br />
list of initi<strong>al</strong>izations. in the correct order. with nils in uniniti<strong>al</strong>ized slots. And there is the :<strong>al</strong>ist<br />
kind. where illils is bound to an aJist with pairs of the form (s/ot-number . illit-code).<br />
111e symbol description will be bound to the instance of the defstruct-description structure<br />
(section 16.5. page 137) that defstruct maintains for this particular structure. This is so that the<br />
constructor conser can find out such things as the tot<strong>al</strong> size of the structure it is supposed to<br />
create.<br />
The symhol k(l'tnmls will be bound (() ,1 <strong>al</strong>istwith pairs of the foml (kr.l'""orc/. v<strong>al</strong>ue).<br />
where each kr,l'u:ord was a keyword supplied to the constructor macro that wasn't the name of a<br />
slot. "no r<strong>al</strong>l/r waslhe "code" Ul<strong>al</strong> followed the keyword. (Sec section 16.6.3.6. page 142. and<br />
section 16.4.2. page 128.)<br />
It is an error not to supply the :cons option to ~efstruct-define-type.<br />
16.6.3.2 :ref<br />
111C :ref option to defstruct-define-type is how the user supplies defstruct with the<br />
nccessary code that it needs to cons up a form that will reference an instance of a stnJcture of<br />
this type.<br />
The :ref option has the syntax:<br />
( : ref (number description arg-J ••. argon)<br />
body)<br />
body is some code that should construct and r<strong>et</strong>urn a piece of code that will reference an<br />
instance of a structure of this type.<br />
The symbol Ilumber will bc bound to the location of the slot that the is to be referenced.<br />
This is the same number that is found in the number slot of the defstruct-slot-description<br />
structure {section 16.5, page 137}.<br />
The symbol description will be bound to the instance of the defstruct-description structure<br />
that defstruct maintains for this particular structure.<br />
The symbols arg-i are bound to the ·fonns supplied to the accessor as arguments. Nonn<strong>al</strong>ly<br />
there should be only onc of these. The /asl argument is the one that will be defaulted by the<br />
:default-pointer option (section 16.4.7. page 132). defstruct will check that the user has supplied<br />
exactly n arguments to the accessor macro before c<strong>al</strong>ling the reference con sing code.<br />
It is an error not to supply the :ref option to defstruct-define-type.<br />
MC:NII.MAN:IJEfSTR 91<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 141 Extensions to defstruct<br />
16.6.3.3 :prcdicate<br />
The :predicate option to defstruct-define-type is how defstruct is told how to produce<br />
predicates for a particular type when the :predicate option to defstruct is used (section 16.4.5.<br />
page 131). Its syntax is:<br />
{ : p red i c ate (description name)<br />
body)<br />
The variable description will be bound to the defstruct-description structure maintained for<br />
the structure we are to generate a predicate for. The variable name is bound to the symhol that<br />
is to he defined as a predicate. b(}{~l' is a piece of code to ev<strong>al</strong>uate to r<strong>et</strong>urn the defining fonn<br />
f()r the predicate. 1\ lypic<strong>al</strong> lise of this option might look like:<br />
(:predicate (description name)<br />
'(defun ,name (x)<br />
(and (frobbozp x)<br />
(eq (frobbozref x 0)<br />
'.(defstruct-description-name»»)<br />
16.6.3.4 :olcrhcad<br />
The :overhead option to defstruct -define-type is how the user declares to defstruct that the<br />
implementation of this particular type of stnlcture "uses up" some number of slots locations in the<br />
ob.ieer actu<strong>al</strong>ly constntcted. This option is used hy variolJs "nllmeo" typcl\ of "trtl('tlJr('~ thM ~t(lre<br />
the name of the stnlcture in one location.<br />
The syntax of :overhead is:<br />
(:overhead n)<br />
where II is a fixnum that says how many locations of overhead this type needs.<br />
This number is only used by the :size-macro and :size-symbol options to defstruct. (See<br />
section 16.4.15, page 135, and section 16.4.14, page 135.)<br />
16.6.3.5 :named<br />
The :named option to defstruct-define-type controls the use of the :named option to<br />
defstruct.. With no argument the :named option means that this type is an acceptable "named<br />
structure". With an argument. as in (:named typl'"" name). the symbol type-name should be that<br />
name of some other structure type that defstruct should use if someone asks for the named<br />
version of this type. (For example, in the definition of the :list type the :named option is used<br />
like this: (:named :named-list).)<br />
MC:NII.MAN:DEFSTR 91<br />
23-DEC-83<br />
• • ... ..' _ • ~\ ' ,,~ ... ~ • r. • .,<br />
.. ~ ~ ~ • 'I.<br />
- .<br />
~ - - "'<br />
.<br />
~<br />
..
Extensions to defstruct J42 <strong>NIL</strong> Manu<strong>al</strong><br />
16.6.3.6 :keywords<br />
"Inc :keywords option todefstruct-define-type. <strong>al</strong>10ws the user to define constructor<br />
keywords (section 16.4.2. page 128) for this type of structurc. (For example the :make-array<br />
constructor keyword for structurcs of type:array on Lisp Machines.) The syntax is:<br />
( : keywordskeyword-I •.. keyword-n)<br />
where each keYK'ord-i is a symbol that the constructor conser expects to find in the keywords <strong>al</strong>ist<br />
(section 16.6.3.1. page 139).<br />
16.6.3.7 :dcfstruct -options<br />
The :defstruct-options option to defstruct,..define-typeis similar to the :keywords option.<br />
It is used to define new options that may appear in the options part of a defstruct for a structure<br />
of this type. Its syntax is:<br />
(:defstruct-options option-I ... option-II)<br />
This defines each oplioll-j to be a option to defstruct that can he used with structures of this<br />
lype. For example. tJ1e :array defstruct type for ih~ Lisp M,tchine uses the :defstruct-options<br />
option as l(lllows:<br />
(:defstruct-options :make-array)<br />
Currently this just works by giving each option-; a non-nun :defstruct-option property (see<br />
section 16.4.22. page 137). but soon it will check to be sure that each oplioll"; is 0111y used as an<br />
oPtion with structures of this type.<br />
16.6.3.8 :derstruct<br />
The :defstruct option to defstruct-define-type <strong>al</strong>lows the. user to run some code and r<strong>et</strong>urn<br />
some fonns as pan of the expansion of the defstruct macro.<br />
The :defstruct option has the syntax:<br />
( : defstruct (description)<br />
body)<br />
body is a piece of code that will be run whenever defstruct is expanding adefstruct fonn<br />
that defines a structure of this type. The symbol description wilJ be bound to the instance of the<br />
defstruct-descriptionstructure that defstruct maintains for this particular structure.<br />
The v<strong>al</strong>ue r<strong>et</strong>urned by the :defstruct option should be a list of fonns to be included with<br />
those that the defstruct expands into. lous. if you only want to run some code at defstruct<br />
expand time. and you don't want to actu<strong>al</strong>ly output any addition<strong>al</strong> code, then you should be<br />
careful to r<strong>et</strong>urn ni1 from the code in this option.<br />
1\·1C:NI1.MAT":DEFSTR 91<br />
23-DEC-83
- ~tt D ~ ·t![tt '.' tt<br />
<strong>NIL</strong> Manu<strong>al</strong> 143 Extensions to defstruct<br />
16.6.3.9 :copier<br />
The :copier option to defstruct-define-type <strong>al</strong>lows the user to tell defstruct how to generate<br />
the copier functions required by the :copier option to defstruct (section 16.4.10, page 134)~ This<br />
option is entirely option<strong>al</strong>, because defstruct <strong>al</strong>ready has enough infonnation to write an adequate<br />
copier function for any given type given the information supplied to the :ref and :cons options to<br />
defstruct-define-type. However. it is som<strong>et</strong>imes desirable to teach defstruct a b<strong>et</strong>fer way to<br />
copy a particular type of structure.<br />
The :copier option has the syntax:<br />
( : cop i e r (descriptioll nomc)<br />
body)<br />
Similar to the :predicate option. dcscription is hound to the instance of the defstructdescription<br />
structure maint~iined for this structure, name is bound to the symbol to be dcfined~<br />
and bod)' is some code to e\'<strong>al</strong>u~lte to g<strong>et</strong> the defining fonn. For example:<br />
(:copier (description name).<br />
t(defmacro ,name (x)<br />
t(copy-frobboz .x)})<br />
16.6.3.10 :implemcntations<br />
The :implementations option to defstruct-define-type is primarily useful to the mainuliners<br />
of defstruct in keeping control of the variations in defstruct types available in different<br />
implementations. Its syntax is:<br />
( : imp 1 ementati ons arg-I .•. arg-n)<br />
'<br />
This makes the defstruct-define-type in which it appears only take effect in<br />
implementations of LISP in which (status feature arg-i) is true for at least one of the arg-i.<br />
those<br />
~1C:<strong>NIL</strong>MAN:DFFSTR 91<br />
23-DEC-83
The) .OOP Iteration Macro 144 Nil. Manu<strong>al</strong><br />
17. The LOOP Iteration Macro<br />
17. t Introduction<br />
loop is a I.JSP macro which provides a programmable iteration facility. The same loop<br />
module operates compatibly in LISP MACHJNE lJSP. MACUSP(PDP-lO and MCLTICS). and <strong>NIL</strong>. and<br />
a moderately compatible package was developed for the MDL programming environment. loop<br />
was inspired by the "FOR" facility of CLISP in INTFRL1~I); however. it is not compatible and<br />
differs in sever<strong>al</strong> deLli1s.<br />
The gener<strong>al</strong> approach is that a form introduced by the word loop generates a single program<br />
J{)OP~ into which a large vari<strong>et</strong>y of features can be incorporated. The loop consists of some<br />
initi,ltiltltion (pr%gue) code. a body which may be executed se\'cr<strong>al</strong> times. and some exit<br />
(epih,gue) code. Variables m~IY be dcchlred lnc<strong>al</strong> to tJle loop. The features arc concerned with<br />
loop variables .. deciding when to end tJle itemtion. putting user-written cude into the loop.<br />
r<strong>et</strong>urning a v<strong>et</strong>lue from the construct. and iterating a variable through various re<strong>al</strong> or virtu<strong>al</strong> s<strong>et</strong>s<br />
of v<strong>al</strong>ues.<br />
The loop fonn consists of a series of chmses. each introduced by a keyword symbol. Forms<br />
appearing in or implied by the clauses of a loop form are classed as those to be executed as<br />
initi<strong>al</strong>ization code, body code. ,Uld/or exit code: within each part of the tcmplate that loop fins<br />
in. they arc executed strictly in the order implied by the origin<strong>al</strong> composition. Thus. just as in<br />
ordinarY l.isp code. side·effects may be used. and nne piece of cnde may depend on fhllowing<br />
another filr its proper operation. This is tJ1C princip<strong>al</strong> phiJosophy difference from I~TFRLlSP'S<br />
"FOR" facility,<br />
Note that loop forms are intended to look like stylized English rather than LISP code. There<br />
is a not41bly low density of parentheses. and many of the keywords are accepted in sever<strong>al</strong><br />
synonymous fonns to <strong>al</strong>low writing of more euphonious and grammatic<strong>al</strong> English. Some find this<br />
notation verbose and distasteful, while others find it flexible and convenient. The fonner are<br />
invited to stick to do.<br />
Here are some examples to illustrate the use of loop.<br />
(defun print-elements-of-list (list-of-elements)<br />
{loop for element in list-of-elements<br />
do (print element)}}<br />
nil.<br />
The above function prints each' element in its argument. which should be· a list It r<strong>et</strong>urns<br />
MC:<strong>NIL</strong>MAN;1.00J Y rM 319<br />
23-DEC-83<br />
> ••<br />
:'. .. '-. .• ". ~>. .... .. ..::-fL~,~.L~.~:i,~:.~·,~?,~,j;~.~-4·~~-s~~r·;~ ~.}i;.,;~ .......... '.
"-4 *<br />
. f t -. . ."). "'E o - ,oW1 t < ... "*('ib*~ d . ., if' " "'ffff'. 'en-'"Q"Y' .... W· 'S " -"f' $' *7 . t' 2<br />
'm<br />
<strong>NIL</strong> Manu<strong>al</strong> 145<br />
Clauses<br />
(defun gather-a1ist-entries (list-of-pairs)<br />
(loop for pair in 1ist-of-pairs<br />
collect (car pair»).<br />
gather-<strong>al</strong>ist-entries takes an association list and r<strong>et</strong>urns a list of the "keys":<br />
(gather-<strong>al</strong>ist-entries '«faa 1 2) (bar 259) (baz») r<strong>et</strong>urns (faa bar baz).<br />
that is,<br />
(defun extract-interesting-numbers (start-v<strong>al</strong>ue end-v<strong>al</strong>ue)<br />
(loop for number from start-v<strong>al</strong>ue to end-v<strong>al</strong>ue<br />
when (interesting-p number) collect number»<br />
The ahove function takes two arguments. which should be fixnums. and r<strong>et</strong>urns a list of <strong>al</strong>l<br />
the numhers in that range (inclusive) which satisfy the predicate interesting-po<br />
,(defun find-maximum-e1ement (an-array)<br />
(loop fori from 0 below (array-dimension an-array 0)<br />
maximize (aref an-array i»)<br />
find-maximum-element r<strong>et</strong>urns the maximum of the clements of its argument. a onedimension<strong>al</strong><br />
array.<br />
(defun my-remove (object list)<br />
(loop for element in list<br />
unless (equ<strong>al</strong> object element)<br />
my-remove is like tJle COM~10N LISP function remove. utilizing the equ<strong>al</strong> predicate. (This is .<br />
like MACLISP del<strong>et</strong>e, but copies the list rather than destnlctively splicing out clements.)<br />
(defun find-frob (list)<br />
(loop for element in list<br />
when (frobp element) r<strong>et</strong>urn element<br />
fin<strong>al</strong>ly (ferror nil "No frob was found in the list -S"<br />
list»)<br />
This r<strong>et</strong>urns the first element of its list argument which satisfies the predicate frobp. If none<br />
is found, an error is generated.<br />
17.2 Clauses<br />
Intern<strong>al</strong>ly, loop constructs a prog which includes variable bindings, pre-jteration (initi<strong>al</strong>ization)<br />
code. post-iteration (exit) code, the body of the iteration. and stepping of \'ariables of iteration to<br />
. their next v<strong>al</strong>ues (which happens on every iteration after executing the body).<br />
A clause consists of the keyword symbol and any Lisp fonns and keywords which it de<strong>al</strong>s<br />
with. For example.<br />
(loop for x in 1 do (print x».<br />
contains two clauses. "for x in (car foo) It and "do (pr i nt x) ". Certain of the parte; of the<br />
clause will be described as being expressions. e.g~ (car faa) in the above. An' expression is a<br />
MC:<strong>NIL</strong>MAN:I.OOPTM 319<br />
23-DEC-83
Clauses 146 NIl. Manu<strong>al</strong><br />
single LISP form. Obviously. it must be followed immediately hy either the end of the loop fonn.<br />
or by a loop keyword. Certain clauses take what is c<strong>al</strong>led a lIIulliple expression: this may be a<br />
single LISP form. or a series of ronns implicitly co11ectcd with progn. A multiple expression is<br />
terminated by the next following atom. which is taken to be a keyword. As a gener<strong>al</strong> rule. loop<br />
clauses which utilize LISP forms de<strong>al</strong> only with single expressions. with the exception of those for<br />
which the fonns are ev<strong>al</strong>uated for effect: specific<strong>al</strong>ly. only the do, initiatty. and fin<strong>al</strong>ly Clauses<br />
<strong>al</strong>low multiple expressions.<br />
This syntax differs slightly from earHer versions of loop (which arc prohably 5tiH in use in<br />
I.lSP implementations other than J';JI). in which <strong>al</strong>l expressions were treated as multiple<br />
expressions. The reason for the change is twof(>ld: first. it common syntactic error in using loop<br />
is to accidenta)J} omit the do keyword (causing the expressions meant to be executed for effcct to<br />
h~come part of the preceding clause). Second. it is anticipated th41t loop will suppon ,Ill Itimplied<br />
do" som<strong>et</strong>ime in the future. making this omission in fact synt
<strong>NIL</strong> Manu<strong>al</strong> 147 Clauses<br />
(loop ... for y = illil then (9 x) for x = (f) ... )<br />
because. as a gener<strong>al</strong> rule. par<strong>al</strong>lel stepping has more overhead than sequenti<strong>al</strong> stepping.<br />
Similarly. the example<br />
(loop for sublist on some-list<br />
and for previcius = 'undefined then sublist<br />
· .. )<br />
which is equiv<strong>al</strong>ent to the do construct<br />
(do «sublist some-list (cdr sublist»<br />
(previous 'undefined sU9list»<br />
«null sublist) ... )<br />
... )<br />
in terms of stepping. would he h<strong>et</strong>ter written as<br />
(loop for previous = 'undefined then sub1ist<br />
for sublist on some-list<br />
· .. )<br />
When iteration driving clauses are joined· with and. if the Loken following the and is not a<br />
keyword which introduces an iterau.m driving clause. it is assumed to be the same as the keyword<br />
which introduced the most recent clause; thus. the above example showing par<strong>al</strong>lel stepping could<br />
have been written as<br />
(loop for sublist on some-list<br />
and previous = 'undefined then sublist<br />
uCl:au~c<br />
· .. )<br />
I..iac keyword ior is impiicd aftcr the and.<br />
The order of ev<strong>al</strong>uation in iteration-driving clauses is that those expressions which are only<br />
ev<strong>al</strong>uated once are ev<strong>al</strong>uated in order at the beginning of the form. during the variablc-binding<br />
phase. while those expressions which are ev<strong>al</strong>uated each time around the loop are ev<strong>al</strong>uated in<br />
order in the body.<br />
One common and simple iteration driving clause is repeat:<br />
repeat expression<br />
This ev<strong>al</strong>uates expression (during the variable binding phase), and causes the loop to<br />
iterate that many times. expression is expected to ev<strong>al</strong>uate to a fixnum. If expression<br />
ev<strong>al</strong>uates to a zero or negative result. the body code will not be executed.<br />
All remaining iteration driving clauses are subdispatches of the keyword for, which is<br />
synonomous with as. In <strong>al</strong>l of them a variable of iteration is specified. Note that, in gener<strong>al</strong>, if<br />
an iteration driving clause imp1icitly supplies an cndtest, the v<strong>al</strong>ue of this iteration variable as the<br />
loop is exited (i.e., when the epilogue code is run) is undefined. (This is discussed in more d<strong>et</strong>ail<br />
in section 17.6.)<br />
Here are <strong>al</strong>l of the vari<strong>et</strong>ies of for clauses. Option<strong>al</strong> parts are enclosed in curly brack<strong>et</strong>s. The<br />
d<strong>al</strong>a-I),prs as lIsed hcre are discussed fully in section 17.4.<br />
for \'ar {data-I)'pr} in exprl {by expr2}<br />
This iterates over each of the clements in the list exprl. If the by subclause is<br />
present, expr2 is e\'<strong>al</strong>uatcd once on entry to the loop to supply the function to be<br />
used to f<strong>et</strong>ch successive sublists. instead of cdr.<br />
MC:<strong>NIL</strong>MAN;1.00PTM 319<br />
23-DEC-83
Clauses . 148 <strong>NIL</strong> Manu<strong>al</strong><br />
for \'ar {d<strong>al</strong>a-/J'f>f'} on eXl'rl {by ('xpr2}<br />
This is like the previous for format. except that voris s<strong>et</strong> to successive sublislc; of the<br />
list instead of successive clements. Note that since var will <strong>al</strong>ways be a IisL it is' not<br />
meaningful to specify a d<strong>al</strong>a-t)'pe unless var is a deslruclurillg p<strong>al</strong>ferll, as described in<br />
the section on deslruc/uring. page 158. Note a1so that loop uses a null rather than an<br />
atom test to implement both this and the preceding clause.<br />
for var {d<strong>al</strong>a-type} = expr<br />
On each iteration. expr is ev<strong>al</strong>uated and var is s<strong>et</strong> to the result.<br />
for var {data-Iype} = exprl then expr2<br />
l'(}r is hound to e.rpr/ when the loop is entered. imd s<strong>et</strong> to ('xl'r2 (rc-e\',lluated) at <strong>al</strong>l<br />
hut the first iteration. Since exprl is e\'.tIU<strong>al</strong>ed during the binding phase. it c~mnot<br />
referenccolher iteration variables s<strong>et</strong> before il~ fur that. usc the fullowing:<br />
for \'ar {dtlld-IYfJl'} first ex!'r! then expr2<br />
This' s<strong>et</strong>s \'ar to ex})rl on the first iteration. and to ex!'r] (re"ev<strong>al</strong>uated) on each<br />
succeeding iteration. The ev<strong>al</strong>uation of both expressions is . perfonned inside of the<br />
loop binding environment. befl)re the loo'p body. This <strong>al</strong>lows the first v<strong>al</strong>ue of rar to<br />
come from the first \';tlue of some other iteration \'ariah1c. <strong>al</strong>lowing such constructs as<br />
(loop for term in poly<br />
for ans first (car term)<br />
then (gcd ans (car term»<br />
fin<strong>al</strong>ly (r<strong>et</strong>urn ans»<br />
for r,;r (41&1:.; iypt) fiOin [xprl {to cxpr2} {by r..i.jlrJ)<br />
This perfonns numeric iteration. var is initj<strong>al</strong>ized to exp,l. and un each succeeding<br />
iteration is incremented by expr3 (default 1). If the to phrase is given. the iteration'<br />
tenninates whenvar becomes greater than expr2. Each of the expressions is eva1uated<br />
only oncc. and the to and by phrases may be written in either order. downto may<br />
be used instead of to. in which case var is decremented by the step v<strong>al</strong>ue, and the<br />
endtest is adjusted accordingly. If below is used instead of to. or above instead of<br />
downto, the iteration will be tenninatcd before expr2 is reached, rather than after.<br />
Note that the to variant appropriate for the direction of stepping must be used for the<br />
endtesr to be fonned corrcctly; i.e. tbec04c will not work if expr3 is negative or<br />
zero. If no limit-specifying clause is gi\'cn~then the direction of the stepping may be<br />
specified as being decreasing by using downfrom instead of from. upfrom may <strong>al</strong>so<br />
be used instead of from; it forces· the stepping direction to be increasing. The datatype<br />
defaults to fixnum. Thus. the idiom for stcpping through a typic<strong>al</strong> COMMON USP<br />
stan/end range in which the stan is inclusive and the end is exclusive, is<br />
for var from SlaTt below end<br />
for var {dat~type} being exprand its path ...<br />
for var {da/a-type} being {eachlthe} path ...<br />
This provides a user-definable iteration fhcility. path names the manner in which the<br />
iteration is to be pcrfonned. The ellipsis indicates where various path dependent<br />
preposition/expression pairs may appear. See the section on Iteration Paths (page 161)<br />
for compl<strong>et</strong>e documentation~<br />
MC:NII.MAN:LOOPTM 319<br />
23-DEC-83
¢; r .•<br />
COf . 1*& t - un ,'hrag-- trw $ - .? Wf n' -. Xt - Sfb'(¥#t&trlttiif
Clauses 150 <strong>NIL</strong> Manwtl<br />
For binding more than one variable with no panicular initi<strong>al</strong>ization. one may usc the<br />
construct<br />
with variable-list {d<strong>al</strong>a-type-list} {and ...}<br />
as in<br />
with (i j k tt t2) (fixnum fixnum fixnurn)<br />
A slightly shorter way of writing this is<br />
with (1 j k) fixnum and (tl t2) ...<br />
These arc cases of deslru!'turillg which loop handles speci<strong>al</strong>1y; destructuring and data type<br />
keywords are discussed in· sections 17.5 and 17.4.<br />
Occasion<strong>al</strong>ly there are various implementationa] reasuns for a \'ariable 1101 to be given a loc<strong>al</strong><br />
type declar4ltioll. I f this is necessclry. the nodeclare clause may be used:<br />
nodecfare rariubie-lisl<br />
"111e variables in variable-iisl are noted by loop as not requiring loc<strong>al</strong> type declarations~<br />
Consider the following: .<br />
(declare (speci<strong>al</strong> k) (fixnum k»<br />
(defun foo (1)<br />
(loop for x in 1 as k fixnum = (f x) ... »<br />
J f k did not have the 1ixnum data-type keyword given for it. then loop would bind it<br />
to nil. and some compilers would complain. On the other hand. the fixnum keyword<br />
<strong>al</strong>so produces a loc<strong>al</strong> fixnum declaration filr k: since k is speci<strong>al</strong>. some compilers will<br />
complain (or error out). The solution is to do:<br />
(defun foo (l)<br />
(loop nodeclare (k)<br />
for x in 1 as k fixnum = (f x) ... »<br />
which tells loop not to make that loc<strong>al</strong> declaration. The nodeclare clause must come<br />
before any reference to the variables so noted. Positioning it incorrectly will cause this<br />
clause 10 not take effect. and may not be diagnosed. It happens that this clause was<br />
introduced due to some peculiar behavior of the MULTICS MACLISP compiler, and<br />
should not be needed in other implementations.<br />
17.2.3 Entrance and Exit<br />
initi<strong>al</strong>ly multiple-expression<br />
This puts 11lUllipie-expression into the prologue of the iteration. It will be ev<strong>al</strong>uated<br />
before any other initi<strong>al</strong>ization code other than the initi<strong>al</strong> bindings. For the sake of<br />
good style, the initi<strong>al</strong>ly dause should therefore be placed after any with clauses· but<br />
before the main body of the loop. initi<strong>al</strong>ly is one of the few loop clauses which are<br />
<strong>al</strong>lowed to be followed by multiple expressions; these expressions will be treated as an<br />
implicit progn.<br />
finaUy multiple-expression<br />
Ibis puts multiple-expression into the epilogue of the loop, which is ev<strong>al</strong>uated when<br />
the iteration terminates (other than by an explicit r<strong>et</strong>urn). For stylistic reasons. then,<br />
this clause should appear last in the loop body. Note that cenain clauses may<br />
generate code which tenninatcs the iteration without nmning the epilogue code; this<br />
behavior is noted with those clauses. Most nowble of these are those described in the<br />
section 17.2.7. Aggregated Boolean Tests. This clause may be used to cause the loop<br />
MC:<strong>NIL</strong>MAN:1.00PTM 319<br />
23-DEC-83
JJ.''-''ilitllll·'·''I· .'·<br />
t<br />
.. Il··T.t.r·.·<br />
.n.rr.t<br />
t<br />
...,.
Clauses 152 Nil. Manu<strong>al</strong><br />
cortecting ...<br />
This causes the v<strong>al</strong>ues of expr un each iteration to be collected into a list.<br />
nconc expr {into var}<br />
nconcing ...<br />
append ...<br />
appending ...<br />
These are likecoltect. but the results are spliced tog<strong>et</strong>her.<br />
(loop for i from 1 to 3<br />
nconc(list i (. i i»)<br />
=> (1 1 2 4 3 9)<br />
The diflercnce is that. for nconc. the v<strong>al</strong>ue of ('xpris not copied oefore heing<br />
spliced. not that the entire list being accumulated is repeatedly cop ted during the<br />
iteration. This is significant in that one m,lyg<strong>et</strong> ahold of the intennediate result while<br />
the iteration is in progress by use of into, and lit<strong>al</strong> list does g<strong>et</strong> destructire!y modified.<br />
count expr {into "or} {data-type}<br />
counting ...<br />
If expr ev<strong>al</strong>uates non-nit a counter is incremented. The data-t)'p(' defaults to fixnum.<br />
sum (').pr {d<strong>al</strong>a-type} {into lIar)<br />
summing ...<br />
Ev<strong>al</strong>uates expr on each iteration. and accumulates the sum of aU the v<strong>al</strong>ues. dnla-t),pe<br />
defaults to number. which for <strong>al</strong>l practic<strong>al</strong> purposes is notype. Note that specifying<br />
d<strong>al</strong>a-l),pe implies that both the sum and the number being summed (the v<strong>al</strong>ue of<br />
expr) will be of thattypc.<br />
maximize expr {d<strong>al</strong>a-t)pe} {into var)<br />
minimize ...<br />
Computes the maximum (or minimum) of expr over <strong>al</strong>l iterations. data-type defaults<br />
to number. Note that if the loop iterates zero times, or if condition<strong>al</strong>ization prevents<br />
the code of this clause from being executed, the result will be meaningless. loop may<br />
choose to code the max or min operation itself by just using arithm<strong>et</strong>ic comparison<br />
rather than c<strong>al</strong>ling max or min, if it deems this to be reasonable based on the<br />
particular LISP implementation and the declared type of the accumulation. As with the<br />
sum clause, specifying data-type implies that both the result of the max or min<br />
operation and the v<strong>al</strong>ue being maximized or minimized will be of that type.<br />
Not only may there be multiple accumulations in a loop, but a single accumulation may come<br />
from multiple places within the same loop Jonn. Obviously, the types of the collection must be<br />
compatible. collect. nconc, and append may <strong>al</strong>l be mixed. as may sum and count, and<br />
maximize and minimize. For example,<br />
(loop for x in '(a b c) for y in '«(1 2) (3 4) (5 6»<br />
collect x<br />
append y)<br />
=> (a 1 2 b 3 4 c 5 6)<br />
MC:<strong>NIL</strong>MAN:I.OOPTM 319
<strong>NIL</strong> Manu<strong>al</strong> 153<br />
Clauses<br />
'Inc following computes the average of the entries in the list list-offrobs:<br />
(loop for x in list-of-frobs<br />
count t into count-var<br />
sum x into sum-var<br />
fin<strong>al</strong>ly (r<strong>et</strong>urn (quotient sum-var count-var»)<br />
17.2.6 Endtests<br />
The following clauses may be used to provide addition<strong>al</strong> control over when the iteration g<strong>et</strong>s<br />
lennin<strong>al</strong>ed. possihly causing exit code (due to fin<strong>al</strong>ly) to be perfonned and possihly r<strong>et</strong>urning a<br />
v<strong>al</strong>ue (e.g.. from collect).<br />
while expr<br />
If expr ev<strong>al</strong>uates to nil. the loop is exited. performing exit code (if any). and<br />
r<strong>et</strong>urning any accumulated v<strong>al</strong>ue. The test is placed in the body of the loop where it<br />
is written. It may appear b<strong>et</strong>ween sequenti<strong>al</strong> for clauses.<br />
until expr<br />
Identic<strong>al</strong> to while (not e:rpr).<br />
This may be needed. for example. to step through a strange data structure, as in<br />
(loop for concept = expr then (superior-concept concept)<br />
until (top-of-concept-tree? concept)<br />
... )<br />
lne following may <strong>al</strong>so be of usc in terminating the iteration:<br />
loop-finish<br />
(loop-finish) causes the iteration to terminate "norm<strong>al</strong>ly", the same as implicit tcnnination<br />
by an iteration driving clause, or by the use of while or until-the epilogue code (if any)<br />
will be run. and any implicitly collected result will be r<strong>et</strong>urned as the v<strong>al</strong>ue of the loop.<br />
For example.<br />
(loop for x in '(1 2 3 4 5 6)<br />
collect x<br />
do (cond «= x 4) (loop-finish»»<br />
=> (1 2 3 4)<br />
This particular example would be b<strong>et</strong>ter written as until (= x 4) in place of the do<br />
clause. Also. the readability of loop constructs suffers from the inclusion of a nonkeyword<br />
construct which affects the behavior of the iteration because the reader of the<br />
code may not be expecting it hidden away in the code. (Stylistic<strong>al</strong>ly it might be<br />
compared with the use of go.)<br />
MC:NI1.MAN:LOOPTM 319<br />
23-I)EC-83
Cl.IUSCS 154 Nil. Manu<strong>al</strong><br />
17.2.7 Aggregated Boolean Tests<br />
All of these clauses pcrfonn some test.<br />
depending on the result of that test.<br />
and may immediately tcnninatc the iteration<br />
aJways expr<br />
Causes the loop to r<strong>et</strong>urn t if expr <strong>al</strong>ways ev<strong>al</strong>uates non-null. If expr ev<strong>al</strong>uates to nil.<br />
the loop immediately r<strong>et</strong>urns nil. without running the epilogue cod,c (if any. as<br />
specified with the fin<strong>al</strong>ly clause): otherwise, t will bc r<strong>et</strong>urned when the loop finishes.<br />
after the epilogue code has been run.<br />
never {'xpr<br />
Causes the loop to r<strong>et</strong>urn t if l'xpr never e"<strong>al</strong>u.ltes non-null. This is equiv<strong>al</strong>ent to<br />
<strong>al</strong>ways (not ('xpr).<br />
thereis expr<br />
If rxpr cv<strong>al</strong>uates non-nil. then thc iteration is tenninatcd and that v<strong>al</strong>ue is r<strong>et</strong>urned.<br />
without running the epiloguc code.<br />
17.2.8 ('ondition<strong>al</strong>ization<br />
These clauses may be used to tfcondition<strong>al</strong>ize" the following clause. They may precede any of<br />
the side-effecting or v<strong>al</strong>ue-producing clauses. such as do. collect. <strong>al</strong>ways, Of r<strong>et</strong>urn.<br />
when expr<br />
if expr<br />
If expr ev<strong>al</strong>uates to nil. the following clause will be skipped. otherwise not.<br />
unless expr<br />
This is equiv<strong>al</strong>ent to when (not expr».<br />
1\.1ultiplc condition<strong>al</strong>ization c1auscs may appear in sequence. If one test fails, then any<br />
following tests in the immediate sequence, and the clause being condition<strong>al</strong>ized, arc skipped. For<br />
instance,<br />
(loop for x ...<br />
when (f x)<br />
unless (g x)<br />
do ••• )<br />
is like<br />
(loop for x •.•<br />
when (and (f x) (not (g x»)<br />
do ••• )<br />
Multiple clauses may be condition<strong>al</strong>ilcd under the same test by joining them with and, as in<br />
(loop fori from a to b<br />
when (zerop (remainder; 3»<br />
collect i and do (pr;nt i»<br />
which r<strong>et</strong>urns a list of <strong>al</strong>l mUltiples of 3 from a to b (inclusive) and prints them as they are<br />
being collected.<br />
~1C:NII.M!\N:1.00PTM 319<br />
23-DEC-83
t<br />
, I<br />
I<br />
I<br />
!<br />
I<br />
<strong>NIL</strong> Manu<strong>al</strong> 155<br />
Clauses<br />
If-then-else condition<strong>al</strong>s may be written using the else keyword. as in<br />
(loop for i from a to b<br />
when (oddp i)<br />
collect i into odd-numbers<br />
else collect i into even-numbers)<br />
Multiple clauses may appear in an else-phrase. using and to join them in the same way as above.<br />
There is a bug ill the handling of multiple else clauses. Beware.<br />
Condition<strong>al</strong>s may be nested. For example.<br />
(loop fori from a to b<br />
when (zerop (remainder i 3})<br />
do (print i)<br />
and when (zerop (remainder i 2»<br />
collect i)<br />
r<strong>et</strong>urns a list of <strong>al</strong>l multiples of 6 from a to b. and prints <strong>al</strong>l multiples of 3 from a to b.<br />
When else is llsed with nested condithm<strong>al</strong>s. the "dangling else" ambiguity is resolved by<br />
matching the else with the innennost when not <strong>al</strong>ready matched with an else. Here is a<br />
complicated example.<br />
(loop for x in 1<br />
when (atom x)<br />
when (memq x *distingu;shed-symbols*)<br />
do (processl x)<br />
~lse do (proc~ssZ x)<br />
elsa when (memq (car x) *speci<strong>al</strong>-prefixes*)<br />
collect (process3 (car x) (cdr x»<br />
and do (memoize x)<br />
else do (process4 x})<br />
Useful with the condition<strong>al</strong>ization clauses is the r<strong>et</strong>urn clause. which causes an explicit r<strong>et</strong>urn<br />
of its "argument" as the v<strong>al</strong>ue of the iteration, bypassing any epilogue code. That is,<br />
when exprl r<strong>et</strong>urn expr2<br />
is equiv<strong>al</strong>ent to<br />
when exprl do (r<strong>et</strong>urn expr2)<br />
if the loop is not "named" (by use of the named clause), and to<br />
when exprl do (r<strong>et</strong>urn -from name expr2)<br />
jf the loop is named name. In other words, r<strong>et</strong>urn arranges to <strong>al</strong>ways r<strong>et</strong>urn from the loop it is<br />
a part of.<br />
Condition<strong>al</strong>ization of one of the "aggregated boolean v<strong>al</strong>ue" clauses simply causes the test<br />
which would cause the iteration to tenninate early not to be performed unless the condition<br />
succeeds. For example.<br />
(loop for x in 1<br />
when (significant-p x)<br />
do (print x) (princ "is significant.")<br />
and thereis (ext~a-speci<strong>al</strong>-significant-p x»<br />
does not make the extra-speci<strong>al</strong>-significant-p check unless the significant-p check succeeds.<br />
MC:<strong>NIL</strong>MAN:1.00PTM 319<br />
23-DEC-83
Clauses 156 NIl. Manu<strong>al</strong><br />
The fonn<strong>al</strong> of a conditionaJized clause is typic<strong>al</strong>ly som<strong>et</strong>hing like<br />
when ('xprl k('yword exprl<br />
Ifexpr2 is the keyword it~ then a variable is generated to hold the v<strong>al</strong>ue of exprl. and that<br />
variable g<strong>et</strong>s substituted for exprl. Thus, the composition<br />
when exprr<strong>et</strong>urn it<br />
is equiv<strong>al</strong>ent to the c1ause<br />
thereis expr<br />
and one may coBect <strong>al</strong>l non-nuH v<strong>al</strong>ues in an iteration by saying<br />
when (':rpr('ssioll collect it<br />
If multiple clauses arc joined with and. the it keyword m,l), only be lIsed in the first. If multiple<br />
whens. unless('s. and/or ifs occur in sequence. the \'<strong>al</strong>ue suhstituled for it will he thilt of the last<br />
tl'Sl perf(mncd. The it keyword is not rccogni/ed in an else-phmsc.<br />
17.2.9 l\1isceUaneous Other ('Iauses<br />
named n<strong>al</strong>11(,<br />
This gives the block (prog) which loop generates a name of name, so that one may<br />
usc the r<strong>et</strong>urn-from fonn lo r<strong>et</strong>urn explicitly out of th<strong>al</strong> particular loop:<br />
(loop named sue<br />
do (loop ... do (r<strong>et</strong>urn-from sue v<strong>al</strong>ue) 0 00 )<br />
... )<br />
1'h(' r<strong>et</strong>urn -from fnnn ~h(n."n C~!.!$CS va!::[' to b~ !mmcdiat~!y rcturn~d a5 :..~c v<strong>al</strong>ue of<br />
the otHer loop. Only one name may be given to any particular loop constmct. This<br />
feature docs not exist in the MACLlSI' version of loop. since MACUSP docs nol suppon<br />
"named progs" or COMMOl" LISP ,blocks.<br />
r<strong>et</strong>urn expression<br />
Immediately r<strong>et</strong>urns the v<strong>al</strong>ue of expression as the v<strong>al</strong>ue of the loop~ without running<br />
the epilogue code. This is most useful with. some son of conditionaJization. as<br />
discussed in the previous section. Unlike most of the other clauses, r<strong>et</strong>urn is not<br />
considered to "generate body code'\ so it is <strong>al</strong>lowed to occur b<strong>et</strong>ween iteration<br />
clauses. as in<br />
(loop for entry in list<br />
when (not (numberp entry»<br />
r<strong>et</strong>urn (errol" ..• )<br />
as frob = (times entry 2)<br />
... )<br />
If one instead desires the loop to have some r<strong>et</strong>urn v<strong>al</strong>ue when it finishes nonn<strong>al</strong>ly t<br />
one may place a ca11 to r<strong>et</strong>um or r<strong>et</strong>urn-from (as appropriate) in the epilogue (with<br />
the fin<strong>al</strong>ly clause. page 150). r<strong>et</strong>urn <strong>al</strong>ways r<strong>et</strong>urns from the loop it is a pan of; that<br />
is, it turns into a c<strong>al</strong>l to r<strong>et</strong>urn if the loop is not "named", r<strong>et</strong>urn-from if it is.<br />
MC:NII.MAN:LOOPTM 319<br />
23-DEC-83
--<br />
N ll. Manu<strong>al</strong> 157 I.oop Synonyms<br />
17.3 Loop Synonyms<br />
define-loop-macro keyword<br />
May be used to make keyword. a loop keyword (such as for). into a Lisp macro which<br />
may introduce a loop form. For example. after ev<strong>al</strong>uating<br />
(define-loop-macro for),<br />
one may now write an iteration as<br />
(for; from 1 below n do ... )<br />
This facility exists primarily for diehard users of a predecessor of loop. Its unconstrained usc<br />
is not recommended. as it tends to dCl'rease the transportahility of the code and needlessly uses<br />
up ~I function n
Dcstructuring 158 Nil. MJnu<strong>al</strong><br />
number<br />
notype<br />
Any number.<br />
Unspecified type (i.e.. anything else). This name is inherited from MACLISP.<br />
Note that explicit specification of a non-numcric type for an operation which is numeric (such<br />
as the summing clause) may cause a variable to be initi<strong>al</strong>izcd to nil when it should be O.<br />
If loc<strong>al</strong> data-type declarations must be inhibited. one can usc the nodecfare clause. which is<br />
described on page 150.<br />
17.5 Dcstructuring<br />
IJrstrucluring provides one with the ability tu "simultaneollsly" assign or bind multiple<br />
v(lriablcs to components of some data structure. Typic<strong>al</strong>ly this is used with list stnJcture. For<br />
example,<br />
h~ls<br />
(loop with 1foo . bar) = 'ea b c) .. 0)<br />
the effect of binding foo to a and bar to (b c).<br />
loop's destructuring support is intendcd to par<strong>al</strong>lel if not augment that provided by the hust<br />
LISP implementation. with a go<strong>al</strong> of minim<strong>al</strong>ly providing destructuring over Jist structure patterns.<br />
Thus, in I -isp implementations with no system dcstructuring support at <strong>al</strong>l. one may still usc liststructure<br />
patterns as loop iteration variables, and in with bindings. In <strong>NIL</strong>, loop <strong>al</strong>so supports<br />
dcstrucIUring over vectors (they should be gener<strong>al</strong> vecto~ Le .. have element-typ<strong>et</strong>).<br />
One may specify the data types of the components of a pattern by using a corresponding<br />
pattern of the data type keywords in place of a single data type keyword. This syntax remains'<br />
unambiguous because whcrever a data type keyword is possible. a loop keyword is the only other<br />
possibility. Thus. if one wants to do<br />
(loop for x in 1<br />
as i fixnum = (car x)<br />
and j fixnum = (cadr x)<br />
and Ie fixnum = (cddr x)<br />
•• 0 )<br />
and no reference to x is needed, one may instead write<br />
(loop for (i j . Ie) (fixnum fixnum . fixnum) ;n 1 ••• )<br />
To <strong>al</strong>low some abbreviation of the data. type pattern, an atomic component of the data type<br />
pattern is considered to state that <strong>al</strong>l components of the corresponding part of the variable pattern<br />
are of that type. That is, the previous form could be written as<br />
( 1 00 p for (i j . Ie) fix n urn i n 1 • 0 • )<br />
This gener<strong>al</strong>ity <strong>al</strong>lows binding of multiple typed variables in a reasonably concise manner, as in<br />
(loop with {a b c) and (i j k) fixnum .. 0)<br />
which binds a. b, and c to nil and i. j. and k to 0 for use as temporaries during the iteration.<br />
and declares i .. j, and k to be fixnums for the benefit of the compiler.<br />
MC:NII.MAN~LOOPTM 319<br />
23·DEC·83
NIl. Manu<strong>al</strong> 159<br />
The Iteration Framework<br />
(defun print-with-commas (list)<br />
(loop for (item. more?) on list<br />
do (princ item)<br />
when more? do (prine ". H»~)<br />
wi1l generate the output<br />
Foo, Bar. Baz<br />
when c<strong>al</strong>led on the list ("Faa" "Bar" ttBaz").<br />
In I.lSP implementations where loop perfonns its own destrucluring. notably MUITlCS MACUS}><br />
and IISP ~1ACIII'I: liSP. one can cause loop to liSt' <strong>al</strong>ready prodded destrllcturing support<br />
instead:<br />
51: loop-u5e-5ystem-de5tru<strong>et</strong>ur1ng? Variable<br />
This variable only exists in loop implementations in LISPS which do not provide<br />
destruclllring support in the default environment. It is by default nil. If changed, then<br />
loop wi'l behave as it docs in I.lSPS which do provide dcstructuring support: destructuring<br />
binding will be pcrfi)rmed llsing l<strong>et</strong>. and destructuring assignment will be perfonned llsing<br />
des<strong>et</strong>q. Presumably if one's person<strong>al</strong>ized environment supplies these macros, then one<br />
should s<strong>et</strong> this variable to t~ there is, however, little (if any) efficiency loss if this is not<br />
done.<br />
17.6 The It£lr:ltion Framework<br />
This section describes the way loop constructs iterations. It is necessary if you will be writing<br />
your own iteration paths, and may be useful in clarifying what loop docs with its input<br />
loop considers Ille act of stepping to have four possible parts. Each iteration-driving clause<br />
has some or <strong>al</strong>l of these four parts, which are executed in this order:<br />
pre-step-endtest<br />
This is an endtest which d<strong>et</strong>ennines if it is safe to step to the next v<strong>al</strong>ue of the<br />
iteration variable.<br />
steps<br />
Variables which g<strong>et</strong> "stepped". This is intern<strong>al</strong>ly manipulated as a list of the fonn (varl<br />
v<strong>al</strong>l var2 v<strong>al</strong>2 ... ); <strong>al</strong>l of those variables arc stepped in paranel. meaning that <strong>al</strong>l of the<br />
v<strong>al</strong>s arc ev<strong>al</strong>uated before any of the vars are s<strong>et</strong><br />
post-step-endtest<br />
Som<strong>et</strong>imes you can't see if you are done until you step to the next v<strong>al</strong>ue; that is, the<br />
endtest is a function of the stepped-to v<strong>al</strong>ue.<br />
pseudo-steps<br />
Other things which need to be stepped. lbis is typic<strong>al</strong>ly used for intern<strong>al</strong> variables<br />
which arc more conveniently stepped here. or to s<strong>et</strong> up iteration variables which are<br />
functions of some intern<strong>al</strong> variablc(s) which arc actu<strong>al</strong>ly driving the iteration. This is a<br />
list like steps, but the variables in it do not g<strong>et</strong> stepped in par<strong>al</strong>lel.<br />
MC:<strong>NIL</strong>MAN:1.00PTM 319<br />
23-DEC-83
"I'he ltermion Framework . 160 <strong>NIL</strong> Manu<strong>al</strong><br />
The ahove <strong>al</strong>one is actuafly insufficient in just about <strong>al</strong>l iteration dri\ ing clauses which loop<br />
handles. What is missing is that in most cases the stepping and testing fhr the first time through<br />
the loop is different from that of aJJ other times. So. what loop de<strong>al</strong>s with is two four-tuples as<br />
above; one for the first iteration. and one fhr the rest. The first may be thought of as describing<br />
codc which immediately precedes the loop in the prog. and the second as following the body<br />
code-in fact. loop docs just. this. but severely perturbs it in order to reduce code duplication.<br />
Two lists of fonns arc constructed in par<strong>al</strong>lel: one is the first-iteration endtests and steps, the<br />
other the rcmaining,:,iterations endtests and steps. These lists have dummy entries in them so that<br />
identic<strong>al</strong> expressions will appe.lr in the scmle position in both. When loop is done parsing an of<br />
the clauses. these lists gel merged bark wg<strong>et</strong>her such that corresponding identic<strong>al</strong> expressions in<br />
hoth lists arc not duplicated unless they arc "simplc" and it is worth doing.<br />
Thus. one lIIay g<strong>et</strong> some duplicated code if one lias multiple iterations. Alternatiyely. loop<br />
may decide to usc and test a flag variable which indicates wh<strong>et</strong>her one iteration has been<br />
perfonned. In genera1. sequenti<strong>al</strong> itcrations have less (}\·crhcad th.m par<strong>al</strong>lel iterations. both from<br />
thc inhercnL overhead of stepping multiple variables in par<strong>al</strong>lel. and from thc s14mdpoint ·of<br />
potentia) code duplication.<br />
One other point which must be notcd ahout pclr<strong>al</strong>lc1 stepping is that <strong>al</strong>though thc user<br />
iteration variables arc guarantecd to be stepped in par<strong>al</strong>lcl. the placement of the endtcst for any<br />
particular iteration may bc either before Of after the stepping. A notable casc of this is<br />
(loop for i from 1 to 3 and dummy = (print 'fool<br />
collect i)<br />
_.... I.. '\ ., '\<br />
-, \.a. c. v J<br />
but prinl~ foo four times. Certain other constructs. such as for l'ar on. mayor may not do this<br />
depcnding on the particular construction.<br />
This prohlcm <strong>al</strong>so means that it may not be Stlfe to examine an iteration variable in the<br />
epilogue of the loop fonn. As a gener<strong>al</strong> rule, if an iteration driving clause implicitly supplies an<br />
endtest. then one cannot know the state of the iteration variable whcn the loop tcnninatcs.<br />
Although one can guess on the basis of wh<strong>et</strong>her the iteration variable itself holds the data upon<br />
which the endtest is based. that guess may be wrong. Thus.<br />
(loop for subl on expr<br />
fin<strong>al</strong>ly (f subl»<br />
IS Incorrect. but<br />
(loop as frob = expr whi le (g frob)<br />
fin<strong>al</strong>ly (f frob»<br />
is safe because the endtest is explicitly dissociated from the stepping.<br />
MC:NII.MAN:1.00PTM .U9<br />
23-DEC-83
.'t'fnc ; mtfrM rt'¥?9 an Tf N '" T" at' , 7thM ~'{ rt t inea@-'"<br />
;'@ rtr$v'xYtc ,""'.nV? cn -u<br />
<strong>NIL</strong> Manu<strong>al</strong> 161 Iteration Paths<br />
17.7 Iteration Paths<br />
Iteration paths provide a mechanism for user extension of iteration-driving clauses. The<br />
interface is constrained so that the definition of a path need not depend on much of the intern<strong>al</strong>s<br />
of loop. The typic<strong>al</strong> fonn of an iteration path is<br />
for var {data-type} being {eachlthe} p<strong>al</strong>hname {preposilionJ exprJ} ...<br />
pathname is an atomic symbol which is defined as a loop path function. The usage and<br />
defaulting of data-type is up to the path function. Any number of preposition/expression pairs<br />
may be present: the prepositions <strong>al</strong>lowable for any particular path are defined by that path. For<br />
example.<br />
(loop for x being the elements of some-sequence from 1 to 10<br />
· .. )<br />
To enhance readability. iteration path names are usu<strong>al</strong>ly defined in both the singular and plur<strong>al</strong><br />
fnnns: this particular example could h,lve been written as<br />
(loop for x being each element of some-sequence from 1 to 10<br />
· .. )<br />
Another fonnat. which is not so gener<strong>al</strong>ly applicable. is<br />
for l'ar{data-I),pc} being exprO and its path-name {prcposiliolll exprl} ...<br />
In this fonnat. var wkes on the v<strong>al</strong>ue of exprlJ the first time through the loop. Support for this<br />
fonnat is usu<strong>al</strong>ly limited to paths which step through some data structure. such as the "superiors"<br />
of som<strong>et</strong>hing. Thus, we can hypothesize the cdrs path, such that<br />
(loop for x being the cdrs of '(a b c . d) collect x)<br />
~; «b C . d) (c . d) d)<br />
but .<br />
(loop for x being '(a b c . d) and its cdrs collect x)<br />
=> «a be. d) (b c . d) (c . d) d}<br />
To satisfy the anthropomorphic among you, his. her. or their may be substituted for the its<br />
keyword. as may each. Egocentricity is not condoned. Some example uses of iteration paths arc<br />
shown in section 17.7.l.<br />
Very often. iteration paths step intern<strong>al</strong> variables which the user does not specify. such as an<br />
index into some data-structure. Although in most cases the user docs not wish to be concerned<br />
with such low-level matters, it is occasion<strong>al</strong>ly useful to have a handle on such things. loop<br />
provides an addition<strong>al</strong> syntax with which one may provide a variable name to be used as an<br />
"intern<strong>al</strong>" variable by an iteration path, with the using "preposition<strong>al</strong> phrase". The using phrase<br />
is placed with the other phrases associated with the path, and contains any number of<br />
keywordh ariable-name pairs:<br />
(loop for x being the elements of seq using (index i)<br />
· .. )<br />
which says that the variable i should be used to hold the index of the sequence being stepped<br />
through. The panicular keywords which may be used are defined by the iteration path; the index<br />
keyword is recognized by <strong>al</strong>l loop sequence paths (section 17.7.1.2). Note that any individu<strong>al</strong><br />
using phrase applies to only one path; it is parsed <strong>al</strong>ong with the "preposition<strong>al</strong> phrases". It is<br />
an error if the path docs not c<strong>al</strong>l for a variable using that keyword.<br />
By speci<strong>al</strong> dispensation, if a path-name is not recognized. then the default-loop-path path<br />
will be invoked upon a syntactic transfonnation of the origin<strong>al</strong> input. Essenti<strong>al</strong>ly. the loop<br />
fragment<br />
MC:NIl.MAN:I.OOPTM 319<br />
23-IJEC-83<br />
$'""}o .... ;: ••<br />
~~:- . . "~ .. ::';:;,:~~;{:i~:l~+~':«':,:,~"{tj\,' . -,
Iteration Paths<br />
162<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
for var bei ng frob<br />
is taken as if it were<br />
for var being default-loop-path in frob<br />
and<br />
for var bei ng expr and its frob •••<br />
is taken as if it were<br />
for var being expr and its default-loop-path in frob<br />
Thus, this "undefined path-name hook" only works if the default-loop-path path is defined.<br />
Ohviously. the usc of this "hook" is comp<strong>et</strong>itive. since only une such hook may be in usc, and<br />
the potenti<strong>al</strong> for syntactic amhiguity exists if frob is the name of a defined iteration path. 'Ibis<br />
feature is not f()f casu<strong>al</strong> usc: it is intended for usc by large systems which wish to usc a speci<strong>al</strong><br />
SyntilX for some fe<strong>al</strong>Ure tJley provide.<br />
17.7.1 Pre-Defined Paths<br />
loop comes with two pre-defined iteratinn pat~ functions: one implements a mapatoms-like<br />
iter.,tion path facility_ and the other is used for defining iteration paths for stepping through<br />
sequences.<br />
17.7.1.1Thc Interned-Symbols Path<br />
The interned -symbols iteration path is like amapatoms (or COMMO!\ LISP do-symbols) for<br />
loop.<br />
(loop for sym being interned-symbols ... )<br />
iterates over <strong>al</strong>l of the symbols in the current package and its superiors (or. in' Maclisp. the<br />
current obarray). This is the same s<strong>et</strong> of symbols which mapatoms iterates over, <strong>al</strong>though not<br />
necessarily in the same order. The particular package to look in may be specified as in<br />
(loop for sym being the interned-symbols in package ••• )<br />
which is like giving a second argument to mapatoms.<br />
In LISP implementations with some son of hierarchic<strong>al</strong> package structure such as USP<br />
MACHINE USP and NIl; one may restrict the iteration to be over just the package specified and<br />
not its superiors, by using the loc<strong>al</strong>-interned -symbols path:<br />
(loop for sym being the loc<strong>al</strong>-interned-symbols {in package}<br />
... )<br />
Example:<br />
(defun my-apropos {sub-string &option<strong>al</strong> (pkg package»<br />
(loop for x being the interned-symbols in pkg<br />
when (string-search sub-string x)<br />
when (or (boundp x) (fboundp x) (plist x»<br />
do (print-interesting-info x»)<br />
In the LISP MACHINE USP and <strong>NIL</strong> implementations of loop. a package specified with the in<br />
preposition may be' anything acceptahle to the pkg-find-package function. The code generated<br />
by this path will comain c<strong>al</strong>ls ((l intern<strong>al</strong> loop functions. with tJ1C CtfL'Ct that it will be transparent<br />
to changes to tJle implementation of packages. In the MACf .ISP implementation. the obarray must<br />
be an array pointer. not a symbol with an array propeny.<br />
MC:NII.Mi\N:I.OOPTM 319<br />
23-I)EC-83
<strong>NIL</strong> Manu<strong>al</strong> 163 Iteration P<strong>al</strong>lls<br />
17.7.1.2 Sequence Iteration<br />
One very common fonn of iteration is that over the c1ement~ of some object which is<br />
accessible by means of an integer index. loop defines an iteration p<strong>al</strong>ll function for doing this in<br />
a gener<strong>al</strong> way, and provides a simple interface to <strong>al</strong>low users to define iteration paths for various<br />
kinds of "indexable" data.<br />
def1ne-loop-sequence-path<br />
(def i ne-1 oop-sequence-path p<strong>al</strong>h-llame-o~lIames<br />
fe/ch-full size-full<br />
.\"('ljucllc('-Iype dcfiJu!t-wu'-type)<br />
l'olli-lIt1I11C-O""I/(//II('s is either an atomic p~tth name or list of path names. fe/ch-full is a<br />
function of two arguments: the sequence. and the index of the item to be f<strong>et</strong>ched.<br />
(Indexing is asslImed to he lero-origined.) si:c-/im is a function of one argument. the<br />
~eqllence: it should r<strong>et</strong>urn the number of clements in the sequence. sequel1ce-type is the<br />
name of the data-type of the sequence, and dljGu/t·l'a,. .. t),pe the name of the data-type of<br />
the clements of the sequence. These last two items are option<strong>al</strong>.<br />
The ~IL implementation of loup utilizes the COMMO!' LISP sequence manipulation primitives<br />
to define both element and elements as iteration paths:<br />
(define-loop-sequence-path (element elements)<br />
elt length)<br />
Then. the loop clause<br />
f',,1" .".,r nn; nn<br />
#'>",....,,, ... ,..,,,<br />
• ...,. • .... w ........ ~ the clements of .n "1"'(. III C.<br />
will step var over the clements of sequence. starting from O. The sequence p<strong>al</strong>ll function <strong>al</strong>so<br />
accepts in as a synonym for of.<br />
The range and stepping of the iteration may he specified with the use of <strong>al</strong>l of the same<br />
keywords which are accepted by the loop arithm<strong>et</strong>ic stepper (for var from ... ); they are by, to,<br />
downto. from, downfrom, below, and above, and are interpr<strong>et</strong>ed in the same manner. Thus,<br />
(loop for var be; n9 the e1 ements of sequence<br />
from 1 by 2<br />
... )<br />
steps var over <strong>al</strong>l of the odd clements of sequence, and<br />
(loop for var be; ng the el ements of sequence<br />
downto 0<br />
... )<br />
steps in "reverse" order.<br />
The <strong>NIL</strong> implementation of loop defines the following addition<strong>al</strong> sequence iteration paths.<br />
Basic<strong>al</strong>1y, they are <strong>al</strong>l speci<strong>al</strong> cases of the gener<strong>al</strong> elements path, but can generate b<strong>et</strong>ter code<br />
because they may know how to access the sequence b<strong>et</strong>ter. (If <strong>NIL</strong>'s compiler were smarter, one<br />
would be able to g<strong>et</strong> the same effect willl type declarations. but that is not the case y<strong>et</strong>.) Each<br />
iteration path name is defined in both the singular and plur<strong>al</strong> fonn.<br />
vector-elements<br />
This will iterate over any type of vector. There re<strong>al</strong>ly isn't a good reason to lise this<br />
over the elements iteration path anymore.<br />
MC:<strong>NIL</strong>MAN:1.00PTM 319<br />
23-))EC-8J
Iteration Paths<br />
164 <strong>NIL</strong> M,mu<strong>al</strong><br />
characters<br />
string -elements<br />
This iterates over the characters of a string. char is used to reference them. hence<br />
the iteration variable defaults to type string-char.<br />
bits<br />
bit - vector-elements<br />
This iterates over the bits in a bit-vector: the iteration variable is declared to be bit,<br />
as it can take on only 0 or 1 . as v<strong>al</strong>ues.<br />
The following arc the speci<strong>al</strong> cases which m~ly be of somewhat more intercst. because they<br />
can generate much bener code kl~(}wing that the sequence is of it pankular simple type:<br />
simple-vector-elements<br />
The sequence must be a simp1c lector.<br />
simple -string - elements<br />
The sequence must be a simple string.<br />
sim~: ~ - bit - vector-elements<br />
The sequence must he a simple bit vcctor.<br />
An such sequcnce iteration paths <strong>al</strong>low one to specify the variable to be used as the index<br />
variable. by use of the index keyword with the using preposition<strong>al</strong> phrase. as described ( with an<br />
example) on page 161.<br />
17.7.2 Defining Paths<br />
This section and the next may not be of interest to those not interested in defining their own<br />
iteration paths.<br />
A loop iteration clause (e.g. a for or as clause) produces. in addition to the code which<br />
defines the iteration (section 17.6), variables which must be bound~ and pre-iteration (prologue)<br />
code. This breakdown <strong>al</strong>lows a user-interfacc to loop which docs not have to depend on or know<br />
about the intern<strong>al</strong>s of loop. To compl<strong>et</strong>e this separation. the iteration path mechanism parses the<br />
clause before giving it to the user function which will r<strong>et</strong>urn those items. A function to generate<br />
code for a path may be declared to loop with the define-loop-path function:<br />
define-loop-path<br />
(dafi ne-l oop-path p<strong>al</strong>h·flame-o~names path-function<br />
Iisl-of<strong>al</strong>lowable-prepositions<br />
datum- J datum- 2 ••• )<br />
This defines p<strong>al</strong>h-/ullClioll to he the handler for the path(s) path-Ilame-or-names. which<br />
may be eithcr a symbol or a list of symbols. Such a handler should fonow the<br />
conventions described below. The datum-; are option<strong>al</strong>; they are passed in to pathfunc/ioll<br />
asa list<br />
The handler will be caned with the following arguments:<br />
path-Ilame<br />
The name ofth.e path which caused the path function to he invoked.<br />
MC:NH.MAN:OPATH 11<br />
23-DEC-83
jiiJ' ?t<br />
t m t n n 't<br />
Nil. Manu<strong>al</strong> 165 heration Paths<br />
l'ariable<br />
'1l1e "iteration variable".<br />
data-type<br />
'Ibe data type supplied with the iteration variable, or nil if none was supplied.<br />
preposition<strong>al</strong>-phrases<br />
'Ibis is a list with entries of the fonn (preposition expression). in the order in which<br />
they were collected. This may <strong>al</strong>so include some supplied implicitly (e.g. an of phrase<br />
when the iteration is inclusive. and an in phrase for the default-loop-path path): the<br />
ordering will show the order of ev<strong>al</strong>uation which should be followed for the<br />
expressions.<br />
inclusive?<br />
'Ibis is t if variable should have the starting point of the path as its v<strong>al</strong>ue on the first<br />
iteration (by virtlle of being specified with syntax like for l'elf being expr and its<br />
p<strong>al</strong>/m<strong>al</strong>lu'). nil otherwise. When t, expr will appear in prepositiun<strong>al</strong>-phrases with the<br />
of preposition: for example. for x being faa and it~i cdrs g<strong>et</strong>s preposition<strong>al</strong>-phrases<br />
of «of faa».<br />
<strong>al</strong>lowed-preposi t iOlls<br />
'1l1is is the list of <strong>al</strong>lowable prepositIOns declared for the pathname that caused the<br />
path function to be invoked. It and data (immediately below) may be used by the<br />
path function such that a single function may handle similar paths.<br />
data<br />
This is the list of "data" declared for the pathname that caused the path function to<br />
be invoked. It may. for instance. contain _ a canonic<strong>al</strong>ized pathname, or a s<strong>et</strong> of<br />
functions or flags to aid the path function in d<strong>et</strong>ermining what to do. In this way,<br />
the same path function may be able to handle different paths.<br />
The handler should r<strong>et</strong>urn a list of either six or ten clements:<br />
variable-bindings<br />
This is a list of variables which need to be bound. 'The entries in it may be of the<br />
fonn variable. (variable expression). or (variable expression data-t)pe). Note that it is<br />
the responsibility of the handler to make sure the iteration variable g<strong>et</strong>s bound. All of<br />
these variables will be bound in par<strong>al</strong>lel; if initi<strong>al</strong>ization of one depends on others. it<br />
should be done with a s<strong>et</strong>q in the prologue-fonns. R<strong>et</strong>urning only the variable<br />
without any initi<strong>al</strong>ization expression is not <strong>al</strong>lowed if the variable is a destructuring<br />
pattern.<br />
prologue-Jorms<br />
This is a list of fonns which should be included in the loop prologue.<br />
the four items of the iteratioll specification<br />
These are the four items described in section 17.6. page 159: pre-step-endtest. steps,<br />
posr-slep-endtest, and pseudo-steps.<br />
another Jour items of iteratioll specification<br />
If these four items are given. they apply to the first iteration. and the previous fOllr<br />
apply to <strong>al</strong>l succeeding iterations; otherwise, the previous four apply to <strong>al</strong>l iterations.<br />
MC:Nll.MAN:I.OOPTM 319<br />
23-DEC-83
Iter<strong>al</strong>ion Paths 166 N II. Manu<strong>al</strong><br />
Here are the routines which are used hy loop to compare keywords for equ<strong>al</strong>ity. In <strong>al</strong>l cases.<br />
a /okcll may he any LISP object. but a keytwJrdis expected to be an atomic symbol. In cerwin<br />
implementations these functions may be implemented as macros.<br />
s 1: 1 oop-tsqu<strong>al</strong> token keyword<br />
This is the loop token comparison function. token is any Lisp object; keyword is the<br />
keyword it is to be compared against.· It r<strong>et</strong>urns t if they represent the same token.<br />
comparing in a manner appropriate for the implementation.<br />
51: loop-tmember lokell keyword-lisl<br />
The member variant of si:loop-tequ<strong>al</strong>.<br />
s1 : 1 oop-tas soc /OkCI1 keyword-<strong>al</strong>isl<br />
The assoc \'ariant of si:loop-tequ<strong>al</strong>.<br />
The followiilg macro turns into the "proper" cude for generating a temporary variable in a<br />
particular I.ISP implementation.<br />
51: loop-gentemp &option<strong>al</strong> prcfi~r<br />
This expands into a c<strong>al</strong>l to the proper function for constructing a temporary variable.<br />
Depending on how it expands. the form prefix may not g<strong>et</strong> used (so it should not have<br />
interesting side effects!). In Nil. (and eventu<strong>al</strong>ly in some other implementations). this<br />
utilizes the gentemp function so that the generated variable wi1l be interned and<br />
somewhat mnemonic: in this case. . nrefix ... (which should he Ii ~vmhnl .,.""", nr Ii "rrino\ will .... hp<br />
used as a prefix of the generated symbol. In other implementations. si:loop-gentemp<br />
will expand to just a c<strong>al</strong>l to gensym. and throwaway prefix.<br />
If gentemp docs g<strong>et</strong> used but prefix is not supplied, then the prefix loopvar- is used so<br />
that the variable is identifiable as originating with loop.<br />
If an iteration path function desires to make an intern<strong>al</strong> variable accessible to the user, it<br />
should c<strong>al</strong>l the following function instead of si:loop-gentemp:<br />
s1 :loop-named-var1ab18 keyword<br />
This should only be caned from within an iteration path function.· If keyword has been<br />
specified in a using phrase for this path, the corresponding variable is r<strong>et</strong>urned;<br />
otherwise. si:loop-gentemp is caned and that new symbol r<strong>et</strong>urned. Within a given path<br />
function. this routine should only be caned once for any given keyword.<br />
If the user specifics a using preposition containing any keywords for which the path<br />
function does not caU si:loop-named-variabte. loop will infonn the user of his error.<br />
MC:NII.Mt\N:LOOIYrM 319<br />
23·DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 167 Iter<strong>al</strong>ion P"llls<br />
17.7.2.1 An Example Path Definition<br />
Here is an example function which defines the string -characters iteration path. This path<br />
steps a variable through <strong>al</strong>l of the characters of a string. It accepts the fonnat<br />
(loop for var bei ng the stri ng-characters of sir ... )<br />
The function is defined to handle the path by<br />
{define-loop-path string-characters string-chars-path<br />
(of»<br />
~1C:Nll.MAN;I.OOPTM 319<br />
23-DEC-83
Iteration Paths 168<br />
Nil. Manu<strong>al</strong><br />
Here is the function:<br />
(defun string-chars-path (path-name variable data~type<br />
prep~phrases inclusive?<br />
<strong>al</strong>lowed-prepositions data<br />
&aux (bindings nil)<br />
(prologue nil)<br />
string-var<br />
index-var<br />
size-var)<br />
(declare (ignore <strong>al</strong>lowed-prepositions data»<br />
(s<strong>et</strong>q string-var (si:loop-gentemp 'loop-string-)<br />
index-var (si:loop-gentemp 'loop-index-)<br />
size-var (si:1oop~gentemp 'loop-size-»<br />
To iterate over the characters of a string. we need<br />
to save the string. sav~ the size of the string.<br />
step an index variable through that range, s<strong>et</strong>ting<br />
the user's variable to the character at that index.<br />
Default the data-type of the user's variable:<br />
(cond «null data~type) (s<strong>et</strong>q data~type string-char»)<br />
; We support exactly one "prepOSition", which is<br />
; required, so this check suffices:<br />
(cond «null prep-phrases)<br />
(ferror nil "OF missing in -S iteration pat~ of -5"<br />
pa t h-name va r i ab 1 e) ) ) .<br />
; We do not support "inclusive" iteration:<br />
(cond «not (null inclusive?»<br />
(ferror nil<br />
"Inclusive stepping not supported in -S path -<br />
of -S (prep phrases c -:S)"<br />
path-name variable prep-phrases»)<br />
; S<strong>et</strong> up the bindings<br />
(s<strong>et</strong>q bindings {list (list variable nil data-type)<br />
{list string-v<strong>al</strong>' (cadar prep-phrases»<br />
(list index-v<strong>al</strong>' 0 'fixnum)<br />
(list size-var 0 'fixnum»)<br />
; Now s<strong>et</strong> the size variable<br />
(s<strong>et</strong>q prologue (list '(s<strong>et</strong>q ,size-v<strong>al</strong>' (string-length<br />
,string-var»»<br />
; and r<strong>et</strong>urn the appropriate stuff, explained below.<br />
(list bindings<br />
prologue<br />
t(= ,index-v<strong>al</strong>' .size-ver)<br />
nil<br />
nil<br />
(list variable '(char ,string-v<strong>al</strong>' ,index-v<strong>al</strong>')<br />
index-var '(1+ ,index-var»»<br />
~tC:<strong>NIL</strong>MAN:LOOPTM 319<br />
23-DEC-83
Nil. Manu<strong>al</strong> 169 Iteration Paths<br />
The first clement of the r<strong>et</strong>urned list is the bindings. The second is a list of forms to be<br />
placed in the prologu('. The remaining clements specify how the iteration is to be perfonned.<br />
This example is a particularly simple case, for .two reasons: the actu<strong>al</strong> "variable of iteration".<br />
index-var. is purely intern<strong>al</strong> (being gensymmed). and the stepping of it (1 +) is such that it<br />
may be perfonned safely without <strong>al</strong>l endtest. Thus index -var may be stepped immediately· after<br />
the s<strong>et</strong>ting of the user's variable. causing the iteration specification for the first iteration to be<br />
identic<strong>al</strong> to the iteration specification for <strong>al</strong>l remaining iterations. This is advantageous from the<br />
standpoint of the optimizations loop is able to perfonn. <strong>al</strong>though it is frequently not possible due<br />
to the semantics of the iteration (e.g.. for l'ar first ('xpr! then ('xl'r2) or to subtl<strong>et</strong>ies of the<br />
stepping. It is safe filr this path to step the user's variable in the ps('udo-sl('ps (the fourth item of<br />
an iteration specification) rather than the "re<strong>al</strong>" steps (the second). because the step v<strong>al</strong>lie C(lll<br />
have no dependencies on any other (user) iteration vari41bles. Using the pseudo-steps gener<strong>al</strong>ly<br />
results in some cflicicncy gains.<br />
I f one desired the index variable in the above definition to be user-accessible through the<br />
using phrase feature with the index keyword. the function would need to be changed in two<br />
ways. First. index-var should be s<strong>et</strong> to (si:loop-named-variable 'index) instead of the c<strong>al</strong>l to<br />
si:loop-gentemp. Secondly. the efficiency hack of stepping the index variable ahead of tie<br />
iter~tion variable must not be done. This is effected by changing the last fOim to be<br />
(list bindings prologue<br />
nil<br />
(list index-var '(1+ ,index-var»<br />
'(= ,index-var ,size-var)<br />
(list variable ~(char ,string-~ar .1naeX-Var),<br />
nil<br />
nil<br />
'(= ,index-var ,size-var)<br />
(list variable '(char ,string-var ,index-var»)<br />
Note that <strong>al</strong>though the second '( = ,index-var ,size-var) could have been placed earlier (where<br />
the second nil is). it is best for it to match up with the equiv<strong>al</strong>ent test in the first iteration<br />
specification grouping.<br />
MC:<strong>NIL</strong>MAN:LOOPTM 319<br />
23-DEC-83
The Flavor Facility 170 <strong>NIL</strong> Manuill<br />
18. The Flavor Facility<br />
IS. 1 Introduction<br />
Languages such as Sm<strong>al</strong>lt<strong>al</strong>k and Act-1 are designed to encourage a style of programming<br />
c<strong>al</strong>led object-oriented programming. LISP MACIIIJl.:E LISP offers a facility for object-oriented<br />
programming as well: it is caHed the Flavor System. or just flavors. NIl. offers a more primitive<br />
version of flavors than is available on the l.isp Machine. but unless you do quite complicated<br />
things with flavors. you will probably never notice the difference.<br />
18.1.1 Object -oriented Programming<br />
Suppose you were writing a file system. You might have sever<strong>al</strong> different types of files.<br />
including. for example. binary files and text files. If you wrote a program to print files on a<br />
user"s tenninaJ. and you wanted it to print ASCII characters when the user printed a text file. but<br />
ncwl numbers when the user printed a binary file. you might implement it as fonows:<br />
(typecase file<br />
(binary (oct<strong>al</strong>1y-print file»<br />
(text (ascii-print file»)<br />
That is. you might dispatch off the type of the file, c<strong>al</strong>ling the appropriate function to print the<br />
file. It might be nicer. however. to keep the infonnation about how the file should be printed<br />
with Ihe fill' itself. 'J11at is. the m<strong>et</strong>hod used for printing itsclfcould be part of the int(>rmation<br />
contained in each file: we could simply decide that every type of file we will support in our<br />
operating system will know how to perform certain operations. and we could specify printing on a<br />
tennin<strong>al</strong> to be one of them. Then we would implement the above as<br />
(send file :print-contents)<br />
where :print-contents is ·the name of a m<strong>et</strong>hod that could be specified for each type of file.<br />
On simply looking at the differences b<strong>et</strong>ween the two samples of code, one might notice that<br />
the second expresses much more clearly and compactly what we are doing: printing the file. We<br />
trust whoever defined this type of file object to have defined a reasonahle :print-contents m<strong>et</strong>hod<br />
for it. and we don't worry any further about type-dispatching and the like. Thus object-oriented<br />
programming constructs can have the effect of fre~ing the programmer from an extra level of<br />
d<strong>et</strong>ail.<br />
This should sound familiar even to users who have not used flavors. because it is similar to<br />
generic arithm<strong>et</strong>ic in COMMO~ LISP. In fact. operations that work for more than one type of<br />
object (like the imaginary :print-contents above) are c<strong>al</strong>led generic operations.<br />
Another thing we might notice about the object-oriented way of doing things is described by<br />
its name. We might say somewhat fancifully that the files in our example above have been raised<br />
from the re<strong>al</strong>m of "inanimate data· J<br />
to being objects that can do things. A file has become an<br />
object th<strong>al</strong> knows how to print itself. and can be asked to do so.<br />
MC:<strong>NIL</strong>MAN:FLAVOR44<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 171 Introduction<br />
Ohjects can know of things besides their m<strong>et</strong>hods for perfonning operations, and this brings<br />
up another advantage of object-oriented programming, which is useful even when one is not<br />
planning on implementing operations that will work on a large class of objects. Two objects of<br />
the same type will share the same m<strong>et</strong>hods for perfonning an operation. But two objects· of the<br />
same type can still have distinct state. They can have instance variables: variables that are loc<strong>al</strong><br />
to each instantiation. in much the same way that scoped variables arc loc<strong>al</strong> to a function c<strong>al</strong>l.<br />
For example. the file objects we were discussing above could have variables :author and :writedate.<br />
and each object would have its own v<strong>al</strong>ue for these variables.<br />
18.1.2 Object-oriented Programming llsing Flavors<br />
When we lise flanlrs to write object-oriented code. the objects themsehes are not flavors.<br />
They are ills/mr/ia/iolls of flavors. The flavor of an object is actu<strong>al</strong>ly its type. We define a flavor<br />
using ~efflavor. The definition of a flavor looks like<br />
(defflavor flavor-name inst<strong>al</strong>lce-variables<br />
com l'ol1cl1/~flavors<br />
optionl option2... )<br />
The flavor-namc can be any symhol. the ills/ancc-variables a (possibly nu11) list of symbols<br />
(variables) and their initi<strong>al</strong> v<strong>al</strong>ues. the component-flavors a list of flavors. and the options will be<br />
described further helow. A more concr<strong>et</strong>e example is:<br />
(defflavor bicycle «wheel-size nil) (gear-ratios nil)<br />
(s~l~ct~d-gear nil)<br />
(distance-travelled nil»<br />
( )<br />
:g<strong>et</strong>tab1e-instance-variables<br />
:s<strong>et</strong>table-instance-variab1es)<br />
The option :g<strong>et</strong>table-instance-variables will cause a m<strong>et</strong>hod that will r<strong>et</strong>urn the v<strong>al</strong>ue of<br />
that instance variable to be defined for each of the instance variables. :s<strong>et</strong>table-instancevariables<br />
will cause a m<strong>et</strong>hod that will <strong>al</strong>low us to s<strong>et</strong> the v<strong>al</strong>ue of that instance variable to be<br />
generated for each instance variable.<br />
If we want to create an instantiation of the flavor bicycle, we use make-instance:<br />
(s<strong>et</strong>q my-bike (make-instance ·bicycle»<br />
r<strong>et</strong>urns<br />
#<br />
or som<strong>et</strong>hing like it This object can be described:<br />
MC:<strong>NIL</strong>MAN:FLAYOR44<br />
23-I)I-:C-83
Introduction 172 <strong>NIL</strong> Manu<strong>al</strong><br />
(describe my-bike)<br />
The instance at address 128788 is of flavor BICYCLE and is 4<br />
Q's long. It directly or indirectly includes flavors (BICYCLE<br />
VA<strong>NIL</strong>LA-FLAVOR), and is of the types (BICYCLE VA<strong>NIL</strong>LA-FLAVOR).<br />
The 4 instance variables are:<br />
WHEEL-SIZE <strong>NIL</strong><br />
GEAR-RATIOS <strong>NIL</strong><br />
SELECTED-GEAR <strong>NIL</strong><br />
DISTANCE-TRAVELLED <strong>NIL</strong><br />
<strong>NIL</strong><br />
We can c<strong>al</strong>ise an instiHlllatlOn of &1 flanlr to execute ,I m<strong>et</strong>hod with send. The mctllods<br />
LT~ated upon definition of a flavor with the option :s<strong>et</strong>table-instanee-variables ha\e the n~lfncs<br />
of the instance \'ariables appended (0 "s<strong>et</strong>·n<br />
, but are in tllC keyword package. Thus we could s<strong>et</strong><br />
lhe v<strong>al</strong>ue of wheel -size like tllis:<br />
(send my-bike :s<strong>et</strong>-wheel-size 27) .<br />
The m<strong>et</strong>hods created on definition of a ftil\'Or with the option :s<strong>et</strong>tabfe-instance-variables are<br />
the same ~IS the names of the variahles. but are in the keyword paCkitge. So we could g<strong>et</strong> the<br />
,'arlle of :wheel-size like this:<br />
(send my-bike :wheel~size)<br />
27<br />
send objcct message &rest args<br />
This is the basic message-passing primitive. It should be used instead of funeaU. which<br />
has been used in the past in LISP MACIUNE LISP.<br />
1 expr-send o~iecl message &rest args<br />
This is to send as lexpr-fune<strong>al</strong>l (which is apply (page 31). as it is defined now) is to<br />
funeaU.<br />
There must be at least one arg given~ and the last one must be either a list or a vector.<br />
The object is sent message with arguments of <strong>al</strong>l of the other args followed by <strong>al</strong>l the<br />
elements of the last arg.<br />
send-forward object message {arg}-<br />
This is only v<strong>al</strong>id within the lexica1 scope of a defm<strong>et</strong>hod definition.<br />
L<strong>et</strong> the flavor which this m<strong>et</strong>hod was defined on be caned jlav. send-forward then does<br />
a s~nd, but stans searching for m<strong>et</strong>hods to handle message after jIav.<br />
n.b. send-forward is neither as efficient as it should be nor as efficient as one would like.<br />
y<strong>et</strong>. Note that it can be used 10 acheive many of the same effects as m<strong>et</strong>hod combination.<br />
MC:NfI.MAN:t:I.AVOR 44<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 173<br />
Introduction<br />
1 expr-send-forward ()~iecl message {arg}*<br />
Like lexpr-send. but does send-forward.<br />
mak.e-i ns tance jla\'o~llame &rest keyworded-argumel1ts<br />
This is the primary instantiation function. The keyworded-argumellls arc <strong>al</strong>ternating<br />
keywords and v<strong>al</strong>ues. Typic<strong>al</strong>ly, they specify initi<strong>al</strong> v<strong>al</strong>ues for the instance variables which<br />
arc initable (as specified with the :initable-instance-variables option to defflavor). '1l1ey<br />
may <strong>al</strong>so be arbitrary keywords which are checked for v<strong>al</strong>idity against those specified with<br />
the :init-keywords option to defflavor. which (merged with the :init-piist specification to<br />
defflavor) will be passed as arguments to the :init m<strong>et</strong>hod of the flavor.<br />
deffl avor jlcl\'UI~l1ame<br />
illsl<strong>al</strong>lce-varhlbles illc/uded-jlm'ors oplions ..•<br />
flawr-nlll1ll' is the name of the flavor being defined. After it is defined. it is acceptable as a<br />
second argument to typep (page 18), which will r<strong>et</strong>urn t if given a second argument of flavor<br />
Ilame and a first argument of an instantiation of jlayo""llwl1e. or any other flavor which directly or<br />
indirectly includes jla\'o~l1<strong>al</strong>l1e.<br />
iIlS/Llllce- rariablcs is a list of inswnce variables or lists of instance variables and forms to e\'<strong>al</strong><br />
to ohtain their initi<strong>al</strong> v<strong>al</strong>ues. These arc not necessarily <strong>al</strong>l of the instance variables of the<br />
instance: some may be inherited from other flavors which jlavor-name is being built from.<br />
However. compiled flavor m<strong>et</strong>hods for jlavor-name may not know about those inherited instance<br />
variables. so if you "know" that a flavor is going to have certain variables and need to use them.<br />
Y01l c;h(\t'~d inc1udr them h('r~. (Note that in the current ~:!!. !ns~ncc '."3:-bh1~ inh~r!tmcc is<br />
perfonlled when the defflavor form is compiled. so one will not receive a diagnostic about this.<br />
The inheritance will be deferred in in some later release. however. to provide for other features.<br />
including the ability to not have the component flavors of flavor-name defined when the defflavor<br />
is being compiled or interpr<strong>et</strong>ed.)<br />
If an atomic instance variable is specified in the instance variables list. then the instance<br />
variable is initi<strong>al</strong>ized "unbound" by make-instance (assuming no initiaHzation was specified with<br />
make-instance). This will cause an unbound variable reference in the 1\IL interpr<strong>et</strong>er; extern<strong>al</strong><br />
("outside accessible") references will just pick out the unbound pointer. as will compiled<br />
references to the instance variable, and probably cause some spastic behavior later.<br />
Otherwise, the instance variable specification should be a list of the ins~1nce variable and an<br />
initi<strong>al</strong>ization fonn, which will be ev<strong>al</strong>uated to d<strong>et</strong>ermine the initi<strong>al</strong> v<strong>al</strong>ue. (<strong>NIL</strong> actu<strong>al</strong>ly does not<br />
use ev<strong>al</strong>, but stores the v<strong>al</strong>ue either as a constant, if it self-ev<strong>al</strong>uates, or as a function of no<br />
arguments which ev<strong>al</strong>uates the initi<strong>al</strong>ization form; this function will be compiled when the<br />
defflavor fonn is compiled.)<br />
The following defflavor options <strong>al</strong>l de<strong>al</strong> with instance variables which must be listed in the<br />
instance-variables given for the defflavor. They may appear as atomic options, like :g<strong>et</strong>tableinstance-variables<br />
and :s<strong>et</strong>table-instance-variables in the bicycle example (page 171). in<br />
which case they refer to an of the instance-variables of the defflavor, or listed with those hey<br />
pertain to, as in<br />
MC:<strong>NIL</strong>MAN:FLAVOR 44<br />
23-I)EC-83
Introduction 174<br />
Nil. Manu<strong>al</strong><br />
(defflavor frob (var-l var-2 var-3) ()<br />
:g<strong>et</strong>table-instance-variables<br />
(:s<strong>et</strong>table-instance-variables var-l var-2»<br />
in which var-1. var-2. and var-3 are <strong>al</strong>l :g<strong>et</strong>table. but only var-l and var-2 are :s<strong>et</strong>table.<br />
:g<strong>et</strong>table- instance - variables<br />
Causes automatic generation of m<strong>et</strong>hods which will· f<strong>et</strong>ch the v<strong>al</strong>ues of the specified<br />
instance variables. ...:ach m<strong>et</strong>hod name is the name of thc variablc interned in the<br />
keyword package. Thus in the bicycle eX&lmple. one may send a bicycle the :distanc<strong>et</strong>ravelled<br />
message to find how far the bicycle h
---_.-._-----_.<br />
<strong>NIL</strong> Manu<strong>al</strong> 175 Introduction<br />
one. and make-instance is supposed to barf if that is not the case.<br />
:required - m<strong>et</strong>hods<br />
Any flavor including this flavor is required to support the listed m<strong>et</strong>hods. This is <strong>al</strong>ledgely<br />
checked ell instantiation time.<br />
:no-vanilla -flavor<br />
Do not include vanilla -flavor. as is done by default.<br />
:included- flavors<br />
Sort of like building the flavor from the named flavors. but they are made to come last<br />
<strong>al</strong>ways. where is l1ie illli('ril<strong>al</strong>lcc-orci('r <strong>al</strong>ld \'llllilla~tla\'(}r insertioll <strong>al</strong>ld tlJis ('xplain('d?<br />
:flavor - not - instantiable<br />
This flanlr is not itself inswntiahlc. This should he specified for things which are not<br />
compl<strong>et</strong>e in thcmsrlves. hut mixill jlavors-flavors which arc meant to be mixed in to<br />
provide some aspel.:l of other flavors.<br />
:init- keyw~rds<br />
AJlowa[~ie keywords which make-instance will pass <strong>al</strong>ong to the :init message when a<br />
fbvor is instantiated.<br />
:default-init-plist<br />
Alternating keyword-v<strong>al</strong>ues. which are supplied to the :init message when a flavor is<br />
instantiated. unless the keyword was supplied <strong>al</strong>ready to make-instance.<br />
:documentation<br />
ummmm<br />
defm<strong>et</strong>hod (flQ\lor-name message-name [message-type» arglist body ...<br />
Defines a m<strong>et</strong>hod m(,ssage-name for flavor. message-type is not supported. do not use it.<br />
arglist is any lambda-list acceptable to <strong>NIL</strong>. self will be bound (lexic<strong>al</strong>ly) for the<br />
ev<strong>al</strong>uation of body.<br />
Lexic<strong>al</strong> instance variables are correctly enclosed by the <strong>NIL</strong> interpr<strong>et</strong>er in this version of<br />
<strong>NIL</strong>. The only time this can fail is if there is any funny stuff with how the definition is<br />
being perfonned, like ev<strong>al</strong>uating a defm<strong>et</strong>hod inside the lexic<strong>al</strong> environment of another<br />
defm<strong>et</strong>hod or a defun. This would not work compiled anyway.<br />
defm<strong>et</strong>hod-primi t iva (flavor-name message-name) arglist body ...<br />
lbis is used to define a m<strong>et</strong>hod without interfacing to de<strong>al</strong> with the self variable or the<br />
instance variables. 111e arguments which the generated function receives wi11 be the object,<br />
the map vector, the message, and the other arguments. This routine exists primarily for<br />
primitive low-level m<strong>et</strong>hod-generation code, as that which might be used by defstruct.<br />
MC:<strong>NIL</strong>MAN:FI.AYOR 44<br />
23-I)EC-83
System-Defined Messages 176 Nn~ Manwll<br />
18.2 System" Defined Messages<br />
Here are. some of the messages the system uses to de<strong>al</strong> with objects defined by defftavor. and<br />
what they mean. .<br />
:print-self strtam level slashifrp<br />
The object should print itself to the stream sitcam. level is the recursion level of printing.<br />
and should be compared against the dynamic v<strong>al</strong>ue of prinlevel. slashify·p being non-null<br />
mC.tnS that thc output should maybe be re-readable: it is bcing done by prinl rather than<br />
prine.<br />
If you use this in a non-trivi<strong>al</strong> fashion (specific<strong>al</strong>ly. if the object will he printed in a nonatomic<br />
fllshion). then it might be re'lsomlble to define m<strong>et</strong>hods fhr the pr<strong>et</strong>ty-printcr using<br />
thc :pp-dispatch and :pp-anaphor-dispatch m<strong>et</strong>hods. ,md define the non-pr<strong>et</strong>ty-printing<br />
:print-self m<strong>et</strong>hod in tenns of how the pr<strong>et</strong>ty-printing is perfonned. This is described in<br />
[7].<br />
: equa 1 uthe,...object<br />
The m<strong>et</strong>hod should r<strong>et</strong>urn t if its object is equ<strong>al</strong> to olher"()~iec(. nil if it is not. olhe,...<br />
object will be of the ex(\ct same type as the object receiving the mess~1ge (a consequence<br />
of the fonn<strong>al</strong> definition of equ<strong>al</strong>. page 20). This message is <strong>al</strong>so used by eqf (page 20)<br />
on numeric<strong>al</strong> types which arc not "primitive" <strong>NIL</strong> data types.<br />
:sxhash<br />
The object should r<strong>et</strong>urn a hash encoding of itself. such that two objects which are equ<strong>al</strong><br />
have the same hash. See the description of sxhash. page 119, for the semantics which<br />
must be enforced, and note <strong>al</strong>so the default :sxhash m<strong>et</strong>hod. page 177.<br />
:8v<strong>al</strong><br />
AJIows extending the ev<strong>al</strong>uator in strange and wondrous ways to handle ev<strong>al</strong>uation of nonlist<br />
fOnTIs. Note that certain types which arc defined· to self-ev<strong>al</strong>uate do so by spcci<strong>al</strong> case<br />
checks in the interpr<strong>et</strong>er, so one cannot change the ev<strong>al</strong>uation behaviour of those types.<br />
The compiler can't handle these extensions however.<br />
: func<strong>al</strong>1 argument-vector<br />
This is what happens by default when a func<strong>al</strong>. is performed on an instance. argumentvector<br />
is a stack vector (section 3.1, page 15) of the arguments.<br />
: describe ?arguments?<br />
This is what is used by the describe function (page 222).<br />
:exh1b1t-self stream<br />
:select-nth n<br />
: store-nth n v<strong>al</strong>ue<br />
These are used by the exhibit function (page 222) to define how exhibition is perfonned<br />
on objects of the given type. lbsic<strong>al</strong>ly. exhibition is initiated by sending the objccta<br />
:exhibit-self message; it should respond by printing out the appropriatc infonnation. and<br />
r<strong>et</strong>urning the nUlnbcr of "slots" Of "indiccs" which it includes. (Try exhibiting various<br />
l'IL objects to see the fonnat: do not include ule clear-screen in the display. The indices<br />
MC:NII.MAN;FLA VOR 44<br />
23-DEC-83
iiutitT<br />
W<br />
Nil. Manu<strong>al</strong> 177 Message I )efaults<br />
printed out in the initi<strong>al</strong> display are printed by this m<strong>et</strong>hod.} Then. the ohject will be<br />
sent (as the llserinteracts) :select-nth and :store-nth messages to select' and store the<br />
corresponding components. GeneraHy.there is no need to define such a m<strong>et</strong>hod for<br />
ordinary flavors. as the m<strong>et</strong>hod inherited from vanilla-flavor will show the instance<br />
variable names <strong>et</strong>c.<br />
: pp-d1 spatch lonnat-description?<br />
:pp-anaphor-d1spatch<br />
These are used hy the !,:1I. pr<strong>et</strong>ty-printer [7]. :pp-dispatch is used to control formatting:<br />
to use this you will need to eonsult the pr<strong>et</strong>ty-primer documentation. :pp-anaphordispatch<br />
is used lO d<strong>et</strong>ect circularities in the structure heing printed: <strong>al</strong>l that is nOlm<strong>al</strong>ly<br />
needed is to c<strong>al</strong>l the fUI1l:tion pp-anaphor-dispatch on each of the components which<br />
will he printed by the :pp-dispatch m<strong>et</strong>hod. These m<strong>et</strong>hods should be defined in pairs.<br />
so that they refer to the same s<strong>et</strong> of components.<br />
18.3 Message Defaults<br />
Here are some of the messages provided by vanilla-flavor. and what they do.<br />
: p r i n t - se 1 f stream level 'slashify-p<br />
Prints som<strong>et</strong>hing vaguely infonnative.<br />
: g<strong>et</strong>-handl er-for messa~e-name<br />
R<strong>et</strong>urns the handler function for the message message-name. or nil. In NIl.. this is.<br />
necessarily of type compiled-function.<br />
: operat 1 on-handled-p message-flame<br />
R<strong>et</strong>urns a non-nun v<strong>al</strong>ue if the object supports a message message-name, nil otherwise.<br />
:send-if-handles message &rest args<br />
If the objcct supports message t then it is sent that message with arguments of whatever<br />
args were passed; otherwise, nil is r<strong>et</strong>urned.<br />
:wh1ch-operations<br />
A list of aU of the messages which the object handles is r<strong>et</strong>urned.<br />
dynamic<strong>al</strong>ly and cached on a per-flavor basis.<br />
This is computed<br />
:equ<strong>al</strong><br />
By default, two objects are equ<strong>al</strong> only if they are eq. If the object has interesting<br />
criteri<strong>al</strong> components, it must define an equ<strong>al</strong> message to compare them.<br />
:sxhash<br />
The default :sxhash simply r<strong>et</strong>urns a hash computation on the name of the flavor. The<br />
reason for thi!\ is that if two objects are equ<strong>al</strong>. their sxhashes must be equ<strong>al</strong>. So, if the<br />
object docs anything interesting for the :equ<strong>al</strong> message. it should probably define a<br />
compatible :sxhash message so that different objects will hash differently,<br />
MC:NII.MAN:FLA VOR 44<br />
23-DEC-83<br />
- . ,<br />
- ~~ ~ -' - ... - - - - '<br />
, '<br />
~ "4' ~ •<br />
~: ~. ' , ,-' ..:, ," ; _..', " .<br />
- ", -. ,- . . '
Message J}efaults<br />
:8xh1b1t-self stream<br />
:s818ct-nth 11<br />
: store-nth 11 v<strong>al</strong>ue<br />
178<br />
Nfl. Manu<strong>al</strong><br />
'Ibe default exhibition m<strong>et</strong>hod displays the <strong>al</strong>l of the instance vari,lbles of the instance.<br />
and their v<strong>al</strong>ues. The selcct and store m<strong>et</strong>hods just <strong>al</strong>low onc to felCh and modify the<br />
variables by index.<br />
: pp-d1 spatch jOnllat-dcscripliol1?<br />
The defillilt :Pp-dispatch m<strong>et</strong>hod "reily-prints the object the way it "rint~ (vi,1 :printself).<br />
,lIld treat~ il as iIIomic. If you define a :print-self m<strong>et</strong>hod for som<strong>et</strong>hing. the :pp_<br />
dispatch m<strong>et</strong>hod ma} n(n fimction 'I~ desired. in Ill<strong>al</strong> it will nnl dn any "mn<strong>al</strong>lil1g nf the<br />
components.<br />
:pp-anaphor-d1spatch<br />
The default :pp-anaphor-dispatch m<strong>et</strong>hod dnes nothing. nn the grounds that the :pp_<br />
dispatch m<strong>et</strong>hod will not be· printing any comp{)ncnt~.<br />
MC:<strong>NIL</strong>MAN:FLAVOR 44
<strong>NIL</strong> Manu<strong>al</strong> 179 Input, Output. and Streams<br />
19. Input, Output, and Streams<br />
Input and output in <strong>NIL</strong> is pcrfonncd by operations on streams. Some streams can operate in<br />
only onc direction (input or output), and some can operate in both.<br />
str8amp x<br />
R<strong>et</strong>urns t if x is a stream. nil otherwise.<br />
Most operations on streams are perfonned by functions which take the stream as one of its<br />
arguments. possihly defaulted. Although ultimatc1y the stream operations turn into messagepassing<br />
using the flavor system. these thnctions arc the pertcrrcd way to do things. as they<br />
pert(lnll what mediation might be necessary b<strong>et</strong>ween the desired eflect and the stream's<br />
~apabi1ities.<br />
19.1 Standard Streams<br />
The folJowing variables have as their \'ah1es streams used for variolls purposes. In the future,<br />
the names will b\.' changed to have • characters at both ends; e.g.. standard - input wi11 become<br />
·standard- input •.<br />
standard-1 nput<br />
Variable<br />
This is used as the default stream for various input functions. and for the toplevel and<br />
breaklevel loops.<br />
standard-output<br />
Variable<br />
This is used as the default stream for various output functions. and for the top level and<br />
breaklevel loops.<br />
termin<strong>al</strong>-io<br />
Variable<br />
The v<strong>al</strong>ue of termin<strong>al</strong>-io is ordinarily the stream which connects to the user's console.<br />
error-output<br />
Variable<br />
This is the stream to which error messages should be sent Nonn<strong>al</strong>ly, it directs output<br />
through the v<strong>al</strong>ue of termin<strong>al</strong>-io (but see comments below), but it could be made to<br />
send them to a file. for instance. (This may not be used properly y<strong>et</strong>.)<br />
query-10<br />
Vanabk<br />
This stream is used to ask questions of the user. Norm<strong>al</strong>1y it uses the tennin<strong>al</strong>, but could<br />
be made to (for instance) log both the input and the output of the transactions .<br />
• trace-output.<br />
Variable<br />
This is the stream to which output from tracing (see the trace function. page 220) is sent<br />
All of the above streams. with the exception of termin<strong>al</strong> -io. are initi<strong>al</strong>ly bound to synonym<br />
streams which pass <strong>al</strong>l operations on to the stream which is the v<strong>al</strong>ue of termin<strong>al</strong>-io.<br />
MC:<strong>NIL</strong>MAN;NEWIO 27<br />
23-DEC-83<br />
.. ' '. . ... ". .... :;'::/:. .<br />
. '. .' . ..'<br />
.<br />
. '.. . ..<br />
_ ~ " • - , c'. :_::- . " ' _. ' _ ' . _ _ ,- "'. "
Stream Creation and Operations 180 Nil. ManuaJ<br />
The v<strong>al</strong>ue of termin<strong>al</strong>-io should not nonn
Slream Creation and Operations ]82 NI14 Manu<strong>al</strong><br />
make-synonym-stream symbol<br />
This milkes a S)'1I01lYIl1 stream. Such ,t stremn directs (most) operations on it to the<br />
current dynamic binding of the variable symbol. In this way. the stream produced can<br />
<strong>al</strong>ways be indirecting to another stream, even when the v<strong>al</strong>ue of symbol changes by its<br />
being bound Of s<strong>et</strong>qed.<br />
make-str1ng-output-stream &option<strong>al</strong> &key (:Iine-Iength 79) (:line-number 1)<br />
(:page-fength 60) (:page-number 1) (:character-position 0)<br />
This crc.Hes a stream which wi11 "ccumulate <strong>al</strong>l .output given tn it. This output may be<br />
obtained as a string by g<strong>et</strong>-output-stream-string, be1ow.<br />
The optiolls are used to initi.tlil.e various param<strong>et</strong>ers of the stre4lrn. so th<strong>al</strong> f
<strong>NIL</strong> Manu<strong>al</strong> 183 Input Functions<br />
19.3 Input Functions<br />
First some functions not specific to ascII mput streams (necessarily). listen and clear-input<br />
could conceivably be meaningful on strange peripher<strong>al</strong>. devices (dreamer, aren't i?).<br />
listen &option<strong>al</strong> input-stream<br />
lllis will r<strong>et</strong>urn nil jf there is no input immediately available from input-sream. non~null<br />
otherwise. On a termin<strong>al</strong>. the intent is that it tells wh<strong>et</strong>her the user has typed some input<br />
which has not been read y<strong>et</strong>. On non-interactive streams it should be true except at endof-file:<br />
most streams probably don't SUppOft it y<strong>et</strong>.<br />
clear-input &oplion<strong>al</strong> input-strcam<br />
Flushes bufiered input from input-stream. This only works on the termin<strong>al</strong> right now. (It<br />
isn '( re<strong>al</strong>ly meaningful for non-interactive streams.)<br />
19.3.1 Ascii Input<br />
Most of the functions which read input t(ike arguments input-strcam and eofmlue. In gener<strong>al</strong>.<br />
if input-stream is nil Of not supplied. it defaults to the v<strong>al</strong>ue of standard-input: if it is the atom<br />
1. the v<strong>al</strong>ue of termin<strong>al</strong>-io will be used.<br />
If no eofv<strong>al</strong>ue is specified. then an error will be sign<strong>al</strong>led at end-of-file. otherwise the eof<br />
v<strong>al</strong>ue will be r<strong>et</strong>urned. Specifying an eofv<strong>al</strong>ue of nil is 110/ equiv<strong>al</strong>ent to specifying no eofv<strong>al</strong>ue,<br />
When input is read from an interactive stream, the characters typed will be echoed at the<br />
user. For those functions which do some significant amount of reading. such as readline or read.<br />
rubout processing will be provided. In this case. specifying an eofv<strong>al</strong>ue means that if the user<br />
auempts to ttruh oul" past the beginning of what he was typing, the function will r<strong>et</strong>urn ('of<br />
v<strong>al</strong>ue. instead of requiring him to type a compl<strong>et</strong>e expression (line, s-expression, whatever the<br />
function c<strong>al</strong>ls for).<br />
What actu<strong>al</strong>ly happens right now is that specifying an eofv<strong>al</strong>ue when reading from an<br />
interactive stream, dies.<br />
read-char &optionaJ input-stream eofv<strong>al</strong>ue<br />
Reads one character from input-stream.<br />
This doesn't seem to take eofv<strong>al</strong>ue y<strong>et</strong>?<br />
peek-char &option<strong>al</strong> input-stream eofv<strong>al</strong>ue<br />
Ibis definition is wrong. The arguments should be peek-type. illput-slream, eofv<strong>al</strong>ue. It<br />
will eventu<strong>al</strong>ly be fixed.<br />
Peck- at a character in the input stream. Like read-char. but the next c<strong>al</strong>l to read-char<br />
will r<strong>et</strong>urn the same character.<br />
MC:<strong>NIL</strong>MAN:NEWIO 27<br />
23-DEC-83
---------------------------------------~====::::.::==--......<br />
5.7.7 •<br />
.,r.~.r.?..-r.. 1I1I1I1I<br />
Output Functions 184 <strong>NIL</strong> Manu<strong>al</strong><br />
unread-char character &option<strong>al</strong> input-stream<br />
Undoes a read -char. peek -char. in the simple case, could have been (som<strong>et</strong>imes. is)<br />
defined as being a read-char followed by an unread-char of the character just read.<br />
Input streams are only required to support the ability to baclC up one character:<br />
unread -chars without intervening read -chars are an error.<br />
multiple<br />
re8dl1 n8 &option<strong>al</strong> input-stream eofv<strong>al</strong>ue<br />
Reads a 1ine of text from input-stream and r<strong>et</strong>urns it. as a string.<br />
r<strong>et</strong>urned. which is t if end-of-file was reached. nil otherwise.<br />
A second v<strong>al</strong>ue is<br />
read &option<strong>al</strong> iI/put-stream ('ofv<strong>al</strong>u('<br />
Reads one s-expression from inpul-slream. and r<strong>et</strong>urns it.<br />
discllssed in section 16.3. page 126.<br />
Reading and reader syntax is<br />
19.3.2 Ilinary Input<br />
The semantics of binary input arc stream specific. In gener<strong>al</strong>. integers of some significance<br />
are read. and Nil. places no speci<strong>al</strong> interpr<strong>et</strong>ation on any particular v<strong>al</strong>ues. The only sort of<br />
binary input <strong>NIL</strong> supports. however. only reads unsigned eight-bit bytes from disk files.<br />
read-byte input-stream &option<strong>al</strong> eofv<strong>al</strong>ue<br />
Reads one byte from input-strt'(lm and r<strong>et</strong>urns it as an integer. unless end of file is<br />
reached. in which case the nonn<strong>al</strong> end-of-file behaviour occurs.<br />
19.4 Output Functions<br />
Similar to the input functions. if an option<strong>al</strong> output-stream argument is not supplied to an<br />
output function. it defaults to the v<strong>al</strong>ue of standard-output.<br />
First some functions applicable to both ascii and binary streams.<br />
force-output oU/put-stream<br />
The purpose of force-output is to ensure that no output which may have been produced<br />
is sitting around in anyone's buffers. If output-stream is buffered by <strong>NIL</strong>. the output<br />
should be sent to the operating system (or whatever). and if necessary, the operating<br />
system told to send the contents of its buffers off to their eventu<strong>al</strong> destination.<br />
In practice this doesn't do anything y<strong>et</strong> in <strong>NIL</strong>.<br />
f1 n 1 sh-output output-stream<br />
This is like force-output. and addition<strong>al</strong>ly docs not r<strong>et</strong>urn until the output has actu<strong>al</strong>ly<br />
reached its destination.<br />
If a stream docs not handle this. which no currently implemented <strong>NIL</strong> streams do, a<br />
force-output is done. q.v.<br />
MC:NII.MAN:NEWIO 27<br />
23-DEC-83
<strong>NIL</strong> ManU4l1 185 Output Functions<br />
c188r-output oU/pllI-stream<br />
The Pllll10se of this is to cause as lillIe as possible of any output <strong>al</strong>ready sent to ou/pu/<br />
s/re<strong>al</strong>l1 to reach its destination: just as force-output attempts to g<strong>et</strong> <strong>al</strong>1 buffers sent off,<br />
clear-output attempts to g<strong>et</strong> <strong>al</strong>l buffers flushed.<br />
"Ibis is primarily intended for tennin<strong>al</strong>s. <strong>al</strong>though it could be meaningful for random<br />
other devices (ascii and binary). It does not do anything. and is not re<strong>al</strong>ly expected to.<br />
to a random disk file.<br />
It doesn't do anything to anything in <strong>NIL</strong><br />
19.4.1 Ascii Output<br />
write-char char &option<strong>al</strong> output-stream<br />
Writes char to (}utpu/-slream.<br />
terpr 1 &option<strong>al</strong> OUlpul-s/ream<br />
fresh-line &optionaJ Oli/pul-stream<br />
terpri perfonns a newline on oUlpu/ .. stream.<br />
fresh -line does so. unless it can d<strong>et</strong>ennine that the "cursor" is at the left margin.<br />
fresh-line is supposed to r<strong>et</strong>urn t if it perfonned a newline. nil otherwise. terpri <strong>al</strong>ways<br />
r<strong>et</strong>urns nil. fllr historic<strong>al</strong> reasons.<br />
ous tr strillg &option<strong>al</strong> oUlpul-stream (start 0) COUllt<br />
Standard !':Il. string-output. Outputs the characters of string, starting at index slart and<br />
proceeding for count characters, to oUlpu/-stream. This is not defined by CO!\1MOi' lISt>.<br />
but has been in <strong>NIL</strong> for some time and is extremely useful for doing efficient output<br />
because it passes a pseudo-substring defined by start and· count <strong>al</strong>ong· to the stream. Most<br />
<strong>NIL</strong> streams do this more efficiently than single-character output, especi<strong>al</strong>ly the· termin<strong>al</strong><br />
stream.<br />
wr 1 t8-str 1 ng sIring &option<strong>al</strong> stream<br />
wr 1 te -11 n e string &option<strong>al</strong> stream<br />
Writes the characters of string to stream. write-line fol1ows them by a newline (terpri,<br />
page 185). In <strong>NIL</strong> this is <strong>al</strong>most <strong>al</strong>ways faster than using a loop of write-chars.<br />
pr1 nc object &option<strong>al</strong> output-stream<br />
pri n1 object &option<strong>al</strong> output-stream<br />
pr 1 nt object &option<strong>al</strong> output-stream<br />
Standard Maclisp-style printing functions.<br />
prin1 is the basic printing function, which attempts to output the printed representation of<br />
object to output-stream in such a way that it might be reconstructable with read. No<br />
. newline or \\hitespace of any kind is output before or after, so delimiters of some sort<br />
might be needed b<strong>et</strong>ween successive c<strong>al</strong>ls.<br />
MC:<strong>NIL</strong>MAN:NEWIO 27<br />
23-DEC-83<br />
. . .,.. ..... ",- -<br />
..... ~. -./"- : ~~ - ~.. -<br />
. .•. . ... ... . ..~... .•.... ~:. ;~~' ~ r:~:';; ~;:; ~~i;.··~ ,..~ ~~,~ ~,~~:~~ '-..;:;.:!C:,C;:?1::.,'.: .' / . .:. .
• 0>' , • .';,', ,-~.,<br />
• :,' ~<br />
~'<br />
:. :~.~-~::; .". ',':, '-:~ '.
<strong>NIL</strong> Manu<strong>al</strong> 187 Fonnat<br />
In r\1I .• pr<strong>et</strong>ty-prinl attempts to d<strong>et</strong>ennine the existence of circular structure. and show<br />
this somehow without blowing up.<br />
The pr<strong>et</strong>ty-printer itself is described in much more d<strong>et</strong>ail in [7].<br />
pr<strong>et</strong>ty .. pr1 nt ()~iccl &option<strong>al</strong> stream<br />
pr<strong>et</strong>ty-prinl. with a terpri first and output of a space character after. This. pr<strong>et</strong>ty-print<br />
is to pr<strong>et</strong>ty - prin 1 as print is to prin 1.<br />
oNccl &oplion<strong>al</strong> stream<br />
Like pr<strong>et</strong>ty-prinl. but does 1101 assume that ol~irci<br />
pr<strong>et</strong>ty~pr1nl-datum<br />
is l.ISP code.<br />
pr<strong>et</strong>ty-pr1nt-datum ()l~irct<br />
Similar.<br />
&option<strong>al</strong> stream<br />
19.6 Format<br />
This section is a quick reworking of the chapter on format which appeared m [3]. It omits<br />
topics specific to implementations of format other than Nil's. and includes references to<br />
differences b<strong>et</strong>ween what <strong>NIL</strong> currently provides. and the definition of format provided by<br />
CO\.1MO!': LISP. It is not known at this time how the COM\40N LISP definition of format wi11 affect<br />
the MACUSP implementation. which utilizes the same source code as the ~J1. implementation right<br />
now. The ~IL version of format will of course be made to confonn to the CO~1MO:--'; LISP<br />
definition.<br />
format destillation cOlztro/·string &rest args<br />
format is used to produce fonnatted output. format outputs the characters of collIro/<br />
SIring. except that tilde C'-tt) introduces a directive. The character after the tilde.<br />
possibly preceded by arguments and modifiers, specifics what kind of fonnatting is desired.<br />
Some directives use an element of args to create their output.<br />
The output is sent to destination. If destillation is nil. a string is created which contains the<br />
output. If destination is t, the output is sent to the "default output destination", the v<strong>al</strong>ue of<br />
standard-output (page 179). Otherwise, destination should be an output stream.<br />
?fot'mat destination comro/-string &rest args<br />
This is equiv<strong>al</strong>ent to format except that destillation is interpr<strong>et</strong>ed just like the stream<br />
argument to print-nil means "the default" (the v<strong>al</strong>ue of standard-output), and t means<br />
"the tennin<strong>al</strong>" (the v<strong>al</strong>ue of terminaf-io). This only ,exists in MACLISP and <strong>NIL</strong>.<br />
A directive consists of a tilde. option<strong>al</strong> decim<strong>al</strong> numeric param<strong>et</strong>ers separated by commas.<br />
option<strong>al</strong> colon (n;") and atsign ("@") modifiers. and a single character indicating what kind of<br />
directive this is. The <strong>al</strong>phab<strong>et</strong>ic case of the character is ignored. Examplcs of control strings:<br />
"-S"<br />
This is an S directive with no param<strong>et</strong>ers.<br />
"-3 t 4 :@s" 'This is an S directive with two param<strong>et</strong>ers, 3 and 4,<br />
and both the colon and atsign flags.<br />
MC:<strong>NIL</strong>MAN;NEWIO 27<br />
23-I)EC-83
Format 188 <strong>NIL</strong> Manu~11<br />
format includes some extremely complicated and speci<strong>al</strong>ized features. It is not necessary to<br />
understand <strong>al</strong>l or even most of its features to use format cfficiently. The beginner should skip<br />
ovcr anything in thc fo1Jowing documentation that is not immediately useful or clear. The more<br />
sophisticated features are there tilr the convenience of programs with complicatcd fonnatling<br />
requirements.<br />
Som<strong>et</strong>imes a numcric paramcter is used to specify a character, for instance the padding<br />
character in a right- or left-justifying operation. In this case a single quote (') fol1owed by the<br />
dcsircd ch.tractcr may be used as a numeric argument. Fur example. you can use<br />
"-5. 'Od"<br />
to print a decim<strong>al</strong> numhcr in five columns with Icading zcros (the first two param<strong>et</strong>ers to -0 ar<strong>et</strong>hc<br />
number of columns and the padding character).<br />
In place of a numeric param<strong>et</strong>er to a dircctive. you C,1Il put the l<strong>et</strong>ter v. which takes an<br />
ilrgumcnt from args as a param<strong>et</strong>er to the directive. Nonn<strong>al</strong>ly this should be a number but it<br />
doesn't rea1Jy ha\'c to be. '111is feature <strong>al</strong>10ws variable column-widths and the like. Also. you can<br />
use thc character # in place of a param<strong>et</strong>er: it represents the number of arguments remaining to<br />
be processed.<br />
It is possible to have a directive name of more than one character. The name need simply be<br />
enclosed in backslashes (U' tt); for example,<br />
(format t tt-\\now\\" (status daytime»<br />
lbe backslashes above are doubled. because hackslash is the quoting character in COMMON LISP.<br />
Bec:!t!sc of this. t.'1~ fer!.':!rd-sbsh Chaf:lctcr {I} '.'.'iH prob:lbly be mnde synonymou:; with buckslush.<br />
but as of y<strong>et</strong> it has not been. As <strong>al</strong>ways. case is ignored here. There is no way to quote a<br />
backslash in such a construct No multi-character operators come with format.<br />
Once upon a time. various strange and wonderful interpr<strong>et</strong>ations were made on c01l1ro/-slring<br />
when it was neither a string nor a symbol. Some of these are still supported for compatibility<br />
with existing code (if any) which uses them; new code. however, should only use a string or<br />
symbol for cOlltro/-string.<br />
19.6.1 The Operators<br />
Here are the operators.<br />
-A arg, any USP object, is printed without slashification (like prine). - nA inserts spaces<br />
on the right. if necessary,' to make the column width at least n.<br />
-millcol.colillc.millpadpadeharA is the rull fonn of -A. which <strong>al</strong>lows <strong>al</strong>eborate control<br />
of the padding. lbe string is padded on the right with at least millpad copies of<br />
padchar: padding characters are then insened colinc characters at a time until the tot<strong>al</strong><br />
width is at least mincol. The defaults are 0 for minco/ and minpad. 1 for colinc, and<br />
space for padehar. The atsign modifier causes the output to be right-justified in the<br />
field instead of left-justified. (The same <strong>al</strong>gorithm for c<strong>al</strong>culating how many pad<br />
characters to output is used.) The colon modifier causes an arg of nit to be output as<br />
O.<br />
-S This is identica1 to -A except that it uses prinl instead of prine.<br />
MC:Nll_MAN:fORMAT 7<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 189 Format<br />
-0 Decim<strong>al</strong> output. arg is printed as a decim<strong>al</strong> integer. -11,111.00 lIses a column width<br />
of II. padding on the left with pad-character III (default of space). using the character<br />
(} (default comma) to separate groups of three digits. These commas are only inserted<br />
if the : modifier is present. Addition<strong>al</strong>ly. if the @ modifier is present. then the sign<br />
character will he output uncondition<strong>al</strong>ly: noml<strong>al</strong>ly it is only output if the integer is<br />
negative. If arg is not an integer. then it is output (using prine) right-justified in a<br />
field 11 wide. using a pad-character of m. with decim<strong>al</strong> output radix and trailing<br />
decim<strong>al</strong> point suppression.<br />
If arg is not an integer. then it is output in the specified field (as hy -A). in<br />
decim<strong>al</strong>.<br />
-0 Oct<strong>al</strong> output. Just like -0: if a"g is not an integer. it is output (as by -A). in oct<strong>al</strong>.<br />
-8 Similar. but hinary (base 2).<br />
-p If arg is not the integer 1. ,1 lower-case "s" is printed. ("P" is for "plur<strong>al</strong>".) -:P<br />
docs the same tlling. after hacking up an argument (like .. -:.... below): it prints a<br />
lower-case s if tl1e lasl argument' was not 1. -@P prints "y" if tl1e argument is L or<br />
"ies"if it is not. -:@P docs the same thing. hut backs up first.<br />
Example:<br />
(format nil "-0 Kitt-:@P" 3) => "3 Kitties"<br />
-* -* ignores one argo -11* ignores the next n arguments. 11 may be negative. -:*<br />
backs up one arg~ - n:. backs up 11 args.<br />
-1l@. is an "absolute gOlO": it "goes to" the 11th argument.<br />
This directive only affects the "loc<strong>al</strong>" args. if control is within som<strong>et</strong>hing like -{,<br />
-% Outputs a newline. -11% outputs 11 ncwlines. No argument is used.<br />
-& Performs a fresh-fine on the output stream (page 185). -Il& outputs n-1 newlines<br />
after the fresh-line.<br />
-x Outputs a space. -I1X outputs n spaces. No argument is used. This directive is<br />
changing in COMMON USP to mean "hexidecim<strong>al</strong> output" (done like -0); to g<strong>et</strong> the<br />
effect of the old -X. one can use - T, or some construct utilizing -< or -{,<br />
Outputs a tilde. - n -<br />
outputs II tildes. No argument is used.<br />
-newline<br />
Ti1de immediately followed by a newline ignores the newline and any whitespace at<br />
the beginning of the next line. With a :, the whitespace is left in place. With an @,<br />
the newline is left in place. This directive is typic<strong>al</strong>1y used when a fonnat control<br />
string is too long to fit nicely into one line of the program:<br />
(format the-output-stream "-&This is a reasonably -<br />
long string-%")<br />
which is equiv<strong>al</strong>ent to formating the string<br />
"-&This is a reasonably long string-%"<br />
-I Outputs a fonnfeed. -Ill outputs It fonnfccds. No argument is used.<br />
MC:<strong>NIL</strong>MAN:FORMAT 7<br />
23-DEC-83
Fonnat 190 <strong>NIL</strong> Manu<strong>al</strong><br />
In the current implementation. -I wiJI do som<strong>et</strong>hing like try to clear the screen on a<br />
termin<strong>al</strong>. However. this will be changed: the intent of -I is to output the page<br />
separator character. which might be inconvenient to type in or have sitting in tJle<br />
middle of a fonnat· string in ones source file. To g<strong>et</strong> the old behavior. use<br />
-:I-eventu<strong>al</strong>ly -I will be changed.<br />
- T Spaces over to a given column. The fun fonn is -destillatiol1,illcremel1tT. which wi11<br />
output sufficient spaces to move the cursor to column destinatioll. I f the cursor is<br />
<strong>al</strong>ready past column destination. it will output spaces to move it to column<br />
destilla/ioll + iucrelllellf. k. t(lf the sm<strong>al</strong>lest integer v<strong>al</strong>ue k possible. illcrrmelll d<strong>et</strong>~llIlts<br />
to 1. This is implemented by tJ1C format-tab-to function. pagc IlJ6. On certain<br />
streams. this may not actu'llly Olltput sptlces. but may usc cursor positioning: mus.<br />
one should not depend on -'I' "erasing" text by the typing of spaces.<br />
This will be changed slightly to eliminate a common and unsightly fencepost.<br />
Currently -Twill do nothing if the "cursor" is exactly at column drstill<strong>al</strong>ioll;<br />
however. it will be changed S(l that spacing will be done then too.<br />
In the future. -@T will do relative positioning.<br />
-0 -0 uses one argument. and applies it as a function to params. It could thus be used<br />
to. for example, g<strong>et</strong> a specific printing function interfaced to format without defining<br />
a specific operator for that operation. as in<br />
(format t "-&; The frob -vQ is not known.-%"<br />
~~~~<br />
• • ....,..,<br />
'~~~h_~"~~+~"\<br />
•• Wa.I ,.,•• If "" '- I I<br />
The printing function should obey thc conventions described in section 19.6.2. page·<br />
194. Note mat tJ1C function to -0 follows the arguments it will g<strong>et</strong>, because they are<br />
passed in as format param<strong>et</strong>ers which g<strong>et</strong> collected before the operator's argument.<br />
Not in COMMON I.ISP.<br />
-[ -[SlrO -;5Irl -;•.• -;slrl1-] is a s<strong>et</strong> of <strong>al</strong>ternative control strings. The <strong>al</strong>ternatives (caned<br />
clauses) are separated by -; and the construct is terminated by -]. For example.<br />
"-[Siamese -;Manx -;Persian -;Tortoise-SheU -;Tiger -;Yu-Hsiang -]kitty".<br />
The argth <strong>al</strong>ternative is selected; 0 selects the first. If a numeric param<strong>et</strong>er is given<br />
(Le. -liD. then the param<strong>et</strong>er is used instead of an argument (this is useful only if<br />
the param<strong>et</strong>er is It # It). If arg is out of range no <strong>al</strong>ternative is selected. Aftcr the<br />
selected <strong>al</strong>ternative has bcen processed, the control string continues after the -].<br />
-[SlrO-;slrl -; .•. -;slrn-:;de!au!I-] has a default case. If the lasl -; used to separate<br />
clauses is instead -:;. then the last clause is an "else" clause, which is performed if<br />
no other clause is selected. For example. "-[Siamese -;Manx -;Persian<br />
-;Tortoise-Shell -;Tiger -;Yu-Hsiang -:;Unknown -] kitty".<br />
-[-lagOO,lagOl,... ;slrO-lagIO,•.. ;5Irl... -] <strong>al</strong>lows the clauses to have explicit tags. The<br />
param<strong>et</strong>ers to each -; arc numeric tags for the clause which follows it. That clause is<br />
processed which has a tag matching the argument. If -:<strong>al</strong> ,a2 ,bl ,b2,... ; is used, then<br />
the fol1owing clause is ~1gged ilOt by single v<strong>al</strong>ues but by ranges of v<strong>al</strong>ues <strong>al</strong> through<br />
a2 (inclusive), bl through b2, ctc. -:; with no param<strong>et</strong>ers may be used at the end<br />
to denote a default clause. For example. n_[";"+,'-,'.,'II;operator -'A,'Z,'a,'z;l<strong>et</strong>ter<br />
-'O,'9;digit -:;other -)".<br />
MC:NII.MAN:FORMAT 7<br />
23-DEC-83
Nil. Manu<strong>al</strong> 191 Format<br />
-:[jil/sr-;Irur-] selects the ]iI/SC control string if arg is nil. and selects the Ime<br />
control string otherwise.<br />
-@[lfUr-] tests the argument. If it is not nil. then the argument is not used up.<br />
but is the next one to he processed. and the one clause is processed. I f it is nil. then<br />
the argument is used up. and the clause is not proccssed.<br />
(s<strong>et</strong>q prinlevel nil prinlength 5)<br />
(format nil "....@[<br />
PRINlEVEl=-D-]-@[ PRINlENGTH=-D]"<br />
prinlevel pr.inlength)<br />
=> "PRINlENGTH=5"<br />
-R If there is no param<strong>et</strong>er. thcn arg is printed as a cardin<strong>al</strong> English nllmh~r. e.g. four.<br />
With the colon modifier, arg is printed as an ordin<strong>al</strong> number, e.g. fourth. With the<br />
atsign modifier. arg is printed as a Roman numer<strong>al</strong>. e.g. ) V. \Vith hoth atsign and<br />
colon. arg is printed as an old Roman numer<strong>al</strong>. c.g. 1111.<br />
I f there is a param<strong>et</strong>er. tilen it is the radix in which to print the number. The flags<br />
and any remaining param<strong>et</strong>ers arc used as for tile -0 directive. 1ndced, -0 is the<br />
same as -10R. The full fonn here is therefore -radix,millco/,pacichar,co1l1mocharR.<br />
-C arg is coerced t(~ a character code. With no modifiers, -C simply outputs this<br />
character. -@C outputs the character so it can be read in again using the # reader<br />
macro: if there is a named character for it. that will be used, for example<br />
It # \R<strong>et</strong>urn": if not. it will be output like "# / Alt. -:C outputs the character in<br />
- justifies le:,.-I within a field millca! widc. lexl<br />
may be divided up into segments with -;-the spacing is evenly divided b<strong>et</strong>ween the<br />
text segments. \Vith no modifiers. the leftmost text segment is left justified in the<br />
field. and me rightmost text segment right justified: if there is only one. as a speci<strong>al</strong><br />
case, it is right justified. The colon modifier causes spacing to be introduced before<br />
MC:NII.MAN:FORMAT 7<br />
23 .. DEC-83
Fonnat 192 <strong>NIL</strong> Manu<strong>al</strong><br />
the first text segment: the atsign modifier c<strong>al</strong>lses spacing to he added aner the last.<br />
millfJcld. default D. is the minimum Ilumoer of fJd(leliar (def~llllt space) padding<br />
characters to he output b<strong>et</strong>ween each segment. I f the to~lI width needed to satisfy<br />
these constraints is greater than minco/. then millco/ is adjusted upwards in co/inc<br />
increments. co/im· defaults to 1. For example.<br />
(format nil "-lO") => "foo bar"<br />
(format nil "-lO:") => " foo bar"<br />
(format nil "-lO:@") => " foo bar"<br />
(format nil "-lO") => " foobar"<br />
(format nil "-lO:@") => " foobar "<br />
(format nil "$-10... ·." 2.59023)<br />
=> "$•••••• 2.59"<br />
If -" is used within a -< construct. then only the clauses which were compl<strong>et</strong>ely<br />
processed arc used. For example.<br />
(format nil "-15" 'fool<br />
=> " FOO"<br />
(format nil "-15" 'foo 'bar)<br />
=> "FOD BAR"<br />
(format nil "-15" 'faa 'bar 'baz)<br />
=> "FOD BAR SAZ"<br />
If the first clause of a -< is tenninated with -:; instead of -;, then it is used in a<br />
spcd'11 wa:i. All Gf the dau5c5 an: pilJ\:c:i5\:d (suh.i(ct ill -'. uf \.:OUi~C). hut un: fif~i.<br />
one is omitted in performing the spacing and padding. When the padded result has<br />
been d<strong>et</strong>ennined. then if it will fil on the current jine of output, it is output. and the<br />
text for the first clause is discarded. If. however. the padded text wi11 not fit on the<br />
current Jine. then the text for the first clause is output before the padded text. The<br />
first clause ought to contain a carriage r<strong>et</strong>urn. The first clause is <strong>al</strong>ways processed,<br />
and so any arguments it refers to wi1l be used; thc decision is wh<strong>et</strong>her to usc the<br />
resulting piece of text. not wh<strong>et</strong>her to process the first clause. If the -:; has a<br />
numeric param<strong>et</strong>er n, then the padded text must fit on the current line with n<br />
character positions to spare to avoid outputting the first c1ause's text. For example,<br />
the control string<br />
"-% 0" .. -{-
<strong>NIL</strong> Manu<strong>al</strong> 193 Fonnat<br />
-{Sfr'" }<br />
This is an iteration constnlct. The argument should be a list which is used as a s<strong>et</strong><br />
of arguments as ·if for a recursive c<strong>al</strong>l to format. The string Sfr is used re.pcatedly as<br />
the control string. Each iteration can absorb as many clements of the list as it likes.<br />
If before any iteration step the list is empty. then the iteration is tenninated. Also. if<br />
a numeric param<strong>et</strong>er n is given. then there will be <strong>al</strong>most II repctitions of processing<br />
of sir.<br />
-:{str-} is similar. but the argument should be a Jist of slIblists. At each rep<strong>et</strong>ItIon<br />
step one slIbtist is lIsed 415 the s<strong>et</strong> of arguments fbr processing sIr: on the next<br />
rep<strong>et</strong>ition a new slIbJist is uscd. wh<strong>et</strong>her or not an of the lastsuhlisl had heen<br />
processed.<br />
-@{Slr-} is similar to -{slr-}. but instead of using one argument which is a list.<br />
<strong>al</strong>l the remaining arguments are used as the list of arguments for the iteration.<br />
-:@{Slr-} comhines thc features of -:{sfr-} and -@{sfr-). 1\11 the remaining<br />
arguments are used. and each one must be a list. On each iteration one argument is<br />
used as a list of arguments.<br />
Terminating the rep<strong>et</strong>ition construct with -:} instead of -} forces sIr to be processed<br />
at least once even if the initi<strong>al</strong> list of arguments is null (however. it will not override<br />
an explicit numeric param<strong>et</strong>er of zero).<br />
If sir is null. then an argument is used as sIr. }tmllst be a string. and precedes any<br />
arguments processed by thc iteration. As an example, the following are equiv<strong>al</strong>ent:<br />
(apply (function format) (list- stream string args»<br />
(format stream "-1{-:)" string args)<br />
rll1is will usc string as a fonnatting sU'ing. lbe -1 { says it will be processed at most<br />
once. and the -:} says it will be processed at least· once. Therefore it is processed<br />
exactly once, using args as the arguments.<br />
-} Terminates a -f. It is undefined elsewhere.<br />
- A This is an escape construct If there are no more arguments rcmammg to be<br />
processed. then the immediately enclosing -{ or -< construct is terminated. (In the<br />
latter case. the -< formatting is perfonned. but no more clauses are processed before<br />
doing the justification. The _A should appear only at the beginnillg of a -< clause,<br />
because it aborts the entire clause. It may appear anywhere in a -{ construct) If<br />
there is no such enclosing construct. then the entire fonnatting operation is<br />
tcnninated.<br />
If a numeric param<strong>et</strong>er is given~ then tennination occurs if the param<strong>et</strong>er is zero.<br />
(Hence _A is the same as- # A.) If two param<strong>et</strong>ers are given. tennination occurs if<br />
they arc equ<strong>al</strong>. If three are given. tennination occurs if the second is b<strong>et</strong>ween the<br />
other two in ascending order.<br />
If - A is used within a -:{ construct. thcn it merely tcnninates the current iteration<br />
step (because in the standard case it tests for remaining arguments of the current step<br />
only); the next iteration step commences immediately. To tcnninate the entire<br />
MC:<strong>NIL</strong>MAN:FORMAT 7<br />
23-DEC-83
Fonnat 194 <strong>NIL</strong> MC:tnu<strong>al</strong><br />
iteration process. use -: A<br />
•<br />
-IIG This is the old fonn of -n@.. above. In COMMO~ I.1SI>. -G is a floating-point<br />
fonnat directive derived from I·URTRAN G fonn<strong>al</strong>. New code should use -@ •.<br />
-F Reserved for fixcd.;field floating-point fonnat.<br />
-E Reserved for exponenti<strong>al</strong> floating-point fi)rmat.<br />
-$ This is 1101 y<strong>et</strong> defilled ill N 1'-<br />
- rdig .ldig jir/d,ptldclwr$ prints arg. a flunum. with exactly rdi/!. digits after the<br />
decim<strong>al</strong> point. The def4tull for rtit!!, is 2. which is convenient fill" printing "mounts of<br />
money. At least /dip, digits will be printed prel'eding the decim<strong>al</strong> point: leading zeros<br />
will be printed if there would be fewer thanldig. The default for ldig is L The<br />
number is right justified in a field /irld columns· long. padded out with padehar. The<br />
colon modifier means that the sign character is to be at the beginning of lhe field.<br />
before the padding. rather than just to the left of the number. 'Inc atsign modifier<br />
says th<strong>al</strong> the sign character should <strong>al</strong>w~ys be output.<br />
In some implementations. if arg is unreason~lbly large. it will be printed in<br />
-field."padchar@A format: i.e. it will be prine'cd right-justified in the specified field<br />
width. This wi11 not happen in the Maclisp implementation, because the range<br />
provided by Honums is not extremely large.<br />
- \ This is not rc<strong>al</strong>ly an operator. If one desires to use a multi-character format operator,<br />
it may oe piaced within baCk siash es, as In -\now\ tor tile now operator. See page<br />
188.<br />
19.6.2 Defining your own<br />
Everything in this section is defined in the MACL1SP and <strong>NIL</strong> implementations of format only.<br />
d<strong>et</strong>1ne-tormat-op<br />
This may be used in two fonnats:<br />
(defi ne-format-op operator varlist body-forms. .• )<br />
and<br />
(defi ne-format-op operator character)<br />
The operator may be a character. suing. symbol. or fixnum code for a character (in <strong>NIL</strong>,<br />
it is coerced using the string function. page 112). Whichever, it is canonic<strong>al</strong>ized (into<br />
upper case) and will be interned into the same package which format resides in. For<br />
example. the format operator for tilde could be defined as<br />
(define-format-op \- '\-)<br />
For the first format. the type of operator is d<strong>et</strong>ennined by decoding varlis!, which may<br />
have one of the following formats:<br />
(params-var)<br />
An operator of exactly zero arguments; params-var will g<strong>et</strong> bound to the<br />
param<strong>et</strong>ers list<br />
(params-l'ar arg-vary<br />
An operator of exactly one argument; params- var will g<strong>et</strong> bound to the<br />
MC:<strong>NIL</strong>MAN;FORMAT 7<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 195 Fonnat<br />
param<strong>et</strong>ers list. and arg- var to the argument.<br />
(params-var . args-var)<br />
An operator of a variable number of args: paramS-l'ar will g<strong>et</strong> bound to the<br />
param<strong>et</strong>ers list. and args-var to the remaining arguments to format (or to the<br />
recursive -{ arguments). The operator should r<strong>et</strong>urn as its v<strong>al</strong>ue some sublist<br />
of args-l'ar, so that format knows how many were used.<br />
A definition for the appropriate function is produced with a bvl derived from the variables<br />
in varUst and a body of body-forms. (The argument ordering in the function produced is<br />
compatible with that on the l.isp Machine. which is arg-l'ar (if any) first, and then<br />
params-var.)<br />
standard-output<br />
Variable<br />
Output from format operators should be sent to the stream which is the v<strong>al</strong>ue of<br />
standard - output.<br />
format: eo 1 on-f1 a9<br />
Variable<br />
format:ats1gn-flag<br />
Variable<br />
These tell wh<strong>et</strong>her or not we have seen a colon or atsign respectively while parsing the<br />
param<strong>et</strong>ers to a format operator. They are only bound in the toplcvel c<strong>al</strong>l to format, so<br />
are only re<strong>al</strong>ly v<strong>al</strong>id when the format operator is first caned: if the operator does more<br />
param<strong>et</strong>er parsing (like -[ does) their v<strong>al</strong>ues should be saved if they will be needed.<br />
Tne params are passed in as a iist ThIS iist. however, may be temporary storage only: one<br />
should not <strong>al</strong>low it to be "passed back" from the c<strong>al</strong>l to the fonnat operator without being copied<br />
first Also, it is recommended that fonnat params be referenced with elt, and their length<br />
obtained with length, in order that they may be reimplemcnted as some sort of sequence in' the<br />
future (which will probably be a stack-<strong>al</strong>located vector for <strong>NIL</strong>).<br />
Conceptu<strong>al</strong>ly, format operates by perfonning output to some stream. In practice, t.his is what<br />
occurs in most implementations; in Mac1isp, there are a few speci<strong>al</strong> SF As used by format. This<br />
may not be possible in <strong>al</strong>l implementations, however. To g<strong>et</strong> around this, format has a<br />
mechanism for <strong>al</strong>lowing the output to go to a pseudo-stream, and supplies a s<strong>et</strong> of functions<br />
which will interact with these when they are used.<br />
format-tyo character<br />
tyos character to the format out.put destination. character may be either an object of type<br />
character, or the fixnum code for a character.<br />
format-prine object<br />
princs objecl to the format output destination.<br />
format-pri n1 object<br />
prin 1 s frob to the format output destination.<br />
MC:<strong>NIL</strong>MAN:FORMAT7<br />
23-0EC-83
Format 196 <strong>NIL</strong> Manu<strong>al</strong><br />
format-lcprinc string capit<strong>al</strong>ize?<br />
This outputs sIring. which must be a string or symbol. to the format output destination<br />
in lower-case. 1f capit<strong>al</strong>ize? is not nil, then the first character is converted to upper case<br />
rather than lower.<br />
format-terpri<br />
Docs a terpri to the format output destination.<br />
format-charpos<br />
format-linel<br />
R<strong>et</strong>urn the charpos and linel of the format output destination. Since in the MACI.lSP<br />
implementation multiple output destinations may be implicitly in use (via outfiles, for<br />
instance). this attempts to choose a representative one. The tennin<strong>al</strong> is preferred if it is<br />
involved.<br />
format-fresh-line<br />
This performs the fresh-line operation ~o the default format destination. 'The hair<br />
involved in this is mostly subsumed by the fresh-line function in NIl.<br />
for.nat- tab -to destillation &option<strong>al</strong> increment<br />
rIbis implements - T to the current format destination (q.v.). In <strong>NIL</strong>, it wi1l utilize the<br />
:tab-to message if that is supported. Otherwise. if it can d<strong>et</strong>ermine the "current position"<br />
of the format destination. it will output the proper number of spaces; <strong>al</strong>l else failing, two<br />
~paC'~C\ will hp output.<br />
format-formfeed<br />
Performs a formfeed on the format output destination. In <strong>NIL</strong>, this will send the'<br />
:formfeed message to the stream if that is supported. the :clear-sereen message if that is<br />
supported, otherwise just output the page separator character. The :formfeed message is<br />
supported by a number of <strong>NIL</strong> streams, and is designed for just this use.<br />
format-flatc<br />
(format-fl ate IannI lann2 ... fonnn)<br />
The fonns are ev<strong>al</strong>uated in . an environment similar to that used inside of format: the<br />
various format output-performing routines such as format-tyo and format-prine may be<br />
used to "perfonn output". In <strong>al</strong>l but the MULTICS MACLISP implementation, standardoutput<br />
will be a stream which simply counts the characters output-it will only support<br />
the :write- char operation.<br />
MC:NJLMAN:FORMAT 7<br />
23-DEC-83
ifSY'· '''7<br />
r • M<br />
ttntn .,<br />
<strong>NIL</strong> Manu<strong>al</strong> 197 Querying the User<br />
19.7 Querying the User<br />
The following routines are built on the fquery function, which is modeled after that of LISP<br />
~1ACIIl~E LISP. fquery is complicated and subject to change, however, and is not jtself<br />
documented here. Of the following routines, y-or-n-p and yes-or-no-p are defined by<br />
C07\1~10~ LISP: the others are not.<br />
y-or-n-p &option<strong>al</strong> message stream<br />
This prints message to stream (which defaults to the v<strong>al</strong>ue of query-io), and then reads a<br />
character from stream. It r<strong>et</strong>urns t or nil depending on wh<strong>et</strong>her the character signified a<br />
posllIye or negative response: space and rllbollt are accepted in place of y and n.<br />
Because it is so easy to gel a mistaken response fhnn this routine. it should be lIsed for<br />
anticipated questions only.<br />
Because it is used for both input and output, Siream must be bi-direction<strong>al</strong>.<br />
yes-(,.'-no-p &option<strong>al</strong> message stream .<br />
This is similar to y-or-n-p. but requires a more compl<strong>et</strong>e answer. Typeahead to stream<br />
is flushed (with clear-input. page 183), and it feeps. before rcading a compl<strong>et</strong>e "yes" or<br />
"no" followed by a new1ine.<br />
format-y-or-n-p jhmuJ/-slrill1!, &rcst jiJnl1<strong>al</strong>-args<br />
Most the time when y-or-n-p is used, people seem to want to lise a fonnat string with<br />
some arguments. This docs that. Input and Olltput is done to query-ia. Otherwise. it<br />
behaves like y-or-n-p.<br />
format-yes-or-no-p fonnat-string &rcst fomrat-args<br />
Similar.<br />
19.8 Filesystem Interface<br />
The <strong>NIL</strong> filcsystem interface is designed to <strong>al</strong>low it to refer to more than one filesystem. The<br />
names of files are not represented as just strings· or lists of components. but are objects of type<br />
pathname. The pathname objects for different filesystems or hosts would be of different types,<br />
and operations on files in the filesystem are perfonned with respect to that type. For instance. we<br />
have under development facilities to <strong>al</strong>low use of the filesyslems of TOPS-20 and ITS through<br />
CHAOS~ET. At the moment, only the loc<strong>al</strong> VMS filcsystem is supponed.<br />
MC:NII MAN:NEWIO 27<br />
23-DFC-83
Filcsystelll Interface<br />
198<br />
19.8.1 Pathnames<br />
A pathname has six criteri<strong>al</strong> components.<br />
host<br />
This component <strong>al</strong>ways contains an object which describes the filesystem the pailiname<br />
refers to. 1\11 pathnames have such a component: no pathname may be fonned without<br />
such a component. 'l1lUs, pathname interpr<strong>et</strong>ation is <strong>al</strong>ways performed with respect to<br />
some host.<br />
device<br />
This is nonn<strong>al</strong>1y a string. naming a device.<br />
directory<br />
1\ string naming a dirC'ctory. or a list of strings. if the directory is structured (that is. if<br />
the pathname is in a subdirectory).<br />
name<br />
/\ string. the "primary" or· "root" name of the file.<br />
type<br />
1\ string. thC' "type" of the file. This is not necessarily as tJle C'x/C'lIsion which wil1 be<br />
used to fonn the host~specific pathname string~ e.g., for a VMS filesystem. a file type of<br />
LIS P corresponds to the C'xtension LS P.<br />
version<br />
Thi~ i~ th(' v('~inn nf tht' pathl1atTl~: H!m~Hy it is an integer.<br />
1\ p<strong>al</strong>hname need not refer to an actu<strong>al</strong> file in a filesystem. nor need <strong>al</strong>l the components<br />
(other than the host) be present. An unspecified component is represented by nil. Such a<br />
component may be supplied by later defaulting operations. Components may <strong>al</strong>so contain certain<br />
keywords which arc interpr<strong>et</strong>edspcciaUy:<br />
:wifd<br />
A "wildcard" component.<br />
: newest<br />
:oldest<br />
These are only applicable to the version component of a pathname. They cause the<br />
reference to the filesystem to refer to the newest or oldest version present Only : newest<br />
is actu<strong>al</strong>ly supported by the VMS filesystem interface.<br />
:unspecific<br />
I f any component in a pathname has this as its v<strong>al</strong>ue. then the pathname does not refer<br />
to a specific file in the filesystem~ but rather to the group of files which match the other<br />
components. This is nonn<strong>al</strong>ly only used for the type or version components. so that one<br />
may refer to the entire group of files with the same device. directory, and name. This<br />
docsn °t have any use in <strong>NIL</strong> y<strong>et</strong>; when ~}L pathnames gain the ability to have arbitrary .<br />
attributes (properties) associated with them, it will be significant.<br />
:implied<br />
I f a path name has this as a componC'nt. it means that the device component is a logic<strong>al</strong><br />
name which will supply the v<strong>al</strong>ue for that component l11is is llsed as a pbceholder for<br />
"pathname merging tt • All components other than the host and device components may<br />
MC:NII.Mi\N:NEWIO 27 23~I)EC .. 83
a'TSSr<br />
Sf tin<br />
<strong>NIL</strong> Manu<strong>al</strong> 199 Fi 1csystem 111 terrace<br />
wke on this as their v<strong>al</strong>ue.<br />
:relative<br />
This can only occur within a structured directory component. It is used in the<br />
representation of VMS rooted directories. For instance, the V\1S pathname<br />
_DBAO: [N I l259 .] parses into a pathname with the string "__ DBAO" as its device<br />
component. and the list (" NI l259" . : re 1 at; ve) as its directory component. <strong>NIL</strong><br />
uses this in pathname merging.<br />
:elipsis<br />
This is used in representing things like nil $ d; s k : [n i 1 ... ].<br />
pathname \,,:mlld produce a directory component of ("NI L" .<br />
prohably be flushed in t~lvor of utilizing just :wiJd instead.<br />
Parsing that into a<br />
:elipsis). It will<br />
19.8.1.1 Pathname Functions<br />
pathname thing<br />
thing is coerced into a pathname.<br />
If it is a pathname, it is r<strong>et</strong>urned.<br />
If it is a list. then it is assumed to be a \L\CI lSi> namc1ist: interpr<strong>et</strong>ation of this, and<br />
MACl.IS}> compatible pathname handling. is discussed in
Filcsystem Interface 200 N II. Manu<strong>al</strong><br />
Under VMS, this is obtained by translating the logic<strong>al</strong> name SYSSLOGIN.<br />
user-work.1 ngd i r- pathname &oplion<strong>al</strong> host<br />
R<strong>et</strong>urns the user's working direclory, as a pathname:<br />
components will be unspecified.<br />
the name, type, and version<br />
For V\1S.<br />
this is obtained from the RMS default directory string. and the 5YS$O 15K<br />
logic<strong>al</strong> name. Note that the RMS default is copied from the command interpr~ter when<br />
the !"II process is created: temporarily exiting the !\H. and changing the default wiH 110t<br />
change the v<strong>al</strong>ue of this.<br />
user-scratchd 1 r- pathname &option<strong>al</strong> host<br />
R<strong>et</strong>urns, as a p<strong>al</strong>hnamc, the directory of the directory which should be used hy programs<br />
for writing "scratch" fiJes.<br />
The loc<strong>al</strong>-vms host uses the v<strong>al</strong>ue of the logic<strong>al</strong> name SYS$SCRATCH if th<strong>al</strong> exists.<br />
otherwise the user's home directory. If for some reason the device field is absent<br />
SYS$OISK is supplied. Note that the v,.lue of the logic<strong>al</strong> name is copied from the<br />
command interpr<strong>et</strong>er when the 'II is created. Temporarily exiting from the 'II "nd<br />
changing the logic<strong>al</strong> name definition will have no effect.<br />
1 n 1 t - f 11 e - pat h name program-name &option<strong>al</strong> host<br />
This r<strong>et</strong>urns the pathn
<strong>NIL</strong> Manu<strong>al</strong> 201 FilcsySlclll I ntcrfacc<br />
perfonned, such as pathname parsing.<br />
merge-pathname-defaul ts pathllame &option<strong>al</strong> defaults de/aul!-Iype defoul!-version<br />
lbis is the main merger. p<strong>al</strong>hname may be anything coercible to apathname. defaults<br />
may be a pathname defaults object. a path name. or a string or symbol (which will be<br />
coerced to a pathname first). de/aull-type and de/aull-version may be whatever is <strong>al</strong>lowable<br />
for types and versions.<br />
If it is necessary. p<strong>al</strong>hname will be, parsed with respect to a host d<strong>et</strong>cnnined from<br />
de/aults. If the directory field of it is missing. then that wiJI be supplied by de/aults.<br />
Therc is somc qucstion as to what shollld happcn if thc dcvicc field of p<strong>al</strong>llllOll1e is<br />
Il1ISSl11g: cllrrcIllI~. it b simpl~ filled in from I.I£:t,'wlls. In the I -isp Machine<br />
implcmcntation of this function. it is supplied as thc dcf;llIlt dcvicc for thc host (perhaps<br />
inconsistcntly. for instance only when parsed from a string?): probably what should<br />
happen is that wh<strong>et</strong>hcr the devicc comcs from de/ilulls or not is dctcrmincd by thc host.<br />
so that it would if thc dcvices wcre re<strong>al</strong>ly structured (with directories in them <strong>et</strong>c.). and<br />
would not otherwisc (wh.ch in I -isp Machine l.isp appears to he mainly for the sake of<br />
the ITS operating system).<br />
If p<strong>al</strong>/mOille has a name supplied, then if the type and version of the resuning pathname<br />
are defaultcd from de/aull-type and default-version, as necessary. Otherwise, the name.<br />
type. and version are defaulted from dc/aulls. Thus:<br />
(merge-pathname-defaults<br />
"[nil.vaz]fcc" "zyz$disk:[gzb]zz.1:;p:3" "'f .. ,.. 1 " ,<br />
" ... .,) I J<br />
, => #<br />
(merge-pathname-defaults<br />
"[nil.vas]" "sysSdisk:[gsb]zz.lsp;3" "vasl")<br />
=> # #<br />
In the above, it is worth noting that It =" as a pathname component is used as a<br />
placeholder for an unspecified component, and that a file type of lisp is mapped (by the<br />
VMS pathname code) into an extension of Isp, and vas I to vas. The specifics of the<br />
syntax and file-type/extension mapping are described elsewhere.<br />
The default v<strong>al</strong>ue of default-version is :newest. The default v<strong>al</strong>ue of default-type is "lisp";<br />
however, it is highly recommended that this not be depended upon, as it may be changed<br />
to come from defoults.<br />
Here are some of the pathname defaults in use in <strong>NIL</strong>.<br />
-1 oad-pathname-defau1 ts* Variable<br />
This is used to provide pathname defaults for load, compile-file, and any similar<br />
functions. It is initi<strong>al</strong>ized to the user's working directory with name F 00 and type lIS P<br />
(sec user-workingdir-pathname. page 200).<br />
MC:<strong>NIL</strong>MAN:NEWIO 27<br />
2J-DEC-83<br />
-: "" " ":;;.;.>, .;: ", "'.' , "<br />
'':''~: ". ' .. - . i,~ ",- ';'.~-: "" '--.. '..,,',:' " -- .. - , . "-"
FHt'system Interface . 202 Nil. Manu<strong>al</strong><br />
*defaul t-pathname-d<strong>et</strong>aults.<br />
Variablf<br />
This provides super-defaults for anything that needs them. such as open. with-open-file,<br />
and parsing a pamname· string out of context. It is initi<strong>al</strong>ized to the user's working<br />
directory with name FDD and type LISP (see user-workingdir-pathname. page 200) ..<br />
*scratch-pathname-dataul ts*<br />
Variable<br />
This is used by things which must write out "temporary" files. Things which use this<br />
should not modify it: it should be left to the user to s<strong>et</strong> default pathnames for hosts<br />
(primarily for the sake of the device and directory) to say where such files should be<br />
written. See user-scratchdir-pathname. page 200.<br />
For example. the current '" compile function creates a file named aaafoo.vas. and<br />
supplies the de\icc and directory from *scratch - pathname-defaults*.<br />
19.8.2 Opening Files<br />
Files arc opened with the open function (page ISO). or with-open-fite (page 181). and may<br />
he dosed wilh~lose (rage 181). open hy default assumes that the open is a reference to a file.<br />
so coerces its fit st argument to a pathname. and then creates a Slre~lln to the specified file in the<br />
filesystem. <strong>NIL</strong> currently employs only two modes of file opening. These are :ascii and :byte<br />
modes.<br />
:asc;j will cause the file to be written as variable-length records. with record-attribute of<br />
carriage-r<strong>et</strong>urn. The existing disk 1/0 code docs not have the intelligence to de<strong>al</strong> with records<br />
longer than 512 hytes. however. so is forced to tenllinatc records when that limit is reached. To<br />
compensate. so that spurious newlines do not g<strong>et</strong> inserted into LISP files. recordsexactJy 512 long<br />
arc assumed to not actu<strong>al</strong>ly be tcnninated. but "continued tt with the next record. when read as<br />
input<br />
:fixnum simply uses fixed-length S12-byte records; this is what vas 1 files use.<br />
fs:close-<strong>al</strong>'-f1'es<br />
In case you do mess up and lose track of some files, this will close <strong>al</strong>l open files (which<br />
have been re<strong>al</strong>ly opened as streams, not just kludgey temporary opens). Every known<br />
host object is supposed to keep track of <strong>al</strong>l streams which it has open. in such a way as<br />
to be secure against timing screws, so that this may at least be done.<br />
Doing (exhibit fs:.host-instances*) should give one a handle on the open files, as the<br />
host instances should point to the filcs they have open. fs:*host-instances* is the list of<br />
<strong>al</strong>l known hosts, and is used to (among other things) drive host-name lookup.<br />
MC:NII.MAN:NEWIO 27<br />
23-1)J-=C-83
~II. Manu<strong>al</strong> 203 Fiksyslcm Intcrface<br />
19.8.3 Other File Operations<br />
probe-f11 e p<strong>al</strong>hname<br />
If p<strong>al</strong>hname (which is coerced to a pathname with the pathname function) can be opened,<br />
its truename is r<strong>et</strong>urned; otherwise. nil is r<strong>et</strong>urned. This may be used to see if p<strong>al</strong>hname<br />
exists and is accessible. (If a file protection error occurs, probe-file r<strong>et</strong>urns nil, <strong>al</strong>though<br />
that may change. as the intent is to see if the file exists.)<br />
~ote file-length and filepos are missing from <strong>NIL</strong><br />
All of the remaining functions in this scction de<strong>al</strong> with either a strcam. or with a pathname.<br />
ror thc fi.mll cr. thc) perform the operation Oil thc open strcam: f(lr the 1.mcr. on the ilk in the<br />
filcsystcm. which may invohc opcning the file tcmporarily. At present. nonc of thcm work on<br />
streams. A futurc edition of the filesyslem code will contain more code written in IISP. and be<br />
much more versatile in this regard.<br />
For the fut ..:tions which arc dcscribed as rcturning an error description. this is prohahly a<br />
string. but may changc to be a more complicated object in the future. (That objcct should.<br />
howc\cr. h
Filcsys(em Interface 204 <strong>NIL</strong> Manu<strong>al</strong><br />
19.8.4 File Matching<br />
<strong>al</strong>l files list-ofpathnames<br />
Rcturns a list of pathnamcs matching <strong>al</strong>l of those in Iist-ofpafhnames. This is done. of<br />
coursc. by appending tog<strong>et</strong>her the lists of pathnames which match each of the pailinames<br />
in list-ofp<strong>al</strong>hllames.<br />
By convcntion. this matches over <strong>al</strong>l those components not specificd in each pathname.<br />
V\1S docs not <strong>al</strong>low matching <strong>al</strong>l devices. howevc('. so the device should be specified. or<br />
will be defaulted from somewhere (where? rms dcfault but it shouldn't be). Newest<br />
\ersinns can be matched <strong>al</strong>so. by lIsing the appropriate patJlname synt~tx. Note that clipsis<br />
spccifk<strong>al</strong>ions in directories. and star spccificati(}n~ in names. <strong>al</strong>l work (ft,rtuittlllsiy.<br />
p('rhap~. hu( Lhey work): e.g .. (aUfUes "[nil...]286*.*:'" r<strong>et</strong>urns a list (If pathnamcs of<br />
tJle files with highest version number of· a1lthe files in the 'II. hierarchy with first three<br />
char~lclers of their namc being "286".<br />
mapa 11 files jUllctioll Iist-(~r-pathllC1mes<br />
C<strong>al</strong>ls fUllctiol1 on each pathnamc whkh matches pathnamcs in list-ofp<strong>al</strong>hllames. 'lois is<br />
esscmi,llIy equiv<strong>al</strong>en( to<br />
(mapc jUl1cliull (a 11 fi 1 as Iisf-o.fp<strong>al</strong>lllloml's»<br />
but c<strong>al</strong>Js junction on each as it is generated rather than consing up the list<br />
In fact. atlfiles is imp1emented in tenns of mapaJlfiles.<br />
map<strong>al</strong>ffires (and hence <strong>al</strong>lfiles) accept a single symbollstring/pathname in place of a list It is<br />
unclear what should be done about this: it is (currently at least) of no usc to <strong>NIL</strong> to de<strong>al</strong> with<br />
multiple specifications at oncc. and in fact· the origin<strong>al</strong> aU files function in MULTICS MACLISP did<br />
not· takc a list. but only a single pathname.<br />
There is <strong>al</strong>so no kludgy testing in <strong>NIL</strong> such that if a namelist is specified it must be a fullyspccified<br />
nameHst (insofar as explicit "*" components arc spccified). Thus using a namclist as a<br />
single pathname will be interpr<strong>et</strong>ed as a list of pathnames. potenti<strong>al</strong>ly resulting (incorrectly) in a<br />
match over <strong>al</strong>l the files on the current device... (That was the reason for the ,k,ludgey check in<br />
MACUSP. you see ... )<br />
19.8.5 Loading Files<br />
load filename &key :verbose :package :s<strong>et</strong>-default-pathname :static :default-pathname<br />
:characters :binary :defaufts :print<br />
:verbose<br />
Boolcan: print out lots of gubbish about loading. Default is v<strong>al</strong>ue of *Ioadverbose-.<br />
:package<br />
override the package specification (if any) obtained. from the file.<br />
:s<strong>et</strong> -default - pathname<br />
Boolean: s<strong>et</strong> the default p<strong>al</strong>hname of the pathnamc-defaults used (see :defaults<br />
and :defauft-pathname. below). Default is v<strong>al</strong>ue of *Ioad-s<strong>et</strong>-default-<br />
MC:NII.MAN:NEWIO 27<br />
23-I)EC-83
.-<br />
I\ II. Manu<strong>al</strong> 205 File~yslell1 Interface<br />
pathname •.<br />
:defaults<br />
Specified pathname-defaults to use in place of the v<strong>al</strong>ue of .Ioad-pathnamedefaults..<br />
(1bis one isn't in COM:vtO~ LISP. Not clear it should be heavily used,<br />
but i can see it has application.)<br />
:default-pathname<br />
Use this for defaulting. in preference to the pathname-defaults. The defaults are<br />
still s<strong>et</strong> in the defaults specified by :defaults (or its absence).<br />
:characters<br />
:binary<br />
Boolean. :binary t implies that the file is a \'ASI. me: :CII:\R:\C ITkS T implies<br />
that the file is LISP text. By default, the file is examined to d<strong>et</strong>ellnine which it is.<br />
And, if no type is specified in filcnamc, first a file with type vast and then a file<br />
with type lisp will be looked for.<br />
:static<br />
Boolean: says to load tile file into the static heap. Default is v<strong>al</strong>ue of .Ioad - instatic<br />
- area •.<br />
:print<br />
Boolean: if not nil. says that the results of ev<strong>al</strong>uation of fonns in the file are to<br />
be printed. Default is nil, and it probably doesn't work anyway: certainly not for<br />
vasl files.<br />
19.8.6 File Attribute Lists<br />
Not too much d<strong>et</strong>ail y<strong>et</strong>... However. it's necessary to use it.<br />
If. on the first line of a source file the characters ft •••"<br />
appear. then the text from the first "•<br />
• _" to the next is parsed as a file attribute /iSI. (Funnyness with multiple lines? Well, anyway, it<br />
works easily on one line.) This text is logic<strong>al</strong>ly a list of keyword/v<strong>al</strong>ue pairs, witiI the v<strong>al</strong>ues<br />
being either single v<strong>al</strong>ues or lists of v<strong>al</strong>ues. The entire construct is made invisible to the<br />
processing language by being placed within its commenting construct<br />
; -.- Mode:Lisp; Package:Compiler; Base:l0; Readtable:<strong>NIL</strong> -.-<br />
might occur as the first line in a <strong>NIL</strong> compiler source file. It says that the mode of the file is<br />
lisp (this being for the benefit of text editors), and that the file should be read and processed in<br />
the compHer package, decim<strong>al</strong> radix, and using the <strong>NIL</strong> readtable. "Lists" of v<strong>al</strong>ues are provided<br />
for by separating the individu<strong>al</strong> items by commas, as in<br />
; -.- Mode:Lisp; LSB:ppdef.pr<strong>et</strong>ty-print-definition -.-<br />
The parsing of tokens in such a construct is pr<strong>et</strong>ty rudimentary and crufty. but essenti<strong>al</strong>ly things<br />
are symbols except for a series of digits (option<strong>al</strong>ly followed by a decim<strong>al</strong> point) which is a<br />
decim<strong>al</strong> integer.<br />
File attributes typicany translate into some speci<strong>al</strong> binding environment needed for the<br />
processing of the file (in some context). '(be following arc pre-defined in <strong>NIL</strong>:<br />
package I'llckagr-namc<br />
The file is processed in the package named package-name.<br />
MC:NII.~1"N:NEWIO 27<br />
23-I)FC-83
Filesystem Interface 206 <strong>NIL</strong> Manu~tl<br />
readtable readlablC'"'lJamp<br />
The file is read in using the readtable named readtable-name.<br />
naming. is dcscribed in section 16.3. page 126.<br />
Syntax. and readtablc<br />
base radix<br />
Binds both the input and output radices. no matter what those damned variables are<br />
named.<br />
radix radix<br />
For those who are confused by base and will be cvcn moreso when the variable is<br />
namcd .base*.<br />
patch-file y('s·0r-110<br />
If yes"or-Ilo is yes (it shouldn"t be specified otherwise). then a variable pruclaiming the<br />
patch-filc-ness of this file is buund. so th~lt various things can see jt and be clc\cr. like<br />
the helpful function which· warns you about rcdcfining a function dcfined by sumcunc elsc<br />
in anothcr file. (said functiun not existing y<strong>et</strong>).<br />
Isb moc/u/r-nnme,s),slem-llt.1me<br />
This is defined by Isn [4]. not NIl. (q.v.).<br />
When a file attribute list c is parsed. the attribute names arc kcywords, and the v<strong>al</strong>ues are<br />
either keywords or intcgers (or lists of keywords or integers).<br />
: f11 e-p 11 st p<strong>al</strong>/mame<br />
If pnf/mnm(> r:m h(' {\p~n~d~ tf1('n this r~tl!ms a d!s~mbodi~d propt'rty list ~':ith the ft!~<br />
attributcs in the cdr. and the lruename of the file in the car. Otherwise. it r<strong>et</strong>urns nil.<br />
This probably should be renamed :file-attribute-list.<br />
fs : proces s .... 1 n -1 oad-env 1 ronment plis! [unct p<strong>al</strong>llllame &rcst args<br />
plis/ should be a parsed file attribute list (with ane\'ell number of clements: the cdr of<br />
what is r<strong>et</strong>urned by the :file-plist message). p<strong>al</strong>hname should be the pathname which the<br />
file attributes were obtained from.<br />
The environment which is specified by that attribute list is established. and then. fimct<br />
c<strong>al</strong>led with arguments of p<strong>al</strong>hname and whatever args were given.<br />
This is what is used by both load. and the compiler. It enables a stable interface to how<br />
bindings and other environment modifications are obtained from the file attributes.<br />
Examination of the source code (the file [<strong>NIL</strong>. IO]PATHN. LSP) will show the convention<br />
which is used for defining addition<strong>al</strong> file attributes. It is basic<strong>al</strong>ly an extension of that defined by<br />
LISP MACI UNE USP.<br />
MC:NII.MAN:NEWIO 27 2] .. DEC .. 83
------------:--:---:-~::::::::_-_-_-_-:::::::::..--:.~.~~IiiI'~.-~:rilllll ·11'_lilt lin.' _sil·__••••<br />
lIf#~~,i~;:h....,~r·,,"-IIIIIIIiIIIiI-... .....<br />
<strong>NIL</strong> Manu<strong>al</strong> 207 Filesystem Interface<br />
19.8.7 Intern<strong>al</strong>s for Vl\1S Record Man~lgement Services<br />
l':II. contains some primitive routines and datastructure definitions with which I/O can be<br />
performed entirely from LISP code. In fact. recently a speci<strong>al</strong>-purpose stream type was written so<br />
that me editor could do very fast record I/O. This is the loc<strong>al</strong>-vms-editor-stream stream,<br />
which is in the source file nil$disk:[nil.io]vloc<strong>al</strong>.lsp, and can serve as an example of<br />
how some of these things arc used. Some of the other primitives which interface to the filesystem<br />
are <strong>al</strong>so written in I.ISP, but arc hidden from the stream code by a function<strong>al</strong> interface~ these arc<br />
in the file nil$disk:[nil.vmlisp]vmsfile.lsp.<br />
19.8.7.1 Data Structures<br />
The dlltastructures lIsed for R\fS fab. rab. nam. and xah hlocks arc <strong>al</strong>l just simple bit vectors<br />
of the appropriate si/e. There arc liSP macros and constants defined to de<strong>al</strong> with them: these<br />
definitions \\ ere generated from the VMS \fD} files. For instance. (si:fac$b_rfm jl~/b) r<strong>et</strong>urns the<br />
record-fomwt field of a fah. (s<strong>et</strong>f (si:fab$b_rlm ii/b) si:fab$c_ var) s<strong>et</strong>s it to the code which says<br />
that the record format is variable-length rec{lrds. Gener<strong>al</strong>l). fields of type byte and word arc<br />
tCtched/s<strong>et</strong> as fiXIlUIllS. longword and quadword fields arc extracted ilHo (freshl~ conscd) simplebit-vectors<br />
of the appropriate length; the s<strong>et</strong>ting operation replaces the bits of the structure (in the<br />
right position) with the bits of the object it is being s<strong>et</strong> to, so the operation is in\'enib1c. See<br />
<strong>al</strong>so the files nil $ dis k : [n i 1 . vm 1 is P ] rms s t r. 1 s p and<br />
nil$disk:[nil.vmlisp]rmssub.ls~<br />
The following routines create these structures:<br />
si:maKe-fab<br />
si:maKe-rab<br />
si:mak,e-nam<br />
s1 :maKe-xab code length<br />
Because xab structures vary, one must specify the xab code and its length. For instance,<br />
(si:make-xab si:xab$c_fhc si:xab$c_fhclen)<br />
creates a xab block used for hacking fi1e header stuff.<br />
Resources are defined for fab, rab, nam, and xab structures:<br />
s1:fab<br />
si:rab<br />
s1:nam<br />
MC:NII.MAN:NEWIO 27
FilcsYS1CIl1 J J1{rrf~lcr<br />
208<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
s 1 : xab code length<br />
Because xab structures can vary in code and length. they must be supplied to the<br />
resource constructor. The appropriate constants are defined. of course. For instance.<br />
(using-resource (si:xab xabdat si:xab$c_dat si:xab$c_datlen)<br />
. . .)<br />
binds xabdat to a xab structure used for obtaining creation and revision dates.<br />
19.8.7.2 Rl\1S and Related I-Iacking<br />
Thr following flln
;\ II. Manu<strong>al</strong> 209 Termin<strong>al</strong> 1/0<br />
51 : rm5$truncrab<br />
51: rm5$update rab<br />
51:rm5$wa1t rab<br />
51 : rm5$read rab<br />
51: rms$5pace rab<br />
51: rm5$wr 1 te rab<br />
51: rm5$enter fab<br />
51: rm5$par5e Jab<br />
51: rm5$remove Jab<br />
51: rm5$rename Jabl Jab2<br />
51:rms$5earch Jab<br />
s 1 : rms Ss<strong>et</strong>dd 1 r lIl'w·dirc('/ory-.\pccijicatioll<br />
R<strong>et</strong>urns. and mayhe updates. the RMS default directory. If ncw-dircctory-spccification is<br />
iii:' ta'ic ~\rs dcf~lilt is nut mGdlfkd: i.lthciWisc. it is SCi to iiCn'-dii t'dUi j -Spn ifiud i(JiJ.<br />
which must be a simple string. This is a fairly direct interface to the SYS$SETDDIR<br />
system service.<br />
If the r<strong>et</strong>urn status is not norm<strong>al</strong> (the v<strong>al</strong>ue of si:rms$_norm<strong>al</strong>). it is r<strong>et</strong>urned in place of<br />
the string.<br />
51: trnlog logic<strong>al</strong>-name<br />
This performs the trnlog system service on the simple string logic<strong>al</strong>-name. It r<strong>et</strong>urns a<br />
simple-string which is the translation, or nil.<br />
19.9 Termin<strong>al</strong> lID<br />
The current ~IL system contains a termin<strong>al</strong> stream which is translates gener<strong>al</strong> operations into<br />
tennin<strong>al</strong>-specific display codes. Characters output to it (via the :write-char message or the writechar<br />
function) arc interpr<strong>et</strong>ed as either display operations (e.g.. carriage-r<strong>et</strong>urn moves the cursor<br />
to the next line or wraps to the top of the screen, and clears the line it moves to). or as graphic<br />
characters (causing certain characters which are 1101 graphic on typic<strong>al</strong> ascii tennin<strong>al</strong>s to to be<br />
printed with cenain conventions). Line wraparound is performed <strong>al</strong>so.<br />
The best way in which this can be accessed is with the cursorpos function. which is M.\CL1SP<br />
compatible. In t:1Ct. the behaviour of the cursorposable tty stream emulates the behaviour of<br />
tennin<strong>al</strong>s under the ITS operating system. down to the lennin<strong>al</strong>-width fencepost bcha\'iour due to<br />
the use of the last column to hold the continuation character. (The "keyword ch~lracter" argument<br />
to cursorpos. as defined by MACLlSP. in fact derives from the second character in the escape<br />
MC:NII.t\1AN:NE\\'IO 27<br />
2.1-{ )1':C-83
Tcrmin4tlilO 210 Nil. Milfludl<br />
sequence used perfonn that cursor operation under ITS. Ah w<strong>et</strong>l.)<br />
cursorpos &option<strong>al</strong> arg/ argl org3<br />
cursorpos is a MACLISP compatibility function. but it offers an interface to the display<br />
tennin<strong>al</strong> code which may be safely and reliably used. Note that the arguments. are<br />
interpr<strong>et</strong>ed in rather strange manners... As a gener<strong>al</strong> rule. cursorp05 is supposed to<br />
r<strong>et</strong>urn nil if it was not capable of perfonning that particular operation on the particular<br />
stream involved, totherwise. It is 1101 the case, however. that it may be used on non~<br />
tennin<strong>al</strong> streams: that is an error.<br />
(cursorpos)<br />
rCl11rn~ the cursor position of termin<strong>al</strong>-io as a pair. (l'crlictll-posilicm. Iwri=ol1l<strong>al</strong>-posilion).<br />
Both positions arc measured zero-origined. from the top-left corner of the screen. nil<br />
should h(' r<strong>et</strong>urned if the stream docs not hme a gener<strong>al</strong>ly mo\ahlc cursor.<br />
(cursorpos "pos hpos)<br />
Positions the cursor of the stream termin<strong>al</strong>-;o at that position. Either vpos or hpos may<br />
be nil. in which case the current v<strong>al</strong>ue is used.<br />
Otherwise. the first arg to cursorpos should be a symbol (or character object). which<br />
may take an addition<strong>al</strong> argument. The case is irrelevant.<br />
C Clears the screen. The cursor moves to the "home" position (top left corner)~ On<br />
a non-display. this outputs a newline .. so <strong>al</strong>ways succeeds.<br />
A Fresh-linc. In this instance. the fresh-line functiun (page ]85) is preferred.<br />
T<br />
Z<br />
ftTop. It The cursor is homed, moved to the topIeft comer.<br />
Home down. Bottom left comer.<br />
L Clear-to-end-of-line. From the current position to the right margin is cleared.<br />
The cursor does not move.<br />
E C}ear~to-end-of-screcn. Current position. to right margin, and <strong>al</strong>l following lines.<br />
are cleared. The cursor does no move.<br />
U<br />
Move Up a line. Wraps around the screen. does not scroll.<br />
o Move Down a line. Wraps around the screen, does not scroll.<br />
F<br />
Move Forward a character position.<br />
S . Move Backward a character position. If at the left margin. effectively does U<br />
then moves to the column to the left of the continuation-character column (i.e.. it<br />
backs up the amount by which the cursor would have moved for a single-position<br />
printing character).<br />
K Erase the character the cursor is over (this would not be the last one typed<br />
nonn<strong>al</strong>1y. see below:)<br />
X B. then K. Simpleminded way to rubout the last character typed.<br />
Hhpos<br />
S<strong>et</strong> the horizont<strong>al</strong> position to hpos.<br />
MC:NII.MAN:NEWIO 27<br />
23;.I)EC-83
NIl. Manu<strong>al</strong> 211 Termin<strong>al</strong> 110<br />
v "pos<br />
S<strong>et</strong> the vertic<strong>al</strong> posilion to vpus.<br />
The insert-line operation<br />
\ The del<strong>et</strong>e-line operation<br />
111e insert-char operation<br />
the del<strong>et</strong>e-char operation<br />
Addition<strong>al</strong>ly, one may specify a stream to cursorpos by giving that as the last argument.<br />
The atom t as a slream means. as with other printing functions. the termin<strong>al</strong> (the v<strong>al</strong>ue<br />
of termin<strong>al</strong>-io). NOle. howe,,' ... that I/O stream a/so lIses the \·,lllIe of termin<strong>al</strong>-io. rather<br />
lh~1Il standard - output. Note <strong>al</strong>so that the f'{mn<br />
(cursorpos • t)<br />
is interpr<strong>et</strong>ed as requesting the cursor position of termin<strong>al</strong> -io: to do a home-up. one<br />
must use some <strong>al</strong>ternate fonn like<br />
(cursorpos 'top)<br />
(cursorpos #\t)<br />
(cursorpos 't 't)<br />
This strangeness is <strong>al</strong>so \1:\CLlSP compatible ...<br />
19.9.1 l\'Iodifying the Termin<strong>al</strong> Characteristics<br />
s<strong>et</strong>-term1 na l-type termin<strong>al</strong>-name<br />
Res<strong>et</strong>s the tennin<strong>al</strong> characteristics from the tenncap entry found for termin<strong>al</strong>-name. See<br />
(not-y<strong>et</strong>-written) .<br />
s1:d<strong>et</strong>erm1ne-and-s<strong>et</strong>-termin<strong>al</strong>-type<br />
This is the routine c<strong>al</strong>led on stanup which either defaults or asks for your tennin<strong>al</strong> type.<br />
: 1 n 1 t-wi th-termcap tenncap-struct<br />
temlcap-slruC[ is what would be r<strong>et</strong>urned by si:make-termcap.<br />
19.9.2 Making More Termin<strong>al</strong> Streams<br />
As noted elsewhere (page 180), open is what may be used to open tennin<strong>al</strong> streams in <strong>NIL</strong>.<br />
The :type keyword specifics that a tennin<strong>al</strong> stream is requested:<br />
:display-tty<br />
This produces a tcnnin<strong>al</strong> stream just like that <strong>NIL</strong> starts up with. Addition<strong>al</strong> options fed to<br />
open may be used to param<strong>et</strong>erize it; these are described below.<br />
:cold-Ioad<br />
This produces a "raw" tty which has no display capahility. It docs perfonn some asciiification<br />
of non-display characters output. but perfonns no functions like line wraparound.<br />
:tty<br />
what docs this do? is it left-over from som<strong>et</strong>hing?<br />
MC:NII.MAN:NEWIO 27<br />
23-DEC-83
Termin<strong>al</strong> 110 212 Nil. Manmll<br />
Interesting addition<strong>al</strong> open keyword arguments which may be specified when opening a<br />
:dispfay-tty:<br />
:termin<strong>al</strong>-type tennin<strong>al</strong>-t),pe-name<br />
The termin<strong>al</strong> capabilities description is obtained from the tenncap entry for ;ennina!-Iypename.<br />
Since one of these is necessary. you might as weB specify the right one rather<br />
than l<strong>et</strong>ting it default (the lookup in the daLlbasc may still be necessary).<br />
:cold-load - stream colcJ.load-strt'am<br />
The first arg to open is ignored. and the innards of cold-load·stream (which must be a tty<br />
stream as created by the :cold-Ioad open-type) is extracted to g<strong>et</strong> to the re<strong>al</strong> termin<strong>al</strong>.<br />
mt.her than opening a new one. (In the ~Il )oadup process. first the termin<strong>al</strong> streams are<br />
s<strong>et</strong> to be a cold-load stream. and then later they arc res<strong>et</strong> to he re<strong>al</strong> display-tty streams<br />
using this. This is less important now than it used to he. but still COIneS in handy on<br />
occasion. It's not clear what lise it might be to users.)<br />
19.9.3 Display TTY 1\1essages<br />
In case you want to hack graphics on another termin<strong>al</strong> Uf som<strong>et</strong>hing... See <strong>al</strong>so the source<br />
code in nil $ dis k : [ nil . i 0 ] cur so r . 1 s p.<br />
: wr1 te-char char<br />
This is what implements write-char to a display tennina!. with <strong>al</strong>l the interpr<strong>et</strong>ation of<br />
char described earlier.<br />
: oustr slril1g slar! count<br />
Note start and COUIlI are not· option<strong>al</strong>. Using this results in a significant efficiency gain<br />
over individu<strong>al</strong> :write-char messages. because the stream attempts to pass <strong>al</strong>ong as many<br />
block-mode operations as possible to VMS.<br />
:wr1 te- raw~char char<br />
This is not actu<strong>al</strong>ly provided by si:dispiay-cursorpos-mixin. but is required to be<br />
supported by flavors which mix that in. It is how s;:display-cursorpos-mixin expects to<br />
g<strong>et</strong> raw codes out to the tennin<strong>al</strong>. Obviously. then. if you <strong>al</strong>so wish to g<strong>et</strong> raw ·codcs to<br />
the tenninaI, you may use this message on display tty streams.<br />
: raw-oustr SIring start count<br />
An<strong>al</strong>ogous.<br />
MC:NlI.MAN;NEWIO 27<br />
23-DEC-8J
NIl. Manu<strong>al</strong> 213 Syntax<br />
20. Syntax<br />
20.1 What the Reader Tolerates<br />
I wil1 defer delli1ed discussion of reader input and printed representation to the forthcoming<br />
("0\1\10:\ I.ISP manu<strong>al</strong> [1]. The LISP MACIlI~F LISP manu<strong>al</strong> [12] <strong>al</strong>so contains a good discussion<br />
of this. What will be presented here is basic<strong>al</strong>ly a summary of what the current ~IL reader<br />
accepts. lItilizing ("0\1\10~ !.lSI> syntax.<br />
Basic<strong>al</strong>ly. the IISP reader reads characters from a stream and fonns tokens out of them.<br />
Cert~lin characters cause addition<strong>al</strong> actions to take place: fl)r instance. the ( character \\ iII c<strong>al</strong>ise<br />
mulliple (hut possibly zero) exprcssions up to a matching ) to be formed into a list. Some<br />
characters are significant only when they are the first non-whitespace character: the # dispatch<br />
macro character behaves like this: # 0403 is the integer 259 (# 0 meaning "read in oct<strong>al</strong>"). but<br />
foo#o403 is the symbol whose name is the string "FOOH0403". Aside from these, the basic<br />
nile is that if a number can be formed from the characters of the token. it is: otherwise. it is a<br />
symbol. The sole exception is that the period character (.) is wken as a COilS £101. If a character<br />
i~ preceded h) a hackslash (\), then <strong>al</strong>l spcci<strong>al</strong> sig.nificance is rcmo\cd from it. induding ca~e<br />
translation. and it is treated as a token constituent.<br />
Thus:<br />
foobar<br />
foo\bar<br />
259.259<br />
259\.259<br />
IFooBarl<br />
IFoo\IBar\\1<br />
Similarly, the symbol whose print name is Foo 1 Bar\.<br />
259<br />
259.<br />
-259<br />
+259<br />
25\9<br />
\259<br />
1259 1<br />
the atomic symbol FOOBAR<br />
The atomic symbol whose print name is FOObAR<br />
A floating point number. (Currently this is a double-float. But see the later<br />
discussion on floating-point syntax. section 2.1.2, page 4.)<br />
The atomic symbol with print name 259.259.<br />
Vertic<strong>al</strong> bars read a symbol with an characters (except for vertic<strong>al</strong> bar and<br />
backslash) interpr<strong>et</strong>ed as constituent characters. So, this is the symbol whose<br />
print name is FooBar. Backslash may be used to include vertic<strong>al</strong> bars and<br />
backslashes in the symbol.<br />
The decim<strong>al</strong> integer 259.<br />
The decima1 integer 259. A trailing decim<strong>al</strong> point explicitly forces decim<strong>al</strong><br />
notation, not floating-point.<br />
The negative decim<strong>al</strong> integer - 259.<br />
The decim<strong>al</strong> integer 259.<br />
The symbol 259.<br />
The symbol 259.<br />
The symbol 259.<br />
MC:NII.MAN:SYNTAX 34<br />
23-DFC-83
What the Reader Tolerates . 214 <strong>NIL</strong> Manu<strong>al</strong><br />
1.0d-5 One times ten to the minus fifth power, as a double-float. Sec section 2.1.2.<br />
page 4.<br />
:foo<br />
A colon in a token uses the characters on the left to name the package the<br />
following symbol is to be read into. The "nu1l't package name means the<br />
package into which keywords are read.<br />
s;:foo The symbol FOO. read into the package named S I (the system-intern<strong>al</strong>s<br />
package),<br />
si:IFoo\IBar\\1<br />
The symhol Foc ISar\. read into the SI package.<br />
foo#0403<br />
The symbol FOON0403.<br />
I f the token consists entirely of . chamcters (and none h,I\'e been slashified). then it is illeg<strong>al</strong><br />
unless there is exactly one: that is a COIlS dOl. which is only leg<strong>al</strong> in list/cons fonnation. 'Ibus .<br />
.100. is the symbol whose print name is . FOC •• but ... is an error.<br />
The primitive syntax for a cons is<br />
«('ar . cJr)<br />
In this notation. a list of items a. b. and c would be written as<br />
(a . (b • (c . nil)})<br />
/.isl sYlllax <strong>al</strong>lows us to "elide" a cons dot with a following cons; the dot is eliminated. as are -<br />
the parentheses of the fol1owing cons:<br />
{n h . (r. . nil)<br />
(a be . nil)<br />
and fin<strong>al</strong>ly. because nil is the same as 0,<br />
(a b c)<br />
llle following characters tcnninate token formation.<br />
cncountered:<br />
( Starts a list or cons. as described above.<br />
and do som<strong>et</strong>hing speci<strong>al</strong> when<br />
) Terminates a list or cons, or some other construct which "matches" with parentheses. such<br />
as #(.<br />
"<br />
Vertic<strong>al</strong> bar terminates token formation.<br />
String syntax. The characters up to the matchine It form the string; .. and \ may be<br />
included by prcceding them with \.<br />
Reads the following expression, and "wraps" it with the function quote. Thus. 'foo· reads<br />
as (quote foo).<br />
ttBackquotc". This is used for constructing expressions. Backquote is described later<br />
(section 20.1.1, page 216). and <strong>al</strong>so in . [3].<br />
Comma is used for performing substitution within backquoted expressions (q.v.).<br />
lbe # character is a diJpauh macro characler. It reads (option<strong>al</strong>) digits as a numeric decim<strong>al</strong><br />
argument, and then dispatches off of the following character. The following arc defined:<br />
MC:NII.MAN:SYNTAX 34<br />
23-Dr:C-S3
JIm 770ns ·rss.rm<br />
<strong>NIL</strong> Manu<strong>al</strong> 215 What the Re .. ,ucr Tolerates<br />
# I expression<br />
Wraps expression with function. similar to '. Thus. # 'car reads as (function car).<br />
#(xl x2 ... xn)<br />
Reads as a simple gener<strong>al</strong> vector 11 elements long (11 may be zero). with those clements.<br />
# * bits<br />
Reads in as a simple bit vector whose elements arc bits (the digits 0 or 1). Thus. #.100<br />
is a simple-bit-vector of length 3: its clement 0 is 1, and its clements numbered 1 and 2<br />
arc both o.<br />
# Bmliol1<strong>al</strong><br />
Reads ration<strong>al</strong>. the syntax for a ration<strong>al</strong> number (which. remember. 111
What the Reader Tolerates 216 <strong>NIL</strong> Manu<strong>al</strong><br />
# ,expressioll<br />
I.oad-time ev<strong>al</strong>uation. If the expression is being reild nonn<strong>al</strong>Iy into r-.;IL, this behaves like<br />
# " However. if it is in a file being compiled. the compiler will arrange to have<br />
expression ev<strong>al</strong>uated at load (Le., vasload) time. when the containing expression is being<br />
constructed. This does not work y<strong>et</strong> in <strong>NIL</strong>.<br />
20.1.1 Backquote<br />
The bockquo/c t:1cility is used filr constructing list structure from a template. Typic<strong>al</strong>ly. most<br />
of the temp)ate is constant. and the most common use is when what is being cre~ltcd is I.lSf> code.<br />
insid~ of macro ddinilioll!\. In the simplest casco the backquote character (') is used instead of<br />
qllote ('). and. where suhstitution inside the template is desired. a fbnn to be ev<strong>al</strong>uated is<br />
preceded hy a comma character. For instance.<br />
(defmacro push (item place)<br />
t(s<strong>et</strong>f ,place (cons ,item ,place»)<br />
This definition reads in as code which is function<strong>al</strong>ly equiv<strong>al</strong>cnt to<br />
(defmacro push (item place)<br />
(list 's<strong>et</strong>f place (list 'cons item place)})<br />
Simple suhstilUlion is r. 'len llot cnough. If the commil in a backquotcd expression is immediatcly<br />
followed by an atsigr: charactcr (@), then. instead of simple substitution. the item being<br />
substituted is "spliced" into the containing list:<br />
'(foo .@bar mumble)<br />
(cons ~foo (append bar '(mumble)'»<br />
For instance. the macro<br />
(defmacro <strong>al</strong>ways-r<strong>et</strong>urning-nil (&body body)<br />
'(progn ~@body nil»<br />
produces expansions<br />
(<strong>al</strong>ways-r<strong>et</strong>urning-nil)<br />
==> (progn nil)<br />
(<strong>al</strong>ways-r<strong>et</strong>urning-nil (do-this»<br />
==> (progn (do-this) nil)<br />
(<strong>al</strong>ways-r<strong>et</strong>urning-nil (do-this) (do-that»<br />
==> (progn (do-this) (do-that) nil)<br />
The splicing is non-destructive on the expression being substituted, as if the splicing happens by<br />
use of append.<br />
In <strong>NIL</strong> (but not COMMON USP), a comma immediately followed by a dot instead of an atsign<br />
is treated similarly, except that <strong>NIL</strong> is free to use dcslructive operations for the splicing; that is.<br />
the splicing IS perfonned as if by ncone (page 58) rather than append.<br />
Backquoted expressions may be nested. They should be assumed to be expanded from the<br />
inside out. Consider the following macro definition:<br />
(defmacro defhack (name fn &aux (place-var (gentemp))}<br />
'(defmacro ,name (,place-var)<br />
'(s<strong>et</strong>f .,place-var (,',fn "place-var»»<br />
In this example. the expansion of the outer backquotc expression causes the v<strong>al</strong>ues of name, tn.<br />
andplace-var to be substituted in; this essenti<strong>al</strong>ly means that we g<strong>et</strong> (using it<strong>al</strong>ics now to show<br />
MC:NJI.MAN:SYNTAX 34<br />
23-DEC-83
.",7- 33 PC - 'sr' ;; 'm' um<br />
<strong>NIL</strong> Manu<strong>al</strong> 217 The l.isp Reader<br />
the suhstitutions)<br />
(defmacro Il<strong>al</strong>lle (place-var)<br />
t (s<strong>et</strong> f ,place-var ( • 'fn ,place-var))<br />
Now. ",111" means that we substitute in the v<strong>al</strong>ue of '''In''. which is of course just /n. which is<br />
what we want: on the other hand, we do want the v<strong>al</strong>ue of place-var to be substituted in here.<br />
so it does not need that quote.<br />
To see another way that this works. one can manu<strong>al</strong>ly pseudo-expand 111e illner backquote in<br />
the origin<strong>al</strong> defhack definition<br />
(defmacro defhack (name fn &aux (place-var (gentemp»)<br />
'(defmacro .name (.place-var)<br />
(list 's<strong>et</strong>f place-var (list' .fn place-var»»<br />
which indeed produces what we want. Gener<strong>al</strong>ly. then. one uses ".." when one wants the<br />
substituted fonn to itself he ev<strong>al</strong>uated and suhstituted with the expansion of the inner hackquote<br />
expression. and ":." when one wants to suhstitute in som<strong>et</strong>hing which is "constant" with respect<br />
to the inner backquote eXf,:msion.<br />
As one fin<strong>al</strong> extension to hackquote. ;\11 <strong>al</strong>lows its use with gener<strong>al</strong> vector syntax. This will<br />
prohably he supported fore\'\,~r and evcr. if for no other reason than the 'II compilcr/codegener<strong>al</strong>or<br />
emits inslructions as \ectors and conslructs them that way.<br />
'H(foo ,(+ 3 7) bar) => H(foo 10 bar)<br />
"Splicing" syntax (".
The Lisp Reader 218<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
;;-.-Mode:Lisp;Readtable:Ml-.-<br />
;; This code uses »:" and "I" as in maclisp.<br />
;;-.-Mode:lisp;Readtable:LM-.-<br />
:; This code reads using the old lispmachine syntax.<br />
C -.-Mode:Fortran;Readtable:Fortran-.-<br />
C This would work if one defined a readtable for Fortran.<br />
% -.-Mode:Lisp:Readtable:Cgol-.-<br />
This is lisp cod<strong>et</strong>n cgol syntax. Yow! % .<br />
define fib(x); if x
Nil. Manu<strong>al</strong> 219 The l.isp Reader<br />
s1 :enter-readtab1e "omr a-readlab/r<br />
Enters a-rrad/ablr giving the syntax for "<strong>al</strong>lle.<br />
specification in the mode-line of a source-file.<br />
name may then appear as a readtablc<br />
create-readtable<br />
R<strong>et</strong>urns a naked read table. with syntax for reading whitepace-deJimited symbols.<br />
s1:add-number-syntax<br />
Adds syntax for parsing numbers to th~ current readtable.<br />
s 1 : add -11 s t - syn tax &option<strong>al</strong> (opell # \() (closr # \)<br />
Adds syntax ftH' parsing lists to the current readwble.<br />
s1: add-pacKage-syntax &option<strong>al</strong> (eltar #\:)<br />
Adds syntax for specifing packages to the current readtable.<br />
s1:add-escape-char-syntax char<br />
tv-takes clUJr the syntax-esc,lpe-character in the current readtable.<br />
s1: add-pref1x-op-macro cliar operaTor<br />
Makes char a read macro that r<strong>et</strong>urns a list of operator and the next thing read.<br />
example.<br />
(si:add-prefix-op-macro NI' 'quote)<br />
For<br />
20.2.4 Alternative Syntax<br />
The eGOL syntax [11] is available by loading the file <strong>NIL</strong>$OISK: [<strong>NIL</strong>. LISPIO]CGOL. LOO.<br />
Further documentation is in the file <strong>NIL</strong>$OISK: [<strong>NIL</strong> .MANUAL]CGOL. TXT. The imp1cmcntors<br />
do not recommend the extensive use of CGOL or any ALGOL-Jike syntax for LISP programming,<br />
especi<strong>al</strong>ly in environments where program readability and editability arc important long range<br />
considerations. However, some feel that syntactic vari<strong>et</strong>y taken in moderation is good for the<br />
soul.<br />
egolread<br />
Rcads a CGOL syntax expression.<br />
ego 1 P r i n t expression<br />
Prints an s-expression lisp program in the CGOL syntax.<br />
Another parscr. for a language with syntax compatible with the symbolic <strong>al</strong>gcbra system<br />
MACSYMA [8], is availablc by loading the file <strong>NIL</strong>$OISK:[<strong>NIL</strong>.VAS]PARSER. which scts up a<br />
readtable named infix. The readmacro character" #$" has been s<strong>et</strong> up to invoke this parser in<br />
the "<strong>NIL</strong>" readtablc. One could then writc the following:<br />
(defun f (v a b x)<br />
#$(v[O.O]:COS«A-S).X)/(Z-Z.(A-S)AZ)+COS(V[l.l].X).<br />
v[O.l]:COS«(A+S).X)/(Z-Z*(A+S)ftZ)-V[l.G].V[O.O].<br />
v[l.O]:V[l.l].V[O,O],<br />
v[l,l]:V[O,l]*V[l.O])$)<br />
MC:NII.MAN:SYNTAX 34<br />
23-DEC-83<br />
"".. ~ .<br />
'.' . . '.' ~". .':. ': , . ' •. ~ .. ' c .~~~;. ~ \'; ,;p~j~fi;;~~':\~' ~:;=~. . •... ..... . · . .., .
Ddwgging and M<strong>et</strong>ering<br />
21. Debugging and M<strong>et</strong>ering<br />
220<br />
<strong>NIL</strong> Manu,!1<br />
21.1 Flow of Control<br />
21.1.1 Tracing<br />
tr ace junction<br />
trace enwraps the definition of junction so that the arguments it is c<strong>al</strong>led with. and the<br />
\'<strong>al</strong>ues it r<strong>et</strong>urns. may be seen. follc/iol/ is not e\'<strong>al</strong>uated.<br />
(dafun f (x) (times x x»<br />
=> f<br />
(trace f) => (F)<br />
(untrace f) => (f)<br />
(trace f) => (f)<br />
(f 3) :printout:<br />
#(1 :ENTER F #(3»<br />
#(1 :EXIT F #(9»<br />
The printout is a VECrOR. Its clements are:<br />
{O] Recursion level for the given function<br />
{I] :enter or :exit<br />
[2] Name of the function.<br />
[3J The vector of arguments, or the vector of r<strong>et</strong>urn v<strong>al</strong>ues.<br />
Say that you wanted a breakpoint on entry to f. Then say<br />
(defun f-bp (level direction name vector)<br />
(eq direction t:enter»<br />
(trace (f (:break f-bp»)<br />
Presently <strong>al</strong>l trace options work this simple and function<strong>al</strong> way, the syntax of a trace option is<br />
(:keyword predicate-junction-to-c<strong>al</strong>l). or simply :keyword which means the same thing as<br />
(:keyword t). Options are :noprint, :break, and :info.<br />
One exception: (trace (f :menue» enters a simple menue of various kinds of trace options.<br />
MC:NlI.MAN;DFBUG 20<br />
23-nEC-83
<strong>NIL</strong> ~1anu<strong>al</strong> 221 Flow of Contfol<br />
21.1.2 Who docs \Vhat, and Where<br />
who-c<strong>al</strong>ls symbol &option<strong>al</strong> &key (type:/ullction)<br />
This searches <strong>al</strong>l compiled-code modules tp find those which reference the t>pe v<strong>al</strong>ue-cell<br />
of symbol. type may take on the v<strong>al</strong>ues :functlon, :v<strong>al</strong>ue, :Ioc<strong>al</strong>-function. Of :Ioc<strong>al</strong>v<strong>al</strong>ue.<br />
It defaults to :function, thus finding <strong>al</strong>l modules which caB the function symbol.<br />
A type of :v<strong>al</strong>ue would find, <strong>al</strong>l those modules which referenced symbol as a speci<strong>al</strong><br />
variable. :Ioc<strong>al</strong>-function and :Ioc<strong>al</strong>-v<strong>al</strong>ue (which should probably be c<strong>al</strong>led :Iexic<strong>al</strong>anyway)<br />
aren't actu<strong>al</strong>ly useful: they would only find uses where the references were not<br />
compiled away, and <strong>al</strong>l loc<strong>al</strong> references are in the current compiler.<br />
Someday this should he smart enough to do searching through <strong>al</strong>l defined functions,<br />
including interpr<strong>et</strong>ed ones.<br />
where1 s function<br />
funcTion should be a symbol or a compiled-function. whereis r<strong>et</strong>urns the compiled-code<br />
module (the module-object) which d~fines fUlIctiol1. or nil if that cannot he dctennined.<br />
It can only d<strong>et</strong>ennine this for compi1ed functions.<br />
Someday (i keep saying that don't i) there will be a more gener<strong>al</strong> mechanism, so that the<br />
source file can be d<strong>et</strong>ennined for <strong>al</strong>l "defined objects", such as those defined with defvar.<br />
defstruct. defmacro. <strong>et</strong>c. Until then, note the following function:<br />
51 :module-50urce-f11e module<br />
This r<strong>et</strong>urns the name of the source file for the module module. The current<br />
implementation .does this by looking at the vasl file from which module was loaded, so<br />
that file must exist on disk (with the same name).<br />
ap rop05 STring &option<strong>al</strong> (pkg package)<br />
This searches through pkg and <strong>al</strong>l of its super-packages (see chapter 15, page 121), and<br />
r<strong>et</strong>urns a list of <strong>al</strong>l of the symbols which contain strillg as a substring.<br />
51: apropos-generate /n arg &option<strong>al</strong> (pkgpackage) (superiors I)<br />
'Ibis function maps the function fn over aU symbols which contain arg (a string or<br />
symbol) as a substring, in the package pkg (and its superiors, if superiors is not nil).<br />
si:apropos-generate uses mapatoms (page 122): it is possible that fn could be c<strong>al</strong>led on<br />
the same symbol more than once, <strong>al</strong>though that will not happen very often in the current<br />
<strong>NIL</strong> implementation.<br />
The apropos function is defined using this, by<br />
(defvar *apropos-list*)<br />
(defun apropos (arg &option<strong>al</strong> (pkg package) (superiors t)}<br />
(l<strong>et</strong> ({*apropos-list* C»~)<br />
(si:apropos-generate<br />
#'(lambda (x) (push x *apropos-list*»<br />
arg pkg superiors}<br />
*apropos-list.)}<br />
One could write \'ariants of this which test the symbol for specific properties. or with<br />
boundp or fboundp, and which print the results as they are computed rather than<br />
MC:<strong>NIL</strong>MAN:DEBUG 20
Examining Objects 222 <strong>NIL</strong> Manu<strong>al</strong><br />
accumulating them in a Jist<br />
21.2 Examining Objects<br />
exhibit object<br />
Invokes an interactive structure editor on the object. There is a "7" command to print out<br />
a command menu. The object is scnt any of the following messages. :exhibit-self.<br />
:select-nth. :store-nth. See the defi~jtions K)r built·in objects in<br />
"(N 1I .. SRC]EXH IRI.LSP".<br />
descr 1 be objcct<br />
Says a few things about the object.<br />
21.3 Debug ~lnd Breakpoints<br />
debug<br />
Enters the dehugger. Various commands. self documenting \'ia the "'!" command. Errors<br />
hy defillilt enter the debugger <strong>al</strong>so. Note that in its current SUlte, siAlck and argument<br />
infonnation displayed requires an addition<strong>al</strong> level of interpr<strong>et</strong>ation placed upon it for it to<br />
be correct. For example, loc<strong>al</strong> variable information currently shows simply the siAlek<br />
b<strong>et</strong>ween c<strong>al</strong>l frames. including argument frames being computed and "dirty" (non-Lisp)<br />
data.<br />
break. tag &option<strong>al</strong> (predicate-fi,nn I)<br />
break ev<strong>al</strong>uates predicate-!onll, which defaults to t If the result of this ev<strong>al</strong>uation is not<br />
nil. then it enters a "break loop". ":bkpt lag" is printed out. and a recursive read-ev<strong>al</strong>print<br />
loop is entered. The prompt for reading says ll)break>. where 11 is the number of<br />
nested break loops currently in force. Note that tag is not ev<strong>al</strong>uated.<br />
break is one of the older debugging tools around. It is not nearly as useful as it had<br />
once been, because in a usp with lexic<strong>al</strong>ly seoped variables, those v<strong>al</strong>ues are not apparent<br />
from the break loop. In <strong>NIL</strong> what is probably moreusefu1 would be to insert explicit<br />
c<strong>al</strong>ls to (debug) in ones code, rather than to break. )n the future. break win in fact do<br />
that. and its arguments will be a format-string and arguments for the fonnat-string (see<br />
format, page 187).<br />
-break v<strong>al</strong>ue lag<br />
This is the intern<strong>al</strong> version of break which eva)uatesboth of its arguments nonn<strong>al</strong>ly. This<br />
is <strong>al</strong>so how you can give a non-constant tag argument to the break loop. When break is<br />
changed.. this function will go away.<br />
MC:NII.MAN:DEBUG 20<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 223 M<strong>et</strong>ering<br />
21.4 1\tl<strong>et</strong>ering<br />
21.4.1 Timing<br />
t 1mer jUnction &option<strong>al</strong> (loops I) arguments<br />
C<strong>al</strong>ls jUnction with arguments arguments (a list or simple gener<strong>al</strong> vector). loops times. and<br />
print" out infonnation on how much time was taken. Try. for example.<br />
(timer #'cons 100 #(a b»<br />
Needs some improvement (() de<strong>al</strong> with function·c<strong>al</strong>1ing and loop overhead: for that reason.<br />
this is not too lI~eful with short fast functions.<br />
CO\1\10,\-IISP defines two functions for obtaining compute and elapsed time. Both r<strong>et</strong>urn<br />
integers in the same units. which can not be assumed to be fixnums. These units arc units of<br />
intern<strong>al</strong> limC'. which cannot be depended on to be the same in different CO\1\10' I.lSP<br />
implementations. They may e\"en differ from one ~IL. release to another.<br />
1 n te rn a 1-t 1 me - un 1 ts - per - second COllS1Lll1t<br />
This is .111 integer v. hich is the numher of "tic~" of intern<strong>al</strong> lime per sl'cond. It h;lprens<br />
that in 'II this is 100. because that is <strong>al</strong>l the accuracy which \\tS pn)\'ides at the<br />
moment. It could change in the future, and its v<strong>al</strong>ue should not be depended on.<br />
g<strong>et</strong>-1ntern<strong>al</strong>-run-time<br />
This r<strong>et</strong>urns the "run time" of the Nil. process in intern<strong>al</strong>-time-units-per-second units.<br />
g<strong>et</strong>-1ntern<strong>al</strong>-re<strong>al</strong>-t1me<br />
This r<strong>et</strong>urns a measure of elapsed time in intern<strong>al</strong>-time-units-per-second units. The<br />
time-base for this time measurement may not be depcnded on: only differences b<strong>et</strong>ween<br />
the v<strong>al</strong>ues of two successive c<strong>al</strong>ls should be used for anything.<br />
runtime<br />
This is the old name for g<strong>et</strong>-intern<strong>al</strong>-run-time. While it is the- same name as the<br />
MACLISP function, it is incompatible-the <strong>NIL</strong> runtime function r<strong>et</strong>urns the run time in<br />
units of hundredths of a second.<br />
elapsed-time<br />
time<br />
elapsed-time r<strong>et</strong>urns a measurement of elapsed time. in seconds. as a double·fioat. Two<br />
such quantities may be compared to d<strong>et</strong>ermine elapsed time. The origin of this number<br />
may not be depended upon: in MACLISP it is the "system uptime"; in ~lL it happens to<br />
be the double·float representation of the number of seconds since thc origin of the<br />
Smithsonian time standard (loc<strong>al</strong> time). This quantity is only re<strong>al</strong>ly accurate to hundredths<br />
of a second. even though it is potenti<strong>al</strong>ly accurate to IOO-nanosecond tics.<br />
The synonym time is provided for MACTISP compatibility; This name should not be used<br />
in new programs. and should be changed in old programs. as the name time will be<br />
ch~l11ged incomp~ltihly by CO\1:\10~ I.Isr. Also. there is a us» \1ACIII'F I.ISP time<br />
function which r<strong>et</strong>urns elapsed time. but as a fixl1um in sixti<strong>et</strong>hs of a second. The<br />
elapsed-time function will continue to exist as the function<strong>al</strong> equi\<strong>al</strong>cnt to the MACLISP<br />
MC:NII.MAN:DEBUG 20<br />
23-1 )FC·g3<br />
i<br />
.'. ;-,'<br />
~<br />
~<br />
.. ~<br />
,_:::;,:~~::~~~~:~'o~~',~__ ~:~~: ~: , _- _. . .
Melering 224 Nil. MmlU,d<br />
time function. however.<br />
s1:pagefault-count<br />
This r<strong>et</strong>urns the number of pagefaults taken by the process since process creation.<br />
Although this number is interesting to look at to see if the !\:IL is thrashing. it must be<br />
taken with sever<strong>al</strong> grains of s<strong>al</strong>t due to the way VMS paging/swapping is perfonned. {The<br />
following discussion should perhaps be somewhere else. under "perfonll<strong>al</strong>lce considerations"?)<br />
The following points arc especi<strong>al</strong>ly of notc. First this number docs not count the<br />
number of faults taken which involved fctchjng a page from the pagefile (or shared image<br />
file). Rather. it includes those "fault\" for pages which still reside in physic<strong>al</strong> memory,<br />
hut are just not contained within the working s<strong>et</strong> Also. the overhead of doing this<br />
paging is charged to thc process nmtime.<br />
Presumably. then. if one s<strong>et</strong>s the working-s<strong>et</strong> extent (the proccss param<strong>et</strong>er/user quota<br />
WSEXTENT) high, then the actu<strong>al</strong> working s<strong>et</strong> in use will apprmlch the number of pagcs<br />
of the joh which arc resident in physic<strong>al</strong> n:tcmory. and the count of pagcfaults will b<strong>et</strong>tcr<br />
approximate the number of pagefautts for non-resident pages.<br />
Note <strong>al</strong>so the room function. whichvcrboscJy describes the "irtu<strong>al</strong> memory usage of the !\IL.<br />
including the size of the living heap (Le .. how much consing has been going on).<br />
The ~1A(,usP·compatible status macro provides a gctime option which r<strong>et</strong>urns the nmtimc (in<br />
the same unite; as runtime docs) which is the contribution to the proces~ runtime hy the garhagccollector.<br />
This is curr~ntly. of course. <strong>al</strong>w~lYs zero, When the garhage-c~1ncctor is availahle, there<br />
will be functions which par<strong>al</strong>lel the above threc. which will r<strong>et</strong>urn the contributions to elapsedtime.<br />
runtime. and pagefaults by the garbage-collector. Note that the v<strong>al</strong>ues r<strong>et</strong>urned by the<br />
above functions will· <strong>al</strong>ways include the contributions by the garbage-collector .<br />
. 21.4.2 Function C<strong>al</strong>ling<br />
The only type of function c<strong>al</strong>l m<strong>et</strong>ering which is available in <strong>NIL</strong> right now is a glob<strong>al</strong><br />
database of how many function c<strong>al</strong>ls (and similar things) of various types have been perfonned<br />
since the <strong>NIL</strong> was first loaded up.<br />
This number-of-function-c<strong>al</strong>ls m<strong>et</strong>ering is basic<strong>al</strong>ly. implemented by the <strong>NIL</strong> compiler. There<br />
are four tables 10 long: the four tables are for m<strong>et</strong>ering<br />
jUnction C'a/ls<br />
Direct function c<strong>al</strong>ls. As in (defun f (x) (g x»).<br />
jUnc<strong>al</strong>/s<br />
Simple func<strong>al</strong>ls.<br />
sends<br />
C<strong>al</strong>ls to send. 'Ibis does not (unfortunately) include lexpr-send.<br />
applies<br />
Cumpiled c<strong>al</strong>ls to apply (= lexpr-funcaU).<br />
lbe 10 entries in c,tch table count the number of such occurences for zero through eight. and<br />
nine-or-more arguments. When the compiler compiles (say) a function caU of two arguments, it<br />
MC:NII.MAN:I1EBUG 20<br />
23-DFC;'S3
<strong>NIL</strong> Manu<strong>al</strong> 225 M<strong>et</strong>cring<br />
will sneak in an instnJction like<br />
incl w A<br />
cl$c<strong>al</strong>l_m<strong>et</strong>er+2(slp)<br />
just before it does the actu<strong>al</strong> function c<strong>al</strong>l. This sequence takes four bytes of code.<br />
The intent of this type of m<strong>et</strong>ering is to measure how intensively various applications perfonn<br />
function c<strong>al</strong>ling. in order that we might· be able to estimate how changes to the function c<strong>al</strong>ling<br />
sequence (such as modifications to the function entry code. function c<strong>al</strong>l-frame s<strong>et</strong>up code. or<br />
even microcode support for either of those or the function can itself) might affect the performance<br />
of 'II programs. Wc have not y<strong>et</strong> actu<strong>al</strong>ly done any measurements with these m<strong>et</strong>ers. However.<br />
in the event that they might be useful to' people. the functions (which are somewhat dirty and<br />
kluog.cy) which read them are documented below.<br />
s1:g<strong>et</strong>-c<strong>al</strong>1-m<strong>et</strong>ers<br />
This r<strong>et</strong>urns an a-list of the v<strong>al</strong>ues of the various c<strong>al</strong>ling m<strong>et</strong>ers. The a-list will be 4 long.<br />
and the first clement of each of these lists is a keyword describing the type of c<strong>al</strong>l: the<br />
remaining 10 clements are the numher of "c<strong>al</strong>ls" of that type for zero through 8. and<br />
(last) nine or more c<strong>al</strong>ls. The keywords are<br />
:function<br />
Direct function c<strong>al</strong>ls<br />
:func<strong>al</strong>l<br />
Compiled c<strong>al</strong>ls to funeaU<br />
:send<br />
Compiled caJIs to send<br />
:apply<br />
Compiled c<strong>al</strong>ls to apply (Iexpr-func<strong>al</strong>l).<br />
s i : show-ca l1-m<strong>et</strong>ers &option<strong>al</strong> (merers (si:ger-c<strong>al</strong>l-m<strong>et</strong>ers)<br />
Prints out the m<strong>et</strong>ers.<br />
s 1 : subtract-ca l1-m<strong>et</strong>ers after-m<strong>et</strong>ers be/ore-m<strong>et</strong>ers<br />
R<strong>et</strong>urns a new "m<strong>et</strong>ers Hst" in which <strong>al</strong>l of the numbers are the difference of the after<br />
and before v<strong>al</strong>ues. All of the entries are assumed to be in the same order.<br />
One could g<strong>et</strong> a display of how much function c<strong>al</strong>ling (<strong>et</strong>c.) was going on by doing som<strong>et</strong>hing<br />
like<br />
(l<strong>et</strong> ({before (si:g<strong>et</strong>-c<strong>al</strong>1-m<strong>et</strong>ers»)<br />
(run-program)<br />
(si:show-c<strong>al</strong>l-m<strong>et</strong>ers (si:g<strong>et</strong>-c<strong>al</strong>1-m<strong>et</strong>ers) before»<br />
MC:NII.MAN:DFBUG 20<br />
23-DFC-83
__________________'1-...<br />
r~ .... r.r.n ...... ".;.-·.·r.711'17171711'1'17711111)1IIIIIIII<br />
System Management 226 Nfl. Manu<strong>al</strong><br />
21.5 System l\1anagement<br />
Included are some minim<strong>al</strong> uti1ity functions for maint<strong>al</strong>nmg subsystems in ~1L. These tools<br />
are not meant to be a comprehensive s<strong>et</strong>. ttaddressing <strong>al</strong>l the issues" as they say. Instead. they<br />
address some of the issues. have been found' useful. and are used <strong>al</strong>ong with individu<strong>al</strong> system<br />
specific procedures for maintaining systems including the editor and MACSYMA.<br />
The practic<strong>al</strong> working procedure on most programs goes som<strong>et</strong>hing like the following: 'lbcre<br />
are a s<strong>et</strong> of source files that make up the program. One of these files defines a variable s<strong>et</strong> to a<br />
list of these file names. and includes code for loading the files. creating needed package<br />
namespace(s). and peforming other functions as needed. Day-tn-day works procedcs in an<br />
increment<strong>al</strong> t~lsion. changes are made to the sources using the {-wilt-in editor. and thcse changes<br />
arc testcd and dchugged using editor commands such as CONTROI,-META-C (compile-dcfun. or<br />
-Z) and other lIlilitcs in the system<br />
as needed. The editor. dehugger. ev<strong>al</strong>uator. andexhihitor are invoked many times during a days<br />
dcvelopment cycle. From lime to time during editing t1le changed files arc saved of course. as a<br />
h(l~kup against environment crashes. At the end of ~hc day. (or perhaps. during lunch hour. or<br />
after sever<strong>al</strong> days). a recompil<strong>al</strong>ion of the changed program files may he eflected. using some of<br />
the functions documented in this section.<br />
A somewhat par<strong>al</strong>1el effort is the maintainencc of a system t11at has "users." The same<br />
melhodology as lIsed in a development system is in effect: except tJ1at now the full-rccompilationcycle<br />
time may he months. and there is a definite targ<strong>et</strong>-environment which is (0 receive system<br />
ch~!!~g~s in t.~c ferm of "p~tch files." {Sec the d~x:umenc~tion of the put~h fucility.}<br />
Some addition<strong>al</strong> functions documented here provide ways to find out som<strong>et</strong>hing about how<br />
modules depend on one another.<br />
21.5.1 An example<br />
; This is an example "system-build" file.<br />
(defparam<strong>et</strong>er .my-files.<br />
'("USR:[ME.SYS]TOPLEVEL"<br />
"USR:[ME.SYS]UTILS"<br />
"USR:[ME.SYS]BASIC"»<br />
(defvar .my-modules. (»<br />
(defun load-my-system ()<br />
(s<strong>et</strong>q -my-modules. (mapcar "load .my-files.»)<br />
(de'fun recompi le-roy-fi les()<br />
(mapcar ,'silent-comfile<br />
(mapcan "(lambda (x)<br />
(if (utils:source-need-compile? x)<br />
(list x»)<br />
.my-files.»)<br />
MC:NII.MAN:DFHUG 20<br />
23-DEC-S3
<strong>NIL</strong> Manu<strong>al</strong> 227<br />
SySl~tn<br />
ManJgcm~nt<br />
{defun silent-comfile (x)<br />
{l<strong>et</strong> «compi1er:*messages-to-termin<strong>al</strong>? (})<br />
(si:print-gc-messages ())}<br />
(comfile x)}}<br />
(defvar *my-undefined-functions-<strong>al</strong>ist*<br />
( ) )<br />
(defun find-my-undefined-functions ()<br />
{s<strong>et</strong>q *my-undefined-functions-a1ist* ()}<br />
{mape<br />
# ' ( 1 amb d a (m)<br />
(if (typep m 'module)<br />
(uti1s:map-over-modu1e-ce11s<br />
#'(lambda (module symbol key)<br />
(if (and (eq key :fun<strong>et</strong>ion)<br />
(not (fboundp symbol»)<br />
(l<strong>et</strong> «a (assq<br />
symbol<br />
*my-undefined-functions-a1ist*»)<br />
{i f a<br />
(unless (memq module (cdr a»<br />
(push module (cdr a»)<br />
(push<br />
(list symbol module)<br />
*my-undefined-functions-<strong>al</strong>ist*»»)<br />
m) ) )<br />
*my-modules*)<br />
*my-undefined-functions-<strong>al</strong>ist*)<br />
21.5.2 "Source (Re)Compilatioo"<br />
ut11s:V8s-source-f11e filename<br />
G<strong>et</strong>s the exact name of source file from the object file, filename.<br />
ut 11 s: source-need-comp 11 e1 source-filename &option<strong>al</strong> object-directory<br />
If there is no object file. or if the version of the number of the present source file is<br />
greater than the version number of the source from which the object was compiled then<br />
this function r<strong>et</strong>urns t.<br />
ut 11 s: V8S- source-needs - recomp11 81 filename<br />
G<strong>et</strong>s the source file name for the object filename and checks the version numbers.<br />
MC:NII.MAN:DEBUG 20
Verifk~ltion 228 <strong>NIL</strong> Manu<strong>al</strong><br />
21.5.,3 Information in l\1odules<br />
The exhibit function can be used to look at modules interactively.<br />
21.5.4 Related Utilities<br />
These are som<strong>et</strong>imes used to store information gathered during system programming. for<br />
example. "bug" cases. lists of undefined functions. sorted lists of speci<strong>al</strong> variables. ctc.<br />
ut i 1 s : p r i" t - i" to - f 1·1 e rXl'rcsshm &option<strong>al</strong> filellame<br />
Prints the {'.%prt'ssioll into the .li/('/I
<strong>NIL</strong> Manu<strong>al</strong> 229 Errors<br />
22. Errors<br />
Errors in <strong>NIL</strong> work by sign<strong>al</strong>ling error conditions using sign<strong>al</strong>. The specifics of this are going<br />
to be changing in various ways: however, the basic interfaces for "creating" errors can hopefully<br />
be kept static, at least insofar as the functions can be made to accept and interpr<strong>et</strong> arguments<br />
upwards-compatibly.<br />
cerror proceedable restartable condition-name lonna/-sIring args<br />
This is what needs to be used to sign<strong>al</strong> correctable errors. For an error to be correctable<br />
(in the current scheme). one uses cerror and gives a non-null proc('cdab1c argument. The<br />
rC.'ilarlah!c arg.ument has lO do with saying that the error can be "restarted" (i.e..<br />
som<strong>et</strong>hing g<strong>et</strong>s tried over again) by throwing to a 141g with name error-restart: this is<br />
hardly. if ever. used. and will probilbly be obsol<strong>et</strong>e quite soon.<br />
condition-name is the name of the condition being sign<strong>al</strong>led: it is typic<strong>al</strong>ly. <strong>al</strong>though not<br />
necessarily. a keyword.<br />
fhrl11a1-Sfrillg is a string suitahle as an argument to format with extra arguments of args:<br />
that i~ how the error message is produced. There arc. however. COl1\ entions on what<br />
particular arguments mean for particular conditions: some of them arc described below.<br />
At some point. the error system and how errors (and non-error conditions) arc sign<strong>al</strong>led<br />
will <strong>al</strong>l change. It should be the case, however. that vanilla uses of cerror, especi<strong>al</strong>ly<br />
cheCK - type place l)'pe-~pecifie,. &option<strong>al</strong> description<br />
check -type expands into code which verifies that the v<strong>al</strong>ue of place (which must be a<br />
place suitable for use with s<strong>et</strong>f-see page 38) is of the type type-specificr. If it is not,<br />
then an error is sign<strong>al</strong>led and place is updated to the newly-supplied v<strong>al</strong>ue. Note that<br />
type-specifier is not ev<strong>al</strong>uated.<br />
description is a string which describes the type; for instance. "an integer", "a prime<br />
number greater than 403". If it is not supplied. then check-type will attempt to<br />
construct such a phrase from type-specifier; however, the current implementation barely<br />
tries at <strong>al</strong>l. so for now it is probably best to specify it.<br />
For example,<br />
(defun oddp (x)<br />
(check-type x gaussian-integer "a guassian integer")<br />
(if (typep x 'complex)<br />
(if (not (logbitp 0 (re<strong>al</strong>part x»)<br />
(logbitp 0 (imagpart x»<br />
{not (logbitp 0 (imagpart x»»<br />
(logbitp 0 x»)<br />
MC:NII.MAN:ERROR 15<br />
23-DEC-83
Errors 230 Nil. Mclllu<strong>al</strong><br />
check - arg place predicat(, &option<strong>al</strong> sIring<br />
check-arg is an oldcr form of check-type. predicate. if it is atomic. is a function of<br />
one argument to be used to test the v<strong>al</strong>ue of place:<br />
(check-arg x fixnump "a fixnum")<br />
I f it is not atomic. then it is a form to· be ev<strong>al</strong>uated to test to see if the v<strong>al</strong>ue of place is<br />
acceptable:<br />
(check-arg x (typep x '(signed-byte 8»<br />
"an eight-bit signed byte")<br />
Even if it wcre to try. check-arg would have even m()r~ tfouhlcconstructing a<br />
descriptivc string on its own than check -type. s() it is rccommended that siloing be<br />
supplicd.<br />
For example.<br />
(defun fact (x &ayx Cans 1»<br />
(check-arg x" (typep x '(integ.er 0 .»<br />
"a non-negati~e integer")<br />
(do «i 2 fl+ i») «>= ; x) ans)<br />
(s<strong>et</strong>Q an~ (* i ans}}})<br />
Hcre are somc of the interesting and well-fonned error conditions defined in <strong>NIL</strong> right now.<br />
and t11e arguments they expect. (Notc that extra arguments may <strong>al</strong>ways be given.)<br />
:wrong- type - argument type-name losing-object<br />
This has to be the most common condition uscd in <strong>NIL</strong>. type-name is the name of the<br />
type of object which was expected. such as number. and los;llg-o~i('ct is the ooject. (The<br />
type-name is not currently used fOf anything. and lots of code just puts a fairly random<br />
symbo1 there.) The v<strong>al</strong>ue r<strong>et</strong>urned is used in place of the v<strong>al</strong>ue of the wrong type. For<br />
example. a subroutine which arg-checks for fixnum:<br />
(defun si:require-fixnum (x)<br />
(do () «fixnump x) x)<br />
(s<strong>et</strong>q x (cerror t nil :wrong-type-argument<br />
"-.-5 is not a fixnum"<br />
'fixnum x»»<br />
Wrong-type-argumcnt checks are so common that it is b<strong>et</strong>ter to subroutinize or macroify<br />
them rather than writing out loops. See, for instance. check -arg (page 230).<br />
:unbound-variable variable<br />
variable was not bound. R<strong>et</strong>urning a v<strong>al</strong>ue uses that as the variable instead..<br />
:undefined- function name<br />
name is not defined as a function.<br />
instead.<br />
R<strong>et</strong>urning a v<strong>al</strong>ue uses that as the function name<br />
:wrong - number - of -arguments random<br />
This is handled spastic<strong>al</strong>ly right· now. will probably be superceded by som<strong>et</strong>hing else. At<br />
least when c<strong>al</strong>led from compiled code. r<strong>et</strong>urning a v<strong>al</strong>ue causes that v<strong>al</strong>ue to be r<strong>et</strong>urned<br />
as if from the losing c<strong>al</strong>l.<br />
:inv<strong>al</strong>id - form fonn<br />
fonn was not meaningful to ev<strong>al</strong>. The r<strong>et</strong>urn v<strong>al</strong>ue is ev<strong>al</strong>uated in place of the bad fonn.<br />
MC:<strong>NIL</strong>MAN:ERROR 15<br />
23-l>EC-S3
NIl. Manu<strong>al</strong> -231- Errors<br />
:io -Iossage t/escril'l ion Jonn<br />
Sort of a catch-<strong>al</strong>l for random I/O errors. description is a string describing the error. and<br />
Jonl1 is the form which produced it; for instance<br />
(del<strong>et</strong>e-file "[fooJbar.baz")<br />
might sign<strong>al</strong> a :io-Iossage error with a descriplion of the string<br />
"%RMS-E-DNF, directory not tound"<br />
and a Jonn like<br />
(del<strong>et</strong>e-file #
En\'ironmelll Enquiries<br />
23. Environnlent Enquiries<br />
. 232<br />
Nil. Mm1U,tJ<br />
23.1 The Host Environment<br />
lisp-implementation-type<br />
This r<strong>et</strong>urns a string which is the name of the uSP implementation, In NIl, this string is<br />
"VAX <strong>NIL</strong>".<br />
lisp-implementat1on-version<br />
This function r<strong>et</strong>urns a string which descrihes the \'ersionsof the systems loaded in the<br />
!\1I. In :\11,. this is the S4Ulle as c<strong>al</strong>ling (si:system-version -info t) (see pitge 282 for<br />
more d<strong>et</strong>ails).<br />
maChine-type<br />
This r(,lllms a string which names the type of machine the !':ll. is running on. such as<br />
"DEC VAX-11/7SO".<br />
machine-instance<br />
Relllrn~a<br />
string which is a (supposedly) unique string naming the m,tchine. such as<br />
"MIT-CORWIN". 'Jbis name wjJJ nonnaJly be the same as that used as the "host" name<br />
by the path name code.<br />
host-software-type<br />
'Ibe sofrware type of the machine. In NIl .•<br />
short-site-name<br />
this is <strong>al</strong>ways "VMS".<br />
This r<strong>et</strong>urns a shon name of the site, for instance "MIT AI Lab", If this was not s<strong>et</strong> up<br />
in the ~II site param<strong>et</strong>ers file. it win default to what is r<strong>et</strong>urned by tJle machineinstance<br />
function.<br />
long-site-name<br />
This r<strong>et</strong>urns a long name for the site. such as "MIT Artifici<strong>al</strong> Intelligence Laboratory",<br />
If this was not s<strong>et</strong> up in the <strong>NIL</strong> site param<strong>et</strong>ers file, it will default to me shon site name<br />
(above). or the machine instance.<br />
23.2 Maclisp-CompatibJe Status Enquiries<br />
(status date)<br />
r<strong>et</strong>urns a list of the year (modulo 100), month. and day of the month.<br />
(status daytime)<br />
r<strong>et</strong>urns a Jist of the current hour, minute, and second.<br />
(status dow)<br />
r<strong>et</strong>urns a symbol which is the fun name of the current day of the week (in English,<br />
sorry), lbe package the symbol is inlCrned in is probably system-intern<strong>al</strong>s: perhaps it<br />
should be the keyword package, or the v<strong>al</strong>ue should be a string anyway.<br />
MC:NII.MAN;ENV 37<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 233 Privileges<br />
(status gctime)<br />
R<strong>et</strong>urns the runtime contribution of the garbage-collector. This is. of course, <strong>al</strong>wilYs 0 in<br />
the current <strong>NIL</strong>.<br />
The first four of these may <strong>al</strong>l be obtained by use of the functions in section 23.5. page 234.<br />
23.3 Privileges<br />
g<strong>et</strong>-privileges<br />
This r<strong>et</strong>urns a list of keywords naming the privileges the ~IL<br />
keywords are listed below.<br />
currently has enabled. The<br />
s<strong>et</strong>-privileges &rest kC)'lt'ortis-and-l'o/U(,S<br />
This takes as arguments <strong>al</strong>ternating privilege keywords and flags: if the flag is nil, the<br />
corresponding privilege is disabled. otherwise it is enabled (if that is possible). s<strong>et</strong>privileges<br />
r<strong>et</strong>urns a list of the privileges which were enabled when it finished, just as<br />
g<strong>et</strong> - privileges docs. For instance.<br />
(s<strong>et</strong>-privileges :sysprv t :bypass nil)<br />
(attempts to) turn on the sysprv privilcgc, (lnd turn offthc bypass privilcge.<br />
The privilege keywords defined are<br />
:cmkrnl<br />
:cmexec<br />
:sysnam<br />
:grpnam<br />
:<strong>al</strong>lspool<br />
:d<strong>et</strong>ach<br />
:diagnose<br />
:Iog_io<br />
:group<br />
:acnt<br />
Note that for this privilege, the name used in VMS is noacnt; however, <strong>NIL</strong> uses acnt<br />
because that is the name used by DeL.<br />
:prmceb<br />
:prmmbx<br />
:pswapm<br />
:<strong>al</strong>tpri<br />
The intern<strong>al</strong> name for this is s<strong>et</strong>pri, however OCL uses <strong>al</strong>tpri, so <strong>NIL</strong> does <strong>al</strong>so.<br />
:s<strong>et</strong>prv<br />
:tmpmbx<br />
:worfd<br />
:mount<br />
:oper<br />
:exquota<br />
:n<strong>et</strong>mbx<br />
:volpro<br />
:phy_io<br />
MC:NII.MAN:ENV 37<br />
23-DEC-8J
Memory Usage<br />
234 <strong>NIL</strong> Manu<strong>al</strong><br />
:bugchk<br />
:prmgbl<br />
:sysgbl<br />
:pfnmap<br />
:shmem<br />
:sysprv<br />
:bypass<br />
:syslck<br />
2.14 l\lemory Usage<br />
room &option<strong>al</strong> str('am<br />
room prints out a fitirly verhose English description of the virtu<strong>al</strong> memory usage of the<br />
'II.. and some related infunnation. In panicular. one of the things it tells is an<br />
estimation of how much space is left for expansion of the !i"illg heap. ~hich is where aU<br />
ordinary consing is pcrfonncd.<br />
Note <strong>al</strong>so the si:pagefault-count function. pagc 224.<br />
23.5 Time and Date<br />
(See <strong>al</strong>so section 23.2. page 232.)<br />
Nil. provides a s<strong>et</strong> of functions for manipulating dates and timcs. A date and time is .<br />
represented in one of two ways: by a ullivers<strong>al</strong>-time, which is an integer number of seconds from .-<br />
00:00 January 1. 1900 GMT, and as a decoded time. which consists of the following components:<br />
seconds<br />
minutes<br />
hours<br />
date<br />
month<br />
The one-origined month number: January is 1, <strong>et</strong>c.<br />
year<br />
The full year, e.g., 1983.<br />
day-of week<br />
The zero-origined day of the week: 0 is Monday, 1 is Tuesday, and 5 is Sunday.<br />
daylighr-sQvings-time-p<br />
t or nil, depending on wh<strong>et</strong>her the decoded time is daylight savings time.<br />
timezone<br />
The number of the timclone: 0 is Greenwich time. 5 is Eastern time, -2 is Eastern<br />
European time, and -4.5 is Indian Standard time.<br />
This decoded time is not represented in any datastructure, but rather is r<strong>et</strong>urned as multiple<br />
v<strong>al</strong>ues by functions which decode univers<strong>al</strong>-time, or passed as argument'i as other functions.<br />
MC:NII.MAN:ENV 37<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 235 Time and I )ate<br />
23.5.1 The Main Functions<br />
The functions in this section arc defined by CO~MO~-I.ISP.<br />
without any package qu<strong>al</strong>ification.<br />
and <strong>al</strong>l may be referred to<br />
g<strong>et</strong>-un1vers<strong>al</strong>-t1me<br />
This r<strong>et</strong>urns the current time in univers<strong>al</strong>-time fonnat.<br />
g<strong>et</strong>-decoded-t1me<br />
This r<strong>et</strong>urns the current time. decoded. as 9 v<strong>al</strong>ues: the current second. minute. hour.<br />
date. month. year. day-or-week. daylight-sadngs-time-p. and time/one. It is <strong>et</strong>lccti\'c1y<br />
(decode-univers<strong>al</strong>-time (g<strong>et</strong>-univers<strong>al</strong>-time))<br />
decode-univers<strong>al</strong>-t1me Ullil'('rsa/-/ill/c &option<strong>al</strong> /il11c:ol1(,<br />
liIllC:UIIC dcl:IlI1t~ to the current timezone (sec page 238). This decodes IIl1ivcrstJ/-liIllC with<br />
respect to lilllc:CJ/lc. and r<strong>et</strong>urns 8 \'<strong>al</strong>ues: the second. minute. hour. d<strong>al</strong>e. month. year,<br />
day-of-week. dayliglll-sa\'ings-time-p. and time7one.<br />
encode-univers<strong>al</strong>-t1me seconds III;IIU/C.\ hours d<strong>al</strong>l' 11101l/1i yCelr &option<strong>al</strong> lil11(':o1/('<br />
tiIllC:OIIC dcf~lllltS to the current [imczone. This encodes the gin:'11 date and time for the<br />
timelone. and r<strong>et</strong>urns a univers<strong>al</strong>-time.<br />
23.5.2 Printing Dates and Times<br />
The following functions arc not glob<strong>al</strong>i7ed. but must be referred to with the time: package<br />
prefix. Most of them arc the same as those provided by LISP MACHINE LISP. All of them take a<br />
des/illatioll argument. which may be a stream. t. or nil. t means use the v<strong>al</strong>ue of standardoutput:<br />
nil me4tns r<strong>et</strong>urn the result as a string. Note that this is compatible with the way the<br />
format function (page 187) interpr<strong>et</strong>s its destination argument. not the way the regular <strong>NIL</strong><br />
printing functions do. The destination <strong>al</strong>ways defaults to t, meaning print the output on<br />
stand ard - output.<br />
time: pr1 nt-t 1me seconds minutes hours da)' month year &option<strong>al</strong> (destination t)<br />
This prints the specified date and time in brief fonnat, to destination. The fonnat used is<br />
"10/03/83 23:02:59"-the month number, the day in the month, the year (modulo 100),<br />
and the time.<br />
t1me:pr1nt-current-t1me &option<strong>al</strong> (destination I)<br />
This docs time:print-time of the current time.<br />
1<br />
t 1 me: p r 1 n t - u n 1 ve r s a 1-t 1 me ullivers<strong>al</strong>-time &option<strong>al</strong> (destination I) limezone<br />
This effectively docs decode-univers<strong>al</strong>-time on univers<strong>al</strong>· lime and timezone (which<br />
defaults to the current timezone). and then time:print-time of the results to destination.<br />
MC:NIIMAN:ENV 37<br />
23-DEC-83
...<br />
Time and Date 236 <strong>NIL</strong> Manu<strong>al</strong><br />
t 1me: pr1 nt-date srcOIu/s minutes hours date month year day-oflhe-week &option<strong>al</strong><br />
(deslillatioll/)<br />
This prints the date in a fonnat like<br />
Friday the seventh of October, 1983; 11:02:59 pm<br />
t 1me :print-current-date &option<strong>al</strong> (deslination I)<br />
Prints the current date. in time:print -date fonnat.<br />
t 1me: pri nt-un 1 versa l-date ul1il'ers<strong>al</strong>-time &optionaI (deslination I) limezolll'<br />
Uses time:print-date to print tile decoding of univers<strong>al</strong>-time and limeZ()l1e.<br />
time: pr 1 nt - br 1 ef -un 1 versa 1-t 1me ullh'rrs<strong>al</strong>-limr &oplionaJ (drs/ina/iol1/) rcferc'II('('-/imr<br />
This prints ul1irrrs<strong>al</strong>-limr in a format likc 10/07/83 23:02. Hnwc\'cr. portions of it wilJ<br />
hc omitted if they are the same· as the corresponding components of the univers<strong>al</strong>-time<br />
refrrencr-/ime (which dcfllllits to the current time). In particular. if the year is the same.<br />
it is omitted. and if the month and day are <strong>al</strong>so the same. the entire date is omitted. So<br />
depcnding on the reference time. one COUld. gel 10/07 23:02 or even just 23:02.<br />
time: p r 1 nt-un 1 versa l-ma i 1-format -date Ullirrrs<strong>al</strong>-lilllc &optionClI (dCSlilJ(1Ii011/)<br />
Prints thc date and time specified by univers<strong>al</strong>-limr in "mail fnnnat". This is a fnnnat<br />
which conforms to that specified in RFC822. "Standard for the fonnat of ARPA Intern<strong>et</strong><br />
Text Messages" [6]. It looks like<br />
Fri, 7 Oct 83 23:02:59 EDT<br />
t 1me: pr1 nt-current-ma 11-tormat-date &option<strong>al</strong> (des/inatiollt)<br />
Prints the current dilte and time. using time:print-universaf-mail-format-date.<br />
23.5.3 Namings<br />
The time package contains a sm<strong>al</strong>l database of names of months and days of the week. in<br />
various formats. The format is split <strong>al</strong>ong two dimensions: the mode. for instance :Iong,<br />
:medium, or :short, and the language. such as :english. There is a glob<strong>al</strong> default for each of<br />
these: .<br />
t1me:*default-language.<br />
The default v<strong>al</strong>ue of this is :english.<br />
time:*d<strong>et</strong>au1t-mode.<br />
The default v<strong>al</strong>ue of this is :Iong.<br />
Variable<br />
Variable<br />
The mode and language are combined (by lookup) into a composite symbol for which the<br />
lookup of the actu<strong>al</strong> text fonnat is performed. For the following functions. one may specify this<br />
composite symbol. such as :long-engJish. just the mode (:Iong), in which case the default<br />
language is used. or just the language. in which case the default nlUde is used. The three<br />
predefincd modes are :lon9. :medium. and :short. and there are entries for the languages<br />
:english. :french. :german. :spanish. and :itatian. Not <strong>al</strong>l mode/language comhinations are<br />
supported: in particular. :medium is treated as a speci<strong>al</strong> case. such that if it is not fimnd. :short<br />
is tried instead. lbc :short mode typic<strong>al</strong>ly implies the short standard abbreviation: this is usu<strong>al</strong>ly<br />
three characters. however it· is two for :german.<br />
MC:<strong>NIL</strong>MAN:ENV 37<br />
23'DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 237 'I'ime and I )ate<br />
t 1 me: mon t h - s t r in g mOlllh &option<strong>al</strong> f1lodespec<br />
R<strong>et</strong>urns a string naming thc month. in thc fonnat spccificd by mot/l'spec. Assuming the<br />
initi<strong>al</strong> dcfault v<strong>al</strong>ues for time:*default-Ianguage* and time: *default-mode*,<br />
(time:month-string 12) => "Decembertt<br />
(time:month-string 12 :short) => ttDec"<br />
(time:month-string 12 :spanish) => "diciembre"<br />
(time:month-string 9 :medium) => "Sept"<br />
(time:month-string 9 :short) => ttSep"<br />
time: day-of-the-week-string day-oJ-the-week &option<strong>al</strong> l1lodespec<br />
Similar:<br />
(time:day-of-the-week-string 1)<br />
(time:day-of-the-week-string 1 :short)<br />
(time:day-of-the-week-string 1 :medium)<br />
(time:day-of~the-week-string 1 :german)<br />
(time:day-of-the-week-string 1 :short-german)<br />
=> "Tuesday"<br />
=> "Tue"<br />
=> ItTues lt<br />
=> "Dienstag"<br />
=> ItDilt<br />
t1me:mode-language-f<strong>et</strong>ch modespec hash-Iable what<br />
This is the primiti\ e v. hich canonic<strong>al</strong>izes the modc. languagc. or composite symhol into a<br />
compositc symhol, and looks that up in hash-fable. what is just a dcscriptivc string for<br />
error rcporting. e.g.. "Month namc". The two above functions use this function to<br />
r<strong>et</strong>rievc vcctors from thc following hash tables. which arc thcn indcxcd into to gct the<br />
namcs.<br />
time: *month-str 1 ngs*<br />
Variable<br />
This is a hash tablc associating the composite mode/language symbols (e.g., :long-engHsh.<br />
:short-german) with vectors of the strings for the given months. The vcctors are zeroorigincd.<br />
so 1 must bc subtracted from the month number bcfore the aref (or sgvref) is<br />
perfonned. The vectors are <strong>al</strong>ways simple gener<strong>al</strong> vectors.<br />
time:*day-of-the-week-str1ngs.<br />
The hash table for day-of-the-week names.<br />
Variable<br />
Thus. time:month-string is defined (modulo error checking) as<br />
(defun month-string (month &option<strong>al</strong> modespec)<br />
(sgvref (mode-language-f<strong>et</strong>ch<br />
(or modespec .default-mode.) .month-strings.<br />
"Month name string")<br />
(1- month»)<br />
F<strong>et</strong>ching the vector and indexing into it can be useful if the vector is going to be used repeatedly,<br />
for instance for printing a directory listing.<br />
t<br />
~<br />
,..<br />
,.<br />
MC:<strong>NIL</strong>MAN:FNV 37<br />
23-()EC-H3
Time and Date 238 <strong>NIL</strong> Manu,tJ<br />
23.5.4 Timezones<br />
.t.. mezone. Variable<br />
The v<strong>al</strong>ue of this is the current timezone. It should be initi<strong>al</strong>ized in the <strong>NIL</strong> site<br />
initi<strong>al</strong>ization file to the correct v<strong>al</strong>ue; otherwise. it will be 5. which is Eastern time.<br />
time: t 1mezone-str .. ng &option<strong>al</strong> timezolle daylighl-savings-p<br />
This r<strong>et</strong>urns the canonic<strong>al</strong> three-charitcter string for the timczone. or nil if the name is not<br />
known to NIl ..<br />
(time:timezone-string 5 nil) => "EST"<br />
(time:timezone-string 5 t) => "EDT"<br />
(time:timezone-string 0 nil) => "GMT"<br />
lill1c:wlt' defintlts to the current timezone. and daylighh~m'il1g.'i-p to the v<strong>al</strong>ue of<br />
(time:daylight-savings-p).<br />
23.5.5 l\1iscellaneous Other Functions<br />
time: leap-year-p year<br />
R<strong>et</strong>urns t if year is a leap ye,)r. nil otherwise.<br />
t1me:dayl1ght-sav1ngs-p<br />
R<strong>et</strong>urns t if it is currently daylight savings time. nil otherwise.<br />
t1me:month-length month year<br />
R<strong>et</strong>urns the length of the month month in year.<br />
t 1 me : day 1 i 9 h t - s a vi n 9 s - t 1me-p hour day month year &option<strong>al</strong> limeZOlle<br />
R<strong>et</strong>urns t if the specified dHy/time is in dayJight savings time in the specified time/one<br />
(which defaults to the current timezone). nil otherwise. (The specified hour is assumed to<br />
be standard time.) Note <strong>al</strong>so section 23.5.6. page 239.<br />
time: day-of-the-wesk (day month year)<br />
R<strong>et</strong>urns the number of the day of the week of the specified date.<br />
t1me:ver1fy-date day m01lth year day-ofweek<br />
If day is a day within month which fell on dayofweek. this r<strong>et</strong>urns nil; otherwise. it<br />
r<strong>et</strong>urns a string describing the conflict<br />
time :moonphas8 &optionaJ ullivers<strong>al</strong>-time<br />
R<strong>et</strong>urns the phase of the moon decoded into five v<strong>al</strong>ues: the (zero-origined) number of<br />
the quarter. the day .. hour. minute. and second. The Quarters are (from 0 to 3) new<br />
moon, first quarter, fun moon, and last. quarter. This is presumably the uncorrected<br />
mean longitude.<br />
MC:<strong>NIL</strong>MAN:ENV 37<br />
23-DFC-83
<strong>NIL</strong> Manu<strong>al</strong> 239 Timc and Date<br />
t1me:pr1nt-moonphase quarter day hour minute second<br />
Prints the phase of the moon in a fonnat like "FM + 2Il3H.29M.57S.". The first field will<br />
be one of "NM", "FQ", "FM", or "LQ". Zero-suppression is perfonned on the other<br />
fields: for instance, "FM + 2D.29M.".<br />
time: pri nt-current-moonphase &option<strong>al</strong> (des/illation t)<br />
Similar.<br />
Note <strong>al</strong>so the g<strong>et</strong>-intern<strong>al</strong>-run-time and g<strong>et</strong>-intern<strong>al</strong>-re<strong>al</strong>-time functions. on page 223.<br />
2.15.6 \',uiations in nH)'light Savings Time<br />
The timezone objects ~Il. lIses to store information on particular time/ones include a function<br />
which may be lIsed to tell if a particular hour. day. month. and year (when intcrpr<strong>et</strong>ed as<br />
sLmdard time) is in daylight time. Most of the initi<strong>al</strong> timezone entries have nil in this component.<br />
which is taken to mean that the zone never uses daylight time. It may be necessary to patch this<br />
up: some functions and hacks arc presented here to aid in this.<br />
t 1me: zoneconv tilll('Z(Jlle<br />
If timezol1c is a timezone object (an object of type time:timezone), it is r<strong>et</strong>urned. If it is<br />
a number. then an existing timezone entry for that offs<strong>et</strong> in the list time: *timezones* is<br />
r<strong>et</strong>urned.· (Otherwise an error is sign<strong>al</strong>led.)<br />
If the daylight-savings-time predicate ~IL supplies is not appropriate for the site (or is just<br />
plain incorrect). it can be patched by<br />
(s<strong>et</strong>f (time:timezone-dst-rule<br />
(t ime: zoneconv timezone-offs<strong>et</strong>»<br />
'beandorfian-daylight-savings-time-p)<br />
where timezol1e-offsc/ is the offs<strong>et</strong> from GMT of the timezone in question, and beandorfiandaylight-savings-time-p<br />
the predicate which tells wh<strong>et</strong>her any particular hour in a particular<br />
year is in daylight savings time.<br />
t<br />
I<br />
I<br />
f<br />
f i<br />
~<br />
I<br />
t1me:regular-american-dayl1ght-savings-t1me-p hour day month year<br />
This r<strong>et</strong>urns t if hour, day. month, and year is b<strong>et</strong>ween 1 am of the last Sunday in April<br />
and 1 am of the last Sunday in October (see below).<br />
t1me:last-sunday-in-apr11 year<br />
R<strong>et</strong>urns the day of the month on which the last Sunday f<strong>al</strong>ls in April.<br />
t1me:last-sunday-1n-october year<br />
R<strong>et</strong>urns the day of the month on which the last Sunday f<strong>al</strong>ls in October.<br />
Computations like "last Sunday in April" are fairly easy to perfonn. To find the last dow day<br />
in a month. find the day-of-the-weck of the last day of the month. and subtract the number of<br />
days it takes to g<strong>et</strong> back to the desired day of the week. For instance,<br />
(defun last-sunday-in-april (year)<br />
(-& 30 (\\& (-& (+& 7 (day-of-the-week 30 4 year» 6) 7»<br />
111C 30 is the last day in April. 4 the month April: 6 is Sunday, and the 75 and arithm<strong>et</strong>ic with<br />
thcm doing modulus stuff. Obviously the arithm<strong>et</strong>ic can be simplified to<br />
~1C:NII.M:\N:ENV 37<br />
23-1)FC-83
Time and Date 240 Nil. Manuitl<br />
(-& 30
,1\ \1..muJl 241 Job/Process and System Information<br />
Iki.:.li.l'C '11 must use the V\1S time to d<strong>et</strong>ennine the abso1ute time. g<strong>et</strong>-univers<strong>al</strong>-time (nnd<br />
.," ~,::;c.., y,hich r<strong>et</strong>urn results based on that quantity. which is just about <strong>al</strong>l the time and date<br />
.' ~ "!,l;" In this ~c:ction) can r<strong>et</strong>urn an incorrect v<strong>al</strong>ue. Also. the quantities r<strong>et</strong>urned by elapsed-<br />
• _ .• ~.. I,<br />
t'rT".~ 'r. 1 F 22)) Jnd g<strong>et</strong>-intern<strong>al</strong>-reaJ-time (page 223) are based on this. meaning that if a shift<br />
'~, l"~ (lut of daylight time occurs and the VMS base time is changed, elapsed time measured<br />
.:', '_ ~,J the shift will be incorrect. There is a variable provided for telling <strong>NIL</strong> about two potenti<strong>al</strong><br />
\. -';,'-;.-v. ide COO\ cntions for bypassing this son of 10ssagc.<br />
t 1:1e: • sy s tem- time - k 1 udge*<br />
Variable<br />
'I hI'-. ma~ take on one of three v<strong>al</strong>ues,<br />
nil This is the default. It means that the \'\is hase time is <strong>al</strong>\\'ays the loc<strong>al</strong> time<br />
(r()[('nti<strong>al</strong>ly daylight time). and hence subject to compl<strong>et</strong>e lossage.<br />
:standard<br />
This means that the \'\1S base time is <strong>al</strong>ways based on the standard time for the<br />
current timclone.<br />
:gmt<br />
This means that the \,\15 hase time is GMT (implies never daylight time).<br />
f'l:hcr of the last two options eliminate the amhigous·hour and incorrect-elapsed-time<br />
r11 ·hkm' \\ hich might bc suffered otherwise. Of course. they mean that <strong>al</strong>l the \\1S<br />
uulJ[i~~ v.hich show dates and times won't work quite right. Oh well.<br />
I !~,: .1!1(1\ e \41flable is examined for conversion of <strong>al</strong>l \'MS intern<strong>al</strong> times into univers<strong>al</strong> time.<br />
\~..: ::\ \!~.::l~. fllr interpr<strong>et</strong>ation of the current time, if the ahove variable is nil. then the<br />
: ' : _:,::~' :\,f,;.. ll: ii,li"I"I(" is ~xdji"dlh:;d. (Thj~ is d lugi\.ai ll.tllU': u~\.:Jhh:f1ll1.:J by Cili.tO~IlCl ~(Jrlware<br />
,:
Job/Process and System Infonnation .<br />
242<br />
<strong>NIL</strong> Manu
Nil. Manu<strong>al</strong> -243 (\Hnpilation<br />
24. Conlpilation<br />
lompil<strong>al</strong>ion is essenti<strong>al</strong>ly the process of translating from one specification into another which<br />
is presumably more cfficient. and probably more low-level in some respects. The ~IL compiler<br />
translates LISP code into the VAX instnlctions neccssary to execute that code: some of these<br />
instructions may perfonn the task directly, while others may c<strong>al</strong>l functions or 1'\11. kernel<br />
subroutines to do it. In any event. the end result is intended to exclude the ~II. interpr<strong>et</strong>er from<br />
thc running of the program. The ~II. compiler does not output \iACR032 code or anything of the<br />
son: rather. it represents the code and data itself. and assembles the code. liSP objects<br />
referenced hy the code. and whatever other infonnation is needed to help construct that data.<br />
into a cOlI/pi/rc/ codr l11udule. This is what the module daw type represents.<br />
\\'hen the 'II compiler compiles a file. it first estahlishes the proper eJl\ironment for the<br />
compilation. as specified hy the file's attrihule list (described in section 19.8.6. page 205). That<br />
done. it reads and processes each fonn in the file. What it docs with each fonn depends on what<br />
the fonn is.<br />
( pro c 1 aim del-Sptc )<br />
If the y<strong>al</strong>ue of the fOl1n dcl-sprc can be d<strong>et</strong>ennined at compile-time. then the compiler<br />
will attempt to assert that proclamation for at least the duration of the compilation. Sec<br />
proclaim, page 46.<br />
(dec 1 are {dcP·spec}.)<br />
The del-specs are processed. and L1Ke effect for at least the remainder of the compilation.<br />
ut=dare ill uli~ UHllCXl i~ son of iikc prociaim with muitipic unevaiu3tea arguments:<br />
howe\er. this usage (non-loc<strong>al</strong> declarations) of declare is being phased out and subsumed<br />
by proclaim. It will be probably bc supported indefinitely. and will <strong>al</strong>so be accepting<br />
certain MACLISP-sty]c declarations which proclaim will not.<br />
(eva l-when k ... -J-lisl [onns . .. )<br />
If compile is a member of kwd-lisl. <strong>al</strong>l of the [onns are ev<strong>al</strong>uated then and there. Then,<br />
if load is a member of kwd-list. the [onns are recursivcly processed.<br />
(progn fonns . .. )<br />
fonns are recursively processed. Note that this is identic<strong>al</strong> to (ev<strong>al</strong>-when (load) fonns ... ),<br />
and upwards-compatible with the MACLlSP (progn 'compile fonns ... ) hack.<br />
(ccmp i 1 e r-l <strong>et</strong> bindings forms • .• )<br />
Establishes the bindings specified by bindings. then recursively processes fomls in that<br />
environment. See page 245.<br />
( de fun Ilame argUst <strong>et</strong>c . .. )<br />
(defun (name property-name) arglist <strong>et</strong>c ... )<br />
The function is compiled, and the appropriate assignment (function cell or putprop) will<br />
be put in the compiler's output file.<br />
( de f mac r 0 name <strong>et</strong>c.. . )<br />
(macro n<strong>al</strong>l1r lambda-list <strong>et</strong>c ... )<br />
Thc specified macro definition for name is added to the compilation environment. Then.<br />
the macro is compiled. so will be there when the compiled output file is loaded. It may<br />
not be depended on that name is defined in the liSP environment itself: only that code<br />
MC:NII.MAN:COMPIL 37<br />
23-I)EC-83
Compilation 244 Nil. Manu<strong>al</strong><br />
being compiled will have the macro run to produce the expansion. If it is necessary for<br />
the macro to actu<strong>al</strong>ly be defined (perhaps in order for it to be c<strong>al</strong>led from within other<br />
macros, as opposed to just expanded in code. being compiled). then the defmacro or<br />
macro fonn should be enclosed within an (ev<strong>al</strong>-when (compiJe ... ) ... } fonn.<br />
(defun name macro lambda-list <strong>et</strong>c .. • )<br />
Ine compiler whines at you and turns this into macro. This is provided to catch old<br />
MACUSJ> code which should probably use defmacro (or at the very least macro) instead.<br />
( de fun l1a1llP fe x p r lambda-lisl elc .• • )_<br />
"1l1e compiler barf.~ at you and turns this into a speci<strong>al</strong> form definition. C<strong>al</strong>ls to it from<br />
compiled code wil1 not work. If name is only around f(lr users to c<strong>al</strong>iintcracti\'cly,<br />
howe\'er, it might just function properly. This is provided only to brute-fi)ree through<br />
some ~f:\U IS]> progr~tms. Gener<strong>al</strong>1y. speci~ll fonns or frxprs should be rewritten as<br />
macros.<br />
( def u n Ilame <strong>al</strong>om elc ... )<br />
The function definition is assumed to be a MACI.ISP lexpr. It is transfonned appropriately,<br />
and compiled. after the compiler g<strong>et</strong>s through giving yuu a hard time.<br />
(defflavor <strong>et</strong>c)<br />
Code to perform the flavor definition at load tin;~ is generated. Addition<strong>al</strong>ly. declarative<br />
information is added to the compilation environment so that defm<strong>et</strong>hods will compile<br />
correctly, and the routines defined for the :outside-accessible-instance-variables can<br />
be compiled correctly.<br />
(defm<strong>et</strong>hod <strong>et</strong>c)<br />
Compiles the code for the defm<strong>et</strong>hod.<br />
a1lyth illg-else<br />
If anything-else is a macro caU or a c<strong>al</strong>l to a function the compiler has speci<strong>al</strong> rewrite<br />
information about, the macro expansion or rewrite is performed~ and the compiler tries<br />
again. Otherwise. anything-else will be ev<strong>al</strong>uated at load time. Currently this i~ done by<br />
compiling the expression. which eliminates load-time dependencies upon macros.<br />
There are various other fonns which implicitly do compile-time processing by vinue of how they<br />
are defined. rather than by the compiler recognizing them speci<strong>al</strong>ty. For instance, defstruct<br />
(currently) by default expands into the appropriate macro, function, and data definitions, with<br />
appropriate use of ev<strong>al</strong>-when. For this reason, the above list cannot be taken as being <strong>al</strong>linclusive.<br />
compile-file input-Jile &key package sel-dejaull-p<strong>al</strong>hname oUlpul:/ile dejiluil-pathname<br />
defaults<br />
Compiles input-jile, storing the vasl file in output-jile.<br />
If package is specified, then the file is read in in that package, in spite of what might be<br />
specified in the source file propcny list (see section 19.8.6, page 20S).<br />
The input-file is defaulted from the dejaull-p<strong>al</strong>lmame if any, and then from dejQuils.<br />
which should be a pathname defilUlts. If sel-dejiJull-p<strong>al</strong>llllame is not nil. then the default<br />
pamname of defoulls (which defaults to the v<strong>al</strong>ue of .toad-pathname-defaults., page<br />
201) is updated.<br />
MC:NII.MAN:COMPIL 37<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 245 Compilation<br />
OU/pul-file defaults to illpu/:/ile with a vasl file type (VMS extension of VAS).<br />
By speci<strong>al</strong> dispensation (to those of me who cannot g<strong>et</strong> out of the habit of using this<br />
feature), if exactly two arguments are given to compile-fife, then the first is the input file<br />
and the second is the output file. This is typicaUy used like<br />
(compile-file "[nil.io]iofun" "[nil.vas]")<br />
The CO:vt:vtO~ LISP definition of compile-file accepts only the keyworded argument outpu/<br />
file.<br />
comfil e ...<br />
Alternate name for compile-file. CO\1\fO~ LISP defines the use of the name compilefile.<br />
hut not comfile, f(lr whatcver that is wonh. .<br />
compil e jUllction<br />
Compiles the interpr<strong>et</strong>ed (and in-core) definition of jUlic/ioll, in-core. That is.<br />
(defun fact (x)<br />
( i f (z e r 0 p
Intcraction Control . 246 <strong>NIL</strong> Manu<strong>al</strong><br />
switch. and these arc now obsoleledby usc of the optimize declaration. compiler-l<strong>et</strong> is<br />
still useful. of course. for communication b<strong>et</strong>ween macros. and that is its intended usc<br />
anyway.<br />
24.1 Interaction Control<br />
compiler: .messages-to-term1n<strong>al</strong>?<br />
Variable<br />
If this is not nil. then the compiler (compile-file and compile. and cvcn the I.SB-defincd<br />
function Isbcl [4}) will print out verbosely on thc termin<strong>al</strong>. If it is nil. nothing will bc<br />
printed. unless crrors occur. which is a separate can of worms. By default. this is t.<br />
24.2 Efficienc),'t Optitnilation .. and Benchmarking<br />
The current :,\11 compi1er is incredihly stllrid in some ways. 8asic<strong>al</strong>ly. it is an o\"crgrown<br />
one-pass code generator: it takes in a USP program. and spits out VAX machine language.<br />
m~lking liber<strong>al</strong> usc of LISP function c<strong>al</strong>ls and speciill subn.dtincs to handle things which arc too<br />
hulky or too complex for it to cod
NIl. Manu<strong>al</strong> 247 Efficiency. Optimization, and Benchmarking<br />
to briefly describe it more gener<strong>al</strong>ly. Basic<strong>al</strong>ly, a function c<strong>al</strong>l is handled hy the c<strong>al</strong>ler "creating"<br />
a c<strong>al</strong>l frame on the stack, filling it in. and then perfonning the actu<strong>al</strong> c<strong>al</strong>l. When such a frame<br />
is created, it can be recognized as such by a debugger (the current one doesn't know beans about<br />
it. but that is beside the point). and. while the arguments are being computed. it is possible to<br />
ten not only what function is aboul to be caned. but which arguments to it have been computed<br />
(and what their v<strong>al</strong>ues are). and which have not. If the compiler decides that it is ok to not have<br />
quile this much debugability. it might decide to try to compute some of the arguments as it<br />
creates the function c<strong>al</strong>l argument frame-this can save both space and time. but means you<br />
cannot tell what is going on while it is happening. No matler which way it does this. it may still<br />
have to push varying length blocks of constants on the stack. Even herc. therc arc spacc/time<br />
tradcofls to hc made: for instancc. helow some threshold. it takcs long.er to do a block -movc<br />
than to do a series of movcs/pushcs. And. therc is a decision as to what constant it is that g<strong>et</strong>s<br />
pushed: a marker (rccognizable by the debugger). or just zeroes (which can be done more<br />
efficicn t I y).<br />
Another area is that of ccrtain functions which can bc inline-coded. but which arc nonn<strong>al</strong>ly<br />
too hulky (0 make it worthwhilc under nonn<strong>al</strong> circumstances. memq is a finc example of this.<br />
Nonn<strong>al</strong>ly. memq is a minisuhr which will give a correctahlc crror if thc list is not a proper list.<br />
and which will d<strong>et</strong>ect circularity. If specd is myc important th,1I1 space and saf<strong>et</strong>y. however. the<br />
compilcr can in line-code the loop. Thc exact d<strong>et</strong>ennination is not only a filnction of the qu<strong>al</strong>ities<br />
specified with optimize. but <strong>al</strong>so the particular circumstances. If the list argument to memq is<br />
known at compile time. then the compiler can verify that it is a non-circular proper list. and thus<br />
no longer has to worry about the "saf<strong>et</strong>y" of the c<strong>al</strong>l. I f in addition the memq is being used for<br />
"plcuil:<strong>al</strong>C vaiuc·'. lh<strong>al</strong> is. in a comeXl iike<br />
( if (memq item lisl) liJell-do-lhis else-dc-this)<br />
whcre the specific v<strong>al</strong>ue of the memq does not matter, then the compiler can just code out the<br />
proper series of eq checks. How many it will be willing to do this for. is once again a<br />
space/time tradcoff.<br />
There is another class of optimization which can be perfonned: that is unfolding of common<br />
cases out of a more generic routine. For instance, the 1 + and 1- functions (page 74) are coded<br />
as minisubrs. They arc fairly generic, since they can accept arguments of any numeric type. But<br />
a common usage is with arguments which are fixnums. If space is not considered particularly<br />
important. but speed is. then the compiler can check to see if the argument is a fixnum. and if<br />
so do the addition or subtraction itself without g<strong>et</strong>ting into the generic routine. Because the code<br />
only does this on things it has verified as fixnums. and because it checks for overflow. this<br />
particular optimization does not involve "saf<strong>et</strong>y",<br />
Another aspect of "saf<strong>et</strong>y" is how likely the operation being perfonned is to produce<br />
som<strong>et</strong>hing "illeg<strong>al</strong>": in a LISP implementation like <strong>NIL</strong>. many objects like fixnums and characters<br />
have their data represented in the pointer. and operations on those objects just do operations on<br />
the pointers. For certain trivi<strong>al</strong> operations. of which many of the character functions (chapter 11)<br />
are characteristic, the compiler might choose to produce code which is a bit more circumspect<br />
ahout what it docs with pointers. what data-types of objects it might generate if given erroneous<br />
inputs. or possibly even wh<strong>et</strong>her it inline codes at <strong>al</strong>l. depending on what the result of an<br />
erroneolls input mig.ht imply. Take. for example. char-upcase: if this were inlinc-coded (it<br />
might not be in this particular version of i\1L). it effectively would be replacing part of the<br />
"address field" of the pointcr which is its argument. by som<strong>et</strong>hing elsc. If that argumcnt was not<br />
a character. but (say) a vector, it is quite likely that the resultant object would be unprintable.<br />
MC:NII.MJ\N:COMPIL 37<br />
23-DEC-83
Ftlicicncy. Optimi/<strong>al</strong>ion. and Benchmarking 248 <strong>NIL</strong> Manu<strong>al</strong><br />
givc garbage whcn examined. and. assuming the existence of a garbage-col1ectoT. cause the<br />
garbage-collcctor to fail in the middle of its operation. leaving thc LISP tot<strong>al</strong>ly useless. Many<br />
operations of. this nature. while having a moderate amount of overhead if done as function c<strong>al</strong>ls<br />
with error checking. can be made to at least not r<strong>et</strong>urn such objects with only a trivi<strong>al</strong> overhead.<br />
\\'hiIc in a sense this masks errors rathcr than d<strong>et</strong>ects them. having your lisp gct blown away by<br />
an iIleg<strong>al</strong> pointcr does not facilitate debugging either. In this regard, the things which heed the<br />
saf<strong>et</strong>y optimization qu<strong>al</strong>ity will gencr<strong>al</strong>ly not inline code at <strong>al</strong>l (depending on their trivi<strong>al</strong>ity) jf the<br />
safcty qu<strong>al</strong>ity is s<strong>et</strong> to 3. (Also. in gencr<strong>al</strong>. only high-level routines might offcr this choice: the<br />
:\11 fixnum-only routines. and character "subprimitives". will <strong>al</strong>ways inline-code. and not offer this<br />
safcty "option".)<br />
Thcrc ,Irc \·cry fe~' things which rccognilc thc compilation-speed optimi/
<strong>NIL</strong> Mdllu<strong>al</strong> 249 Illlroduction to thc STEV E editor<br />
25. Introduction to the STEVE editor<br />
25.1 Introduction<br />
STEVE is a gener<strong>al</strong> purpose screen oriented text editor based upon the EMACS editor. In many<br />
respects STEVE and E\1ACS arc identicaL with the primary difference being that STEVE is written in<br />
Nil. for the DEC VAX -11 series computers and can be c<strong>al</strong>led directly from the i'll. interpr<strong>et</strong>er.<br />
Those who arc familiar with EMACS will be able to usc STEVE immediately, and should skip to<br />
the end of this chapter, as the first part is meant to be an introduction to STEVE.<br />
25.2 G<strong>et</strong>ting Started<br />
There is one diflcrence h<strong>et</strong>w.een the editor environment and the rest of '" to he aware of.<br />
IkGllI~e the editor and \"\1S ha\"c conflicting uses for many of the control keys. the editor must<br />
nm in "pass<strong>al</strong>l" mode. This implies tJlat the nonn<strong>al</strong> interrupt cmrmands do not norm<strong>al</strong>ly work in<br />
tJle editor. So the first command to learn is tile ediLOr command to r<strong>et</strong>urn to \\!1atc\er you \.\ere<br />
doing hefore you entered the editor. It is a two key command typed hy holding down the<br />
"Control" ke) and pressing the "Z" key twice.<br />
Control-Z Control-Z R<strong>et</strong>urn-to-superior.<br />
Exit tJle editor and r<strong>et</strong>urn to whoever c<strong>al</strong>led it. This is tJle nonn<strong>al</strong> way to exit from<br />
STFVE.<br />
Now that you know how to exit the editor you may be curious how to enter it. Of course<br />
tJlis is not an editor command, but ratJ1er a 1'lL function.<br />
ad &option<strong>al</strong> wh<strong>al</strong>-Ia-edit<br />
Enters the editor, r<strong>et</strong>urning to whatever you were working on before. If you have not<br />
run the editor since starting <strong>NIL</strong> it will be compl<strong>et</strong>ely initi<strong>al</strong>ized with one empty buffer.<br />
or<br />
Norm<strong>al</strong>ly one types (ed) to the <strong>NIL</strong> interpr<strong>et</strong>er to g<strong>et</strong> into STEVE. what-ta-edit may be a<br />
path name (or string naming a file), or the name of a function. If given, the editor will<br />
try to find the file or function definition and l<strong>et</strong> you edit it: otherwise the argument is<br />
ignored. There arc editor commmands to find files and function definitions anyway, so<br />
the argument is not re<strong>al</strong>ly very importan~ except that it can be convenient. and can be<br />
used from programs.<br />
MC:<strong>NIL</strong>MAN;EDITOR 18<br />
23-DEC-83
Editing Files 250 <strong>NIL</strong> Manu<strong>al</strong><br />
25.3 Edit i ng Files<br />
The principle purpose of an editor is to create or modify a file. In broad outline an editor is<br />
used by reading a file into a buffer. modifying it somehow and then writing it back to some long<br />
term storage device. gener<strong>al</strong>ly a disk. Most of the editor commands arc concerned with modifying<br />
a buffer. and will be expained later. In order to understand the commands for reading and<br />
writing files one should know about the gener<strong>al</strong> structure of STEVE and its buffers.<br />
I <strong>NIL</strong> I<br />
I Editor I<br />
I \<br />
I \<br />
J Buffer-l I<br />
I Buffer-2 I<br />
I File-l I<br />
I File-2 I<br />
As the diagram shows. the editor runs inside Nil.. and contains any number of buffers, each<br />
of which is associated with a file. This diagram can be modified by creating a new buffer or<br />
kiHing one, or by changing the file associated with any buffer. There arc editor commands for <strong>al</strong>l<br />
of these operations. and for some more complex combinations of them. The editor <strong>al</strong>ways selects<br />
one buffer as the current buffer, and displays a section of it around the cursor.<br />
The fonnat of this display is· one of the features of an EMACS style editOr like STEVE, and is<br />
the reason it is c<strong>al</strong>led a "screen editOr".<br />
MC:<strong>NIL</strong>MI\N:EDITOR 18<br />
23-DEC-83
Nil. Manu<strong>al</strong> 251<br />
Editing Files<br />
This is a picture of what an editor I<br />
display might look like except that is is very'<br />
sm<strong>al</strong>l. ,<br />
Note that the cursor is at the end of ,<br />
the previous paragraph. ,<br />
I<br />
I<br />
I<br />
STEVE foo (LISP) disk:[cre]bar.lsp {3} --. I<br />
I<br />
I<br />
The hox in the diagram represents tllcedgcs of a ternlin<strong>al</strong> screen. The two paragraphs are<br />
thc contents of a huffer. The single line below tllat is c<strong>al</strong>led the mode line. It contains as l1Hch<br />
in f'(mnation ahout the currcnt sUite of the cditor as is convenient. From tllis we see that tlle<br />
buffcr is named "foo" and that it is associated with the file "disk:[cre}bar.lsp". The notation {3}<br />
after the file name indicates that the current version number is 3. If the file does not exist on<br />
disk the version number and tlle braces will be missing from tlle mode line. The star (*) on the<br />
right of the mode line indicates that the buffer has bcen changed so it is not the same as the file<br />
Oil Ul~~. Tile \.:Uln:1ll po~ition uf the cursor is at the end of the first paragraph. (On most<br />
tennin<strong>al</strong>s a cursor shows up as a blinking underscore or box. though this depends upon tlle exact<br />
type of tennin<strong>al</strong>. In this chapter we show the cursor as a underline (-) since it is fairly difficult<br />
to print a blinking cursor.)<br />
Under the mode line is a blank area of sever<strong>al</strong> lines. This is c<strong>al</strong>led the mode area and it is<br />
where most error messages and prompts are shown.<br />
We are <strong>al</strong>most ready to start expaining the individu<strong>al</strong> editor commands. The only other thing<br />
you should know first is how they arc typed. Most STEVE commands are either one or two<br />
character commands. Since one adds <strong>al</strong>phab<strong>et</strong>ic characters to the buffer simply by typing them<br />
(not that you know this y<strong>et</strong>) STEVE must not use <strong>al</strong>phab<strong>et</strong>ic characters for its commands. Instead<br />
the control characters are used. (The control characters are typed by holding down the "control"<br />
key and pressing some other key, just as the capit<strong>al</strong> l<strong>et</strong>ters are typed by holding down the shift.<br />
key.) Since there are not enough control keys for <strong>al</strong>l of STEVE'S commands it <strong>al</strong>so uses a m<strong>et</strong>a<br />
key. A M<strong>et</strong>a key is similar to a shift key or a control key. Now we can have the characters Ha U ,<br />
"A", "Control-A", "M<strong>et</strong>a-A", and "Control-M<strong>et</strong>a-A".<br />
Unfonunately most termin<strong>al</strong>s do not have a m<strong>et</strong>a key. Not to worry, though, STEVE is<br />
designed to work without i~ just as certain text justifiers are designed to work with tennin<strong>al</strong>s<br />
which have no lower case. Three commands are "bit-prefix" commands. Typing one of these will<br />
change the next character you type just as if you had been holding down the corresponding<br />
combination of control and m<strong>et</strong>a keys.<br />
MC:NII.MAN:EDITOR 18<br />
23-I)FC-83<br />
. -'- .:.-- - ... .. - ,-,:,. . ~ . ,~.- .<br />
·,,:.':'. ,;~, ~~ ~i~~£~~~)' ::~' ," .":: ":,,.:~: ,,' , ' .
Editing Files 252 Nil. Manu<strong>al</strong><br />
Altmode<br />
Prefix~M<strong>et</strong>a<br />
Pressing Allmode (marked SELECT or ESCAPE on some termin<strong>al</strong>s) will make the next<br />
character a "m<strong>et</strong>a" character. For example Allmode F(two characters) is the same as<br />
Al<strong>et</strong>a-F (one character).<br />
Control- Prefix-Control<br />
A<br />
Pressing Control;. t (control-uparrow) wilJ make the next character a "control" character.<br />
For example Control-t F (two characters) is the same as COlllrol-F (one character). On<br />
some termin<strong>al</strong>s. notably the vnoo. ((mtrol-t is typed as ('olllrol-- (control tilde);<br />
norm<strong>al</strong>ly. the A character is a shifted 6. so one holds down control, shift, and 6.<br />
Control-Z Prefix-Control-M<strong>et</strong>a<br />
Pressing ('emlrol-/. will make the next ch41r41cter be both a control and a m<strong>et</strong>a character.<br />
For example CUll/rol-/' F (two characters) is the s.lnle as COlllrol-Alela-F (one ch~lracler).<br />
All of these bit-prefix commands add the qu<strong>al</strong>ity to the next character. There is no problem<br />
with doing it twice. The two character sequences COlllrol-ZZ and ('oll1ro/-7. ('o11lrol-Z both 4lre<br />
read as ('olllro/-Alela-/..<br />
We are now ready swrt expaining the various editor commands. These are the commands you<br />
will use to create buffers and write files. All of these commands arc safe to use since they will<br />
notice if you are about to destroy any of your work and ask you if you re<strong>al</strong>ly want to do that.<br />
Control-X Control-F Find-File<br />
Find-File will prompt filr a file name and you should type it from the keyboard. If there<br />
is a buffer for that file then it wiU be selected and be the new current buffer. Otherwise<br />
a buffer is created for the file and the file is read in from disk if it exists there. Find<br />
File is the most common way to read a file from disk. It creates a new buffer for each<br />
file which is convenient. When Find-FHe creates a buffer it lIses the file name without<br />
any extention as the buffer name. Since the name of each buffer must be unique this<br />
docsn't work when you are editing two files which have the same name but are on<br />
different directories or have different extensions (file types), so Find-File will notice if you<br />
are doing this and will ask you for a new buffer name to use.<br />
Control-X Control-S Save-File<br />
Save-File . writes the current buffer to its associated file, and changes the mode line to<br />
indicate that the buffer and file are now identic<strong>al</strong>. (This is not done until the output is<br />
compl<strong>et</strong>e. so if there is a disk error or some other error you will not think it has . been<br />
saved when it hasn't been.)<br />
Control-X Control-V Visit-File<br />
Control-X Control-R<br />
Visit-File is 1ike Find-File except that it re-uses the current buffer. destroying its contents.<br />
It is still safe since it will·offer to save it if any changes have been made to it<br />
Control-X Control-W Write-File<br />
Write~File writes the current buffer to a file, but .unlike save file it wi1J prompt you for<br />
the file name.<br />
MC:NII.MAN:EDITOR 18<br />
2]-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 253 Editing Files<br />
As an example. suppose that the screen looks like the diagram ahove. If you type Colllrol-X<br />
COl1tro/- H' (\\'rite-File) the editor will prompt you for a file name. Assume you want to save the<br />
file into disk:[cre]baz.lsp. You type "disk:[cre]baz.lsp". The screen will look like<br />
this:<br />
This is a picture of what an editor<br />
display might look like except that is is<br />
sm<strong>al</strong>l.<br />
Note that the cursor is at the end of<br />
the previous paragraph.<br />
STEVE foo (LISP) disk:[cre]bar.lsp {3} -- •<br />
Write File:disk:[cre]baz.lsp_<br />
I<br />
I<br />
verYI<br />
I<br />
I<br />
I<br />
I<br />
I<br />
I<br />
I<br />
I<br />
I<br />
I<br />
Notice that the cursor is temporarily placed in the mode area. After the command is<br />
compl<strong>et</strong>e it will r<strong>et</strong>urn to the text in· the buffer. The editor will fill in an incompl<strong>et</strong>e file<br />
specification for you. using the file specification associated with the huffer. In this example the<br />
liic mum.:
Modifying the huffer 254<br />
Nil. Manu<strong>al</strong><br />
This is a picture of what an editor I<br />
display might look like except that is is veryl<br />
sm<strong>al</strong>l._<br />
I<br />
Note that the cursor is at the end of I<br />
the previous paragraph.<br />
I<br />
I<br />
I<br />
I<br />
STEVE foo (LISP) disk:[cre]bar.lsp {I} -- I<br />
Wr it in 9 F i 1 e . . . I This lil1l' ...<br />
Wr i t te n SAl. LSP : 1 [CRE ]01 SK :<br />
I Theil litis line<br />
Nolice th<strong>al</strong> the cursor has r<strong>et</strong>urned to the huffer text ~Uld that the star (*) has been removed<br />
from the mode line to indicate that the buffer and file arc identic<strong>al</strong>. and that the version number<br />
h'l~ heen changed to 1. This is because the new file name did not exist on disk. Had the file<br />
been sm ed under its old name the version number would have been incremented by 1 from 3 to<br />
4. Fin<strong>al</strong>ly the file name in the mode area has been updated so that Save· File wm usc the new<br />
file name.<br />
25.4 l\lodifying the buffer<br />
25.4.1 The Simplest Commands<br />
As I hinted before. typing any <strong>al</strong>phanumeric character will add it to the buffer. In fact<br />
<strong>al</strong>most any character that you can type without holding down the control key will act like this.<br />
Also, the del<strong>et</strong>e (or rubout) key will del<strong>et</strong>e the last character before the cursor. If you can place<br />
the cursor where you want it and del<strong>et</strong>e· and insen characters then you are <strong>al</strong>ready able to make<br />
any editing change you have to. Since it is so simple to change characters in the buffeT, STEVE<br />
concentrates on commands to put the cursor where you want it quickly and easily. The first few<br />
such commands are:<br />
Control-F Forward-Character<br />
COlllro/-F moves the cursor forward one character in the buffer. (The end of a line<br />
counts as one character.)<br />
Control-B Backward-Character<br />
{ontrol- B moves the CUrsOT backward one character in the buffer.<br />
Control-N Down-Re<strong>al</strong>-line<br />
Move straight down to the next line.<br />
Control-P Up-Re<strong>al</strong>-line<br />
Muve straight up to the previous line.<br />
MC:NII.MAN:EDITOR 18<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 255 Modifying the buffer<br />
These are the commands to. move up down right and left.<br />
Now you know how to edit a file! If you can you should probably try to use STEVE to create<br />
a simple file and save it. Print it if you can and compare it to what you see on the screen. See<br />
what happens if you try to back up before the beginning of the buffer using Colllrol- B or<br />
Control-Po Type enough lines to fill up the screen (use R<strong>et</strong>urn to end each line) then a few<br />
more. What happens when the cursor is about to move onto the mode line? Now usc Control-P<br />
to move back.<br />
25.4.2 Now that you know the Simplcst Commands<br />
Now that you know the simplest commands there are many others that you should learn.<br />
There are some gener<strong>al</strong> facts ahollt ti1e editor which will help you g<strong>et</strong> more out of each command<br />
which 1 will expain first.<br />
25.4.2.1 Numcric Argunlcnts<br />
It is possible to give any command a numeric argument. The command or may not lise it.<br />
but you can <strong>al</strong>ways supply it. In fact, if you don't supply an argument an argument of one (1) is<br />
implied. There are sever<strong>al</strong> ways to specify an argument. In <strong>al</strong>l cases the numeric argument is<br />
typed before the command. The most gener<strong>al</strong> way to specify an argument is:<br />
Univer!<strong>al</strong>-Argument<br />
COlltrol-V followed by a positive or negative integer specifics ti1at integer as the argument<br />
for tile following" command. Cvmrul-V with no number specifics an argument of four (4).<br />
Control-V Alillus with no number is treated speci<strong>al</strong>ly as an argument of minus 1 (-l).<br />
Some commands treat Control-V with no number differently than Control-V 4.<br />
For termin<strong>al</strong>s with a m<strong>et</strong>a key it may be easy to usc the m<strong>et</strong>a-digit keys.<br />
M<strong>et</strong>a-O, M<strong>et</strong>a-I, ... , M<strong>et</strong>a-g, M<strong>et</strong>a-Minus<br />
Control-M<strong>et</strong>a-O, ... , Control-M<strong>et</strong>a-g, Control-M<strong>et</strong>a-Minus<br />
Auto-Argument<br />
Any of the M<strong>et</strong>afied numeric digits begin a numeric argument. It is just like Control-V<br />
followed by the digit. Notice that repeated m<strong>et</strong>a digits are multiplied tog<strong>et</strong>her.<br />
Control-O, ... , Control-g, Control-Minus<br />
Auto-Argument-Digit<br />
The control-digits end any previous digit and act as digits in an argumenL Thus Control-2<br />
Co Iltrol-3 is the argument twenty-three (23). Any arguments before or after a sequence of<br />
control-digits will be multiplied by the fin<strong>al</strong> control-digit argument. Because most<br />
termin<strong>al</strong>s do not send control-digits these must be specified using the uparrow bit-prefix<br />
(for instance, by typing Control-' 2), so in practice they are not used much. Note that<br />
the Control-'sI illus must be specified first<br />
If sever<strong>al</strong> arguments are specified they are multiplied tog<strong>et</strong>her. The primary use of multiple<br />
arguments is to type Control-V severa) times in a row. r .. ach Control-V multiplies the argument<br />
by four (4). So lOll/rol-V COll/rol-V is sixteen (16) and lVlltrol-V lOll/ml-U Cuntrol-V is sixtyfour<br />
(64). The. cursor movement commands treat the argument as a repeat count (as do most<br />
MC:<strong>NIL</strong>MAN:EDITOR 18<br />
23-DEC-8J
Modifying the buffer 256 <strong>NIL</strong> Manu<strong>al</strong><br />
commands where that· is me:.lningful). Some useful combinations are {olllro/-U ('omra/-V<br />
('(Jlltra/-F which moves forward about a quarte~ of a line, and COIl/ro/-V COlltro/-N which moves<br />
down four Iines~ You will. find many other "Cliches" or combinations of editor commands which<br />
you use automatic<strong>al</strong>ly to do one thing.<br />
25.4.2.2 Contro)-X<br />
As I said bef(lfe there arc not enough keys on a keyb~ard tbr <strong>al</strong>l of the commands. defined in<br />
STF\,J.:. The Al<strong>et</strong>a key is one way of g<strong>et</strong>ting more characters so STFVF can have a Jarge number of<br />
single character commands. But it is not enough. To g<strong>et</strong> e,"cn morc commands STF\T uses the<br />
key COlltml-X as a prefix chara
Nil. Manu<strong>al</strong> 257 Modifying the buffer<br />
If you type a question mark (7) while typing a Alcta-X command you will see a list of <strong>al</strong>l<br />
possihle ways to finish the command. This is typed in the upper part of the screen, over the text.<br />
(As soon as the Al<strong>et</strong>a-X command is finished. the text will be re-displayed.) If the list is longer<br />
than one screen fu 1 the word to. mo r e ." will appear on the last line above the mode line. Type<br />
5;pace to see the next screenful of commands. Type COlllrol-G to abort the entire Afela-X<br />
command. (There are sever<strong>al</strong> other commands which use the upper part of thc screen<br />
temporarily. All of these will print to.more." in the bottom line and expect either a ... S·pace to<br />
continue. or a COlllrol-G to abort. Any other character causes an abort. and is then used as a<br />
command.)<br />
A summary of speci<strong>al</strong> ,\I ela- X characters.<br />
Del<strong>et</strong>e<br />
E"icape<br />
Space<br />
Control-G<br />
Control-W<br />
Control-ll<br />
?<br />
Ruhout the last character showing in the command.<br />
Compl<strong>et</strong>es the command and separates arguments.<br />
Compl<strong>et</strong>es a word.<br />
Abort everything.<br />
Rubollt a word. Works while typing arguments <strong>al</strong>so.<br />
Start over. Rubout the entire M<strong>et</strong>a-X command. (Doesn't abort.)<br />
Help.<br />
Most commands which are nonn<strong>al</strong>ly executed using AINa-X are smart about their arguments.<br />
They can dctenlline how many you have typed and will prompt you for any that are required.<br />
Often it is easier to use ,Urla-X commands this way since the prompt will tell you what kind of<br />
urgumcnt hi typc. Si.iiiiC commands can d,,) cliinpkti(iil flif Y\JU "if ,,)ihcrw b(: hdp you lY 1-'(: tli(:<br />
arguments. The C()l1lrvl-JUela-X command is a variant of Alcro-X which is designed to lake<br />
advantage of this. The difference is that the command is executed as soon as it is compl<strong>et</strong>ed,<br />
either by Escape or Space. Otherwise it is exactly the same as Alela-X.<br />
25.4.2.4 ~farks and Regions<br />
Associated with each buffer is a ring which may store up to eight (8) marks. These are buffer<br />
pointers created by certain commands for future reference. There is a command to create a mark<br />
where the cursor is and a command to go to the last mark. and some other commands .. The text<br />
b<strong>et</strong>ween the cursor and the last mark is c<strong>al</strong>led the region. Many commands operate on this<br />
region.<br />
25.4.2.5 KUling and Un-killing<br />
Whenever more than one character is del<strong>et</strong>ed it is stored in a place c<strong>al</strong>led a kill-ring. Should<br />
you decide that it was a mistake to del<strong>et</strong>e it then you may r<strong>et</strong>rieve it with the un-kill command<br />
(Conlroi- Y). This <strong>al</strong>so l<strong>et</strong>s you copy text from one place to another, by killing it. moving the<br />
cursor and then un-killing it. To make severa) copics type COlllrol- Y scver<strong>al</strong> times. The<br />
command un-kill-pop CHela- Y) will r<strong>et</strong>rieve thc next to last peice of killed text. If A/r/a-}' is<br />
used right after lO1l1r(J/- Y or Alela-r the previous un-kill is del<strong>et</strong>ed first (Unlike ns E\1ACS.<br />
Alela- r can be used at any time.)<br />
MC:NII.MAN:E))ITOR 18
M(~or Modes 258 Nil. Manu<strong>al</strong><br />
25.4.2.6 List Oriented COlnmands<br />
A number of commands operate on "lists", These are nonn<strong>al</strong>ly defined as LISP lists with<br />
b<strong>al</strong>anced parentheses. This definition is controned by a syntax table and may vary in different<br />
major modes (see below). For example. in l.sa mode the characters { and } are· a type a<br />
parenthesis and will define a list The editor knows about doublcquote syntax for strings and<br />
vertic<strong>al</strong>-bar syntax for symbols,<br />
25.4.2.7 *more*<br />
A number of commands will overwrite the text on tJle screen, There is no need to worry.<br />
the text has not changed and will redisplayed when the current command is finished. If this<br />
merwrite fills the top part of the screen tJlen the word u.more." will be primed on tJle line<br />
above the mode-line. The editor will wait for you to rend tJle screen and type a space. The<br />
space will not be put into tJle buffer. it just indicates tJlat you arc ready to see me next screenful<br />
of informatio"'l. If you type lOl1lro/-G it will abort ~see below),<br />
25.4.2.8 Aborts<br />
When the editor is reading from the tennin<strong>al</strong> it usu<strong>al</strong>ly will abort if you type l ol1trol-G. lbe<br />
word "aborted" will appear in the mode area. This is a good thing to try if you are losing.<br />
though it doesn °t work in some places it should.<br />
25.5 Major Modes<br />
When editing different kinds of documents it is often convenient for some editor commands to<br />
behave slightly differently. For example, when editing a program it seems most useful to have<br />
the Tab key indent the current line so it lines up with the corresponding syntactic unit above it,<br />
but when editing a paper you want the tab key to indent for a paragraph. STEVE has a number<br />
of major modes which are designed for speci<strong>al</strong> kinds of editing. Most of the major modes are<br />
very similar, so there is no need to relearn much when you change modes.<br />
Bolio mode<br />
A mode bujJt on Text mode (see below) indendcd for sources to the text justifier Bolio,<br />
Knows about Bolio comments. Also assumes that Bolio is being used to document a Lisp<br />
program. so the paren echo hack is turned on and AI <strong>et</strong>a-. tries to find a function<br />
definition. The Control-M<strong>et</strong>a digits are used to change to that number font. Control<br />
AI <strong>et</strong>a-· insens a "pop font" command.<br />
FUndament<strong>al</strong> mode<br />
The basic mode upon which most other modes are built Not used for much editing,<br />
since usu<strong>al</strong>ly there is a b<strong>et</strong>ter and more speci<strong>al</strong>ized mode for any particular job,<br />
Lisp mode<br />
For editing LISP programs. The principle features are that parentheses arc matched as<br />
they arc typed (try it. it is hard to explain) and that the Tab key knows how to indent<br />
for LISP code.<br />
MC:N1I.MAN:EDITOR 18<br />
23-I)I:C-83<br />
, ,<br />
...:.: ::/~ "~\.~~·i;.:. ~,., __ ..~..
<strong>NIL</strong> Manu<strong>al</strong> 259 Help and Self" I )ol'lllnentation<br />
LL mode<br />
Lisp Listener mode is not re<strong>al</strong>ly for editing documents. It simulates the liSP (or !'\IL) top<br />
level loop by ev<strong>al</strong>uating each top level fonn as soon as it is typed, and printing the result<br />
into the buffer. There are sever<strong>al</strong> reasons to use this mode for interactive testing.<br />
Because you are typing at the editor you have its full power to modify a form as you<br />
type it in. You are not limited to del<strong>et</strong>cing the last charactcrs typed as you would be<br />
nonn<strong>al</strong>ly. Even after a fonn is executed you may modify it and re-use it by backing up<br />
(with COlltrol-P), editing it, and then re-executing the fonn with !..tela-/. or by erasing<br />
and re-typing the last close paren. Fin<strong>al</strong>ly. there is a record of what you have done. and<br />
the results. You may save the buffer mid print it. You may add comments as you work.<br />
LSB mode<br />
For editing I.SB program~. The primary difference from 1 -isp mode is that the characters {<br />
and } arc <strong>al</strong>so treated as Parentheses.<br />
Test mode<br />
This should be dyked out. It is not useful except for debugging the editor itself.<br />
Text mC:',e<br />
For editing english (or german or french .. ,) text. T(lb is 1101111411 and ,Hela-. only searches<br />
the loaded buffers without trying to find the source file through the function definitinn.<br />
Obis may be wrong... comments?) Paragraph commands search for lines which begin with<br />
a white space character rather than for blank lines (as they do in program modes.)<br />
25.6 iieip and Seii Documentation<br />
STEVE has a sever<strong>al</strong> commands designed to hclp you when you don't know how do som<strong>et</strong>hing.<br />
The principle commands are Alela-? and COfllrol-Al<strong>et</strong>a-? which is the more gener<strong>al</strong> of the two.<br />
\\'hen you type {Oil trol-AI ela-? the editor will prompt you in the mode area with:<br />
Help (type? for options):<br />
You respond with a single character. The choices are<br />
A Apropos. (You type a Word to search for.)<br />
C Document a Character. (You type the character.)<br />
o Describe a command. (You type the command name.)<br />
K Document a Key. Identic<strong>al</strong> to C.<br />
S Syntax. (You type a character.)<br />
A (Apropos) prints <strong>al</strong>l paragraphs in the help file which contain a string.<br />
finding documentation on some concept. Also available through AI ela-X Apropos.<br />
It is useful for<br />
C (Character) finds the name of thc command that a key is bound to and then treats that just<br />
like D (Describe) would. Also available through Al<strong>et</strong>a-X Describe-Key. (Type the full name.<br />
AI ela-X Describe confuses compl<strong>et</strong>ion.)<br />
U (Uescribe) searches for a paragraph in the hclp file which contains the string in the first<br />
line of the paragraph. The help file is structured so that paragraph will he the documentation for<br />
that command when it is fully typed. If this is losing because you don't know the fun name of<br />
the command try Apropos instead. Also available through AI <strong>et</strong>a-X Describe.<br />
MC:NII.MAN:EDITOR 18<br />
23-DEC-H3
Glossary ofCommclllds 260 <strong>NIL</strong> Manu<strong>al</strong><br />
K (kcy) is anothcr namc filf C (Ch
Nil. MmlU<strong>al</strong> 261 Glossary of Commands<br />
Glossary Of STEVE commands<br />
25.7.J Speci<strong>al</strong> Character Commands<br />
Backspace<br />
Backward-Character<br />
Move the cursor backward one character or more if given an argument.<br />
Tab<br />
Insen a tab.<br />
Insert-tab (In non-LISP modes)<br />
Tab<br />
Indent-For-Lisp (In LISP modes)<br />
Indent tJle current line according to the nesting struclUre.<br />
Linefeed<br />
linefeed<br />
Break the current line and indent the next line. Equiv<strong>al</strong>ent to Rl'IUfll followed by Tab.<br />
R<strong>et</strong>urn<br />
Crlf<br />
Insert a line separator or just move. to the next line jf before two blank Jines.<br />
comme'1t ender if there is one.<br />
Altmode<br />
Bit-Prefix M<strong>et</strong>a<br />
Make the next character be a Alela character.<br />
Skips<br />
Rubout<br />
Backward-Del<strong>et</strong>e-Character (in non LISP modes)<br />
Del<strong>et</strong>es one character before point. If given an argument kills that many characters before<br />
nnint<br />
r •.-.•-<br />
25.7.2 Control Character Commands<br />
Control-Altmode Exit-Editor<br />
R<strong>et</strong>urn to whoever caned the editor, gener<strong>al</strong>ly the <strong>NIL</strong> interpr<strong>et</strong>er.<br />
Control-Space<br />
S<strong>et</strong>-or-pop-mark<br />
With no argument places a mark at point. With an argument pops the last mark and<br />
goes to it<br />
Control-;<br />
Indent-for-comment?<br />
Inserts a comment on the current line or adjusts the placement of an existing comment.<br />
Control-<<br />
Mark-Beginning<br />
Place a mark at the beginning of the buffer.<br />
Control-=<br />
What-Cursor-Position<br />
Prints the X and Y coordinates of the cursor on the screen, the current character and the<br />
number of characters before point and the percentage of the file which that is. Line<br />
separators count as two characters since that is how many they occupy in a file. See<br />
Count - Lines - Region<br />
Control-><br />
Mark-End<br />
Place J mark at the end of the buffer.<br />
MC:<strong>NIL</strong>MAN:EOITOR 18<br />
23-DFC-83
c<br />
Glossary of Commands 262<br />
Control-@<br />
S<strong>et</strong>-or-pop-mark<br />
With no argument places a mark at point. With an argument pops the Jastrnark and<br />
goes to it.<br />
Control-A<br />
Beginning-Of-Line<br />
Move the cursor to the beginning of the current line.<br />
Control-B<br />
Backward-Character<br />
Move the cursor back one character or more if given an argument.<br />
Control-C<br />
Exit-Editor<br />
R<strong>et</strong>urn to whoever c<strong>al</strong>led the editor. gener<strong>al</strong>ly the ~Il interpr<strong>et</strong>er. CCJIllrol-C should<br />
inlerrupt ule editor as it docs in the rest of 'II. but because the editor must be in Pass<strong>al</strong>l<br />
mode that is not possible.<br />
Control-D<br />
Del<strong>et</strong>e-Character<br />
I :>C1<strong>et</strong>e the character that the cursor is on.<br />
Control-E<br />
End-Of-'.ine<br />
Mo\'e the cursor to the end of the cunent line.<br />
Control-F<br />
Forward-Character<br />
Move the cursor forward one character or more jf given an argument.<br />
Control-G<br />
COlltroJ-G will abort the editor if it is reading from the termin<strong>al</strong>.<br />
Control-H<br />
R~ckw~rd-C~aracter<br />
Just like Comru/-B. COlllro/-H is Backspace in seven-bit ASCII.<br />
Control-I<br />
Tab<br />
Conlrol-! docs whatever Tab would do. In Lisp Mode and its derivatives (see major<br />
modes. below) this indents according to the syntax of text as a LISP program. In non-Lisp<br />
modes this is a norm<strong>al</strong> Tab.<br />
Control-J<br />
Indent-New-Line<br />
Equiv<strong>al</strong>ent to R<strong>et</strong>urn followed by Tab. Ends the current line and indents the next line.<br />
Control-K<br />
Kill-Line<br />
Kill to the end of the current line. If the cursor is at the end of a line it kills the line<br />
separator. With an argument kills that many lines.<br />
Control-L<br />
New-Window<br />
Dear the screen and redisplay everything. Useful if the screen is garbaged somehow· (for<br />
example if someone sends you mail). The window is moved to put the cursor in the<br />
middle of the screen. With an argument puts the cursor that many lines from the top of<br />
the screen. With a negative argument counts fTomthe bottom of the screen.<br />
Control-M<br />
CRLF<br />
Insert a line separator or just move to the next line if before two blank lines. Skips<br />
comment ender if there is one.<br />
Control-N<br />
Down-Re<strong>al</strong>-Line<br />
Move the cursor straight down one line or more if given an argumenl<br />
Control-Q<br />
Open-Line<br />
Puts a R<strong>et</strong>urn right after the cursor. With an argument creates that many blank lines.<br />
MC:NII.MAN:EDITOR 18<br />
23-DEC-83
Nil. Manu<strong>al</strong> 263 Glossary of Commands<br />
Control-P<br />
Up-Re<strong>al</strong>-line<br />
Move the cursor up one line or more if given an argument.<br />
Control-Q<br />
Quoted-Insert<br />
The next character is treated as an <strong>al</strong>phanumeric character regardless of what it is. This is<br />
how to put control characters into the buffer. Al<strong>et</strong>a characters cannot be put in the<br />
buffer, because they cannot be in <strong>NIL</strong> strings.<br />
Control-R<br />
Reverse-I-Search<br />
Increment<strong>al</strong>ly search backward through the buffer for a string.<br />
Control-S<br />
I-Search<br />
I ncrement<strong>al</strong>ly search the butler for a string.<br />
Control-T<br />
Transpose-Characters<br />
Exchange the character before the cursor with the character at the cursor.<br />
Control-U<br />
Univers<strong>al</strong>-Argument<br />
Read an argument for the next command.<br />
Control-V<br />
Next-S·.reen<br />
Move the window and the cursor forward <strong>al</strong>most one scrccnful. The last two lines of l.he<br />
window arc now the top two lines. With a numeric argument moves the window and<br />
cursor that many lines.<br />
Control-W<br />
Kill-Region<br />
Kill the region b<strong>et</strong>ween point and mark and save it in the kill ring.<br />
Control-X<br />
Prefix-Character<br />
COil tro 1-X is a prefix character. Type any character after it for a two character command.<br />
Control-Y<br />
Un-Kill<br />
G<strong>et</strong> the most recent kill out of the kill ring and insen it in the buffer. With an argument<br />
N g<strong>et</strong>s the Nth kill. With just Control-Vas an argument. it leaves the cursor before the<br />
un-killed text.<br />
Control-Z<br />
Bit-Prefix Control-M<strong>et</strong>a<br />
Read the next character as a Control-AI <strong>et</strong>a character.<br />
Control-\<br />
Prefix-M<strong>et</strong>a<br />
Read the next character as a Al<strong>et</strong>a character.<br />
Control-]<br />
Abort-Recursive-Edit<br />
R<strong>et</strong>urn from a recursive edit without doing anything more.<br />
Control- ....<br />
Bit-Prefix Control<br />
Read the next character as a Control character.<br />
Control-Rubout<br />
Backward-Oel<strong>et</strong>e-Hacking-Tabs<br />
Like Rubout except that a Tab is first expanded into spaces. This is useful for indenting<br />
things. In Lisp modes Rubout and Control-Rubout are interchanged.<br />
MC:NII.MAN:EDITOR 18<br />
23-DEC-83
Glossary of Commands 264' <strong>NIL</strong> MmlU<strong>al</strong><br />
25.7.3 M<strong>et</strong>a Key commands<br />
M<strong>et</strong>a-Linefeed<br />
Indent-New-Comment-Line<br />
Equiv<strong>al</strong>ent to Control-N M<strong>et</strong>a-:<br />
M<strong>et</strong>a-R<strong>et</strong>urn<br />
Back-To-Indentation<br />
Put the cursor on the first non white-space character in the current line. (Tabs and spaces<br />
arc white-space.)<br />
M<strong>et</strong>a-Altmode<br />
Start a minibuffer.<br />
Minibuffer<br />
M<strong>et</strong>a-#<br />
Change-Font-Word<br />
Change the font of the pre\,ious word~<br />
M<strong>et</strong>a-(<br />
Make-parens<br />
Enclose the next I.ISI) exprcs..~ion in parens. With an argument enclose that many I.ISP<br />
expressions.<br />
M<strong>et</strong>a-)<br />
Move-Over-Right-Paren<br />
Move past the next close parenthesis. then do a I.illr/ecd.<br />
M<strong>et</strong>a-.<br />
Oefun-Search-All-Buffers<br />
Find a defun. In some modes this will look at the subr object to find the module a<br />
grovel around to find and load the file where the function is defined. In most text modes<br />
(other than bolio) it just searches the loaded buffer.<br />
M<strong>et</strong>a-;<br />
lnoent-t"or-comment?<br />
Inserts a comment on the current line or adjusts the placement of an existing comment.<br />
M<strong>et</strong>a-<<br />
Goto-Beginning<br />
Put the cursor at the beginning of the buffer.<br />
M<strong>et</strong>a-=<br />
Count-Lines-Region<br />
Prints the number of lines b<strong>et</strong>ween point and mark in the mode area. Also prints the<br />
number of buffer characters. b<strong>et</strong>ween point and mark (counting the line separator as one<br />
character. See What-Cursor-Position.)<br />
M<strong>et</strong>a-><br />
Goto-End<br />
Put the cursor at the end of the buffer.<br />
M<strong>et</strong>a-?<br />
Describe-Key<br />
Reads a key from the keyboard and prints its documenta~on.<br />
M<strong>et</strong>a-A<br />
Backward-Sentence<br />
Move. to the end of the previous sentace.<br />
M<strong>et</strong>a-B<br />
Backward-Word<br />
Backup one word. (With an argument backs up that many words.)<br />
M<strong>et</strong>a-C<br />
Capit<strong>al</strong>ize a word.<br />
M<strong>et</strong>a-O<br />
Kill the next word.<br />
Uppercase-initi<strong>al</strong><br />
Kill-word<br />
MC:<strong>NIL</strong>MAN:EDITOR 18<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong><br />
Glossary of Commands<br />
M<strong>et</strong>a-E<br />
Forward-Sentance<br />
Move the cursor to the end of the current sentance.<br />
M<strong>et</strong>a-F<br />
Forward-Word<br />
Move over one word. With an argument moves over that many words.<br />
M<strong>et</strong>a-H<br />
Mark-Paragraph<br />
Put point at the beginning of a paragraph and mark at the end.<br />
M<strong>et</strong>a-I<br />
Insert-Tab<br />
Puts a tab into the buffer. Alela-I doe's not change in Lisp modes.<br />
M<strong>et</strong>a-J<br />
Equiv<strong>al</strong>ent to COlllrol-N Afcla-:.<br />
Indent-New-Comment-Line<br />
M<strong>et</strong>a-K<br />
Kill-Sentence<br />
Kill the sentence after the cursor.<br />
M<strong>et</strong>a-L<br />
Lowercase-Word<br />
Convert the next word to 4111 lowercase characters.<br />
M<strong>et</strong>a-M<br />
Back-To-Indentation<br />
Move the cursor to the first non white-space character in the current line.<br />
M<strong>et</strong>a-N<br />
Oown-Comment-line<br />
If the current line has a blank comment del<strong>et</strong>e it. rlllen move to the next line and add<br />
or adjust the comment start in the correct column.<br />
M<strong>et</strong>a-p<br />
Up-comment-Llne<br />
If the current line has a blank comment del<strong>et</strong>e it. Then move to the previous line and<br />
add or adjust the comment start in the correct column.<br />
M<strong>et</strong>a-R<br />
Move-To-Screen-Edge<br />
With an argument move to the beginning of that line on the screen. With a negative<br />
argument count from the bottom. With no argument move one third from the top.<br />
M<strong>et</strong>a-S<br />
Center-Line<br />
Centers the non white-space characters in the current . line.<br />
M<strong>et</strong>a-T<br />
Transpose-Words<br />
Exchange the words before and after the cursor.<br />
M<strong>et</strong>a-U<br />
Uppercase-Word<br />
Conven the next word to <strong>al</strong>l upper case characters.<br />
M<strong>et</strong>a-V<br />
Previous-Screen<br />
Move point and the window back so the two top lines become the two bottom lines.<br />
With an argument move that many lines.<br />
M<strong>et</strong>a-W<br />
Copy-Region<br />
Put the text b<strong>et</strong>ween point and mark in the kill ring but do not del<strong>et</strong>e it from the buffer.<br />
M<strong>et</strong>a-[<br />
Backward-Paragraph<br />
Move to the beginning of a paragraph. In Lisp modes a paragraph begins with a blank<br />
linc. Otherwise a paragraph begins with a line that starts with a white-space character.<br />
M<strong>et</strong>a-\<br />
Oel<strong>et</strong>e-Horizont<strong>al</strong>-Space<br />
Del<strong>et</strong>e any spaces or tabs around the cursor.<br />
MC:NII.Mt\N:EDITOR 18<br />
23-I)EC-8]
I<br />
Glossary of Commands 266 <strong>NIL</strong> Manu<strong>al</strong><br />
Forward-Paragraph<br />
Move to the end of a paragraph.<br />
M<strong>et</strong>a~]<br />
M<strong>et</strong>a- Del<strong>et</strong>e-Indentation<br />
A<br />
Join the current line to the previous line and del<strong>et</strong>e white space as appropriate. Leaves<br />
the cursor where the line separator wa~ . so a Linefeed undoes the effect of AI ela- t .<br />
M<strong>et</strong>a--<br />
Buffer-Not-Modified<br />
Clears the flag which says the current buffer has been changed. The star (*) in the mode<br />
line wiIJ be erased. He careful with this command: usc it only when you arc slire there<br />
have not been any dMnges to the buffer that yuu want saved.<br />
M<strong>et</strong>a-Rubout<br />
Backward-Kill-Word<br />
K ill the word befor the cursor.<br />
25.7.4 Control-l\l<strong>et</strong>a Commands<br />
Control-M<strong>et</strong>a-Backspace Mark-Defun<br />
Put point at the beginning of a defun and mark at the end.<br />
Control-M<strong>et</strong>a-Linefeed Indent-New-Comment-Line<br />
Equiv<strong>al</strong>ent to COl1lro/-N Alelo-,' .<br />
Control-M<strong>et</strong>a-R<strong>et</strong>urn Back-lo-Indentation<br />
Move the cursor to the first non white-space character in the current line.<br />
Control-M<strong>et</strong>a-(<br />
Backward-Up-List<br />
Move backward to next enclosing open parenthesis.<br />
Control-M<strong>et</strong>a-)<br />
Forward-Up-List<br />
Move forward to next enclosing dose parenthesis.<br />
Control-M<strong>et</strong>a-;<br />
Kill-Comment<br />
Kill the entire comment field on the current line.<br />
Control-M<strong>et</strong>a-? Editor-Help<br />
Self documentation function. Type a single character (one of A, C, D. K, S, or 7) to<br />
select which type of help you want.<br />
Control-M<strong>et</strong>a-@<br />
Mark-Sexp<br />
Put the mark at the end of the next LISP expression.<br />
Control-M<strong>et</strong>a-A<br />
Beginning-Of-Defun<br />
Backup to the beginning of the current or previous defun. Does not require matched<br />
parentheses or a compl<strong>et</strong>e defun.<br />
Control-M<strong>et</strong>a-B<br />
Backward-Sexp<br />
Move backward over one USP expression.<br />
Control-M<strong>et</strong>a-C<br />
Compile-Sexp<br />
_ Compile the current defun. Only works. for <strong>NIL</strong> code. lbe compiled function is loaded<br />
into the current <strong>NIL</strong><br />
Control-M<strong>et</strong>a-D<br />
Down-List<br />
Move to the inside of the next list in the buffer.<br />
MC:NH .MAN:EDITOR 18<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 267 Glossary of Commands<br />
Control-M<strong>et</strong>a-E<br />
End-Of-Defun<br />
Move to the end of the current or next defun. Does not require matched parentheses or<br />
a compl<strong>et</strong>e defun.<br />
Control-M<strong>et</strong>a-F<br />
Forward-Sexp<br />
Move forward over one LISP expression.<br />
Control-M<strong>et</strong>a-H<br />
Mark-Defun<br />
Put point at the beginning and mark at the end of the current defun.<br />
Control-M<strong>et</strong>a-J<br />
Indent-New-Comment-Line<br />
Equiv<strong>al</strong>ent to lOl1lrol-N Al<strong>et</strong>a-: .<br />
Control-M<strong>et</strong>a-K Kill-Sexp<br />
K ill the next J .lSI> expression.<br />
Control-M<strong>et</strong>a-M Back-To-Indentation<br />
Move the cursor to the first non white-space character in the current line.<br />
Control-M<strong>et</strong>a-N<br />
Forward.-L i st<br />
Move forward over one list.<br />
Control-M<strong>et</strong>a-O Split-Line<br />
Break a line at the cursor and indent the second h<strong>al</strong>f so it starts in the same column.<br />
Control-M<strong>et</strong>a-P<br />
Backward-List<br />
Move backward over one list.<br />
Contro/-M<strong>et</strong>a-Q<br />
Indent-Sexp<br />
Apply tab to every line in the LISP expression fol1owing the cursor except. for the first<br />
line.<br />
Control-M<strong>et</strong>a-R<br />
Reposition-Window<br />
Try to place the beginning of the current dcfun at the top of the window without moving<br />
the cursor. Does not require b<strong>al</strong>anced parentheses.<br />
Control-M<strong>et</strong>a-T<br />
Transpose-Sexps<br />
Exchange the previous and next USP expressions.<br />
Control-M<strong>et</strong>a-U<br />
Backward-Up-List<br />
Move backward to the previous enclosing open parenthesis.<br />
Control-M<strong>et</strong>a-V<br />
Scroll-Other-Window<br />
In two window mode scrolls the other window forward.<br />
lines.<br />
With an argument scrolls by<br />
Control-M<strong>et</strong>a-W<br />
Append-Naxt-Kill<br />
If the next command is a kill command the previous kit1 wi11 be appended to it, even if<br />
it would not otherwise be. Has no effect if the next command is not a kill command.<br />
Control-M<strong>et</strong>a-X<br />
Instant-Extended-Command<br />
Read an extended (named) command from the keyboard and execute it. If compl<strong>et</strong>ion<br />
finishes the command name it will be executed instantly. without waiting for a Relurn.<br />
Control-M<strong>et</strong>a-[<br />
Beginning-Of-Defun<br />
~1o\'c to the beginning of the current or previous defun.<br />
MC:NII.MAN:EDITOR 18
, .... e "r,<br />
Glossary of Commands 268 Nil. Manu<strong>al</strong><br />
Control-M<strong>et</strong>a-]<br />
End-Of-Defuo<br />
Move to the end of the current" or next dcfun.<br />
Control-M<strong>et</strong>a- .... Del<strong>et</strong>e-Indentation<br />
Join the current line to the previous line and del<strong>et</strong>e whitc space as. appropriate. Leaves<br />
the cursor where the line scparator was, so a Lillefeed undocs the cffect of Col1lro/<br />
Alela-t .<br />
Control-M<strong>et</strong>a-Rubout Backward-Kl11-Sexp<br />
Kill the I.ISP cxpression bcfhre me cursor.<br />
25.7.5 Control-X Commands<br />
Control-X Control-A Toggle-Auto-Fil1-Mode<br />
\\'ith no arg. togglcs auto fin mode. With a negativc arg. turns it off. With a positive<br />
arg. turns it on and s<strong>et</strong>s Fill Column to that number.<br />
Control-X Control-B L i st-Buffers-<br />
I -ists <strong>al</strong>l huffers and their meljor modes.<br />
Control-X Control-Z<br />
Exit-Editor<br />
R<strong>et</strong>urn to whoever c<strong>al</strong>led the editor. gener<strong>al</strong>ly the <strong>NIL</strong> interpr<strong>et</strong>er.<br />
Control-X Control-D Directory"-Display<br />
I.ist <strong>al</strong>l versions and types of the current file. With an argument reads a pathname and<br />
t.· , . t ••<br />
II:'\.!) <strong>al</strong>l fll\;~ WIIU,':U Illdu.:n u.<br />
Control-X Control-F Find-File<br />
Find-File wiH prompt for a file name and you should type it from the keyboard. If there<br />
is a buffer for that file thcn it will be selected and be the new current buffer. Otherwise<br />
a buffer is created for the file and the file is read in from disk if it exists therc. Find<br />
File is the most common way to read a file from disk. It creates a new buffer for each<br />
file which is convenient. When Find-File creates a buffcr it uses the file name without<br />
any extention as the buffer name. Since the name of each buffer must be unique this<br />
doesn't work when you are editing two files which have the same name but are on<br />
different directories, or have different extensions (file types) so Find·File will notice if you<br />
are doing this and will ask you for a new buffer name to use.<br />
Control-X Tab<br />
Indent-Rigidly<br />
With an argument shifts <strong>al</strong>l lines in the region right (or left if negative) that many<br />
columns.<br />
Control-X Control-l Lowercase-Region<br />
Conven <strong>al</strong>l characters b<strong>et</strong>ween point and mark to lower case.<br />
Control-X Control-N S<strong>et</strong>-Go<strong>al</strong>-Column<br />
COlllroi-N and COJllro/·P try to move to the go<strong>al</strong> column if there is one. With an<br />
argument removes the go<strong>al</strong> column. Otherwise s<strong>et</strong> it to the current cursor position.<br />
Control-X Control-O Del<strong>et</strong>e-Blant-Lines<br />
Del<strong>et</strong>e <strong>al</strong>l blank Jines foUowingpoint, and if the current is blank del<strong>et</strong>e <strong>al</strong>l blank lines<br />
before it.<br />
MC:NIl.MAN:EDITOR 18<br />
23-DEC-83
NIl. Manu<strong>al</strong> 269 Glossary of Commands<br />
Control-X Control-P Mark-Page<br />
Put point (.It the beginning and mark at the end of the current page.<br />
Control-X Control-Q S<strong>et</strong>-File-Read-Only<br />
With positive argument s<strong>et</strong>s file read only.<br />
With negative argument s<strong>et</strong>s buffer read only.<br />
With zero argument <strong>al</strong>lows any access.<br />
Control-X Control-R Visit-File<br />
Visit-File is like Find-File except that it re-uses the current buffer. destroying its contents.<br />
It is still safe since it will oITer to save it if any changes have been made to it.<br />
Control-X Control-S Save-File<br />
Sa\c-File writes the current buffer to its associated file. and changes the mode line to<br />
indicate that the buffer and file are now idemic<strong>al</strong>. (This is not done until the output is<br />
compl<strong>et</strong>e. so if there is a disk error or some other error you wiJI not think it has been<br />
StH'ed when it hasn't been.)<br />
Control-X Control-T Transpose-lines<br />
Exchange the cllrrent and previous lines.<br />
Control-X Control-U Uppercase-Region<br />
Convert <strong>al</strong>l characters b<strong>et</strong>ween point and mark to upper case.<br />
Control-X Control-V Visit-File<br />
Visit-File is like Find-File except that it fe-uses the current huffer. destroying its contents.<br />
Control-X Control-W Write-File<br />
Write-File writes the current buffer to a file. but unlike save file it will prompt you for<br />
the file name.<br />
Control-X Control-X Exchange-Point-And-Mark<br />
Put point where mark is and mark where the point was.<br />
Control-X Altmode<br />
Ev<strong>al</strong>uate the symbol n + n.<br />
this does the right thing.<br />
Re-Execute-Minibuffer<br />
Alera-X and some other commands s<strong>et</strong>q + appropriately so<br />
Control-X #<br />
Change-Font-Region<br />
S<strong>et</strong>s the font number of the region to the argument. Good for Bolio at least<br />
Control-X (<br />
Start-Kbd-Macro<br />
Begins defining a keyboard macro.<br />
Control-X 1<br />
One-Window<br />
Make the current window fill the entire screen and discard <strong>al</strong>l other windows.<br />
Control-X 2<br />
Two-Windows<br />
Split the current window into two windows. Can create any number of windows until<br />
they g<strong>et</strong> two sm<strong>al</strong>l.<br />
Control-X 3<br />
View-In-Other-Window<br />
Split the current window into two windows but stay in the top h<strong>al</strong>f ..<br />
Control-X 4<br />
Visit-In-Other-Window<br />
Combines Find-File and two window mode. Asks for a file to find. then displays it in a<br />
MC:NII.MAN:FDITOR 18<br />
2J-DFC-83
Glossary of Commands 270 Nil. Manu<strong>al</strong><br />
new second window.<br />
Control-X;<br />
S<strong>et</strong>-Comment-Column<br />
S<strong>et</strong>s the comment column to the current cursor column. Comment commands try to start<br />
comments in the comment column.<br />
Control-X =<br />
What-Cursor-Position<br />
Shows the X and Y coordinates of the cursor on the screen. the current character and<br />
how far through the buffer you are.<br />
Control-X A<br />
Append-lo-Buffer<br />
Adds the text of region to the end of another buffer.<br />
Control-X B<br />
Select-Buffer<br />
Asks for a buffer name and creates or selects CI buffer of that name.<br />
Control-X F<br />
S<strong>et</strong> Fill Column<br />
S<strong>et</strong>s the fin column to be the argument. if given. or else the current cursor position.<br />
Control-X G<br />
G<strong>et</strong>-Q-Reg<br />
Asks for the name of a LISP variable and tries to interpr<strong>et</strong> its v<strong>al</strong>ue as. text to inscrt into<br />
the buffer.<br />
Control-X H<br />
Mark-Whole-Buffer<br />
Put point at the beginning of the buffer and mark at the end.<br />
Control-X K<br />
Kill-Buffer<br />
R~:trl" :t h~lff~r n~rne'~nd km~ th~! buffer.<br />
Control-X l<br />
Count-lines-Page<br />
Prints the number of lines in the current page in the mode area.<br />
Control-X 0<br />
Selects the next window.<br />
Other-Window<br />
Control-X T<br />
Transpose-Regions<br />
Transposes two regions defined by point and the last three marks.<br />
Control-X X<br />
Put-Q-Reg<br />
Asks for a lisp variable and saves the text in the current region there. Designed to be<br />
undone with Gct-Q-Reg (Contro/-X G).<br />
Control-X [<br />
Previous-Page<br />
Move point to the previous page boundary.<br />
Control-X]<br />
Next-Page<br />
Move point to the next page boundary.<br />
Control-X Rubout Backward-Kill-Sentence<br />
Kills text to the previous end of sentence.<br />
MC:NlI.MAN:EDITOR 18<br />
23-DEC-83
Nil. Manu<strong>al</strong> 271 Glossary of Commands<br />
25.7.6 M<strong>et</strong>a-X Commands<br />
Apropos<br />
Scarches the documentation for a string and prints <strong>al</strong>l paragraphs which contain the string.<br />
Auto-Fill-Mode<br />
Toggle auto fill mode. With an explicit argument. turn it on if positive. and off if<br />
negative. I forg<strong>et</strong> what 0 does. Unfortunately this docs not change the mode line. It will<br />
in thc next vcrsion.<br />
Bolio-Mode<br />
Bolio mode is huilt on Text mode. hut has features from Lisp mode. In particular Alcla·.<br />
docs a Find Function and the parenthesis b<strong>al</strong>ancing hack is turned on. Comments are<br />
Bolio comments. Also. ('ollfro/·,Hcta·digit and C0I11ro/·AlcIO·* insert a Co1l1rol·F followed<br />
hy themselves. as font switching commands.<br />
Comment-Region<br />
Adds comments to the beginning of each line b<strong>et</strong>ween point and mark. Can be undone<br />
with :\IcIO·X Ullcommel11·Region. Won't work for languages with a comment terminator (l<br />
think).<br />
Compile<br />
Compiles the file associated with the current buffer. With a pathname argumcnt compiles<br />
that file instead. Asks if you want the file loaded when done.<br />
Copy-Made-Line<br />
Copy the first non·blank line of the last buffer selected to the first line of this buffer. An<br />
argument is the name of a buffer to use instead.<br />
Del<strong>et</strong>e-File<br />
Read~ a file name and del<strong>et</strong>es it. Asks for confinnation.<br />
Describe<br />
Reads a command from the keyboard and searches for documentation on it.<br />
Describe-Char-Syntax<br />
Rcads a character and lists its editor syntax. For nonn<strong>al</strong> characters just type the character<br />
and R<strong>et</strong>urn. For speci<strong>al</strong> chractcrs you must type its symbolic name in accordance with<br />
the currcnt readtable.<br />
Ev<strong>al</strong>uate<br />
Reads and ev<strong>al</strong>uatcs one <strong>NIL</strong> fonn. Prints the v<strong>al</strong>ue in the mode area. Pass<strong>al</strong>l mode is<br />
turned off during ev<strong>al</strong>uation for saf<strong>et</strong>y.<br />
Fundament<strong>al</strong>-Mode<br />
Scts the major mode for the current buffer to Fundament<strong>al</strong>.<br />
Help-M<strong>et</strong>a-X-Commands<br />
Lists the AI ela· X commands. This will probably go away and be subsumed under some<br />
more powerful help function.<br />
Kill-loc<strong>al</strong>-Variable<br />
Removes the currcnt buffer's loc<strong>al</strong> binding of a variable.<br />
Kill-Same-Buffers<br />
Asks for each buffcr wh<strong>et</strong>her to kill it or save it.<br />
MC:NII.MAN:EDITOR 18<br />
23·DEC·83
Glossary of Commands 212 Nil. Manu<strong>al</strong><br />
Kill-Variable<br />
Attempts to makunbound some variable. May change or go away.<br />
lisp-Mode<br />
Scts the major mode of the current buffer to Lisp. Turns on the parcnthesis echo hack<br />
and some other features.<br />
ll-Mode<br />
S<strong>et</strong>s the major mode of the current buffer to LL (Lisp Listener). Lisp Listener mode is<br />
built on l.isp mode. but has the feature that a defun is ev<strong>al</strong>uated and printed into the<br />
buffer when it is finished. It acts like the top-level loop in many ways. except <strong>al</strong>l input<br />
m1d output is san~d in a buffer.' You <strong>al</strong>so g<strong>et</strong> to usc Tab and the other editor features<br />
which help typing f .JSP forms.<br />
loc<strong>al</strong>-Bind<br />
Bind some variable to some v<strong>al</strong>ue when in the current buffer. lf prompting fi)r input this<br />
will tell you what the current vaJue is.<br />
lSB-Mode<br />
Makes the current major be LSH.<br />
<strong>al</strong>so parentheses.<br />
Make-loc<strong>al</strong>-Variable<br />
Like h<strong>al</strong>f of Loc<strong>al</strong>-Rind.<br />
Very similar to Lisp mode. except that { and }. arc<br />
Makes the variable loc<strong>al</strong> to tl1e current huffer .. but doesn't<br />
change its v<strong>al</strong>ue. Not sure if this is useful. it. is an attempt to sort of be compatible with<br />
EMACS.<br />
Name-KBD-Macro<br />
If there is a keyboard macro this will <strong>al</strong>low you to name it and to put it on a key. Asks<br />
for the key. then asks for confinnation about that.<br />
Overwrite-Mode<br />
This is not a major mode. It is <strong>al</strong>so not finished. It is supposed to make self-inserting<br />
characters overwrite the existing characters rather that move them over. This much works,<br />
but there is some other hair which is unimplemented.<br />
Query-Replace<br />
Replace <strong>al</strong>l occurances· after point of the first argument with the second argument. Asks<br />
about each replacement. "?" will list the options in the mode area. Space does the<br />
replacement, Rubout does not. Escape exits immediately. Period (.) makes the replacement<br />
then exits, and Comma makes the replacemen~ then waits for a Space before continuing<br />
(so you can see the change before moving to the next one).<br />
Rename-Buffer<br />
Change the name of the current buffer.<br />
Renam.e ... Fi le<br />
Takes two file name arguments. Renames the first to the second.<br />
Reparse-Mode-line<br />
Res<strong>et</strong> the m,ljor mode and <strong>al</strong>l loc<strong>al</strong> variables from the file property list of the file<br />
associated with the current buffer.<br />
Replace<br />
Replace <strong>al</strong>l occurrences of the first argument with the second argument. Acts<br />
MC:NII.Mt\N:EDITOR 18<br />
23-DEC~83
<strong>NIL</strong> Manu<strong>al</strong> 273 Glossary of Commands<br />
instantaneously (wen. as fast as a V AX can go) and leaves the cursor where it was. Note:<br />
Currently the cursor is left at where the last string was replaced.<br />
Save-A11-Fi·les<br />
L<strong>et</strong>s you save any modified buffers. Asks about each one separately.<br />
S<strong>et</strong>-Key<br />
The first argument is a Key and the second is a binding. Control-X keys can be specified<br />
like (# \Control-X # \Control-B). Keys should be specified is accordance with the current<br />
readtable.<br />
S<strong>et</strong>-Variable<br />
s<strong>et</strong>s a LISP \ariable to some v<strong>al</strong>ue.<br />
S<strong>et</strong>-Visited-Fi1ename<br />
Changes the file name associated with the current buffer. but docs not change the buffer<br />
or write any files.<br />
Test-Mode<br />
1\ major mode build on LL mode (Lisp Listener) but with pass<strong>al</strong>1 turned off. Not fe<strong>al</strong>ly<br />
Slife why I did this. except to test the editor. since Pass<strong>al</strong>l is ofT in 1.1. mode when<br />
reading and ev<strong>al</strong>uating a fonn.<br />
Text-Mode<br />
The major mode for editing text. Also try Bolio mode.<br />
Trace-Current-Defun<br />
Tries to tind the name of the current defun and caU trace on it. Given and argument will<br />
trace that function instead.<br />
Uncomment-Region<br />
Tries to remove comments from a region of commented code. Meant to be used with<br />
Alela-X Comment-Region.<br />
Underline-Region<br />
If the tennin<strong>al</strong> supports underlining change the visible part of the region so it is<br />
underlined. Waits for you to type a space, then reverts to the nonn<strong>al</strong> display and l<strong>et</strong>s<br />
you continue.<br />
View-Buffer<br />
Shows the contents of a buffer in screenfuls.<br />
View-File<br />
Shows the contents of a file in screenfuls. Until the <strong>NIL</strong> garbage collector works this is<br />
much less efficient than visiting the file since <strong>al</strong>l of the lines are wasted compl<strong>et</strong>ely.<br />
View-Kbd-Macro<br />
Shows the sequence of characters in a keyboard macro in the mode area.<br />
View-Mail<br />
This is just a hack which runs View-File over the VMS mail file sy s$l og in: rna i 1 . rna i.<br />
If it docsn'r work, don't use it<br />
View-Variable<br />
Prints the v<strong>al</strong>ue of a LISP variable. Doesn't barf if the variable is not bound. 'Other than<br />
that it is no b<strong>et</strong>ter than Afcta-X Ev<strong>al</strong>uate.<br />
MC:<strong>NIL</strong>MAN:EDJTOR 18<br />
23-DEC-83
Extending the Editor 274 <strong>NIL</strong> Manu<strong>al</strong><br />
What-Page<br />
Prints the current page number and ·1ine number.<br />
Write-region<br />
Writes the text b<strong>et</strong>ween point and mark to a file.<br />
supplied.<br />
Asks for the file name if it is not<br />
25.8 Extending the Editor<br />
E\'en1U(Jl1y the intern<strong>al</strong>s of the editor wi11 he documented pr<strong>et</strong>ty compl<strong>et</strong>ely. Currently the<br />
intern<strong>al</strong>s arc suhjcct to change. so any ex(ention may be broken by futurc changes to tJle editor,<br />
1-10we\·cr. ,IS any haCKer knows. ,l program does not change a1l that quickly... So one may<br />
assume th,H most of the intern<strong>al</strong>s will not. change much. ttNol being documented" means that I<br />
don't know which parts will change and which parts won't. su you pays your money ,md you<br />
klkcs your chances.<br />
25.8.1 Editor Functions<br />
An editor function ;, just a <strong>NIL</strong> function in the package STEVE. Currently the name of the<br />
function as given in th'smanu<strong>al</strong> or with the Describe-Key command is the name of the <strong>NIL</strong><br />
function. unless th<strong>al</strong> conflicts with some other ~ll. function. (There has been some t<strong>al</strong>k of adding<br />
a consistent prefix or suffix to aU editor commands to distinguish them from other interna1 editor<br />
r.~_<br />
• VA<br />
example the I.lSP fonn (steve:forward -word) will move the cursor forward one word. just like<br />
Alela;.F would. Numeric arguments arc passed in the glob<strong>al</strong> variable steve:*argument •.<br />
steve: ed1tor-b1 nd-Icey key-sequence binding &option<strong>al</strong> motir-name<br />
key-sequence may be either a character object or a list containing two character objects. It<br />
is ev<strong>al</strong>uated. The code field of these characters should not be an ASCII control character;<br />
use the bits field to select a control character. A list is interpr<strong>et</strong>ed as a two character<br />
command using a prefix character (gener<strong>al</strong>ly Control-X). The binding is not ev<strong>al</strong>uated. It<br />
may be a function name, an editor command macro specification or a key indirection.<br />
Nonn<strong>al</strong>ly the binding is a function name to c<strong>al</strong>l when the key is typed. The function will<br />
be c<strong>al</strong>led with no arguments.<br />
If the binding is a character object the binding for that character object is used instead.<br />
This is only used for binding Control·/ to Tab. so it may not be very robust<br />
A list is used to define an editor command macro. The car of the list is a function and<br />
the cdr. is a list of arguments. When the editor is reading the key as a command the<br />
function is c<strong>al</strong>led and its v<strong>al</strong>ues are r<strong>et</strong>urned as the "key" and command. This is hairy<br />
and should not be used lightly. Look at the code for numeric arguments and bit-prefixes<br />
to see how it can be used.<br />
lbe mude--Ilame is used to find the binding table for that major mode. The major mode<br />
must be declared when this is executed. The default is to usc the current major modc.<br />
which is nonn<strong>al</strong>ly fundament<strong>al</strong> when not in the editor. i.e. when linking· <strong>NIL</strong>.<br />
MC:NII.MAN:EDITOR 18<br />
2J-I)EC-83
<strong>NIL</strong> Manu<strong>al</strong> 275 Extending the Editor<br />
If the binding is a symbol then it is <strong>al</strong>so defined as a Alcta-X command. Not sure if this<br />
is good but thaCs the way it is right now.<br />
steve: ed1 tor-defun-Key key-sequence name &body fonns<br />
A cross b<strong>et</strong>ween defun and editor-bind-key. Dcfuns name to be a no argument function<br />
with a body of jonus and binds it to key-sequence using editor-bind -key. There is some<br />
debate about wh<strong>et</strong>her to use this function or not.<br />
A number of the editor functions take option<strong>al</strong> arguments which arc intended to make it<br />
easier to usc them from I"II. code. Usu<strong>al</strong>1y these
Extending thc Editor 276 <strong>NIL</strong> Manu<strong>al</strong><br />
steve: make-l1 ne buffer previous Ilext&option<strong>al</strong> sIring<br />
R<strong>et</strong>urns a line in buffer b<strong>et</strong>ween prel'ious and next containing siring. If next is nil this<br />
will be the end of the buffer.<br />
steve: buffer spec &key :create<br />
spec may be a pathname. a buffer name (as a string). a buffer or an edit-cursor. The<br />
v<strong>al</strong>ue is either nil or a buffer. which is found or created using spec. The keyword<br />
argument cre<strong>al</strong>e d<strong>et</strong>ermines jf the buffer is created when it docs not exist <strong>al</strong>ready. 'lbe<br />
default is to creatc a new buffer.<br />
steve:po1nt 5P(,(, &key cre<strong>al</strong>e<br />
l.ikc buffer except r<strong>et</strong>urns an edit-cursor. The argument ('reat(' controls wh<strong>et</strong>her a butfer<br />
is crcated in order to build the edit-cursor. (If there is () buffer then an edit-cursor will<br />
a1ways be r<strong>et</strong>urned. regardless of the v<strong>al</strong>ue of creau. An edit-cursor must hm"c a bufl'er.)<br />
The edit-cursor may Of may not have a window.<br />
steve: paint-selected spec &kcy cre<strong>al</strong>e<br />
l.ike point except that the edit-curSOf is selected" as the current cursor and its huffer is the<br />
current buffer.<br />
This last function uses primitives which are useful in their own right.<br />
steve:select-po1nt point<br />
Make poi11l he the current cursor and its huffcr the current huffer.<br />
steve: select-po1nt-1n-current-w1 ndow poini<br />
Like select-point except the window of the current cursor is stolen. This is usu<strong>al</strong>ly the<br />
right way tp sclect a cursor.<br />
SonIC common operations on lines. These arc done carefully, so as to do the right thing at<br />
the beginning and end of the buffer.<br />
steve: line-next line<br />
R<strong>et</strong>urn the line after line or nil if at the end of the buffer. This is a macro generated by<br />
defflavor.<br />
steve: line-previous line<br />
R<strong>et</strong>urn the line before line or nil if at the beginning of the buffer.<br />
steve:nth-next-l1ne line n<br />
R<strong>et</strong>urn the line n lines after line ~ If the cnd of the buffer is reached. the last line in the<br />
buffer is r<strong>et</strong>urned. If n is 0 the first argument is r<strong>et</strong>urned. If n is negative, moves<br />
backward.<br />
steve:nth-prev1ous-l1ne lille n<br />
Like nth-next-line except moves up for positive n.<br />
MC:Nl'.MAN:EDITOR 18
n .-<br />
@"<br />
<strong>NIL</strong> Manu<strong>al</strong> 277 Extending the Editor<br />
Some operations on bps.<br />
:advance-pos n<br />
Ask the bp to advance by 11 chars. Line separators count as 1 character. Bombs back to<br />
the editor top level at beginning and end of buffer.<br />
: move lille Il<br />
Place the bp pointing to the nth character of line.<br />
:g<strong>et</strong>-char<br />
R<strong>et</strong>urn the character that the bp points to.<br />
:g<strong>et</strong>-char-forward<br />
R<strong>et</strong>urn the character that the bp points to and advance over it.<br />
:peek-char-backward<br />
R<strong>et</strong>urn the character before theme that the bp points to.<br />
:g<strong>et</strong>-char-backward<br />
R<strong>et</strong>urn the character hefore the one that the bp points to hackup to point to it.<br />
Note the unpleasant asymm<strong>et</strong>ry of names. However. none of these can be interpr<strong>et</strong>ed as standard<br />
stream messages.<br />
25.8.3 Other Functions and Conventions<br />
Editor errors.<br />
steve:save-<strong>al</strong>l-f11es<br />
This is the Al<strong>et</strong>a-A' S<strong>al</strong>'e-All-Files function. It may be c<strong>al</strong>led from outside the editor if the<br />
editor is broken, and may be able to save your buffers.<br />
steve: ed-lose [oml<strong>al</strong>-string &restv [onnat-args<br />
Abort any operation immediately. Print the Jonnat-string and ring the bell. then r<strong>et</strong>urn to<br />
the editor top-level. The [orowt-string is printed in the mode area. Pass<strong>al</strong>1 mode is<br />
turned off while aborting to the top level, so if a bug causes a rep<strong>et</strong>itive error you can<br />
escape by typing Conlrol-C at the right instant. Keep trying, it works, but it may take a<br />
few tries.<br />
steve: ed-warn [onnat-string &restv [ormat-args<br />
Like ed -lose except the ben is not rung. In gener<strong>al</strong> ed -lose is used when the editor<br />
d<strong>et</strong>ects an error. and ed -warn is used for predictable events, like the Colllro/-G abort out<br />
of a command reader. I fee1 that if the user has <strong>al</strong>ready done som<strong>et</strong>hing to cause an<br />
abort h('/she will not want to hear how ups<strong>et</strong> the editor is. The bell is to bring attention<br />
to som<strong>et</strong>hing unexpected.<br />
MC:<strong>NIL</strong>~1AN:EDITOR 18<br />
23-DEC-S3
1':Xlcnding thc Editor 278 Nil. Manu<strong>al</strong><br />
steve: ed-w8rn1 ng jiJnnl1l-s/ring &restv jbnll<strong>al</strong>-args<br />
Print ji)rm<strong>al</strong>-slrillg in the mode area, and continue. Docs not cause an exit to the editor<br />
top-level. but continues any operation in progress.<br />
steve: wi th- no- pas s811 &body fom7s<br />
Execute fonns with the termin<strong>al</strong> not in pass<strong>al</strong>l mode. S<strong>et</strong>s up an unwind-protect form so<br />
an abort is o.k.<br />
steve: *ed1tor-dev1ce-mode*<br />
Variable<br />
The editor s<strong>et</strong>s the tennin<strong>al</strong> to pass<strong>al</strong>l mode only if this variable is t. If you write an<br />
editor function which turns pass<strong>al</strong>l 011' and on yuu should <strong>al</strong>ways usc the fimn:<br />
(send termin<strong>al</strong>-io :s<strong>et</strong>-device-mode<br />
:pass<strong>al</strong>l steve:*editor-device-mode*)<br />
Arguments.<br />
steve:argument?<br />
Use the fonn (steve:argument?) to d<strong>et</strong>ermine if any numeric a 'gument was given.<br />
steve:c-u-only?<br />
R<strong>et</strong>urns t if the argument was Colllroi-U with no number.<br />
steve:rea1-arg-sup?<br />
(and (steve:argumentl) (not (steve:c-u-only71»)<br />
But more efficient in 'code and runtime.<br />
steve: buffer-beg1 n1 &option<strong>al</strong> bp<br />
Test wh<strong>et</strong>her bp (or the current cursor) is at the very beginning of the buffer.<br />
steve: buffer-end? &option<strong>al</strong> bp<br />
Similar; test for the end of the buffer.<br />
steve: f1 rst-l1 n8? &option<strong>al</strong> bp<br />
R<strong>et</strong>urns t if the bp is anywhere in the first line of its buffer.<br />
steve: 1 ast-l1 n8? &option<strong>al</strong> bp<br />
An<strong>al</strong>ogous.<br />
steve: not-buffer-begin &option<strong>al</strong> bp<br />
steve: not-buffer-ef)d &option<strong>al</strong> bp<br />
steve: not-f1rst-l1 ne &option<strong>al</strong> bp<br />
steve: not-18st-11 ne &option<strong>al</strong> bp<br />
R<strong>et</strong>urn to the editor top level if the bp fails the given test. Otherwise do nothing.<br />
MC:NII.t\1AN:EDITOR 18<br />
23-DEC-83
NIl. Manu<strong>al</strong> 279 Extending the Editor<br />
Redisplay<br />
steve:make-screen-1mage<br />
This is poorly named. It used to be different. Now it is the redisplay entire and<br />
compl<strong>et</strong>e. Just c<strong>al</strong>l it and the screen will be redisplayed. (If a character has been typed it<br />
will exit immediately.)<br />
steve:s<strong>et</strong>up-mode-area<br />
Generate and print a current mode line.<br />
Some functions use the upper area of the screen to print things. The redisplay must he<br />
told that tJlis has happened. This is handled by using sever<strong>al</strong> speci<strong>al</strong> tlmclions to position<br />
tJ1e cursor and to do terpri. It is possihle that this will he changed and that there will be<br />
a speci<strong>al</strong> stream which keeps track of such things. I was sick of defining speci<strong>al</strong> purpose<br />
streams when I got to this.<br />
steve:overwrite-start<br />
Begin to overwrite the display. If there has b~en some overwriting of the screen since the<br />
last redisplay s141rt after it. Otherwise start at the top.<br />
steve:overwr1te-home<br />
Start at the top <strong>al</strong>ways.<br />
steve:overwrite-terpr1<br />
Move the cursor to the next overwrite line. 'r11is will do .more* processing as needed.<br />
steve:overwrite-done<br />
Always c<strong>al</strong>l this when finished with an overwrite display. This makes overwrite-start begin<br />
in the right place if c<strong>al</strong>led before a redisplay.<br />
Reading from the tennin<strong>al</strong>.<br />
steve :mx-prompter function jonn<strong>al</strong>-string &restv fonnat·args<br />
Prompts in the mode area using jonnat-slring and jonnat-args, then reads from the<br />
tennin<strong>al</strong> using junction. Handles C011lrol-G and has some addition<strong>al</strong> intern<strong>al</strong> hair which<br />
<strong>al</strong>lows compl<strong>et</strong>ing functions to be defined. May be modified to handle ? as a help key<br />
somehow.<br />
steve:read-f11e-name<br />
Can only be used as an argument to mx-prompter. Reads a file name and r<strong>et</strong>urns it as<br />
a string. Some day this will do compl<strong>et</strong>ion.<br />
steve:read-buffer-name<br />
Only for usc as an argument to mx -prompter. Will do buffer name compl<strong>et</strong>ion and<br />
respond to? Example:<br />
steve:(mx-prompter ,'read-burfer-name "Foo(-a): " faa)<br />
MC:NIl MAN:EDITOR 18<br />
23-DEC-83
The Patch Facility 280 <strong>NIL</strong> Manu<strong>al</strong><br />
26. l"he Patch Facility<br />
The patch facility provides a means by which a program (whatever that might mean) may be<br />
increment<strong>al</strong>ly updated: it essenti<strong>al</strong>ly a bookkeeping operation. and is primarily designed for<br />
providing the updates necessary for a dumped-out system. In the context of the patch facilIty.<br />
such a program unit is c<strong>al</strong>led a patchable system: usc of thc term system in this context means<br />
the same thing, but may not in other contexts. (NlI. has no more sophisticated system-building<br />
tools currently. <strong>al</strong>though it cenainly has whatever primitives might be needed.)<br />
The design of the !\Il. patch facility is origin<strong>al</strong>ly derived from the uSP M:\CIII~F I.ISP patch<br />
fllcility [121. That was first implemented from scrcttch in \1:\('1 lSi>. and some time later the<br />
\1.\( 'lISP \·ersinn was copied and modified to he more appropriate for ;\11. This is noted because<br />
there arc \ariou~ design flaws and misfcatures of the filciJity. which arc inherited and are due in<br />
part to the application of the techniques used to a different programming environment. A future<br />
release should have a redesigned facility which will correct these things.<br />
P<strong>al</strong>chah1c systems have both m(~;or and millor .version numbers. The major ve/sinn number<br />
corresponds to a compl<strong>et</strong>e new system generation. like when a :\11 maintainer (one of' the authors)<br />
loads lip a new :'\11. having incorporatcd any fixes into the source files and rccompiled any files<br />
which needed it. '1l1e minor version number is incremented whenever an update is made. The<br />
updates are maintained on disk: each one corresponds to a particular file (a patch file) which<br />
implements the fix (usu<strong>al</strong>ly. some function and variable definitions the same as in a newer version<br />
of some source file). A patch directory is maintained for each major version number: it<br />
ClIUtll\'·ICtic~ (ami JC~I iiJc!'l) iilc Pi.lll.:itc~ fur ciu.:h minor vcr~ion numher. Finaiiy. each p<strong>al</strong>chabie<br />
system has a p<strong>al</strong>ch system definitiol1 Jife. which primarily provides <strong>al</strong>l kinds of default attributes<br />
about the system. which include the current version number and the location of the otlier files in<br />
the filesystem (thus the only place a pathname need ordinarily be specified to the patch facility is<br />
when pointing at the patch system definition file to define the patch system origin<strong>al</strong>ly).<br />
A typic<strong>al</strong> cycle of usage for the authors might thus look like this. We have a freshly-made<br />
<strong>NIL</strong>. say version 175 (the Release 0 version). As bugs are found. they are accumulated into patch<br />
files. One person might accumulate sever<strong>al</strong> fixes over the course of a day into a single patch file.<br />
This might then be the update which makes Lisp 175.0 become Lisp 175.1. Exportation of the<br />
patch directory and the patch files for Lisp 175 to other sites will then <strong>al</strong>low them to be loaded<br />
by other dumped-out <strong>NIL</strong>s of Lisp version 175. Eventu<strong>al</strong>ly. one of us will decide that the<br />
changes are too far-reaching or too numerous. and decide to go on to another system version.<br />
This norm<strong>al</strong>ly involves ensuring that aU updated sources are recompiled, loading up a new <strong>NIL</strong>,<br />
and telling the patch system we want a new major version number. Note that the last is<br />
independent. conceptu<strong>al</strong>ly, from loading up a new <strong>NIL</strong>: it is an operation which says that what<br />
we have on disk is a new version. A conceptu<strong>al</strong> bug in the distributed <strong>NIL</strong> is the case with which<br />
one may load up a <strong>NIL</strong> and increment the version number. Unless one is actu<strong>al</strong>ly modifying the<br />
files which g<strong>et</strong> loaded. onc's site should remain at <strong>NIL</strong> version 175. If it does not. then a bug<br />
report referring to the <strong>NIL</strong> version is meaningless to us.<br />
At the end of section 26.4. page 285. is a description of a more common usage of the patch<br />
system. where it is used for a system which is /luI dumped out.<br />
MC:NII.MAN:PATCH 25<br />
23-DEC-83<br />
. . ,<br />
0~j~}l~~
Nil. Manu<strong>al</strong> 281 User Functions<br />
26.1 User Functions<br />
load - pa tchas &rest poorly-desiglled-keywords<br />
Loads patches for the specified (or <strong>al</strong>l) systems. This takes keyword arguments in a nonstandard<br />
fashion. <strong>al</strong>though that is expected to be changed incompatibly in the future. All<br />
of them except for :systems take 110 arguments. They are:<br />
:systems list-afsystems<br />
Load patches for the specified list of patch systems. rather than <strong>al</strong>l those currently<br />
defined.<br />
:verbose<br />
Be verbose. (Verhosity is forced when there is interaction. of course.) This is the<br />
d<strong>et</strong>lUll.<br />
:silent<br />
Don't be verbose.<br />
:noselective<br />
Don't be interactive. just load the patches. The d~',:ault is to query the user on<br />
each patch,<br />
:selective<br />
Query for loading of each patch, This is the default. Note that one may answer<br />
P instead of Y or N to the query: this means proceed. which will cause <strong>al</strong>l<br />
succeeding patches to be loaded non-interactively. load-patches is (supposed to<br />
be) clever to force verbose typeout when it is going to ask. and inhibit it again if<br />
:silent was specified and the loading was proceeded.<br />
The standard l'IL default init file does a<br />
(load-patches :noselective)<br />
to load patches without querying. but verbosely (so that you see what might be taking it<br />
a while during startup).<br />
The fol1owing two functions, if given no arguments, print infonnation about <strong>al</strong>l defined<br />
systems: otherwise, about the systems given as arguments.<br />
pr 1 nt-sys tam-mod 1 f1 cat ions & rest systems<br />
This prints infonnation about the systems as they exist in core. For each system. it lists<br />
its (current) status. and lists the minor version numbers that have been loaded, and their<br />
dcscrip tions.<br />
pr1 nt-systam-h1 story &rest systems<br />
This reads the patch directory for the named systems off of disk. and displays the<br />
infonnation: <strong>al</strong>1 patches and their descriptions are listed (wh<strong>et</strong>her or not they have been<br />
loaded), status changes (the system status may change with a particular minor version<br />
number) are noted, and the "in-core" status with respect to <strong>al</strong>l of this is shown.<br />
Note that <strong>al</strong>though the patch directory is read from disk. the patch system must be<br />
defined in-core in order for this to know where to look for the patch directory.<br />
MC:NII.MAN;PATCH 25<br />
23-DEC-83
Patch System I n formation 282 Nil. Manu<strong>al</strong><br />
26.2 Patch System Information<br />
s1 :system-vers1on-1nfo &option<strong>al</strong> briefp<br />
R<strong>et</strong>urns a string describing .the versions and statuses of the patch systems defined. If<br />
briefp is specified and not nil, then the status infonnation will be abbreviated, some<br />
rinsignificant") systems will not be shown, and the name of the primary system rLisp")<br />
will be omitted (it <strong>al</strong>ways comes ·first).<br />
s1 :g<strong>et</strong>-system-vers1on &option<strong>al</strong> system<br />
R<strong>et</strong>urns multiple v<strong>al</strong>ucs describing the current version of thcspecified patch system:<br />
• the major version number.<br />
• the minor version number,<br />
• and the system status keyword.<br />
By some speci<strong>al</strong> strange dispensation. if system is not defined as a patch system, nil is<br />
r<strong>et</strong>urned as each of the v<strong>al</strong>ues.<br />
s1 :g<strong>et</strong>-system-vers1on-l1st syslem<br />
This is a vestigi<strong>al</strong> r~mnant of Maclisp implementation. Equiv<strong>al</strong>ent to<br />
( m u 1 tip 1 e - v<strong>al</strong> u e - 1 i s t (s i : g<strong>et</strong> - s y s t e In" V e r S ion S)'SI em) )<br />
(In ~1:\n IS£>, the multiple-\'<strong>al</strong>ue support code docs not normany reside in core. and code<br />
which runs interpr<strong>et</strong>ed and needs to examine system version infonnation (for instance<br />
when loading up a system) might not want to force it to be loaded.)<br />
s1! pr1nt.-hAr~1 tt &option<strong>al</strong> 'Otrp(lIn In()Jr.nu!~r:if-t:f)"f'?<br />
This is what prints the startup message. If look-oul-ofcore? is not nil. then si:printher<strong>al</strong>d<br />
reads the patch directories off' of disk so that it can show what the current versions<br />
and statuses are (what you would g<strong>et</strong> if you do load-patches). With a non-null look-oUIof<br />
core? si:prilll-heraid effectively docs a (si:update-system-statuses nil) (q.v.).<br />
s1: update-system-status8s? system-list<br />
Looks on disk and corrects (if necessary) the in-core status information for each of the<br />
systems in system-lisl, or <strong>al</strong>l defined patch systems if that is nil. The reason for this is<br />
that it is possible for the status of a system to change on disk (a particular patch might<br />
be deemed to be broken, or the system might be deemed to be no longer experiment<strong>al</strong>,<br />
for instance). This is done implicitly by load-patches. and by si:print-her<strong>al</strong>d with a<br />
non-null second ar$ument.<br />
26.3 Adding Patches<br />
For th~ fonowing s<strong>et</strong> of functions. a default systcm/minor-version-numbcr pair is maintained.<br />
from which system-name and mil1or-version-number are defaulted. The system name origin<strong>al</strong>ly<br />
defaults to lisp, which is the name of the <strong>NIL</strong> patchable system. (This should be changed.)<br />
s;;add-patch creates a new minor version number, <strong>al</strong>locates it in the patch directory. and s<strong>et</strong>s<br />
this in-core default patch version to that. 111cn one can (for instance) do (si:compile.. loadpatch)<br />
to test that patch. If the function docs not know which minor version numher to de<strong>al</strong><br />
with, then it will cyclc thruugh aU of thcm, from the "most likely" one first. asking. One way to<br />
filrce this behavior is to specify a system but not a minor version number to one of these<br />
functions.<br />
MC:NII.MAN:PATCH 25<br />
2)-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 283 Adding Patches<br />
s 1 : add - pa tch &option<strong>al</strong> system-name descriptiol1 &rest options<br />
This <strong>al</strong>locates a new minor version number for the patchablc system s),slell1-ll<strong>al</strong>llc. with a<br />
description of description and environment options of options (sec the :environmentoptions<br />
keyword to the si:initi<strong>al</strong>ize-patch-system function. on page 285). It then c<strong>al</strong>ls<br />
si:re-edlt-patch. below.<br />
s1: re-ed1 t-patch &option<strong>al</strong> system-name millor-version-number<br />
Creates a patch file for the appropriate file (if necessary). and c<strong>al</strong>ls the built-in editor on<br />
it.<br />
s i : comp 118 - pa tch &option<strong>al</strong> !l),SICI11-IIc1I11C mill"r- version-numbcr<br />
Compiles U1C specified patch. This routine relllrns sever<strong>al</strong> v<strong>al</strong> lies: the first of which is the<br />
path name of U1C compiled file. so that it may he loaded.<br />
s 1 : comp 118-1 oad - pa tch &optionaJ s),stem-name minor-vcrsion-number<br />
Compiles and loads the specified patch.<br />
s 1 : fin 1 s h - pa tch &option<strong>al</strong> system-name mil1or-versioll-llumber<br />
"Compl<strong>et</strong>es" the specified patch: that is. marks it as finished. I f a patch is not<br />
"finished". then load-patches wiJl not load it (nor any succeeding patches).<br />
s 1 : abort - pa tch &option<strong>al</strong> system-name millor-version-number<br />
Flushes (aborts) the specified patch. Any patch files arc not del<strong>et</strong>ed. hO\l,'e\,er: you should<br />
consider doing that manu<strong>al</strong>ly. If the minor version numher was the highest in lise, it wi1l<br />
be rellsed. in which case a later si:add-patch will usc the existing text file to start.<br />
Otherwise, there will be a missing minor version number, which is ok.<br />
s1: s<strong>et</strong>-patch-env1ronment system millor-version-l1umber &rest options<br />
In case you forgot with add-patches. this s<strong>et</strong>s the option environment to opticms. Note<br />
it docs not update the file attribute list in the' source file of the patch ! You must do that<br />
manu<strong>al</strong>ly.<br />
s1: s<strong>et</strong>-system-status system status &option<strong>al</strong> major-version minor-version<br />
Note that "this takes weirder than nonn<strong>al</strong> arguments. This s<strong>et</strong>s the status of the specified<br />
version of system to be status. It is willing to modify the status list of major versions<br />
differing from that defined in the current environment. (Not to say that that would not<br />
be equ<strong>al</strong>ly useful for some of the other functions ... )<br />
The typic<strong>al</strong> use of this is to s<strong>et</strong> either the current or the 0 minor version number of the<br />
current major version of some system to either :released or :broken, with the current<br />
status being :experiment<strong>al</strong> (the default when a new major version number is made). Or.<br />
to change the status of an antiquated system from :released to :obsol<strong>et</strong>e.<br />
MC:NIl.MAN:PATCH 25<br />
23-DEC-83
Defining Patch Systems 284 <strong>NIL</strong> Manu<strong>al</strong><br />
26.4 Defining Patch Systems<br />
s1: new-patch-system system-name pat/moille &option<strong>al</strong> (do-what :increment-<strong>al</strong>ld-define)<br />
s1: 1n1t1<strong>al</strong>1ze-patch-system system-name p<strong>al</strong>hllame &key :initi<strong>al</strong>-version<br />
:patch - directory :patch - file :compilation - function :editing - function<br />
:insignificant :default-directory :default-device :nodefault<br />
:environment-options<br />
:nodefautt<br />
If not nil. then si:initi<strong>al</strong>ize-patch-system will read in an eXlsttng version of the<br />
patch system definition file from pelflmam (appropriately dd:lllltcu) (0 provide<br />
de~lllils for those options not specified. Otherwise. hopefully appropriate default<br />
defaults arc used.<br />
:initi<strong>al</strong>-version<br />
May be used to specify the version to he uscd. Thiswitl be written into the<br />
patch system definition file as the CUrrl'1I1 version. which means that c<strong>al</strong>ling<br />
si:new-patch-system with the (typiccdl) :increment-and-define keyword will<br />
increment it first.<br />
:patch -directory<br />
A fonnat string which should take one argument. which is . the major system<br />
version. to construct the patch directory pathnamc for that major system version.<br />
·n~tr.h -fil~<br />
r·· -<br />
A format string which should take two arguments. the major and minor system<br />
versions (in tllat order). to construct the patch file patllname for thepatchs of<br />
those versions. Alternately. it may be a list of two such fonnat strings: the first<br />
will be used as the source file pathname. the second for the \'asl fiJ~. (This may<br />
be used to split the stuff across directories or even structures, for instance if the<br />
sources are kept in a different place because of lack of disk space. or are simply<br />
not kept somewhere on some particular machine.)<br />
:compi lation - function<br />
The function caUedby compile-patch <strong>et</strong>c. By default compile-file (page 244) is<br />
used. This should be a. symbol. not a closure or compiled-function object. The<br />
function wiH be given a first argument of the input pathname. and other<br />
kcyworded argumenl~<br />
of :output-file and :s<strong>et</strong>-default-pathname (which will be<br />
nil so as to not modify pathname defaultS). That is,<br />
( 1 sbe 1 illpul-parhname<br />
: output-fi 1 e output-pathname<br />
:s<strong>et</strong>-default-pathname nil)<br />
:editing- function<br />
The editing function which should be used to edit a patch file. It is c<strong>al</strong>1ed with a<br />
single argument. the patch file path name. The default function simply r<strong>et</strong>urns the<br />
list of "now" "edit" and the pathname 9 which is then r<strong>et</strong>urned by si:add-patch<br />
or si:re-edit-patch.<br />
:insignificant<br />
If not nil. then si:system-version-info will not show this system when in brief<br />
MC:NII.MAN:PATCH 25<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong><br />
285 I )cflning Patch Systems<br />
mode.<br />
:default-directory<br />
:default-device<br />
These are used to construct the default pathnames used for the :patch-directory<br />
and :patch-file options, when they are not supplied. They are 1101 used in<br />
defaulting (<strong>al</strong>though they probably should be). The default-defaults for these are<br />
taken from p<strong>al</strong>hllame. and if absent from that. the directory name defaults to<br />
system-name. These options are significantly less useful in 'II. than they were in<br />
the ~1ACI .IS}> version of this code ...<br />
:environ ment - options<br />
This and some of the code involved is parti<strong>al</strong>ly but not tot<strong>al</strong>ly archaic: it predates<br />
:\11. file attrihute lists. and was put in to compensate for their ahsence. The code<br />
in Release 0 still performs redundant bindings of the in\ohed attributes.<br />
However. the data in this option list is used to <strong>al</strong>so initi<strong>al</strong>ize the textu<strong>al</strong> file<br />
property list when si:add-patch initi<strong>al</strong>izes the 'patch file. Because of the<br />
kludginess of this. only a few options are supported. <strong>al</strong>though it is extensible if<br />
need be (see the code). The options currently handled are<br />
:package<br />
The package name (default is "SYSTEM-INTERNALS", which is probably<br />
a poor choice)<br />
:input-radix<br />
The input iadix (default i5 dedman.<br />
LSB, which has been distributed with <strong>NIL</strong>, is a patchablc system <strong>al</strong>so. However, the nonn<strong>al</strong><br />
~IL environment does not have LSB loaded by default. There is a file which can be loaded which<br />
wi1110ad up <strong>al</strong>l of the parts of LSB. (It is <strong>NIL</strong>$DISK:[LSB]LOAD.LSP. if you have ISB online.)<br />
Esscnti<strong>al</strong>ly, it s<strong>et</strong>s up the Isb package and loads up <strong>al</strong>l of the component files of lSB and<br />
performs whatever initi<strong>al</strong>izations are needed, and then does<br />
(si:new-patch-system<br />
"LSB" "<strong>NIL</strong>$DISK:[LSB.PATCH]SYSOEF"<br />
:define)<br />
(load-patches :noselective)<br />
The file N 1 L$D ISK : [LSB . PATCH ]SYSDE F • PSD was created with the si:initi<strong>al</strong>ize-patch-system<br />
function. Once that has been created, this refcrence to it in the ISB loadup file is the only<br />
pathname reference necessary; <strong>al</strong>l others are contained in that file.<br />
With the LSB patchable system, the files which are loaded by the loadup file are not nonn<strong>al</strong>ly<br />
modified except via patches. However, at strategic points. like when many files are being changed<br />
at once, or incompatible changes are being made. or the patches become numerous. then <strong>al</strong>l of<br />
the files are changed (for instance, recompiled) at once, and the maintainer manu<strong>al</strong>ly increments<br />
the version number of the LSD patchable system by doing<br />
(si:new-patch-system 'lsb "nil$disk:[lsb.patch]sysdef"<br />
:increment)<br />
which increments the on-disk version number. Then. when someone loads the loadllp file. they<br />
g<strong>et</strong> the new files. the new major version number, and (until new patches gel made) no patches<br />
loaded.<br />
MC:NII.MAN:PATC1-I25<br />
23-DEC-83
Defining Patch Systems 286<br />
M~intaining the system in this way <strong>al</strong>so result'i in a shorter turnaround time for testing out<br />
sm<strong>al</strong>l fixes. and g<strong>et</strong>ting them "inst<strong>al</strong>led"; larger source files do not need to be rccompiled.<br />
~lC:~II.~1AN:PATCH 25<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 287 T<strong>al</strong>king to <strong>NIL</strong><br />
27. T<strong>al</strong>king to <strong>NIL</strong><br />
27.1 Startup<br />
'Inc first thing ~IL docs when it starts up is to attempt to figure out what kind of tennin<strong>al</strong><br />
you arc using. The way <strong>NIL</strong> figures out how to t<strong>al</strong>k to a particular tennin<strong>al</strong> is that it uses<br />
"tennin<strong>al</strong> capahilities" database (a C~IX lenncap database). "Ibe VMS logic<strong>al</strong> name term is used to<br />
name the tennin<strong>al</strong> type: ~II ignores VMS tenninaI infonnation. If no such logic<strong>al</strong> name is<br />
defined. then ~Il will assume tJle tenninaI is a simpleminded printing termin<strong>al</strong>. and prompt you<br />
for a tcnninaI name.<br />
The termin<strong>al</strong> names which arc both supported and known to work fairly wen arc<br />
vt52<br />
Standard DEC VTS2.<br />
c100<br />
Human De~:gned System's concept-"IOO. This will probably work for their Concept-l08<br />
<strong>al</strong>so.<br />
aaa<br />
Ann Arbor Ambassador<br />
vt100<br />
DlT vt100. Obviously you should make sure your vt100 is in ANSI mode. Also. autolinewrap<br />
should be disabled.<br />
In OCL. one m igh t say<br />
$ define term "cIOO"<br />
if one was on a concept-H)(). Or. if your tennin<strong>al</strong> varied. you might put in your log in. c om file<br />
$ inquir term "Termin<strong>al</strong> type (in doublequotes. default vt52)"<br />
$ if term _eqs. "" then term := "vt52"<br />
$ define term "-'term'"<br />
which would prompt for the tennina] type to assign to the term logic<strong>al</strong> name, defaulting it to<br />
whatever was convenient.<br />
When <strong>NIL</strong> starts up, it loads your illit file if it exists. This would be a file on your login (not<br />
default) directory named <strong>NIL</strong> ~ I N I. (lnit file conventions are discussed on page 200.) Then it<br />
enters its standard read-ev<strong>al</strong>-print loop.<br />
~1C:NII.M;\N:TAI.K 16<br />
23-DEC-83
"I'hc Toplevcl J .(lOP 288 <strong>NIL</strong> Manu<strong>al</strong><br />
27.2 The Toplevel Loop<br />
•<br />
••<br />
•••<br />
Variable<br />
The v<strong>al</strong>ue of this is the last thing the top)cvel (or brcakJevcl) loop ev<strong>al</strong>uated (and<br />
presumably printcd).<br />
The previous v<strong>al</strong>ue of •.<br />
The previolls "<strong>al</strong>ue of ••.<br />
Variable<br />
Variable<br />
+<br />
Variable<br />
The \'<strong>al</strong>ue of this is the last thing rcad in by the top)evcl (ur breakleve1) loop.<br />
++<br />
+++<br />
Previous v<strong>al</strong>ues.<br />
Variable<br />
Variable<br />
\\<br />
Variable<br />
This has as its v<strong>al</strong>ue the lteClor of v<strong>al</strong>ues r<strong>et</strong>urned from the last thing ev<strong>al</strong>uated' by the<br />
toplc\ cl (or brcaklcyel) loop. That is. its first (number 0) e)cment will be the v<strong>al</strong>ue of •.<br />
This variable is <strong>al</strong>so used by the dcbuggcr the way • is by the toplcvel loop. but that<br />
will bc changcd eventu<strong>al</strong>ly.<br />
If an ev<strong>al</strong>uation error occurs and you abon back to toplevcl, then the v<strong>al</strong>uc of the • variables<br />
docs not g<strong>et</strong> cycled. but the + variables do: thus. + is the fonn which got the error, but • is<br />
still the last thing r<strong>et</strong>urned by toplcycl ev<strong>al</strong>uation. C0\1\10\ LISP intends to change this. (What<br />
<strong>NIL</strong> docs is compatible with MACLISP.)<br />
27.3 Entering and Exiting <strong>NIL</strong><br />
Typing the character control-Y norm<strong>al</strong>ly exits from NIl. The same command which started<br />
the <strong>NIL</strong> initi<strong>al</strong>ly may then be used to resume it. The <strong>NIL</strong> can be resumed in other ways too. For<br />
instance, if nil was thc command used to stan the nil,<br />
nil<br />
will resume the existing NJL,<br />
nil/kill<br />
will kill the <strong>NIL</strong>, and<br />
n i 11 pro c e e d will resume the <strong>NIL</strong>, but not <strong>al</strong>low it to type out. and will leave you in the<br />
command interpr<strong>et</strong>er. If the Nil. attempts to type out (or. in fact, c<strong>al</strong>ls any of<br />
the following functions). it will wait until it is explicitly resumed.<br />
If SIL is reading input from the tennin<strong>al</strong>, the input processor command for "m<strong>et</strong>a"<strong>al</strong>unode'"<br />
which may be typed as the character sequcncc CUllIro!- \ a!/mode, will r<strong>et</strong>urn control to the<br />
command interpr<strong>et</strong>er. When the <strong>NIL</strong> is resumed. it will automatic<strong>al</strong>ly redisplay the typein it is<br />
accumulating.<br />
MC:NII.MAN:TALK 16<br />
23-DEC-83
-., il"AIIl'ii!il':!I' '. '~-~--' -' 7r' '''r ,'" ' :"°11' E'"<br />
N II. Manu<strong>al</strong> 289 Entering and Exiting <strong>NIL</strong><br />
Sc\'e'r<strong>al</strong> functions are provided for r<strong>et</strong>urning from Nil to the \'\1S command language<br />
interpr<strong>et</strong>er (ell) in a more programmable fashion. In <strong>al</strong>l of the t()lIowing functions where a string<br />
is involved with passing control back to the cu. the string may have a maximum length of 256<br />
characters. This is checked for by <strong>NIL</strong><br />
v<strong>al</strong> r<strong>et</strong> &option<strong>al</strong> command-line<br />
(v<strong>al</strong>r<strong>et</strong>) r<strong>et</strong>urns control to the CLI. The <strong>NIL</strong> is suspended until later resumed.<br />
(v<strong>al</strong> r<strong>et</strong> cOll1l11tllJti-lin(') r<strong>et</strong>urns to the n.I (suspending the ~II,).<br />
comm<strong>al</strong>ld-lin(' to be interpr<strong>et</strong>ed as a command line by the CI.J.<br />
and addition<strong>al</strong>ly causes<br />
quit<br />
The passlIlI termin<strong>al</strong> mode is cleared, and restored when the 'II is reslImed.<br />
a string ~lrglll1lcnt works hy c<strong>al</strong>ling the \'\tS lib$do_command library routine.<br />
(quit) exits the <strong>NIL</strong>, causing it to be killed.<br />
v<strong>al</strong>r<strong>et</strong> with<br />
Currently. (quit SIring) kiHs the !\Ii. and causes Siring to be printed instead of "N II.<br />
Terminated": howe\ er this will probably be changed so that SIring will be interpr<strong>et</strong>ed (IS a<br />
command line. as with v<strong>al</strong>r<strong>et</strong>.<br />
Pass<strong>al</strong>l mode is cleared on exit.<br />
\\'hen the ~II. is terminated. there is a noticeable pause before the command language<br />
interpr<strong>et</strong>er r<strong>et</strong>urns. This is due to the controlling program (R'II.. nlllning in the ell)<br />
waiting t()r the process to actu<strong>al</strong>ly go away. V\fS image rundown wkes a noticeable time.<br />
and if one were to not wait after requesting process del<strong>et</strong>ion. starting up a <strong>NIL</strong> of the<br />
same name immediately could cause the new R~IL to be confused. (This is the same as<br />
happens when nil/I< i 11 is used in the cu.)<br />
ex 1 t - and - run - program (pathname)<br />
Control is r<strong>et</strong>urned from <strong>NIL</strong> to the CLI. and the program image found in pathname is<br />
then run. The l'IL will have been suspended. ~IL applies no defaulting to pathname,<br />
however. the command interpr<strong>et</strong>er will supply a default file type of exe and will default<br />
the device and directory to the RMS default<br />
PassaJl mode is cleared on exit. eXit-and-run-program works by having the R<strong>NIL</strong><br />
program caIl the lib$run_program library routine.<br />
proceed-nil &option<strong>al</strong> SIring<br />
Control is r<strong>et</strong>urned from the <strong>NIL</strong> to the CLI. However. the <strong>NIL</strong> is resumed. so will<br />
continue running "without the tennin<strong>al</strong>". If a SIring is supplied, then that is printed (as<br />
with quit). Similarly (as· with quit). the interpr<strong>et</strong>ation of Siring should probably be<br />
changed to be a command line for the eLI to execute.<br />
MC:NII.MAN:TALK 16<br />
23-DEC-83
VMS 290 Nil. Manu<strong>al</strong><br />
27.4 VMS<br />
VMS usurps control-Y as interrupt-to-superior. Resuming your <strong>NIL</strong> gives it a tty-r<strong>et</strong>urn<br />
interrupt which makes it frob the cursor so that it knows where the cursor is. (This is why it<br />
goes to the bottom of the screen on a display tty.)<br />
Other tennin<strong>al</strong> intermpts are aU perfonned by dispatching from c(}ntrol-C~ after the control-C<br />
is typed another character is read. ("?" lists options.) The contro]-C processing is perfunncd by<br />
l.isp code. This means that control-C win not be processed if interrllpt~ arc severc1yinhibited.<br />
The ~II system hy speci<strong>al</strong> dispensation will enter the VMS debugger if multiple control.;Cs are<br />
typed and arc hC'ing ignored: so if som<strong>et</strong>hing large and uninterruptih1c is happening. like creating<br />
it veClOr with a mjllion clements. or som<strong>et</strong>hing not so large but your system is slow. you might<br />
throw the :"11 out to the V\IS debugger.<br />
It is highly unlikely that Nil. will enter the V~fS debugger unless explicitly told to do so.<br />
Here arc two \,\15 debugger commands that are useful for r<strong>et</strong>urning back to the wurld. Say<br />
c<strong>al</strong>l debug .<br />
and the lisp dehugger will be entered. (Exiting $oftly from the Lisp dcbug;:i:·'r with "q••<br />
will<br />
r<strong>et</strong>urn to the \'\IS debugger. One may <strong>al</strong>so perfonn a non-loc<strong>al</strong> exit from the l.isp debugger with<br />
control-G or X.) One can <strong>al</strong>so just<br />
c<strong>al</strong>l quit<br />
frum the V~fS· debugger. which docs a throw just like contro)-G docs from the control-C prompt.<br />
'.11(\ only prnhll'm witl1 ~H thi~ is. tJ,:lt ifth~ 'A1S d~bugg~r g<strong>et</strong>s dynamka1!y laadt'd inta t'1c<br />
11\11. some part of it will end up where ~IL thinks it is putting its heap (Le.. where it is anocating<br />
the memory to use for consing). and U1C ~Il.. will die shortly thereafter.<br />
s1:11sp-debugger-on-except1ons<br />
Vanabk<br />
If non-null, then error conditions and faults will trap to the LISP error handler rather than<br />
bombing out to the \~S debugger. This can happen from memory access violation errors,<br />
floating overflow and underflow, integer divide by zero, ctc.; in gener<strong>al</strong>, any such error.<br />
For instance, a reserved operand fault might occur if a variable-field byte instruction was<br />
given a bad size.<br />
If the lisp debugger is used from some exception<strong>al</strong> condition, remember that the stack may<br />
not be in a nice-looking state, so examination of what the debugger thinks are loc<strong>al</strong> variables near<br />
the top may resull in more trouble. Note <strong>al</strong>so that the Lisp code is not run at AST level, but<br />
rather as a continuation of the condition: r<strong>et</strong>urning a v<strong>al</strong>ue from the debugger r<strong>et</strong>urns that v<strong>al</strong>ue<br />
from the most recent VAX procedure c<strong>al</strong>l, which is probably the function within which the error<br />
was sign<strong>al</strong>led. Also. the USP code which handles such errors binds si:lisp-debugger-on"<br />
exceptions to nil when it is running: examination of non·USP data by the debugger from such<br />
an error as if it were usp data might cause a memory protection violation, and blowout to the<br />
VMS debugger.<br />
Note <strong>al</strong>so the s<strong>et</strong>-privileges and g<strong>et</strong>-privileges functions (page 233). which can be used to<br />
s<strong>et</strong> or g<strong>et</strong> the privileges the 1"11. process has enahled.<br />
~lC:<strong>NIL</strong>M"N:T"LK 16<br />
23-I)FC-83
N II. Manu<strong>al</strong> 291<br />
I nSl41llation<br />
27.5 Inst<strong>al</strong>hltion<br />
There are 4 parts to inst<strong>al</strong>ling VAX - <strong>NIL</strong> at your site.<br />
J<br />
Restoration of the nil directory hierarchy from the backup tape.<br />
2 Definition of the required logic<strong>al</strong> names and symbols.<br />
3 Invoking the LISP dynamic Iinkcr.<br />
4 Handling System and User considerati
I nsutllation 292<br />
<strong>NIL</strong> Mctllu<strong>al</strong><br />
example: To go from \,~1S 3.0 to VMS 3.4 you may have to do the following:<br />
$ BLISS/LIB <strong>NIL</strong>LIB:NIlLIB<br />
$ SET OEF [NIl.FOO]<br />
$ BLISS RNIl<br />
$ @R<strong>NIL</strong>LINK<br />
$ NLINK<br />
$ LISPLINK<br />
[Step 4)<br />
See the file <strong>NIL</strong>$OISK:[<strong>NIL</strong>.COM]<strong>NIL</strong>INSTAL.COM. which can be mo,'ed (perhaps edited first)<br />
to SY$$MANAGE R. Then add this to SYSTARTUP. COM: .<br />
$@SYS$MANAGER:<strong>NIL</strong>INSTAl<br />
Then lIsers who \\ ~lIll to usc \11 must h~lve executed in their login files:<br />
$@<strong>NIL</strong>$DISK:[<strong>NIL</strong>.COM]USYMS<br />
This will s<strong>et</strong> up the the standard way of c<strong>al</strong>ling Nil .•<br />
$ <strong>NIL</strong><br />
Which will run r\JL as a subprocess. 'tV or (v<strong>al</strong>r<strong>et</strong>) will exit the subprocess: to resume, type:<br />
$ <strong>NIL</strong><br />
or to kill the subprocess:<br />
$ <strong>NIL</strong>/KILL ! from OCl<br />
(QUIT)<br />
from IISP<br />
The directory [<strong>NIL</strong>.SITE1 has two files of interest: [<strong>NIL</strong>.SITE]SITEPARAMS which jf it exists<br />
in compiled fonn will be loaded right before the LISPLINK saves thcvinu<strong>al</strong> memory image.<br />
And [NII..SITEjDEFAULTJNI. which is loaded at "re-startup" time if the user docs not have a<br />
SYS$I.OGIN:<strong>NIL</strong>INI file. After N1L is created on your system then you should edit<br />
SITEPARAMS and compile it. The information is noncritic<strong>al</strong> however.<br />
Upon startup <strong>NIL</strong> will look for the logic<strong>al</strong>-name ftTERM" to d<strong>et</strong>cnnine the type of termin<strong>al</strong> it<br />
is connected to. For example:<br />
$ Define TERM "vt100"<br />
Presently it docs an its own cursor positioning using the data in the file <strong>NIL</strong>STERMCAP. If the<br />
logic<strong>al</strong> name "TERM" is not defined then <strong>NIL</strong> will prompt the user for the info upon stanup.<br />
[Option<strong>al</strong> Verification 1<br />
In <strong>NIL</strong> do:<br />
(LOAD "NIlSDISK:[NIl.VERIFY)VERIFY")<br />
(VERIFY "TEST")<br />
Then sit back and watch the little demonstration. No. we do not have program verification<br />
technology to the point where this gives a proof of correctness for the <strong>NIL</strong>. However ... , then run<br />
$ DIFFERENCES NIlSOISK:[<strong>NIL</strong>.VERIFY]TEST.LIS<br />
(What if FaiJure?j<br />
If you ran out of disk space in step 1, then we can suggest that you somehow make more space<br />
temporarily. (e.g. backup and del<strong>et</strong>e fites), and then prune down to the minimum given in<br />
NII.S])ISK:(<strong>NIL</strong>.PORT]MINIPORT.COM when step 3 is compl<strong>et</strong>ed.<br />
MC:<strong>NIL</strong>MAN~T;\I.K 16<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 293 How the Nil. Control Works<br />
Step 2 couldn't fail. as <strong>al</strong>l it does is define logic<strong>al</strong> names and symbols.<br />
Step 3 could fail if various system generation param<strong>et</strong>ers and account quotas are not s<strong>et</strong> high<br />
enough. Many sites will fail here, as the default VIRTUALPAGECNT of 8 thousand pages is not<br />
sufficient. (Although it is sufficient to do LX B<strong>NIL</strong> which does not load the compiler): 16<br />
thousand pages is enough to g<strong>et</strong> started in lisp programming. Other things to look out for are<br />
insufficient pagefi1c and per-account pagefile quota.<br />
Default account param<strong>et</strong>ers as supplied by DEC have found to be sufficient under VMS 3.0.<br />
but some sites have been found to severly restrict param<strong>et</strong>ers. which has proved to be extremely<br />
frustrating. at that suhs<strong>et</strong> of those sites where the loc<strong>al</strong> expertise for debugging prohlems caused by<br />
Stich restrictions is insufficient.<br />
It is possihle to nll1 <strong>NIL</strong> on a V AX-11/750 with a single RK07 disk. (a mere 27 megabytes!)<br />
as we do here at MIT. However. it is not possihle to link a <strong>NIL</strong> on such a tig.ht system. Ide<strong>al</strong><br />
system environments have been found on sites config.ured to rlln large databases efficiently.<br />
In step 4. note that the running <strong>NIL</strong> image is mostly pure. sharable. code and data, so there<br />
is a big performance payotf in proper insWllation and SYSG EN tuning on a multi-<strong>NIL</strong> -user<br />
system. If LISPl.lNK works. but <strong>NIL</strong> docs not, then it may be due to insufficient glob<strong>al</strong> sections<br />
and pages.<br />
rOther Options]<br />
If vou want to be able to use the VMS debugger on the nmning lisp imrlgf' rhf'n ('1(C'('ut(' th('<br />
following:<br />
$RUN [<strong>NIL</strong>.HACKS]SETDEBUG<br />
Giving <strong>NIL</strong>$DISK:[<strong>NIL</strong>.EXF]LISP.EXE: as the filename, and answering Y to the question. With<br />
this s<strong>et</strong>ting <strong>NIL</strong> will start up in the VMS debugger. and you must type GO(CR) to actu<strong>al</strong>ly start<br />
it.<br />
27.6 How the <strong>NIL</strong> Control Works<br />
This section notes how some of the above stuff works, for the interest of VMS haCKers, or<br />
those wishing to extend the above function<strong>al</strong>ity.<br />
Program control of <strong>NIL</strong> under VMS works in a fairly strang~ way (or at least so it will appear<br />
to someone used to operating systems in which there is more explicit job/termin<strong>al</strong> association and<br />
more "monitor" control of inferior processes). This is a function of VMSS lack of a concept of a<br />
job "having control of the termin<strong>al</strong>", and the fact that the N1L process does not contain a<br />
command language interpr<strong>et</strong>er in its image: the spawn and at tach commands are only<br />
implemented by conventions applied by the CLI.<br />
The command nil typic<strong>al</strong>ly invokes the R<strong>NIL</strong> program. This is an image which runs within<br />
the CI I process, and "controls" the !'Il., which is kept in a separate process. The nil command<br />
implicitly supplies lots of arguments to R<strong>NIL</strong>. one of which is the job name of the <strong>NIL</strong> process.<br />
R'II ~ ill create one if there is none, or will do som<strong>et</strong>hing else to it (like resuming it) depending<br />
on addition<strong>al</strong> arguments given (like ni l/proceed or ni 11k ill). RNll communicates to the<br />
<strong>NIL</strong> process with mailboxes. When the ~Il is resumed. the RNll. attempts to read from one,<br />
MC:<strong>NIL</strong>MAN:TALK 16<br />
23-DEC-83
How the <strong>NIL</strong> Control Works 294 <strong>NIL</strong> Manu<strong>al</strong><br />
w<strong>al</strong>ling. It r<strong>et</strong>urns either when it succeeds in reading a mesSt1ge (as happens with v<strong>al</strong>r<strong>et</strong>). or if it<br />
is abnorm<strong>al</strong>ly exited (41S with typing contro)-V).<br />
VMS in its current state does not have the concept of a particular process having "contro'" of<br />
the termin<strong>al</strong> it shares with the rest of the process trec. <strong>NIL</strong> handles this by having a number of<br />
event and st<strong>al</strong>e flags which ten it wh<strong>et</strong>her or not it is <strong>al</strong>lowed to read from or write to the<br />
tennin<strong>al</strong>. When a Nil. is exited. the R~II. program clears those flags: when it is resumed. they<br />
arc turned back on again.<br />
Exiting from ~II with contfol-Y works in a particularly strange fashion. The VMS (ennin<strong>al</strong><br />
dri\er will give it control- Y AST (0 any process whi(:h has enahled it with no conceptu<strong>al</strong>ization<br />
of what program is "in comrol or the tennin<strong>al</strong>. The control-Y is handled by the CI.I. which<br />
then commences image nmdown of the R~IJ. program. R~1I has (In exit handler which then s<strong>et</strong>s<br />
the tenllinaI input and output enabled flags off in the!':11 process. (As a speci<strong>al</strong> case. it may <strong>al</strong>so<br />
exit similarly if the ~II. is terminated somc other way. perhaps by ex it to the "'1S debugger in<br />
thc <strong>NIL</strong> process. It recognizes the mailbox message for this. and prints "<strong>NIL</strong> Terminated".)<br />
'<br />
Control-C has a similar control problem. When a controJ-C is typed on the termina1. the<br />
termin<strong>al</strong> drivcr nms t11C AS.,. routincs for <strong>al</strong>l processes which have enahled thclll. (Multiply. if a<br />
process has cnah1cd more than one.) In the current implementation. thc ~II. process en~lhJes the<br />
conlrol-C AST. \Vhen the AST routine is run. it attempts to d<strong>et</strong>ennine if it should be the<br />
rccipicl1l of that interrupt. by checking to see if it "has control of the tennin<strong>al</strong>" (i.e.. the<br />
terminaHnput-enabled flag is on), If not. it ignores the intermpt (and of course fe-enables the<br />
rlln"'l\l.r 'H::'\<br />
_ ............ ~ • .... _ ..".,_ Ifit thin"&:-<br />
••• ~ _ ................<br />
it U'"lC'<br />
""..# th,. ..,.""n'"'''' .... f ,I.. "<br />
....................,.-...... •." w.'" ;... ,,,......_t of<br />
a.&,,~ •• t. • .., .... ,-. ""'''-t.l''''''''.' "..........,..1.. th,.. .... "" ,..,..n, ...." •• .."I.r I." 1-0,..1-...<br />
"L.v. '- , ... v , ......,<br />
keep other <strong>NIL</strong>s on Lhe same temlin<strong>al</strong> from having to think about it. i guess), and queues a LISP<br />
interrupt for control-C. There is one time when t11is can break down: if the ~ILis suspended<br />
when the AST is delivered. the AST wiJI not be run until the r\1l. is resumed. However. when<br />
the Nil. is resumed. the R:'\Il. delivers ita couple other ASTs which cause the tennina) input and<br />
output flags to be turned on! If this manages to happen before -the control-C AST routine g<strong>et</strong>s<br />
around to checking thesc flags (as it invariably docs). then the SIL will think that this control-C<br />
was for it, and behave accordingly. So, if you resume a <strong>NIL</strong> and it acts likc you just typed a<br />
control-C, it is probably because of that control-C you typed at the d i sp 1 ay program h<strong>al</strong>f an<br />
hour ago; type "n" at the n>Interrupt)'· prompt to make it go away.<br />
There is a design change which eliminates this problem. and addition<strong>al</strong>1y <strong>al</strong>lows controlled<br />
interruptibiHty out of arbitrary wait operations (not just tcnnin<strong>al</strong> input and output, which are<br />
speci<strong>al</strong> cased). It involves a sweeping change to lots of code. however. so cannot be put in bits<br />
at a time.<br />
MC:<strong>NIL</strong>MAN;TAJ.K 16<br />
23-I)EC-83
Ofirjrnttxd't<br />
N II. Manu<strong>al</strong> 295' Peripher<strong>al</strong> Utilities<br />
28. Peripher<strong>al</strong> Utilities<br />
This chapter will accumulate documentation on various minor utilities which are distributed<br />
with I'lL. but which are not necessarily part of <strong>NIL</strong> proper.<br />
28.1 The Predicate Simplifier<br />
Nil offers a predicate simplifier. which simplifies l.lsp-format predicates into disjunctive nonn<strong>al</strong><br />
t{lfI11. This progr,lm was origin<strong>al</strong>ly written hy I )eepak Kapur with thc help of Ramcsh Patil for<br />
th~ PRO'I OSYS 1"'\1 'llItomatic programming project directed h) \Villi4lm Martin at ~v11T in the mid<br />
1lJ70s. Since then. it has heen convened to lise ISH [4]. hrought lip in both liSP \1:\CIII:\F liSP<br />
and '11. and imprm ed at a low levcl. The code for this is not loaded hy dcf~Hl1t in '": it<br />
exists as nil$disk:[nil.utilities]simp. and to load it. the package definition file<br />
nil$disk:[nil.utilities]simp.pkg should he loaded first. This may he perflmned<br />
automatic<strong>al</strong>ly by use of<br />
( r e qui r e 's imp)<br />
See require. page 123.<br />
This simplifier only re<strong>al</strong>ly works on simple predicatcs and connectives. It perfonns some<br />
trivi<strong>al</strong> canonic<strong>al</strong>izations of arithm<strong>et</strong>ic operations and inequ<strong>al</strong>ities (equ<strong>al</strong>. greaterp. and lessp), but<br />
it does not truly recognize identities or other relations among them. There is <strong>al</strong>so a read-time<br />
(compile-time) condition<strong>al</strong>ization for wh<strong>et</strong>her it attempts to de<strong>al</strong> with existenti<strong>al</strong> quantification. as<br />
r('nr('c('''tt.,.t<br />
·-r·--- ..··_- h"<br />
......<br />
f"rnlC Ilf th,.. ft,\rnl<br />
J ."'..................- " ..."." ••<br />
(for-some (kl k2 ... kll) pred)<br />
This feature is nonn<strong>al</strong>ly turned off, which simplifies the intern<strong>al</strong> dawstructures used and improves<br />
the efficiency in the other cases. Again, simplification of fonns containing existcnti<strong>al</strong> quantification<br />
does not <strong>al</strong>ways reduce as well as it should. To g<strong>et</strong> this one would have to recompile simp with<br />
that feature turned on.<br />
simp pred-fonn<br />
Simplifies prcd-fonn. For example.<br />
(simp '(and c d (or a b») =><br />
(or (and a c d) (and bed»<br />
s1mpor pI p2<br />
s impand pi p2<br />
Approximately equiv<strong>al</strong>ent to<br />
(s imp (1 is t and-or-or pI p2»<br />
s 1mpnot pred<br />
Simplifies the not of pred.<br />
simp 0 r 11 s t pred-Iist<br />
S 1mpandl1 s t pred-list<br />
Simplifies the or or and of pred-list.<br />
MC:<strong>NIL</strong>MAN;UTILS 15<br />
23-DEC-83
\ Mini-MYCIN<br />
296 N II. Manu<strong>al</strong><br />
.s 1mpor pi p2<br />
.s 1mpand 1'1 pl<br />
pI and p2 must <strong>al</strong>ready be in disjunctive nonna} fonn. i.e .• <strong>al</strong>ready simplified (as r<strong>et</strong>urned<br />
by some simplification c<strong>al</strong>l). l'bisis faster than using simpor or simpand .<br />
• s impor 11 s t pred-list<br />
.$ impandl i st pred-list<br />
Simplifics thc or or and of the predicates in pred-list. which must be <strong>al</strong>ready simplified .<br />
• s 1mpnot pred<br />
Simplifies the not of pre(/. which must be ah'c41dy simplificd.<br />
There is <strong>al</strong>so a hack for doing both uniqui1.ing of predic411es r<strong>et</strong>urned. and <strong>al</strong>so "atomizing".<br />
associating an atomic symbol with a predicate (which will be expanded out in subsequent<br />
simplification). The fonner was important in the PIW-I0 ~ACI.ISP version when large databases<br />
associating predicates with probabilities were in use. See the source code if either of thesc are<br />
desircd.<br />
28.2 A l\1ini-MYCIN<br />
'Ibis is a sm<strong>al</strong>l production rule systcm upon which class projects in the MIT course 6.871<br />
were implcmentcd. Some students in the course ulught this tenn by Prof. P<strong>et</strong>er Szolovits and Dr.<br />
Ramesh PatiJ used this code in <strong>NIL</strong>. The directory <strong>NIL</strong>SOISK: [MYCIN] has what the students<br />
gut to st
<strong>NIL</strong> Manu<strong>al</strong> 297 Maclisp Compatihilil) for Macsyma<br />
28.3 1\1aclisp Compatibility for Macsyma<br />
The directory NI L$OISK: [MACSYMA] has some code in that is used for compiling and<br />
running MACSYMA in <strong>NIL</strong> and that will be useful to anyone porting a MACLISP program.<br />
The file ALOAO. LSP has an autoloading handler that works by handling the :undefinedfunction<br />
error condition. This might be a gener<strong>al</strong>ly useful thing to have around.<br />
The file PKGMC. LSP illustrates the usc or. pkg-create-package and intern-loc<strong>al</strong> in order to<br />
build a namespace that shadows conflicting or incompatibly defined functions and variahles.<br />
The file N I LCOM. LSP gives definitions of the functions map. subst. member. and assoc,<br />
which are compatible with \1 ACI.JSP.<br />
MC:<strong>NIL</strong>MAN:UTILS 15<br />
23-DEC-83
Foreign Language Interface 298 <strong>NIL</strong> Manu<strong>al</strong><br />
29. Foreign Language Interface<br />
29.1 Introduction<br />
It is desireable to be able to can from <strong>NIL</strong> procedures that are written in other VMS<br />
supported languages. such as FORTRAN, COBOL. PLI. Buss. C. PASCAL. Ian {Basic}. <strong>et</strong>. a1.. not<br />
to mention procedures written in MACR032. and VMS library routines and system services.<br />
Fortunately this is easy. due to the the uniform VMS object and symhol table file format.<br />
uniform procedure c<strong>al</strong>l mechanism. and rich s<strong>et</strong> of 1'\11. datMypes from which to construct<br />
d41tastructures compatible with what various fhreign language routines expect to receive.<br />
The presently implemented interface is by no means the last word in sllch endevors: for<br />
example it makes no <strong>al</strong>lempt to enforce datatype restrictions in argument passing: however. it is<br />
t(lUlH.l to be function<strong>al</strong>. and is used in the ~II. system ibc1f to access some VMS system services.<br />
to increment<strong>al</strong>y debug parl~ of the assembly-language kerna1. and to interface to "numbercrunching"<br />
f'C.·'TRAN subroutines and to some users .existing C libraries.<br />
29.2 Kernel and System-Services<br />
The executable code for such procedures is <strong>al</strong>ready in the lisp process address space. therefore<br />
accessing them is only a matter of defining an argument-data-convention interface. searching the<br />
lisp or system symbol table to g<strong>et</strong> the required machine address. and creating a lisp subr<br />
tr'lmpoline. similar to an element of a transfer vectors the VMS linker would create when one<br />
references sharable libraries.<br />
s 1 : defsysca 11 (lisp-name vms-symbol) &rest arguments pees<br />
Does everything needed to reference a routine in "LISP.STU" or "SYS.STBtt. The lispname<br />
is defined as a speci<strong>al</strong>-form taking <strong>al</strong>ternating named arguments as in a defstruct<br />
defined constuctor. For example, the routine to convert a vms error code into a humanreadable<br />
string:<br />
(defsysc<strong>al</strong>1 ($g<strong>et</strong>msg sys$g<strong>et</strong>msg)<br />
(msgid :in :long :required)<br />
(msglen :out :word :required)<br />
(bufadr :out :string :required)<br />
(flags :in :byte)<br />
(outadr :in :bits»<br />
(defun decode-vms-error-code {loss-code &option<strong>al</strong> (flags 15)<br />
&aux len)<br />
(using-resource (string-buffer string Z56)<br />
($g<strong>et</strong>msg msgid loss-code msglen len<br />
bufadr string flags flags]<br />
N.R. Ca1ls to SI:DEFSYSCALL. and to many other system intern<strong>al</strong> primitives work when<br />
-compiled-, but not when intepr<strong>et</strong>ed. The example above is from code in the systems"<br />
intern<strong>al</strong>s package.<br />
MC:<strong>NIL</strong>M:\N:VMSOBJ 15<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong> 299 V~IS object files<br />
29.3 Vl\1S object files<br />
To caB a procedure in a vms object file the user must do three things. define an argument<br />
interface. c<strong>al</strong>l the dynamic loader. and enable the trampolines for specific procedures. For<br />
example:<br />
(def-vrns-c<strong>al</strong>l-interface myfoo)<br />
(defun hack-foo ()<br />
(list (hack-vrns-object-file "[gjc.nil]footest")<br />
(enable-vms-c<strong>al</strong>l-trampoline<br />
'rnyfoo 'foo "[gjc.nil]footest.stb"»)<br />
(hack-foo)<br />
! S<strong>et</strong>s up for this BLISS<br />
MODULE FOOT EST =<br />
BEGIN<br />
GLOBAL ROUTINE FQO = 259;<br />
END<br />
ELUOOM<br />
s1:def-vms-c<strong>al</strong>l-1nterface name &rest arglisl<br />
Same as defsysc<strong>al</strong>l. but doesn't actu<strong>al</strong>ly look into any symbol table or create any<br />
trampoline. Only works when compiled.<br />
s1: hack-vms-object-f11e obj-jile<br />
C<strong>al</strong>ls the VMS linker on a single object file. and then reads the executable code into a<br />
bitstring in the lisp address space. Presently a VMS subprocess interface is not<br />
implementcd, (which is the easiest way for lisp to invoke the VMS linker), so instead the<br />
user is asked to execute a VMS command file lisp writes. This happens twice for every<br />
file so hacked. What a kludge.<br />
s1 :enable-vms-c<strong>al</strong>l-trampol1ne name vms-symbol slb-jile<br />
S<strong>et</strong>s up the trampJine for name using the address of the vms-symbol from the stb-file.<br />
29.4 Data Conversion<br />
At a certain level it helps to know the data representations supported by the V AX hardware<br />
itself, and what representations the various language compilers. including lisp, build on this base.<br />
L<strong>et</strong>s face it, at this point, unless you are willing to de<strong>al</strong> with such issues its best to forward<br />
specific interface reqllcsts to tile implementors. and wc'll try to at least provide a family of<br />
r<br />
cxisting examples which should make things obvious, or presolved. Even though the macrology<br />
provided by defsysc<strong>al</strong>l <strong>et</strong> aI. may m,lke it easy. it by no means m,tkes things foolproof. as any<br />
such excursions outside the lisp-world-firew<strong>al</strong>l we s<strong>et</strong> up arc frought with fmstrating debugging<br />
problems.<br />
MC:<strong>NIL</strong>MAN:VMSOBJ 15<br />
2J-DEC-8J
lowcr Ic,"cl routincs 300 <strong>NIL</strong> Manu<strong>al</strong><br />
In garhage collection. the system will not be forgiving of any violation of the mles of register<br />
and stack usage. and raw address placement.<br />
29.5 lower level routines<br />
As if the ones above weren"t low-level enough.<br />
s1: locate-symbol-table-v<strong>al</strong>ue symbol &rest stb-filenames<br />
R<strong>et</strong>urns nu)) or a fixnum.<br />
s 1 : cons truct-sys tem- symbo l-trampo 11 ne hiS-bits lo24-bits<br />
R<strong>et</strong>urns a tr.lInpoline suhr which jumps to the address specified.<br />
MC:<strong>NIL</strong>~1AN:VMSOBJ 15<br />
23-DEC-83
""WWX e m z<br />
Nil. Manu<strong>al</strong> 301 What Will Break<br />
30. What Will Break<br />
Various changes arc anticipated for future releases of <strong>NIL</strong>, just as some have taken place for<br />
this release. This chapter notes some of the significant implementation changes which have <strong>al</strong>ready<br />
occurred. and describes some which are anticipated.<br />
30.1 \Vhat Broke Since Release 0.259<br />
The single 1110S( significant change since release 0.259 is that there arc now four diffcrent<br />
formats of floating-point numhcrs. Bccausc thc new fOl11l<strong>al</strong>S do not appcar spontancously, and thc<br />
dcfault com"crsion from ration<strong>al</strong> to floating-point still produces double-float. it is unlikely that<br />
this will he particularly noticcable. "About the only possihle point of lossage here is that the v<strong>al</strong>uc<br />
of the system constant pi (page 76) is now a long-float. This is in keeping \vith the philosophy<br />
that such constants should bc in the longest format possible, and that uses which require a shorter<br />
fonnat can usc a form like<br />
(float pi O.OdO)<br />
or<br />
(coerce pi 'double-float)<br />
which will perfonn the coercion at compile time. Most othcr changcs to arithm<strong>et</strong>ic havc been<br />
additions. extensions, and fixes. For instance, the CO~MO~ LISP di\'ision and con\'ersion-tointcger<br />
functions floor, ceiling. truncate. and round now exist. Certain routines (most notably<br />
those four "division" rOlltines. and numerator. denominator. gcd. oddp. evenp. ration<strong>al</strong>. and<br />
i~tiviia:;za) hu;:c ~ccn cxtendcd t,j c\/nipk;.: numh'fs. iii ufJ~i ill dHu\\ Ill'l1lijJlIlaiioll~ 011 gdu~~i<strong>al</strong>l<br />
ration<strong>al</strong>s. See chapter 10. page 71. on numbers. for complcte information.<br />
The usc of nil in a lambda-Jist as a placeholder for an unused var is now discouraged: the<br />
compiler will issue a warning about it. The variable should be named. and then declared with<br />
the ignore declaration, as in<br />
(multi~le-v<strong>al</strong>ue-bind (foo bar baz) (mumbledy-frotz)<br />
(declare (ignore bar»<br />
... )<br />
A slight change has been made to the loop macro. The syntax<br />
(loop for x in lonnl form2<br />
do ... )<br />
which is interpr<strong>et</strong>ed as<br />
(loop for x in (progn fonnl fonn2)<br />
do ... )<br />
is being phased out. except for those "clauses" which are run tot<strong>al</strong>ly for effect, not for v<strong>al</strong>ue.<br />
Whcn multiple expressions are encountered in ~ place where a v<strong>al</strong>ue-r<strong>et</strong>urning expression is<br />
expected, a warning is issued, but the expansion is the same as before. The only "clauses" for<br />
which such multiple expressions will remain v<strong>al</strong>id are initi<strong>al</strong>ly. fin<strong>al</strong>ly, and do.<br />
There are a numher of other sm<strong>al</strong>l isolated changes which are not worth listing here, but<br />
should gener<strong>al</strong>ly be c\'ident when the code is compiled. having to do with what names are<br />
preferred for certain low-level functions, and corrections to what keyworded arguments certain<br />
functions take.<br />
MC:NII.MAN:BREAK 31<br />
23-DEC-83
What Broke Since Release 0.259 302 Nil. Manu<strong>al</strong><br />
Pathname stuff which lIsed to give you SYSSOISK as a device name now (correctly) uses its<br />
tr~inslation (specific<strong>al</strong>ly. user-workingdit-pathname). This is mentioned because it was predicted<br />
in the last release.<br />
The length (page 49) and jist-length (page 59) functions have been changed slightly. Neither<br />
finds a non-null termination of the list acceptable any more: this is in keeping with the CO~MON<br />
I.lSP definition. and (for length) is more consistent with its use as a gener<strong>al</strong> sequence length<br />
function (a list with a non-null elld is not considered a proper sequence). length continues to<br />
ghe an error if the list is circular: list-length wi1J r<strong>et</strong>urn nil when given a circular list.<br />
Certain d<strong>et</strong>:llIlts within defstruct (page 125) ha\e changed. as have certain conventions. The<br />
d<strong>et</strong>~IlJl( lype of a defstruct-defined structure is now a typed object: objects of this type can he<br />
checked t(lr wilh typep by lIsing the name of the structure as the type name. The. :conc-name<br />
option is noy,' on by dcf;mlt. and one must specify (:conc-name nil) to g<strong>et</strong> the old behaviour.<br />
Fin<strong>al</strong>ly. the keywords specified to keywordcd constnlctor macros. and to <strong>al</strong>terant macros. arc<br />
intended to be keyword symbols (interned in the keyword package). e.g..<br />
(make-person : head /7raJ :name name)<br />
<strong>al</strong>though non-keyword symbols will be accepted in the interim.<br />
Use of "destructuring" with l<strong>et</strong> is bci~g<br />
see nol-Yfl-wrillen.<br />
phased ou.t. Usc the function no/"yel-wrillell instead;<br />
Declaration scoping for speci<strong>al</strong> fonns is slightly different than it used to be. It is. in fact.<br />
~nm{'whllt mor(' {'(ln~i~t('nt th;m h('fnr('. (,h~ptl;'r ". which is n{'w. d~St:r!b{'s d('cbra!!0!1S in d('t~i!.<br />
The main difference is that declarations now scope over the "init fonns" in speciaJ forms that<br />
have them. like l<strong>et</strong>. l<strong>et</strong> •. do. prog. ctc. That is. the dc:l-specs in<br />
(l<strong>et</strong> « vo~1 v<strong>al</strong>-I) (vo,-.2 vol-2»<br />
(decl are dcl·spe~l dcl-sper-2 .•. )<br />
Jon11s . •• )<br />
that do not pertain to bindings of the variables va,..] and va,.. 2, are "in force" not only during<br />
the ev<strong>al</strong>uation of jonns. but of "101-] and "101-2. The major consequence of this is that, with<br />
declarations. l<strong>et</strong> cannot be trivi<strong>al</strong>ly turned into a lambda expression without parsing the<br />
declarations. In the expression<br />
( ( 1 ambda (va,..] va,..2)<br />
(dec 1 are dcl-spec-] dcl-spec-2 ••• )<br />
jonns • .• )<br />
v<strong>al</strong>-1 v<strong>al</strong>-2 )<br />
the declarations have no influence whatsoever on the ev<strong>al</strong>uation of v<strong>al</strong>-] and v<strong>al</strong>-2.<br />
MC:<strong>NIL</strong>~1AN:BREAK 31<br />
23-DEC-S3
~ •.-..-.......;.....~~-~~~ ~~mlll'''17Iml'I-!ltJ:!.'.rlri!r.iI1I'-'llr II.' .-Tltlr.'.1•••<br />
1717171517_1'.111 _____.-117__.-.t_______<br />
<strong>NIL</strong> Manu<strong>al</strong> 303 Future Changes<br />
30.2 Future Changes<br />
Some of these are the same as those anticipated as of Release O.<br />
30.2.1 Default Floating-Point Format<br />
The default floating point fonnat is going to change from the current double-float to singlefloat.<br />
This will <strong>al</strong>most certainly happen with the next release. The format of course could not be<br />
changed with this release and maintain any semhlance of upwards compatihility, because the<br />
I'rcrious release did not support single-float form<strong>al</strong>. Because of contagion rules. there arc re<strong>al</strong>ly<br />
just two ways one might start generating single-floats instead of douhle-tloats: when reading.. and<br />
when pertlmning some irrationa1. transcendent<strong>al</strong>. or othepA'ise awful function on ration<strong>al</strong> inputs.<br />
I f in f~lct the change matters at <strong>al</strong>l for an application (it might not if only generic arithm<strong>et</strong>ic was<br />
heing lIsed). then one could avoid problems by judicious lise of explicit cOIHersion to floating<br />
point. and by being careful to explicitly spedt: the exponentiation character in I.lSP source files so<br />
that the datatype will be explicit.<br />
30.2.2 New Pack,lge Facility<br />
The CO\1\10~ LISP package definition is fin<strong>al</strong>ly fin<strong>al</strong>. and should appear in the next release. It<br />
is unlikely that anything other than code which operates on or with packages explicitly will have<br />
to be changed, with the possible exception of references to "intern<strong>al</strong>" in one package made from<br />
another package.<br />
30.2.3 Vector-push and Vector-push-extend<br />
The argument order to vector-push and vector-push-extend will be changed so as not to<br />
be unmnemonic<strong>al</strong>ly different from that of push. Currently, the vector is the first argument, and<br />
the object to push is the second: these two will be reversed. This change became known just as<br />
release 0.259 became ready, and got lost or forgotten so never made it into this release. Ah well.<br />
30.2.4 l\lultiple V<strong>al</strong>ues<br />
In the future, <strong>NIL</strong> will "natively" support a multiple-v<strong>al</strong>ue r<strong>et</strong>unl mechanism. For it to do so<br />
requires that the compiler understand them at a moderately low level: it will be producing code<br />
for receipt of them from function c<strong>al</strong>ls, it will have to flag function ca11s which will be passing<br />
them back to another c<strong>al</strong>ler, and it must recognize and compile away <strong>al</strong>l loc<strong>al</strong> multiple-v<strong>al</strong>ue<br />
passing.<br />
~The<br />
mechanism, which has only been designed at a fairly high level, is this.<br />
Given the compiler behaviour described above. the only place which compiled code can<br />
receive multiple v<strong>al</strong>ues from is a function can (or a non-lexic<strong>al</strong> throw. but we will ignore this for<br />
the sake of simplicity in this description). This means, that when multiple v<strong>al</strong>ues arc being passed<br />
back (r<strong>et</strong>urned or generated). if we can recognize those function c<strong>al</strong>ls which arc simply being<br />
made to pass back any v<strong>al</strong>ues to their c<strong>al</strong>lers (and thus <strong>al</strong>so recognize those which are expecting<br />
MC:N(I.~·1:\N:BRE/\K 31<br />
.~:" ~ . ,', ...<br />
' " ": ,:.~ . ',.~,' .
Future Changes 304 <strong>NIL</strong> M,mu<strong>al</strong><br />
some v<strong>al</strong>ue or v<strong>al</strong>ues in particular). we can trace up the sL1ck to find the can which is ultimately<br />
expecting the mulliple v<strong>al</strong>ues. (The function c<strong>al</strong>l frames are quite fonn<strong>al</strong> and stylized in <strong>NIL</strong>)<br />
So what we do is to have the caner which is expecting multiple v<strong>al</strong>ues <strong>al</strong>locate a place for<br />
them on the stack and put a marker there, before it <strong>al</strong>locates the caU frame for the furiction. it is<br />
about to c<strong>al</strong>l.<br />
We have an function c<strong>al</strong>ls which simply pass back their v<strong>al</strong>ues as the v<strong>al</strong>ue of the function<br />
they are contained in. marked as such. so that examination of the can can d<strong>et</strong>enninc this. In the<br />
following. the c<strong>al</strong>ls to foo and bar would be so m~lrked. but baz would not:<br />
(defun frobnic~te (x y)<br />
(if (zerop xl (foo y)<br />
(mvprog! (bar x (sub! y»<br />
(baz (sub! x) y»»<br />
J f (S,lY) within bar there is a c<strong>al</strong>l (v<strong>al</strong>ues Ihis fha/). ulen a speci<strong>al</strong> subroutine goes look ing up the<br />
SLICK. finds the frame where bar is c<strong>al</strong>led. sees that it passes back its v<strong>al</strong>ues out of its c<strong>al</strong>ling<br />
function. so traces the function frame pointer to the. c<strong>al</strong>ler of frobnicate. <strong>et</strong>c.<br />
If. on the Olher hand. with baz there is a similar v<strong>al</strong>ues can. tmcing back to Ulat c<strong>al</strong>l to<br />
baz reve<strong>al</strong>s that baz is expected to r<strong>et</strong>urn only one v<strong>al</strong>ue (of interest. at most), so no further<br />
tracing is done.<br />
There are two further points of interest about this scheme. By appropriate usc of speci<strong>al</strong>ized<br />
m:1rkl'rc;: \\lh('r~ !TlllhirJ~ v~lH(,C;: are ('~p('ct('d_ fa~t dispatching may he p('rfiJrm('d for d('?!!ng W!t.~<br />
variolls situations. such as multiple-v<strong>al</strong>ue-list. for instance.<br />
A somewhat kludgey extension is to use this for things like "number c<strong>al</strong>Jingt'-one routine<br />
c<strong>al</strong>ling an0ther for (say) flonum v<strong>al</strong>ue. The one producing the flonum, instead of consing it.<br />
looks back and if the fin<strong>al</strong> destination is expccting a Honum in some speci<strong>al</strong> way (having, for<br />
instance. pre-<strong>al</strong>located a space on the stack for it). then the representation is stored there without<br />
consing. otherwise the v<strong>al</strong>ue is consed in the heap and passed back via the nonn<strong>al</strong> v<strong>al</strong>ue r<strong>et</strong>urn<br />
mechanism. The kludge involved here is that if the producer is interpr<strong>et</strong>ed code, someone has to<br />
coerce the nonn<strong>al</strong> v<strong>al</strong>ue r<strong>et</strong>urn into the hacked onc. This only is necessary when such a compiled<br />
routine is c<strong>al</strong>ling into interpr<strong>et</strong>ed code, so will probably be done by the interpr<strong>et</strong>er-trapping<br />
subroutine.<br />
The interpr<strong>et</strong>er-trap wrapper must be capable of recognizing when a v<strong>al</strong>ue has been stored<br />
"properly" into the compiled receiver. because if the producer is compiled and the interpr<strong>et</strong>er has<br />
produced the v<strong>al</strong>ue such that it got passed back "natur<strong>al</strong>ly". then it has been stored <strong>al</strong>ready<br />
without being consed, even with intervening interpr<strong>et</strong>ation!<br />
It is of note that this stack-searching is not directly an<strong>al</strong>ogous to a deep-binding variablebinding<br />
scheme. in terms· of . efficiency and paging overhead <strong>et</strong>c.~ because in the variable binding<br />
scheme the searching must be done up the entire stack (or <strong>al</strong>ist or whatever) every time. the time<br />
for each search growing in proponion to the depth of the· stack. but for this the search tenninatcs<br />
whenever va1ues are not being passed back to the previous caner.<br />
MC:<strong>NIL</strong>MI\N:BREAK 31<br />
23-DEC-S3
<strong>NIL</strong> Manu<strong>al</strong> 305 Future Changes<br />
30.2.5 Variable Naming Conventions<br />
CO\1MO!\ LISP is establishing a unifonn naming convention for system-defined param<strong>et</strong>ers and<br />
constants. Essenti<strong>al</strong>ly. <strong>al</strong>l system-defined param<strong>et</strong>ers (those variables whose v<strong>al</strong>ues are <strong>al</strong>lowed to<br />
be changed. i.e. that param<strong>et</strong>erize the behavior of the system) will have asterisks (.) at each end<br />
of their names. Thus. the variable base wiJ] become .base. (~IL uses si:standard-output-radix<br />
now anyway). and package will become .package•.<br />
1\]) system-defined constants. stich as cha~-code-limit. will not. Part of the justification for<br />
tJlis is that the compiler and inlerpr<strong>et</strong>er should he able to d<strong>et</strong>ermine when one is modifying a<br />
constant. but not a param<strong>et</strong>er. so th(.~ constants require less visu<strong>al</strong> distinction. This is in fact<br />
curremly the case. as defconstant (page 24) now works.<br />
The change of these variables is indeed going to be catastrophic to both lIsers and the :\11<br />
system itself: Note. however. that one may do (say)<br />
(who-c<strong>al</strong>ls 'package :type :v<strong>al</strong>ue)<br />
to find <strong>al</strong>l modu1cs (i.e.. restricted to compiled code) whicL reference the speci<strong>al</strong> v<strong>al</strong>ue cell of<br />
package.<br />
30.2.6 Garbage Collection-<br />
When the garbage-co])ector is finished. there wiJ] be two major incompatibilities noticeable.<br />
First. tJle format of compiled output files will change. Although initiaHy (for bootstrap and<br />
debugging purposes) old fonnat files will be accepted. it is unlikely tJlat this will still be the case<br />
by the time the garbage collector is released. Even if it is me case that such old files can be<br />
loaded. the garbage-collector will not be able to safely run afterwards. Second. mere is an<br />
incompatible change which must be made to the way unwind - protect is compiled. This cannot<br />
be handled upwards-compatibly. as it involves compiler knowledge about stack usage from tJle <strong>NIL</strong><br />
kernel, so old code might not be able to run correctly. Recompilation. of course, will fix<br />
everything.<br />
Obviously. when there is a garbage-conector. dirty operations like playing with addresses and<br />
changing types become substanti<strong>al</strong>ly more dangerous, and should be avoided by <strong>al</strong>l code except<br />
for the garbage-collector itself.<br />
30.2.7 Error System<br />
A new error system and debugger interface is being designed. The arguments to error,<br />
cerror, and/or ferror may be changed incompatibly. <strong>al</strong>though it is hoped that old uses will be<br />
able to be distinguished from new uses. condition -bind uses will have to be recompiled.<br />
Condition names may work upwards-compatibly, however. Note that now, sign<strong>al</strong> erroneously<br />
forces entry to the debugger if the condition goes unhandled: this will be changed. To enhance<br />
the ability of future code to d<strong>et</strong>ect old uses. a few conventions may be helpful:<br />
(I) The first two arguments to cerror should <strong>al</strong>ways be t or nil.<br />
(2) Always usc a string for the "error string" or "fonnat string" for <strong>al</strong>l three error functions.<br />
(MACLISP-compatible use of error can g<strong>et</strong> by WitJlout this if the "string" is a symbol, but<br />
contains at least one space in its text.)<br />
MC:<strong>NIL</strong>MAN:BREAK 31<br />
23-DEC-83
Future Changes 306 NIl. Manu4t1<br />
'Inc future debugger, which is mostly· compl<strong>et</strong>e now hut needs the new error system. will be<br />
Jnuchbcltcr able to p
·57 '17 . 2'7K2·- 37 r- -iSH'<br />
7<br />
-.<br />
XX<br />
<strong>NIL</strong> ~-1anLlaI 307 Future Changes<br />
<strong>Reference</strong>s<br />
1. Steele. G. L.. Common l.isp Refercnce Afanu<strong>al</strong>. Carnegie-Mellon University Department<br />
of Computer Science Spice Project. (in preparation). Actu<strong>al</strong>ly. it's now in-press with<br />
Digit<strong>al</strong> Press.<br />
2. Steele. G. L.. <strong>et</strong> <strong>al</strong>.. An Oveniew of Common LISP, paper prcscnted at 1982 AeM<br />
symposium on LISP and Function<strong>al</strong> Programming. 1982 ACM 0-89791-082-6/82/008/0098<br />
3. Bawden, A., <strong>Burke</strong>. G. S .. and Hoffman. C. W.. Alaclisp /:'x/ellsiol1s. MIT I.ahoratory<br />
for Computer Science. Camhridge. Mass. TM-203. July 1981.<br />
4. <strong>Burke</strong>. G. S .. I.SIl Alanu<strong>al</strong>. TM-~OO. MIT Lahoratory for Computer Science. Cambridge,<br />
Mass .. (.Julle 1981).<br />
5. <strong>Burke</strong>. G. S. .and Moon. D.. I.oop hef(]lioIlAlacro. TM-169, MIT Laborat 'ry for<br />
Computer Sciencc. Camhridgc. Mas~ .. (Janu~'ry 1981). (Revision in preparation.)<br />
6. Crocker. David H. (rcyised by). Slandard Ihr Ihe Form<strong>al</strong> of ARPA 11I1('rl1('/ Tex!<br />
Alcssagcs. N<strong>et</strong>work Information Center Request For Comments: SRI Intern<strong>al</strong>tiona1.<br />
~fcnlo Park, CA, (August 1982).<br />
7. Hawkinson. L. 8.. and <strong>Burke</strong>. G. S. Unfinished, unpublished memo/documen~1tion on<br />
the pr<strong>et</strong>ty-printer noted in section 19.5. pagc lR(): cnpicl\ of an int~rim vC'rc;:ion :tr(,<br />
included with ,It distribution kits.<br />
8. Mathlab Group. Alacsyma <strong>Reference</strong> Alanu<strong>al</strong>. MIT Laboratory for Computer Science,<br />
Cambridgc. Mass., (1977).<br />
9. Moon, D. A., AI AC LISP <strong>Reference</strong> flrlanu<strong>al</strong>, MIT Laboratory for Computer Science.<br />
Cambridge. Mass., (1974).<br />
10. Postcl, 10n. and Harrensticn. Ken, Time Protocol. N<strong>et</strong>work Infonnation Center Request<br />
For Comments: SRI Intem<strong>al</strong>tion<strong>al</strong>. Menlo Park, CA. (May 1983).<br />
11. Pratt. Vaughan R.. CGOL - an Alternative Extern<strong>al</strong> Representation for Lisp users. AI<br />
Working Paper 121. (March 1976)<br />
12. Weinrcb. D., and Moon. D., Lisp Alachille Afanu<strong>al</strong>, MIT Anifici<strong>al</strong> Intelligence<br />
Laboratory, Cambridge, Mass .• (July 1981).<br />
13. White. 1. L.. Constant Timc Interpr<strong>et</strong>ation for Sh<strong>al</strong>low-bound variables in the Presence of<br />
Alixed SPECIAVLOCAL Declar<strong>al</strong>ions. paper presented at 1982 ACM symposium on<br />
LISP and Function<strong>al</strong> Programming. 1982 ACM 0-89791-082-6/82/008/0196<br />
MC:NII.MAN:M;\NUAL 74<br />
23-DEC-83
Concept Index<br />
308<br />
Concept Index<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
&aux lambda-list keyword .•••<br />
&kc} lambda-list keyword •••<br />
&option<strong>al</strong>lambda-list keyword .•<br />
&rest\ lambda-list keyword ••<br />
a-list ••••••<br />
array • • . . • •<br />
31Ta~ disp1:lcemcnt .<br />
arr:1\ mnk .••<br />
:i!'l{'II•••••••<br />
a:-~"ri:iti()n list •••<br />
<strong>al</strong>l\ihar~ \ariahles.<br />
bad:LJlIotc .•.•<br />
bdl:l\ iour<strong>al</strong> equ<strong>al</strong>ity<br />
bCllchmarkmg.<br />
bignutn •••.•<br />
bit \cctor ..••<br />
bit-\ cctor-clements loop iteration rath<br />
bib loop iteration path. •<br />
boolean f<strong>al</strong>se. •<br />
boolean truth. •<br />
byte specifier. •<br />
byte specifier.<br />
cnaracler nilS •<br />
character code.<br />
character fonl •<br />
character s<strong>et</strong> •<br />
characters loop iteration path •<br />
closures • • . • • • • •<br />
Compilation • • • • • • • •<br />
compiled code module • • • • •<br />
conditionaJizing clause(s}, in loop •<br />
cons dot ••••<br />
cons dot ••••<br />
CRC instruction ••<br />
data type keywords. in loop<br />
decoded time •<br />
denominator • • • • • •<br />
dcstructuring. • • • • •<br />
disembodied propeny list •<br />
dispatch macro character<br />
displaced arrays. • •<br />
displaced index offs<strong>et</strong>. • •<br />
displacing arrays. • • • •<br />
DST _SITE logic<strong>al</strong> name<br />
dynamic extent •<br />
dynamic extent<br />
dynamic scope<br />
efficiency.<br />
clement type •<br />
• • • • • 14<br />
14<br />
13<br />
15<br />
• •••• 63<br />
• )03<br />
103<br />
• 103<br />
qq<br />
b.l<br />
14<br />
• .21h<br />
• 20<br />
.246<br />
• 71<br />
• .7<br />
• 164<br />
• J64<br />
6,28<br />
• •• 6<br />
84<br />
89<br />
• •••• 94<br />
94<br />
94<br />
99<br />
• 164<br />
• •• 13·<br />
• 243<br />
• 243<br />
• 154<br />
• 213<br />
• 214<br />
• 117<br />
• IS7<br />
.234<br />
• •• 4<br />
• .23.26<br />
• 39<br />
• 214<br />
• 107<br />
• • 107<br />
• 103<br />
• 241<br />
12<br />
12<br />
12<br />
.246<br />
• 103. 104<br />
clements loop iteration path<br />
empty Jist ••••<br />
equ<strong>al</strong>ity •••••••<br />
erTOr conditions. • . •<br />
extcndcd character s<strong>et</strong> •<br />
extent<br />
fCXI'TS<br />
file attribute Jist. .<br />
fhnum ••••.<br />
navurS)SlCm ••<br />
g<strong>al</strong>lssian integer.<br />
g<strong>al</strong>lssian ration<strong>al</strong><br />
gcncrafilcd \ariablcs. •<br />
~ensyming.<br />
gensym4i ••<br />
hosts •••<br />
identity of objects •<br />
implicit progn •<br />
indefinite extent •<br />
indefinite scope •<br />
, inil file • • • •<br />
integer ••••<br />
intern<strong>al</strong> time ••<br />
interned-symbols loop iteration path .<br />
interpr<strong>et</strong>er closures<br />
iteration. • • • •<br />
keyword symbols •<br />
keyworded arguments • • • • • •<br />
keywords •<br />
kill-ring . • • • • • • • • • • •<br />
lambda list keywords<br />
lambda lists • •<br />
l<strong>et</strong>Jist. • • • •<br />
lexic<strong>al</strong> scope. •<br />
lexpr. • • •<br />
lint cell ••••<br />
Ustsyntax •••<br />
logic<strong>al</strong> name. • • • • • •<br />
logic<strong>al</strong> name. DST_SITE. • •<br />
loop ••<br />
macro<br />
macro c<strong>al</strong>l •<br />
major modes. •<br />
merging and defaUlting of pathnames • •<br />
m<strong>et</strong>a key •••<br />
mixin flavors<br />
module ••••<br />
163<br />
• .6.28<br />
• •• 20<br />
229<br />
• •• 99<br />
· .• 12<br />
244<br />
205<br />
• •• 71<br />
170<br />
. 5<br />
• •. 5<br />
· .38<br />
.67<br />
• •• 67<br />
197<br />
• •. 20<br />
• •• 22<br />
.12<br />
· .12<br />
287<br />
· . 3<br />
223<br />
• •••• 162<br />
• . • . . .13<br />
144<br />
• •• 6<br />
• • • .14<br />
• •• 6<br />
257<br />
• .13<br />
• •• 13<br />
.26<br />
· .12<br />
244<br />
• •• 70<br />
214<br />
287<br />
241<br />
144<br />
• .23<br />
.23<br />
258<br />
200<br />
• • • • • • 251<br />
175<br />
• 8<br />
23-DEC-83
•• EPS 272<br />
n<br />
n<br />
Nil. Manu<strong>al</strong><br />
309 Concept Index<br />
multiplc "<strong>al</strong>ucs .••....<br />
multiple accumlilation~. in loop. •<br />
multiple expressIOn . . . . .<br />
name .••<br />
numerator.<br />
obarray. •<br />
object equ<strong>al</strong>ity<br />
oblist ..••<br />
optimi/ation .<br />
order of c\3Iu:ltion in iteration clauses. in loop.<br />
package. . •<br />
packages . .<br />
pa~sa 11 mode .<br />
patch directof)<br />
patch facility.<br />
patch file . •<br />
patch s~stem definition file .<br />
patchable system. . .<br />
path name defaults. .<br />
penasi\c declaration<br />
plist .•<br />
pname ••<br />
ppss •••<br />
print name<br />
!,rinf n~mp<br />
printed representation.<br />
propeny list •<br />
propeny lists. . • • •<br />
.• 36<br />
152<br />
146<br />
· 6<br />
· 4<br />
121<br />
.20<br />
121<br />
246<br />
147<br />
• 6<br />
121. 127. JJ7<br />
2R9<br />
280<br />
280<br />
280<br />
2RO<br />
280<br />
200<br />
.42<br />
· 6<br />
• 6.66<br />
.89<br />
.66<br />
· (;<br />
· 3<br />
.6.39<br />
39.65<br />
random numbers. .<br />
mnk. array<br />
ratio •.<br />
record ..<br />
scope .•••......•.........<br />
sequences •••.•..•.•.•.•.....<br />
sequenti<strong>al</strong> \'s par<strong>al</strong>lel binding and initi<strong>al</strong>ization. in loop .<br />
significand . . . • . . • • . . . . • . . •<br />
simple-bit.;.\,ector-elements loop iteration path<br />
simple-string-clements loop ilcr<strong>al</strong>ion path . •<br />
simple-\Cclor-clclllcnts loop iteration path<br />
speci<strong>al</strong> ....<br />
speci<strong>al</strong> variahles<br />
stack vector<br />
streams ....<br />
string . • . .<br />
string-clements loop iteration path<br />
stnlcture •..<br />
~~ n()n~ m stream .<br />
lenll logic<strong>al</strong> name. . . . . . .<br />
tenninatmg the iteration. in loop.<br />
translation table<br />
type specifier •<br />
univers<strong>al</strong>-time.<br />
\atuc equ<strong>al</strong>ity . . • . . .<br />
\ariahlc bindings, in loop.<br />
vector ••.•<br />
vector-elements loop iteration path<br />
· 86<br />
.103<br />
4<br />
7<br />
12<br />
• 48<br />
.146<br />
• 91<br />
.164<br />
.104<br />
.104<br />
II<br />
• • 11<br />
• 15<br />
.179<br />
• 7<br />
.104<br />
• 7<br />
.18:2<br />
.287<br />
.153<br />
.100<br />
· 16<br />
.234<br />
· 20<br />
.149<br />
· .103<br />
· .163<br />
23-DEC-83<br />
:':.' ~, .~ .. "<br />
,: "." ' - - ,<br />
,
Message Index<br />
310 Nil. M'lnu<strong>al</strong><br />
Message Index<br />
:ad\'ancc-pos<br />
(to bp) •<br />
. '.<br />
• 277<br />
:pp-anaphor-dispatch. • • • • • • • • • • • • • 177<br />
:dcscribc.<br />
:cqu<strong>al</strong>. •<br />
:cqu<strong>al</strong><br />
(In \'anill3- namr)<br />
:C\:ll ••••<br />
:c\hibit-sclf .<br />
• • 176<br />
• • 176<br />
• ]77<br />
• • • • • 176<br />
• 176<br />
:pp-anaphor-dispatch<br />
(to vanilla- navor) • •<br />
:pp-dispatch.<br />
:PP" dispatch<br />
(to \'anilla-flamr) •.<br />
:prinl-sclf.<br />
178<br />
177<br />
178<br />
176<br />
:c,hihit-sclf<br />
(to, anilla-fla\or)<br />
:filc-rlis1<br />
:fullcail •<br />
:gct-char<br />
(to bp). • • • • • •<br />
:gct -char-backward<br />
(to bp) •••.•<br />
:gCl-char-forward<br />
(to bp). • • • •<br />
:gct-nandlcr-tor<br />
(to ,'anilla-flavor)<br />
:init ~ with -lcnncap<br />
(to si:display-cursorpos-mixin). • •<br />
:move<br />
(to bp) •<br />
:open ••••<br />
:opcration-handled-p<br />
(to vanilla-navor) •<br />
:oustr<br />
(to si:display-cuTSorpos-mixin) •<br />
:peck -char-backward<br />
(to bp). • • • • • • • • • •<br />
• 178<br />
· .;:06<br />
• 17ft<br />
••••• 277<br />
• •• 277<br />
• •• 277<br />
.177<br />
.211<br />
.277<br />
• 181<br />
.177<br />
• •• 212<br />
• • 277<br />
:prinl-sclf<br />
(to\'anilla-na\'or) •<br />
:raw-oustr<br />
(to si:display"cursorpos-mixin). •<br />
:sclcct-nth<br />
:sclcct-nth<br />
(to vanilJa-navor) • • •<br />
:scnd -if - handl~<br />
(to vanilla-flavor) •<br />
:sct -path name •<br />
:storc-nth •<br />
:5tore-nth<br />
(to vanilla-flavor) •<br />
:sxhash •<br />
:sxhash<br />
(to vanilla-flavor) • • •<br />
:which-operations<br />
(to vanilla-flavor) • •<br />
:wrile-char<br />
(to si:di.~Jay-c:ursorpos-mixin).<br />
:write-raw-char<br />
•<br />
177<br />
212<br />
176<br />
178<br />
177<br />
181<br />
176<br />
178<br />
176<br />
177<br />
177<br />
212<br />
23·DEC·83
<strong>NIL</strong> Manu<strong>al</strong> 311<br />
Resource Index<br />
si:fab. · .................. . 207<br />
si:nam · .................. . 207<br />
si:rah. · .................. . 207<br />
Resource Index<br />
si:fah ..<br />
si:nam<br />
si:rah. .<br />
si:xah ..<br />
207<br />
207<br />
. 207<br />
••• 208<br />
23-DEC-83
Variable and Const.ant Index 312 <strong>NIL</strong> Manu<strong>al</strong><br />
Variable and Constant Index<br />
*<br />
*.<br />
•••<br />
format:*/ # -\'ar.<br />
*:autodin-ii-hash-poiynomi<strong>al</strong> •<br />
*:ccitt-hash-poJynomi<strong>al</strong> . •<br />
*:crc-16-ha,h-polynomi<strong>al</strong><br />
SIC\c:*&lrgumcnt* .•..•<br />
*hasl'*, , , .•••. , •<br />
lii1lc:"da~ -of-the-week-strings* .<br />
lime: *dd':llIl1- L1nguag.c* • •<br />
time: *default-modc*, . • .<br />
·default-p<strong>al</strong>hIl3mc-dd1ult!\*<br />
stC'\ c:*cuilur-dc\ icc-mode* •<br />
r.,: ·host- inslances*, • . • •<br />
*)u;ld- p<strong>al</strong>hnamc-defaults* .<br />
('ompilcJ:*mL':-..;;ag~-to-tcrmin<strong>al</strong>'! .<br />
·modules* . , • • • . • • • ,<br />
limc:·monlh-strings· . . • . .<br />
compiicr:*opcn-compilc-carcdr-switch<br />
compiler:*upcn -compiic-xref-switch •<br />
·package· . ., •••••<br />
*random-state*, • , • , •<br />
*rcad-dcfault-float-format*•<br />
·scr<strong>al</strong>ch-pathnamc-dcfauiLS*<br />
umc:*s),stcm-lImc- kludgc· •<br />
·limclOnc*, •• , ••••<br />
form<strong>al</strong>: *top-char-printer •<br />
-trace-output·<br />
+ ..<br />
++ .<br />
+++<br />
format:atsign-flag • • • • • •<br />
*:autodin-ii - hash -polynomi<strong>al</strong> •<br />
base<br />
•••••••••<br />
.288<br />
.288<br />
• 288<br />
• • • 191<br />
• • 117<br />
• •• 117<br />
• • • 117<br />
• 274<br />
• • 305<br />
• •• 1.'1<br />
• •• 23()<br />
• • 236<br />
• •• 202<br />
• • 278<br />
• •• 202<br />
• 201<br />
• • 24()<br />
• •. 123<br />
• 237<br />
• 245<br />
• • 245<br />
• • 305<br />
• • 86<br />
4. 72<br />
• • 202<br />
• .241<br />
• •• 238<br />
• • 191<br />
• 179<br />
• • 288<br />
• •• 288<br />
• 288<br />
• • 195<br />
• • 117<br />
• •• 305<br />
double-float-epsilon<br />
Constant •••••<br />
double-float-negative-epsilon<br />
Constant .••<br />
error-output. • •<br />
• .93<br />
• .93<br />
179<br />
format:*/#-\'ar • . 191<br />
fomlat:*top-char-printef. 191<br />
u)mlat:atsig.n- flag.. .<br />
lQ5<br />
fom131:colon-flag. )Q5<br />
1k-hoSl-instances* • 202<br />
intern<strong>al</strong>-lime-units- per-~ond<br />
('onstant. • • • • • •• • • • • . • • • • 223<br />
lcaSl-nCg
NIl. Manu<strong>al</strong><br />
313 Variahle and Constant Index<br />
most - posit i\"c-Iong - float<br />
Constant ..•....<br />
most - posit ivc-shon - float<br />
Constant. . . . . . .<br />
most-positi\"c-singlc-float<br />
Constant.<br />
msgfilcs.<br />
package.<br />
pi<br />
Constant.<br />
prinlc\ cl<br />
query-io<br />
rcadlahle<br />
~hon - float -epsilon<br />
Constant ...•<br />
short- flo<strong>al</strong>-ncg:ni\c-cpsilon<br />
Constant ..... .<br />
si:chars~ nl:nSm_3Jpha<br />
Constant ....•.<br />
si: charsyntaxSm_both_case<br />
Comitant ..•.•.<br />
si:charsyntax$m_digit<br />
Constant .•.••.<br />
c;i~('h:trc;ynt:n~m~r~!,hir<br />
Cons1.3l1t ..•...<br />
si:charsynt3xSm_lowcr_case<br />
Constant ...•..••<br />
si:charsyntaxSm_standard<br />
Constant. .•.....<br />
si:charsynLaXSm_upper_case<br />
Constant. ••••••.<br />
• 92<br />
.92<br />
• 92<br />
ISO<br />
122.305<br />
.76<br />
17h<br />
179<br />
• 218<br />
.93<br />
.93<br />
102<br />
102<br />
102<br />
101<br />
102<br />
10~<br />
101<br />
si:charsyntax$v_<strong>al</strong>pha<br />
Constant .•.•..<br />
si:charsynLaX$\'_both_case<br />
Constant •..•<br />
si:charsyntax$,,_digit<br />
Constant ••.•<br />
si:charsyntax$v -.sraphic<br />
Constant •.•••<br />
si:charsyntaxSv_Iowcr_case<br />
Constant ..... .<br />
si:charsyntax$,_standard<br />
Constant ..... .<br />
si:l'harsynt~lx $\ _upper_case<br />
Constant •.<br />
si:dchug -input. . . . . .<br />
si:dchug-output . . . . .<br />
si: lisp-dchuggcr-on -exceptions.<br />
si:loop-usc-systcm -destnlctllring? .<br />
si:standard-output -radix<br />
singlc- flU:ll-Cpsilon<br />
Constant .•....<br />
singJc- float -neg<strong>al</strong>i\c-cpsilon<br />
Constam .•<br />
standard-input. • • • .<br />
standard-output . • . .<br />
si:standard-outpul-radix<br />
stcvc:·argumcnt*. • . •<br />
~!~v~: *~di! O!'-dC':ice-med<strong>et</strong>ermina\-io<br />
. • . • . . .<br />
time: *day -of -the-week -strings·<br />
time: ·default -Ianguage* .<br />
timc:*defau1t-modc· .•.<br />
time:*month-slrings*. • •<br />
time:·system -time-kludge-<br />
.102<br />
.102<br />
.102<br />
.101<br />
.102<br />
.102<br />
.101<br />
.180<br />
.180<br />
.21JO<br />
.]59<br />
• •.. 305<br />
. •......... 93<br />
93<br />
· •.. 179<br />
• .179. 195<br />
.305<br />
.274<br />
.278<br />
.179 "<br />
.237<br />
• •• 236<br />
.236<br />
• •.. 237<br />
• .241<br />
23-DEC-83
Function. Macro. and Speci<strong>al</strong> Form Index 314<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
Function, Macro, and Speci<strong>al</strong> ForD1 Index<br />
%char-downcase-code. •<br />
%char-upease-code ••••<br />
%comcn-d_float-to-time<br />
'kom:cn-limc-lo-d_float<br />
%digil-char-in-radix-p<br />
%digil-char-to-weight .<br />
%digit-wcight-to-char •••••••<br />
%dph ..•.•.••.<br />
s~ s:ri·{j\llllm-a.,h -with-o\ crflow-lrapring .<br />
s~:-.:(·:,lhlllllll-dirkrcllrl·-wilh-mcrl1ow-lraJlJling.<br />
s~s:('(/n\lIll1n-JllllS-\\ ilh-mcrllo\\ -tr
NIl. Manu<strong>al</strong> 315 Function. Macro. and Speci<strong>al</strong> Form Index<br />
a"h. .83 cdaadr . · 56<br />
a"h& . .89 cdaar · 56<br />
asin .77 cdadar • .56<br />
ao;inh. . 18 cdaddr • .56<br />
<strong>al</strong>iSOC . • 64 cdadr · 56<br />
aC\sq • 64 cdar • · 56<br />
atan .11 cddaar • · 56<br />
atanh. .18 cddadr • · 56<br />
cddar .56<br />
bigp .19 cdddar • · 56<br />
bil . 109 cddddr. · 56<br />
hil-and . 109 cdddr 5h<br />
hil-andd 109 cddr. · 56<br />
bil-<strong>al</strong>ldc~ . 109 cdr · 56<br />
bit-C · 95<br />
steve:c-u-onlyt 278 char>=. • 95<br />
c .... r . 56 character • .96<br />
caaaar .56 characterp . • 19<br />
caaadr .56 check-argo • 230<br />
caaar • .56 check-type .229<br />
caadar .56 clear-input .183<br />
caaddr • 56 clcar-output • .185<br />
caadr. .56 dose. . .181<br />
caar<br />
· . . • 56 fs:close-<strong>al</strong>l-files • . . .202<br />
cadaar .56 closure. .13<br />
cadadr .56 cJosurep .13.19<br />
cadar. • 56 cJrha~ • .118<br />
caddar • 56 cnarnef • .181<br />
cadddr .56 code-char .96<br />
caddr. · . .56 coerce . 9<br />
cadr • 56 comfile • .245<br />
car • . .56 compile .245<br />
case • 29 coml'ilc-file • .244<br />
~cq. . .30 si:compilc-load-p<strong>al</strong>ch. .283<br />
catch • • 35 si:compilc-patch . .283<br />
cdaaar . 56 compiler-l<strong>et</strong> • .245<br />
2J-DEC-8J
Function. Macro. and Speci<strong>al</strong> Fonn Index<br />
316<br />
<strong>NIL</strong> Manu<strong>al</strong><br />
C'omplex •.•<br />
concatenate. •<br />
cond •.<br />
conjugate<br />
cons •• '. . .<br />
consp ..<br />
si:conslrucl-system-symbol-trampoline<br />
timc:comcn-\ms-timc-to-uni\'crs<strong>al</strong>-time. •<br />
cop~ -<strong>al</strong>ist<br />
COP}-Iist •••<br />
cop~-scq ••<br />
co('~ -synlhol •<br />
C'OJl~ -tree . .<br />
COp~3IiSt ••.<br />
co('}symhol<br />
cn(')trce.<br />
C(}l\. • •<br />
cosh ••<br />
count ••<br />
count-if.<br />
count-if-not .<br />
cre<strong>al</strong>c-rcadL1ble. •<br />
cursorpos .••<br />
79<br />
50<br />
28<br />
75<br />
57<br />
18<br />
.300<br />
• 240<br />
59<br />
59<br />
51<br />
66<br />
59<br />
59<br />
69<br />
59<br />
77<br />
78<br />
52<br />
52<br />
52<br />
219<br />
• 181.210<br />
time:day-of-the-week •<br />
• ••• 238<br />
time:day-of -the-week-string •<br />
• ••• 237<br />
lime:daylight-savings-p • . •<br />
• .238<br />
timp:n:tylight-c;::winrl;-timf'-!'<br />
· 21~<br />
dehu~ •<br />
.222<br />
deer. ...•<br />
• ••• 39<br />
declare •••<br />
• • .41,243<br />
decode-float. •<br />
• 91<br />
decode-univers<strong>al</strong>-ljme •<br />
· •• 235<br />
si:def-,-ms-c<strong>al</strong>J-inlcrface ••<br />
• .299<br />
dcfconstant. • • •<br />
• ••• 24<br />
deffiavor ..•••<br />
• • 171.173<br />
define-fonnat-op •<br />
• ••• 194<br />
define-loop-macro<br />
• 157<br />
define-loop-path •<br />
• • 164<br />
definc-loop-sequence-path. •<br />
• •• 163<br />
defmacro .••••••<br />
• • 23<br />
defm<strong>et</strong>hod. • • • • •<br />
• 175<br />
dcfmcthod-primitive ••<br />
• ••• 17S<br />
defparam<strong>et</strong>er. • • . •<br />
• • 24<br />
defstruct. • • • •••<br />
• 125<br />
defstruct - define-type<br />
• .138<br />
si:defsysc<strong>al</strong>l. •<br />
• • 298<br />
defun •<br />
· .22.243<br />
defvar. • • •<br />
• • 24<br />
del<strong>et</strong>e. • ••<br />
• • 53<br />
del<strong>et</strong>e- file • •<br />
.203<br />
del<strong>et</strong>e-if. • .<br />
S3<br />
del<strong>et</strong>c-if-not •<br />
53<br />
deposit - byte .<br />
90<br />
deposit-field •<br />
86<br />
describe •••<br />
• • 222<br />
si:dctennine-and-sct-tennin<strong>al</strong>-type • • • • • • • • 211<br />
difference. •<br />
digit -char. •<br />
digil-char-p.<br />
do .•<br />
do· •••<br />
dolist •••<br />
dolimes •.<br />
doveelor<br />
dpb •<br />
dpb&.<br />
ed .•<br />
stC\ e:ed-losc.<br />
stcvc:cd-warn<br />
Slc\'c:cd-warning. .<br />
stc\'c:cditor-hind-kcy .<br />
s1e\c:cditor-dcfun-kcy<br />
eighth • • •<br />
c1a('scd -time. . • • .<br />
ell. . . • . . . . .<br />
si:cnablc-l"ms-caH-lrampoline<br />
ene'ode- univers<strong>al</strong>-time.<br />
si:entcr-rcadtablc.<br />
eq ••<br />
eql ••<br />
equ<strong>al</strong>.<br />
equ<strong>al</strong>p ••<br />
e\'2~-whef! .<br />
even}'<br />
c'-er) •••<br />
exhibit ••<br />
exit -and-run-prOiram<br />
exp<br />
expt •••<br />
tboundp<br />
fceiling • •<br />
moor .••<br />
fifth • • •<br />
file-author<br />
file-crcation -date.<br />
file-length.<br />
filepos • •<br />
fill. • • •<br />
fiU-pointer<br />
find •••<br />
find-if ••<br />
find-if-not<br />
finish-output<br />
si:finish-patch • •<br />
first • • • • • • •<br />
Slc\'e:first-line1. •<br />
fixnunlp • • • ~ • •<br />
fixp •••<br />
float ••.<br />
noat-digit~<br />
float-precision ••<br />
• •• 74<br />
• .97<br />
• ••••.••• 97<br />
· • . . . . .33<br />
· • • . . . • . .33<br />
.33<br />
• .-32<br />
• •• 33<br />
· .85<br />
• •••.•••• 89<br />
24q<br />
• 277<br />
277<br />
278<br />
274<br />
275<br />
.56<br />
223<br />
.4Q<br />
299<br />
235<br />
219<br />
.20<br />
• ••• 20<br />
• 20.176<br />
. ••••• 21<br />
· . 25. 24~<br />
• •• 73<br />
· .55<br />
222<br />
289<br />
.76<br />
.76<br />
• ••• 68<br />
• .81<br />
• •• 81<br />
••••• 56<br />
• 203<br />
203<br />
• •••• 203<br />
203<br />
• ••• 52<br />
106<br />
• •• 51<br />
• .51<br />
· .51<br />
184<br />
283<br />
• ••• 56<br />
• 278<br />
.19<br />
.19<br />
• •• 78<br />
• •• 92<br />
.92<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong><br />
317 Function, Macro. and Speci<strong>al</strong> Fonn Index<br />
float-radix.<br />
float-sign<br />
floatp ..<br />
flonump.<br />
floor ..<br />
fmakunbound .<br />
force-output.<br />
format ..•.<br />
fonnat -eharpos.<br />
(omlat- fl<strong>al</strong>e. .<br />
fon11:I1- form feed •<br />
form:1l- fresh -line. .<br />
fOrm:lI-lcprinc .<br />
fonnm-lincl .<br />
fo01131- prin 1. .<br />
funn:1t-pnne.<br />
form<strong>al</strong>-Iah-to<br />
form<strong>al</strong>-Icrpri. . .<br />
fom1<strong>al</strong>-tyo .<br />
form<strong>al</strong>-) -or-n-p.<br />
fomlat -ycs-or-no-p<br />
fourth . • .<br />
fquery ..<br />
fresh-line.<br />
fround ••<br />
fs:close-<strong>al</strong>l- files<br />
(c;:process- in -load-environment. •<br />
f~C' •..<br />
«.ct...•<br />
("ymc\,<strong>al</strong><br />
ftruncate<br />
func<strong>al</strong>l .<br />
gcd .••<br />
gcnsym •<br />
gcntcmp.<br />
g<strong>et</strong> •••<br />
g<strong>et</strong> - a-byte.<br />
g<strong>et</strong>-a-byte-2c ••<br />
si:gct-c<strong>al</strong>l-m<strong>et</strong>ers. • •<br />
g<strong>et</strong>-decoded-time.<br />
g<strong>et</strong>-internai-rcai-time.<br />
g<strong>et</strong>-intcrnai-run-time •<br />
gct-output-strcam-string. • •<br />
gct-pnarne. • •<br />
s<strong>et</strong>-privileges • • • •<br />
g<strong>et</strong>-properties • • • •<br />
si:g<strong>et</strong> -system-version •<br />
si:g<strong>et</strong> -system -version -list<br />
·gct-univers<strong>al</strong>-time<br />
g<strong>et</strong>f •••••<br />
g<strong>et</strong>hash •••••<br />
si:gctjpi-string • •<br />
si:g<strong>et</strong>jpi-v<strong>al</strong>ue •<br />
gcll. • • • ••<br />
si:gctsyi-string .<br />
si:g<strong>et</strong>syi-v<strong>al</strong>ue •<br />
.91 glob<strong>al</strong>i7.e ...<br />
.92 go •.•••.<br />
.19 graphic-char-p<br />
• 19 grcatcrp .••<br />
.79<br />
.68<br />
184<br />
187<br />
196<br />
196<br />
196<br />
1%<br />
1%<br />
196<br />
195<br />
195<br />
196<br />
196<br />
195<br />
197<br />
197<br />
.56<br />
}97<br />
185<br />
.81<br />
202<br />
206<br />
.Ql<br />
.69<br />
.69<br />
. 81<br />
.30<br />
. 75<br />
.67<br />
.67<br />
.65<br />
III<br />
111<br />
•• 225<br />
235<br />
• 223<br />
• 223<br />
182<br />
.69<br />
233<br />
.40<br />
282<br />
•••••• 282<br />
•••••••• 235<br />
.39<br />
US<br />
242<br />
241<br />
.69<br />
242<br />
242<br />
si:hack-vms-ohjcct~file. .<br />
haipart .•..•<br />
hash -table-count<br />
hauiong ....<br />
haulong& ...•<br />
host-software-typc .<br />
if ...<br />
imagpan<br />
illcf ..<br />
init- file-pathnamc .<br />
si:initi<strong>al</strong>i/c-patch-s},stcm<br />
int-char ....•<br />
intcger-decode- flo<strong>al</strong><br />
inl<strong>et</strong>! ," r-)ength .<br />
intcrr ...<br />
intern-soft<br />
intersection •<br />
isqn .•<br />
last •<br />
stc\'c:last-linc? .<br />
timp"I:llO:t .IO:llnn::ly-in-:l!"ril<br />
timc:last-sunday-in-uctoher .<br />
tcm .<br />
Idb •••<br />
ldb& ••<br />
Idh-tcst<br />
IdiIT •••<br />
time:lcap-year-p. •<br />
length<br />
lessp.<br />
l<strong>et</strong> •••<br />
l<strong>et</strong>· •<br />
lexpr-func<strong>al</strong>l<br />
lexpr-send • •<br />
lexpr-scnd - forward.<br />
stcve:line-next. • •<br />
steve:line-previous •<br />
lisp-implementation-type •<br />
lisp-implementation-version •<br />
list • • •<br />
list· • • •<br />
list -length<br />
listen<br />
listp. • •<br />
load .••<br />
load-byte.<br />
load -patches<br />
si:loc<strong>al</strong>e-symboi-tab)c-v<strong>al</strong>uc •<br />
log ••<br />
logand ••••••••.•••<br />
.122<br />
• 34<br />
· 94<br />
· 74<br />
.299<br />
· 84<br />
.118<br />
· 84<br />
• 89<br />
.232<br />
• 2R<br />
5<br />
· 39<br />
.200<br />
.284<br />
.96<br />
· 92<br />
· 83<br />
.122<br />
.122<br />
• 62<br />
.77<br />
· 58<br />
.278<br />
.'~Q<br />
.239<br />
· 75<br />
• 85<br />
· 89<br />
· 85<br />
.60<br />
.238<br />
· 49<br />
• 74<br />
• 26<br />
• 26<br />
• 31<br />
.172<br />
.173<br />
.276<br />
.276<br />
.232<br />
.232<br />
• 57<br />
• 57<br />
· 59<br />
.183<br />
• 18<br />
.204<br />
.90<br />
.281<br />
.300<br />
.76<br />
· 81<br />
23-DEC-83
Function. Macro. (Iud Speci<strong>al</strong> Fonn Index<br />
J18<br />
Nil. Manu<strong>al</strong><br />
logand& .•.<br />
Jogandcl ••<br />
. Jogandc 1 &. .<br />
logandc2 •••<br />
Jogandc2& ••<br />
Joghitp •<br />
logbitp&.<br />
logcounl.<br />
logcount&<br />
logcqv ••<br />
Jugcq\& •<br />
Jo~ior .•<br />
Jogior& •<br />
lognand •<br />
Jognand&<br />
Jugnm .•<br />
Jognor& •<br />
lognnt. .<br />
lognot& •<br />
logon". ..••.<br />
logorcl& •••<br />
lugurc2 .<br />
logorc2&.<br />
logtest ••<br />
loglcst& •<br />
logxor. • • •<br />
logxor& •<br />
lonr-c.;itl'-n:unl'<br />
si:lnokup-rcadlablc<br />
1001' • • • • • •<br />
loop-finish. • • •<br />
si:lool'-gcntemp. .<br />
si: 1001'-namcd - ,'ariable.<br />
si:loop-ta~soc. •<br />
si:loop-tequ<strong>al</strong>. •<br />
. si:loop-tmcmber<br />
lower-case-p .•<br />
machine-instance.<br />
machine-type •<br />
macro .••••<br />
make-array. • .<br />
make-bit-vector<br />
steve:make-bp •<br />
make-char •••<br />
si:make-fab •••<br />
make-hash-table •<br />
makc-instance ••<br />
stc\'c:make-line. •<br />
make-list ••<br />
si:make-nam. • •<br />
si:makc-rnb • .<br />
make-random-state • •<br />
l'Otc"c:makc-scrcen-im3ge •<br />
maL:e-sequence. • • • •<br />
makc-string • • • • • •<br />
maL:e-Slring-inpul-Slrcam<br />
88<br />
82<br />
88<br />
82<br />
88<br />
81<br />
89<br />
83<br />
89<br />
81<br />
88<br />
• • • • • 81<br />
RR<br />
82<br />
88<br />
82<br />
88<br />
83<br />
89<br />
8~<br />
88<br />
82<br />
88<br />
83<br />
89<br />
81<br />
88<br />
· :n,<br />
• 218<br />
• 144<br />
• 153<br />
• 166<br />
· 166<br />
.1b6<br />
• 166<br />
• 166<br />
• 9S<br />
• 232<br />
• 232<br />
• 24<br />
• 103<br />
• • 110<br />
• ••• 275<br />
.96<br />
• 207<br />
• ••• 118<br />
• • 171.173<br />
• 276<br />
• 58<br />
• '2D7<br />
• • 201<br />
• 86<br />
· 279<br />
.50<br />
• • 114<br />
.182<br />
makc-string -output-stream.<br />
makc-~)mhol • • • •<br />
makc-sy nonym -stream<br />
make~vcctor. •<br />
si:make-xab •<br />
makunbound.<br />
map .•.<br />
mapaUfilcs.<br />
mapatoms.<br />
mapc .••<br />
mapcan •<br />
mapcar •.<br />
mapcon ..<br />
mapl •••<br />
maplist· •<br />
mask-field<br />
n13X<br />
•••<br />
mad ....<br />
max& •<br />
. mcmber ••<br />
memq • • • ••••<br />
mcrgc-pathnamc-dcfauits<br />
min.<br />
minS ••<br />
min& .•<br />
minus<br />
minu~ ••<br />
m~ ...<br />
timc:modc-languagc- fClch •<br />
si:modulc-sourcc- file .<br />
time: month -length<br />
timc:month-string • • • • •<br />
timc:moonphase • • • • • •<br />
multiple-v<strong>al</strong>ue. • •<br />
multiple-v<strong>al</strong>ue-bind<br />
multiple-v<strong>al</strong>ue-list .<br />
multipie-v<strong>al</strong>ue-prog1<br />
multiple-v<strong>al</strong>ue-s<strong>et</strong>q •<br />
steve:mx-prompter •<br />
name-char<br />
namestring<br />
nbutlast ••<br />
ncone. • •<br />
noons •••<br />
si:new-p<strong>al</strong>Ch-system<br />
nibble •••••<br />
nibble-2c ••<br />
nintersection •<br />
ninth. • • • •<br />
not •••••<br />
stcve:not -buffer-begin<br />
!neve:nol-buffer-end<br />
stcve:not-first-line •<br />
stcve: not -last-line • • • •<br />
notany ••••••<br />
notc-modute-pathname • •<br />
182<br />
.b6<br />
182<br />
108<br />
207<br />
• •. 68<br />
32.54<br />
204<br />
122<br />
· . .31<br />
• •• JI<br />
• •• 31<br />
. .31<br />
• • • -' 1<br />
.31<br />
• •. 85<br />
.74<br />
• •• 91<br />
• •• 87<br />
.61<br />
.61<br />
201<br />
.74<br />
.91<br />
.87<br />
.75<br />
.73<br />
• •• !H<br />
2~n<br />
221<br />
238<br />
237<br />
238<br />
• •• 37<br />
• • .37<br />
•• 37<br />
.37<br />
.37<br />
279<br />
• •• 97<br />
199<br />
.59<br />
.58<br />
• •• 57<br />
284<br />
• • 111<br />
111<br />
• •• 62<br />
.56<br />
• •• 28<br />
278<br />
278<br />
278<br />
278<br />
• •• S5<br />
124<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong><br />
319 FunClion. Macro. and Speci<strong>al</strong> Form Index<br />
si:nntc-primitivc-font .<br />
notc\ct).<br />
nrcconc.<br />
nrc\"crsc.<br />
nscl-di/Tcrcnce.<br />
n~t -cxclusi,"c-or .<br />
n~ring-down~c ..•<br />
nstring-upcasc • •<br />
nsublis •••<br />
nsubst ...<br />
nsubstitute. .<br />
nsubstitute-if<br />
osubslillltc-if -not.<br />
nth .•.•...<br />
SIC\ c:nth-ncxl-Iine<br />
stc\c:nlh-prc\ inus-line<br />
nthcdr .<br />
null ••<br />
numbcrp<br />
mmion<br />
oddp .•<br />
opcn ••<br />
or •••<br />
ouslr •<br />
stc"c:overwrile-done<br />
ste\c:merwrilc-homc •<br />
~1(,\(,:O\'f'rwrir('-~~rt "<br />
SIC\c:o\,crwrilc-tcrpri .<br />
si:paclcage-symbolconc.<br />
si:pag~faull-count.<br />
pairlis ..•<br />
pairp ••••••<br />
pathname ••••<br />
pathnamc-device •<br />
pathname-directory •<br />
pathname-host •<br />
pathname-name • •<br />
pathname-type. •<br />
pathname-version.<br />
peck-char ••.••<br />
pkg-create-package •<br />
pkg - find -package.<br />
pkg-goto<br />
plist ••<br />
plus ••<br />
pJusp ••<br />
stcve:point. •<br />
stcve:point-selected. •<br />
pop ..•.<br />
position •••••<br />
position - if. . • .<br />
posilion-if-nol. •<br />
utils:pp-inlo-file •<br />
prctty-prin 1 . • •<br />
prcny-prinl-datum. •<br />
WI<br />
· .55<br />
.58<br />
.52<br />
.62<br />
.62<br />
115<br />
115<br />
· .61<br />
.60<br />
. 54<br />
.54<br />
• •• 54<br />
.57<br />
· . 276<br />
· 276<br />
.57<br />
• 18<br />
.19<br />
.62<br />
.73<br />
180. 211<br />
.29<br />
• . 185<br />
• • 279<br />
• 279<br />
27Q<br />
279<br />
.70<br />
• 224<br />
• •• 64<br />
.19<br />
• • 199<br />
· 199<br />
199<br />
• 199<br />
••• 199<br />
199<br />
• • 199<br />
••• 183<br />
• • 122<br />
. ...... . 122<br />
122<br />
.69<br />
.74<br />
.73<br />
276<br />
••• 276<br />
••••••••• 38<br />
.51<br />
.51<br />
. 51<br />
228<br />
186<br />
187<br />
prclty-print •<br />
prclly-print-datum.<br />
print<br />
prine. . • • . • • .<br />
print •.••...<br />
limc:print -bricf-univers<strong>al</strong>-timc. •<br />
lime:print-current-datc. . • . .<br />
limc:prinl-current-mail-fonnat -date<br />
time:print-current-moonphase<br />
time:print-currcnl-time •<br />
timc:prinl-datc • .<br />
si:print-hcr<strong>al</strong>d. . •..<br />
utils:prillt - into-file. . .<br />
timc:prim-moonphasc<br />
f1rinl-s~ stcm - hisIOt)" . .<br />
print - s~ stcm -modi fic<strong>al</strong>ions<br />
tiflle:print-lime • • • • • .<br />
timc:print-uni\crs<strong>al</strong>-datc .<br />
timc:print -univcrs<strong>al</strong>-mail- format-d<strong>al</strong>e. .<br />
timc:print -uni\crs<strong>al</strong>-lime<br />
probc-file . . • • . • . . . .<br />
proceed-nil. . . • • . • . • .<br />
tkproccss-in-Ioad-cnvironmenl<br />
proclaim •••••<br />
prog .<br />
prog*<br />
progl<br />
nroo') r· -4,;'-<br />
progn<br />
prog"<br />
progw<br />
progwf ••<br />
pmgwq.<br />
provide.<br />
ps<strong>et</strong>q<br />
push.<br />
putprop<br />
quit •••<br />
quotient •<br />
random ••<br />
rassoc ••<br />
rassq •••<br />
ration<strong>al</strong>.<br />
ration<strong>al</strong>ize<br />
si:re-edit -p<strong>al</strong>ch<br />
read •••••<br />
stevc:rcad-buffer-name •<br />
read-byte •••••<br />
read-char •••••••<br />
5tc\'e:rcad-file-name<br />
rcadline • • • • • • •<br />
steve:rc<strong>al</strong>-arg-sup? •<br />
rc<strong>al</strong>p<strong>al</strong>1 .•••••<br />
.187<br />
.un<br />
.185<br />
.185<br />
.185<br />
.236<br />
.236<br />
.236<br />
.239<br />
.235<br />
.236<br />
.282<br />
.228<br />
.239<br />
· .281<br />
.281<br />
.235<br />
.2''''<br />
.2~, ,<br />
.235<br />
.203<br />
.llN<br />
.206<br />
46.243<br />
· . 35<br />
35<br />
22<br />
:22<br />
22<br />
27<br />
• . 27<br />
27<br />
· 27<br />
.123<br />
· 26<br />
38<br />
· 65<br />
.289<br />
75<br />
. ••. 86<br />
· .64<br />
. ••• 64<br />
• 78<br />
. ••••• 78<br />
• .283<br />
.184<br />
.279<br />
.184<br />
· .183<br />
.279<br />
.184<br />
• .278<br />
· • 5<br />
.239<br />
tirne:rcgular-amcrican-daylight-saving.s-time-p .<br />
rem •••••••••••••.••••• ". 80
Function. Macro. and Speci<strong>al</strong> Fonnlndex<br />
320<br />
Nil. Manuell<br />
remaindcr<br />
remf •.<br />
rcmhash ••<br />
remmc ••.<br />
rcmo\c-if ••<br />
remmc-if -nOl<br />
rcmpTop ••<br />
rename- filc<br />
rcplacc •••<br />
require •.<br />
si: r~q uirc-charartcr<br />
l'i: rcquin:-l'haracter-Jhnum •<br />
rl'!\~l- fi 11- poi III er<br />
rest ••.••<br />
r<strong>et</strong>urn .•••<br />
r<strong>et</strong>urll-from<br />
rC\3ppcnd .<br />
rC\'crsc . • •<br />
si: mlsSclose<br />
si:nns~n)\)ncct<br />
si:rmsScrcate .<br />
si:nnsSddc(c .<br />
si:nns$disconncct .<br />
si:rmsSdisplay. •<br />
si:rmsSenter • •<br />
si:rms$crase •<br />
si:rmsScxlcnd.<br />
si:rms$find. .<br />
si:nnsSnush<br />
si:rmsSfrcc. •<br />
si:rms$g~t • •<br />
si:mlsSnxt\'ol. • • • • •<br />
si: mls$opcn<br />
~i:rmsSparsc •<br />
si:nns$put •<br />
si:nnsSrcad.<br />
si:rms$reJcase. •<br />
si :nnsSrcmove<br />
si: nnsSrename<br />
si: rmsSrcwind.<br />
si:rms$scarch •<br />
si:rmsSsctddir.<br />
si:nns$space . • • • • •<br />
si:rmsStrunc •<br />
si: rms$update.<br />
si:nns$wait.<br />
si:nns$write • • • • • •<br />
room •<br />
rot<strong>al</strong>ef.<br />
round.<br />
rpJaca •<br />
rplacd •<br />
runtime •••<br />
sarncpnamcp •<br />
SlC\'C:savc-<strong>al</strong>J - files.<br />
sbit. • • • • • •<br />
• • 80<br />
• • 40<br />
• 118<br />
53<br />
53<br />
53<br />
65<br />
• 203<br />
52<br />
123<br />
• • • • • 97<br />
97<br />
• • lOb<br />
57<br />
• • • • • 34<br />
34<br />
S8<br />
52<br />
• 208<br />
· • 20R<br />
.208<br />
• 208<br />
• 208<br />
• 208<br />
.209<br />
• 208<br />
• 208<br />
· ?OR<br />
• 208<br />
• 208<br />
.208<br />
.208<br />
• • 20R<br />
.209<br />
.208<br />
• 209<br />
.208<br />
.209<br />
.209<br />
.208<br />
• .209<br />
• 209<br />
.209<br />
• 209<br />
.209<br />
• 209<br />
• 209<br />
.234<br />
39<br />
79<br />
56<br />
••••• 56<br />
.223<br />
.66<br />
• 277<br />
• 109<br />
sc<strong>al</strong>c- n03t •<br />
schar •••<br />
second ••<br />
stcvc:scJcct -I'oint .<br />
!.1c"c:sclcct-point-in-currcnt-window<br />
seiCt1q . • • • • ••••<br />
send ••••<br />
send-forward<br />
s<strong>et</strong> •••••<br />
s<strong>et</strong>-di ffcrcnce<br />
s<strong>et</strong>-cxclusivc-or •<br />
sel-ldb& .•••<br />
si:~t -~nch-cO\·irollmcnl. .<br />
s<strong>et</strong> -I'rhilcgcs . • • • . • • • • • .<br />
si:sct-!\ystcm-st:nus. •<br />
sct-tcmlin<strong>al</strong>-typc.<br />
self •.<br />
s<strong>et</strong>l'list • •<br />
selq .•<br />
~tsynlax .•••.<br />
lICtsyntax -sharp-macro. •<br />
~c\"c:sctul'-modc-arca<br />
seventh ..<br />
5gner .•••••<br />
shillf. • • • • •<br />
short-site-name<br />
si:show-c<strong>al</strong>l-mclcrs. •<br />
Q:lJ.jr1 .<br />
si:%syi ••••••<br />
si:abon-p3Ich . • • •<br />
si:add-cscape-char-syntax •<br />
si:add -list-syntax. • • •<br />
si:add-numhcr-syntax ••<br />
si:add-packagc-!o"yntax •<br />
si:add-patch. • • • • •<br />
si:add-prcfix-op-macro •<br />
si:apTopos-@cnerate. • • • • • • •<br />
si:compilc-load-patch. • •<br />
si:compile-patch • • • • •<br />
si:construct-syslcm-symbol-trampoline. •<br />
si:def-vms-c<strong>al</strong>l-intcrface. • • • • •<br />
.91<br />
114<br />
.56<br />
276<br />
276<br />
.30<br />
172<br />
172<br />
.• 69<br />
...•••. 62<br />
. •.••..• 62<br />
•.• 89<br />
28]<br />
233<br />
283<br />
211<br />
.38<br />
.69<br />
.25<br />
si:dcfsyscaU • • • • • • • • • • • • • • • •<br />
si:dctcrmine-and -s<strong>et</strong>-tennin<strong>al</strong>-type •<br />
si:enablc-vms-c<strong>al</strong>l -trampoline<br />
si:enter-readtable. • •<br />
si:finish-p<strong>al</strong>ch • • •<br />
si:gct-ca11-m<strong>et</strong>ers ••••<br />
si:g<strong>et</strong>-system-version • •<br />
si:gct -syslem-version-list<br />
si:gctjpi-string •<br />
si:gctjpi-v<strong>al</strong>ue • • • • • • •<br />
si:gctsyi-string. •<br />
si:gcL~yi-v<strong>al</strong>ue .•<br />
si:had-vms-objcct-fiJc •<br />
si:initiaIi7c-patch-systcm •<br />
si:locate-S}mbol-tablc-v<strong>al</strong>ue •<br />
si:lookup-rcadtable. • • • •<br />
~IR<br />
218<br />
279<br />
.56<br />
109<br />
••• 39<br />
232<br />
225<br />
242<br />
242<br />
283<br />
219<br />
219<br />
219<br />
219<br />
283<br />
219<br />
221<br />
283<br />
283<br />
300<br />
299<br />
298<br />
211<br />
299<br />
219<br />
283<br />
225<br />
282<br />
282<br />
242<br />
241<br />
242<br />
242<br />
299<br />
2.84<br />
300<br />
218<br />
23-DEC-83
<strong>NIL</strong> Manu<strong>al</strong><br />
321 Function, Macro, and Speci<strong>al</strong> Form Index<br />
si:loor-genlemp ...<br />
si: lool'-n;ullcd-\'ariablc<br />
si:loop-tassoc •<br />
si:loor-tequ<strong>al</strong> •<br />
si:loop-uncmbcr .<br />
si:make- fab . .<br />
si:makc-nam.<br />
si:make-rab .<br />
si:make-xab. .<br />
si:modulc·sourcc-file<br />
si:ncw-p<strong>al</strong>ch-s),slcm<br />
si:uolc-rrimili\ c- fOIll .<br />
si:r:1ckagc-!'~ mholconc.<br />
....<br />
si:ragcl~lUlt-rount.<br />
si:rrinr-t.cr<strong>al</strong>d . . .<br />
si:rc-cdil-r:1lch ..<br />
si:rcqllirc-charactcr . .<br />
si:rcquirc-characlcr-{hnuIn.<br />
si:mlsSciosc . .<br />
si:nllsSconncct .<br />
si:nnsScreatc. •<br />
si:nnsSdcJctc.<br />
si:rmsSdisconncct .<br />
si:rrn~Sdisplay .<br />
si:nnsScnter. •<br />
si:rmsSerasc •<br />
si:rmsScx tend<br />
c;i'rmc;~finn<br />
si:mlsSflush<br />
si:mlsSfrcc.<br />
si: mls$g<strong>et</strong> .<br />
si:rrnsSnxt\'ol. .<br />
si: nnsSopcn . •<br />
si: rmsSparse •<br />
si:nnsSput. • •<br />
si:nns$rcad . .<br />
si:nnsSrelease • • • • •<br />
si:rmsSremove •<br />
si:rmsSrename •<br />
si:nnsSrewind<br />
si:rmsSscarch. •<br />
si:rmsSs<strong>et</strong>ddir<br />
si: rmsSspace. •<br />
si:rmsStrunc. •<br />
si: rms$update<br />
si:rms$wait • •<br />
si:rmsSwJite •<br />
si:sel-patch-environmcnl.<br />
si:sct-systcm-status. .<br />
si:show-c<strong>al</strong>l-mcters. •<br />
si:subtract -c<strong>al</strong>l-m<strong>et</strong>ers .<br />
si:systcm-vemon-info.<br />
si:trnlog. • • • • • •<br />
si:updatc-systcm -statuses?<br />
sign<strong>al</strong> ••<br />
signum.<br />
signum&<br />
]66<br />
16b<br />
166<br />
166<br />
166<br />
207<br />
207<br />
207<br />
· 207<br />
221<br />
284<br />
101<br />
.70<br />
224<br />
282<br />
· 283<br />
.97<br />
. 97<br />
208<br />
208<br />
208<br />
208<br />
208<br />
· • 208<br />
209<br />
208<br />
208<br />
2(\8<br />
208<br />
... 208<br />
208<br />
• . 208<br />
208<br />
209<br />
••• 208<br />
• • 209<br />
208<br />
209<br />
· 209<br />
208<br />
209<br />
209<br />
209<br />
• • 209<br />
209<br />
209<br />
209<br />
283<br />
283<br />
225<br />
225<br />
282<br />
209<br />
282<br />
229<br />
.77<br />
.88<br />
simp.<br />
simpand ••<br />
simpandlist<br />
simplc-hit-vector-Icngth<br />
simple-gener<strong>al</strong> - vcctor-Iength<br />
simplc-vector-Iength<br />
simpnot ..<br />
simpor .•<br />
simporlist.<br />
sin<br />
sinh.<br />
sixth.<br />
somc.<br />
son .<br />
sonC3r .<br />
utils:source- need -COnlrilc?<br />
sqrt •••<br />
s..\tatus ..... .<br />
stablc"son ~ . . •<br />
st:mdard-char-p .<br />
status ••••<br />
Sle\c:argumcnt? • •<br />
slc\'c:huffcr. . • •<br />
slcYc:buffcr-begin? •<br />
stcvc:huffcr-cnd? • • • . •<br />
stevc:c-u-only? • .<br />
stcvc:cd-Iosc ..<br />
stc\c:ed-waming.. .<br />
Slc\c:cditor-bind-kcy.<br />
stc\,c:edilor-dcfun-key •<br />
stevc: first -line?<br />
slc\c:lasl-linc? ••<br />
stcvc:linc-ncxt. • •<br />
steve:Jine-previous .<br />
steve:makc-bp. . • .<br />
stevc:make-line • • •<br />
steve:makc-scrcen -image<br />
ste"c:mx" prompter. •<br />
stc\'c:not-buffer-begin<br />
steve: not -buffer-end •<br />
steve: not - first -line •<br />
stcve:not-last-line ••<br />
Sleve:nth-next-line. •<br />
stevc:nth-previous-line •<br />
stevc:overwritc-done.<br />
steve:overwJite-home •<br />
stcvc:overwnte-start •<br />
stevc:overwritc-tcrpJi. •<br />
steve:point • • • • •<br />
Slevc:point -selectcd. •<br />
stc"e:rcad-huffcr-name •<br />
stevc:rcad-file-name<br />
stcvc:rc<strong>al</strong>-arg-sup? •<br />
stcvc:sa,c-<strong>al</strong>l-filt.'S •<br />
stcvc:sclcct-point. •<br />
stcve:sclcct-point-in-currcnt-window<br />
.295<br />
.295<br />
.295<br />
· .110<br />
.109<br />
.109<br />
.295<br />
.295<br />
· .295<br />
77<br />
• 78<br />
50<br />
54<br />
55<br />
55<br />
.127<br />
76<br />
87<br />
55<br />
94<br />
87.224<br />
.278<br />
.276<br />
.278<br />
.278<br />
.278<br />
.277<br />
.~T?<br />
.278<br />
.274<br />
.275<br />
.278<br />
.278<br />
.276<br />
.276<br />
.275<br />
.276<br />
.279<br />
.279<br />
• .278<br />
.278<br />
.278<br />
. .•. 278<br />
.276<br />
.276<br />
.279<br />
.279<br />
.279<br />
.279<br />
.276<br />
.276<br />
.279<br />
.279<br />
.278<br />
• •• 277<br />
.276<br />
.276<br />
23-DEC-83
Function, Macro. and Speci<strong>al</strong> Fonn Index<br />
322 <strong>NIL</strong> Manu<strong>al</strong><br />
stc"e:sctup-modc-arca. •<br />
Slc\c:with-no-pass<strong>al</strong>i<br />
streamJl. • .<br />
siring . . . .<br />
string-apJlend<br />
slring-char-p.<br />
siring-downca!>c.<br />
siring-equ<strong>al</strong> • • •<br />
!.lring-equ<strong>al</strong>-hash .<br />
string-greate", . .<br />
siring-left-trim ..<br />
siring-kngth .. .<br />
slring-lcssl1 ... .<br />
sliing-lIol-(.'qu<strong>al</strong><br />
siring-JHlI-grcatcrp<br />
stnng-nol-Icssp. •<br />
Slring-nre\ers~ . •<br />
slrillg-re\ erse. . .<br />
slli IIg - re\ crsc-sea rch . .<br />
string - n?\ l'rsc-Sl':Jrch-char<br />
st ring -rc\crsc-scarch" not -char<br />
slring-rc\crsc-scarch-not-SCI •<br />
slJing-re\'crsc-search-s<strong>et</strong> .•<br />
st ring - right - trim •<br />
string-search. • • ••<br />
string-!iCarch-char. • • • • • • • •<br />
string-scarch-nol-char.<br />
!ilring-'I('arrh"nnr-~t<br />
string-search-sct<br />
siring-Irim. •<br />
!lolring"upC3:ie •<br />
string/: .<br />
siring( .•<br />
Slring = •<br />
Slringp<br />
subl •<br />
sublis. •<br />
subseq.<br />
subsctp<br />
subst •<br />
substitute<br />
substitute-if •<br />
substitute-if - not<br />
substring. • • •• •• • • • •<br />
si:suhlract-c<strong>al</strong>l-m<strong>et</strong>ers • •<br />
subtypep.<br />
svref ••••••<br />
sxhash ••..••<br />
sys:sxhash-combine •<br />
symbol- function<br />
S} mbol-Jlame • • •<br />
!\ymhol-paciage.<br />
symbol-pliSl ••<br />
• • 279<br />
• • 278<br />
• 179<br />
• • 112<br />
• 115<br />
• • }9<br />
• •• JJ4<br />
• • • • 113<br />
• • 119<br />
•.•• 113<br />
• 115<br />
• 114<br />
•••• 113<br />
• •• 113<br />
• 113<br />
· .• ID<br />
• • • • • 115<br />
• • • • • 115<br />
)]6<br />
• • • • 116<br />
• 116<br />
• • 116<br />
••• 116<br />
• US<br />
• 116<br />
• • 116<br />
• • 116<br />
111\<br />
• • • J 16<br />
• 115<br />
• 114<br />
• • 113<br />
• 113<br />
• 113<br />
• 113<br />
• • 119<br />
• • 114<br />
• 113<br />
19<br />
75<br />
• • • • • 60<br />
••••• SO<br />
62<br />
60<br />
53<br />
• • • • • 54<br />
54<br />
• 115<br />
.225<br />
• 18<br />
• 109<br />
• 119<br />
• • 119<br />
68<br />
66<br />
• • • • • 67<br />
6S<br />
symhol - \'<strong>al</strong>uc<br />
symholconc •<br />
symbolp ••<br />
symcvaJ .••<br />
!l)'s:%fixnum-ash-with-m·crflow-trapping.<br />
!\ys:%fixnum- differencc-with -overflow-lraJlJling • .<br />
sys:%fix num -plus-with-overflow-trapping .<br />
sys;%fixnum-limcs-with-ovcrflow-trapping •<br />
s),s:sxhash-combinc •••<br />
· .68<br />
· .70<br />
• • 18<br />
.69<br />
.90 .<br />
· .90<br />
· .90<br />
• .90<br />
119<br />
si:syslcm-vcrsion-info. • 282<br />
taghod) .<br />
tailp •<br />
lan ••<br />
tanh.<br />
tenUl •<br />
tcrpri •<br />
thc ••<br />
third.<br />
Jhrow.<br />
time.<br />
. ....... .<br />
.......<br />
timc:comcn-\·ms-Lime-to-uni\crs<strong>al</strong>-timc.<br />
limc:da)-of-the-wcck. • • • • •<br />
timc:day"of-the-wcci-string.<br />
timc:daylight-savings-p • • •<br />
time: daylight -s<strong>al</strong>ings-time-p •<br />
time: last -sunday-in-april • •<br />
'imp'I~~f-Qlnrt~y-in-n("tn~r<br />
timc:lcap·ycar-p. • • • • •<br />
limc:modc-languagc-fctch •<br />
timc:month -length<br />
timc:monLh-string • • • • •<br />
limc:moonJ'hasc . • • • • •<br />
time:prim-bricf-univcrs<strong>al</strong>-time • •<br />
time:print-current-date • • • •<br />
timc:print -current-mail-fonnat.. date.<br />
time:print -currenr-moonphase<br />
time:print-current-time •<br />
time:print - date. • • •<br />
timc:prinl-moonphase ••<br />
• •• 34<br />
• .5Q<br />
••••••• 77<br />
•••••• 78<br />
• •• 56<br />
185<br />
.47<br />
• •• 56<br />
• •• 30<br />
223<br />
• 240<br />
238<br />
237<br />
238<br />
238<br />
239<br />
~3Q<br />
. 238<br />
237<br />
238<br />
. 237<br />
238<br />
••••• 236<br />
236<br />
•• 236<br />
239<br />
235<br />
236<br />
239<br />
timc:print-time. • • • • . . . . . . 23S<br />
time: pri nt ·univers<strong>al</strong>-date ••••• 236<br />
time:print-univcrs<strong>al</strong>-maiJ-(onnat-d<strong>al</strong>e. •<br />
236<br />
time:print-univers<strong>al</strong>-time • • • • • • •<br />
235<br />
timc:rcgular-american - da)·Jjg.ht -savings-time-p • 239<br />
time:timezone-string • • • • •<br />
238<br />
time:verify-date<br />
238<br />
time:zoneconv •<br />
• • • • • 239<br />
timer. • • • ••<br />
223<br />
times. • • • •<br />
. . ~ .75<br />
time:timezone-suing<br />
238<br />
to-SIring •<br />
112<br />
trace •••<br />
179,220<br />
si:tmlog ••<br />
209<br />
truncate ••<br />
• •• 79<br />
typcca.~ ••<br />
• •• 30<br />
typep. •<br />
.18
N II. Manu<strong>al</strong><br />
323 Fum:tion. Macro. and Speci<strong>al</strong> F0n11 Index<br />
union.<br />
unless.<br />
unread-char.<br />
unwind-protcct.<br />
si:updatc-systcm -statuscs? .<br />
uppcr-case-p . . • • .<br />
uscr-homcdir-p<strong>al</strong>hnamc .<br />
uscr-scr3tchdir-pathnamc<br />
lIscr-workingdir-p<strong>al</strong>hnamc .<br />
1I1ils:pp-into-lilc. • . . .<br />
1I1ils:print-illI0-lilc .•..<br />
1IIils:sourcl'-nl'cd-compilc? .<br />
utils:\a~-sourrc-lilc ..•.<br />
utib.:\a~-s()urcc-nccds-rccompilc? .<br />
\<strong>al</strong>rel .. .<br />
vailies .. .<br />
\<strong>al</strong>ucs-list.<br />
\'<strong>al</strong>ucs-\ ector.<br />
ulils:vas-sourcc-Iilc .<br />
utils:\:ls-sollrcc-nccds-rccompilc? .<br />
\CClor •••••<br />
vcctor-lcngth<br />
vcctor-pop . •<br />
vcctor-push .<br />
vcctor-push-extend •<br />
\,C'rforp ....<br />
\cri(v. . . . • .<br />
timc:\crify-datc<br />
vref ••<br />
.62<br />
.29<br />
184<br />
.36<br />
282<br />
.95<br />
199<br />
• 200<br />
200<br />
228<br />
228<br />
• 227<br />
227<br />
227<br />
289<br />
.36<br />
.37<br />
.37<br />
227<br />
227<br />
· 109<br />
108<br />
106<br />
106<br />
106<br />
lQ<br />
228<br />
· 2J8<br />
108<br />
when •.<br />
whercis •<br />
who-c<strong>al</strong>ls.<br />
with-input - from -string<br />
stcl'c:with-no-passaU •<br />
with-oJ;>en-file. • . •<br />
with-output-to-string •<br />
writc-bits. •<br />
write-byte. .<br />
write-char.<br />
write-line.<br />
write-string •<br />
loons •••<br />
y-or-n-p ••<br />
yes-or-no-p. .<br />
zerop. • • ••<br />
time:loneconv • •<br />
\&.<br />
.28<br />
221<br />
221<br />
182<br />
• 278<br />
181<br />
182,<br />
186<br />
•••••••• 186<br />
185<br />
· 185<br />
185<br />
.57<br />
197<br />
• • 197<br />
.73<br />
239<br />
.88<br />
.91<br />
87.88<br />
23-DEC-83