/
symbols.tex
329 lines (268 loc) · 13.1 KB
/
symbols.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
\section{Symbols and Packages}
\markright{\arabic{section}. Symbols and Packages}
\subsection{Symbols}
A symbols is assured to be unique if it is interned in a package.
The uniqueness is tested by symbol's print-names.
There are no duplicated symbols in a package which have the same print-name
as other symbols in the package.
When EusLisp is running, there always is a special package called
the current package, which is referred by {\bf lisp:*package*}.
When a symbol without a package name is read by the reader,
the current package is searched for to locate the symbol with the same
print-name.
If no such symbol is found, search is continued in the packages listed
in the package use list of the current package.
If still no such symbol is found,
a new symbol object with the designated print-name is created
and is interned in the current package.
The package can be specified by prefixing the package name followd by a colon(:).
If a symbol name is preceeded by a package name, the search begins
in the designated package.
Every symbol may have at most one home package.
If a symbol has no such home package, it is said to be an uninterned symbol.
Uninterned symbols can be created by the {\bf gensym} or {\bf make-symbol}
function, and they are prefixed by "\#:" when printed.
Since these symbols are not interned, two such symbols with the
same print-name are not guaranteed to be equal.
Usually, when the lisp reader encounters a symbol,
the reader converts the print-name string of the symbol to uppper case.
Thus, for example, if you input {\tt (symbol-name 'car)},
EusLisp responds {\tt "CAR"} instead of {\tt "car"}.
Note that {\tt (make-symbol "car")} returns $|${\tt car}$|$ instead of
{\tt car} or {\tt CAR}.
If you want the reader to make symbols constituted by lower case letters,
use reader's escapes, $\backslash$ and $|...|$.
\begin{refdesc}
\funcdesc{symbolp}{object}{
returns T if {\em object} is an instance of CLASS symbol or its subclasses.}
\funcdesc{symbol-value}{symbol}{
gets {\em symbol}'s special value. Lexical (local) variables'
values cannot be retrieved by this function.}
\funcdesc{symbol-function}{symbol}{
gets {\em symbol}'s global function definition.
Lexical (local) function cannot be taken by this function.}
\funcdesc{symbol-package}{sym}{
returns the package where {\em sym} is interned.}
\funcdesc{symbol-name}{sym}{
returns {\em sym}'s print-name.
Note that {\bf symbol-name} does not copy the pname string,
whereas {\bf string} does.
Thus, if you change the string returned by {\bf symbol-name},
the symbol becomes inaccessible through normal intern procedure.}
\funcdesc{symbol-plist}{sym}{
Returns {\em sym}'s property list (plist).
EusLisp's plist takes the same form as an association list,
which consists of dotted pairs of an attribute name and its value.
This is incompatible with Common Lisp definition which requests a plist
to have linear lists of attribute name and value.
In EusLisp, plist is not the unique facility of symbols.
Any objects instantiated from a class that inherits {\bf propertied-object}
can have property lists.
To set and retrieve these plists in propertied-objects,
{\bf propertied-object-plist} macro should be used instead of
{\bf symbol-plist}.
However, {\bf get} and {\bf putprop} work for either object.}
\funcdesc{boundp}{symbol}{
Checks if {\em symbol} has a globally bound value.
Note that symbols used for local and object variables
always have bound value and {\bf boundp} cannot test the bound state
of these local variables.}
\funcdesc{fboundp}{symbol}{
Checks if {\em symbol} has a globally bound function definition.}
\funcdesc{makunbound}{symbol}{
{\em symbol} is forced to be unbound (to have no special value).
Note that lexical (local) variables always have values assigned and
cannot be {\em makunbound}ed.}
\funcdesc{get}{sym attribute}{
retrieves {\em sym}'s value associated with {\em attribute} in its plist.
{\tt = (cdr (assoc {\em attribute} (symbol-plist {\em sym})))}}
\funcdesc{putprop}{sym val attribute}{
Putprop should be replaced with the combination of {\bf setf} and {\bf get}.}
\funcdesc{remprop}{sym attr}{
removes attribute-value pair from {\em sym}'s property list.}
\specialdesc{setq}{\&rest forms}{
for each form in {\em forms}, assigns the second element to the first element, which is either a symbol or a dotted-pair.
The first element is searched for in the name spaces of local variables,
object variables, and special variables in this order unless explicitly
declared special.}
\funcdesc{set}{sym val}{
assigns {\em val} to the special value of {\em sym}.
{\bf Set} cannot assign values to local or object variables.}
\specialdesc{defun}{symbol lambda-list \&rest body}{
defines a global function to {\em symbol}.
First element in {\em body} can be a documentation string.
Use {\em flet} or {\em labels} for defining local functions.}
\specialdesc{defmacro}{symbol lambda-list \&rest body}{
defines a global macro.
EusLisp does not have facilities for defining locally scoped macros.}
\macrodesc{defvar}{var \&optional (init nil) doc}{
If {\em var} symbol has any special value, {\bf defvar} does nothing.
If {\em var} is unbound, it is declared to be special and
{\em init} is set to its value.}
\macrodesc{defparameter}{var init \&optional doc}{
{\em defparameter} declares {\em var} to be special and
{\em init} is set to its value,
even if {\em var} already has value.}
\macrodesc{defconstant}{sym val \&optional doc}{
{\em defconstant} sets {\em val} as {\em sym}'s special value.
Unlike {\em defvar, defparameter} and {\em setq}, the value set by
{\em defconstant} cannot be altered by these forms.
If the value of a constant symbol is tried to be changed,
an error is reported.
However, another {\em defconstant} can override the previous
constant value, issuing a warning message.}
\funcdesc{keywordp}{obj}{
T if {\em obj} is a symbol and its home package is {\bf KEYWORD}.}
\funcdesc{constantp}{symbol}{
T if the symbol is declared to be constant with defconstant macro.}
\funcdesc{documentation}{sym \&optional type}{
retrieves documentation string of {\em sym}.}
\funcdesc{gensym}{\&optional x}{
creates a new uninterned symbol composed of a prefix string and a suffix
number like {\tt g001}.
Uninterned symbols are denoted by the \#: package prefix indicating
no package is associated with the symbols.
Symbols with \#: prefix are unreadable symbols and
the reader cannot create references to these uninterned symbols.
{\em X} can either be a string or an integer,
which is used as the prefix or the suffix.}
\funcdesc{gentemp}{\&optional (prefix "T") (pkg *package*)}{
creates a new symbol interned in {\em pkg}.
In most applications, {\bf gensym} is preferable to {\bf gentemp}, because
creation of uninterned symbols is faster and uninterned symbols are
garbage collect-able.}
\end{refdesc}
\subsection{Packages}
Packages provide separate name spaces for groups of symbols.
Common Lisp introduced the package system in order to reduce the
symbol (function and variable name) conflict problems
in the course of developing huge software systems
which require more than one programmer to work together.
Each package may have internal symbols and external symbols.
When a symbol is created in a package, it is always internal,
and it becomes external by {\bf export}. External symbols in different
packages are referenced by prefixing the package name and a single colon,
as {\tt x:*display*}, while referencing internal symbols in other packages
requires double colons, as {\tt sys::free-threads}.
In order to omit this package prefixing, a package may \bfx{import} symbols
from other packages.
Moreover, \bfx{use-package} allows importing all external symbols
from another package at once.
When symbols are exported or imported, symbol name conflicts can be detected,
since every symbol in any packages must have the unique print name.
\bfx{Shadow} allows creating a symbol with the same print name as the
existing symbol in a package by virtually removing the old symbol from
the package.
EusLisp defines following eight packages;
\begin{description}
\item [lisp:] All the lisp functions, macros, constants, etc.
\item [keyword:] keyword symbols
\item [unix:] unix system calls and library functions
\item [system:] system management or dangerous functions; nicknames=sys,si
\item [compiler:] EusLisp compiler; nicknames=comp
\item [user:] User's work space
\item [geometry:] geometric classes and functions
\item [xwindow:] X-window interface; nickname=x
\end{description}
These packages and user-defined packages are linked in the system's
package list, which can be obtained by {\bf list-all-packages}.
Each package manages two hash tables to find and locate internal and
external symbols.
Also, a package records its name (string or symbol) and a list of nick names,
and a list of other packages that the package is using.
{\bf *Package*} is a special variable
that holds the current package for read and print.
If \bfx{*package*} is not {\tt user:},
top-level prompt changes to indicate the current package,
like {\tt mypkg:eus}\$.
\begin{refdesc}
\constdesc{*lisp-package*}{
Lisp package.}
\constdesc{*user-package*}{
User package.}
\constdesc{*unix-package*}{
Unix package.}
\constdesc{*system-package*}{
System Package.}
\constdesc{*keyword-package*}{
Keyword Package.}
\funcdesc{find-symbol}{string \&optional (package *package*)}{
finds and locates the symbol which has {\em string} as its print name
in {\em package}. If found, the symbol is returned, NIL otherwise.}
\funcdesc{make-symbol}{string}{
makes a new uninterned symbol by the print name of {\em string}.}
\funcdesc{intern}{string \&optional (package *package*) (klass symbol)}{
tries to find a symbol whose print-name is same with {\em string}.
If the search succeeds, the symbol is returned.
If fails, a symbol whose print-name is {\em string} is newly made,
and is located in {\em package}.}
\funcdesc{list-all-packages}{}{
returns the list of all packages ever made.}
\funcdesc{find-package}{name}{
find the package whose name or nickname is equal to the {\em name} string.}
\funcdesc{make-package}{name \&key nicknames (use '(lisp))}{
makes a new package by the name of {\em name}.
{\em Name} can either be a string or a symbol.
If the package already exists, error is reported.}
\funcdesc{in-package}{pkg \&key nicknames (uses '(lisp))}{
changes the current package (the value of {\bf *package*})
to {\em pkg}.}
\funcdesc{package-name}{pkg}{
returns the string name of the {\em pkg} package.}
\funcdesc{package-nicknames}{pkg}{
returns a list of nicknames of {\em pkg}.}
\funcdesc{rename-package}{pkg new-name \&optional new-nicknames}{
changes the name of {\em pkg} to {\em new-name} and its nicknames
to {\em new-nicknames}, which can either be a symbol, a string,
or a list of symbols or strings.}
\funcdesc{package-use-list}{pkg}{
returns the list of packages which are used by {\em pkg}.}
\funcdesc{packagep}{pkg}{
T if {\em pkg} is a package.}
\funcdesc{use-package}{pkg \&optional (curpkg *package*)}{
adds {\em pkg} to {\em curpkg}'s use-list.
Once added, symbols in {\em pkg} become visible from {\em curpkg}
without package prefix.}
\funcdesc{unuse-package}{pkg \&optional (curpkg *package*)}{
removes {\em pkg} from {\em curpkg}'s use-list.}
\funcdesc{shadow}{sym \&optional(pkg *package*)}{
makes a symbol interned in {\em pkg},
by hiding existing {\em sym}.}
\funcdesc{export}{sym \&optional (pkg *package*)}{
{\em sym} is a symbol or a list of symbols.
{\bf export} makes {\em sym} accessible from other packages as
external symbol(s).
Actually, {\em sym} is registered as an external symbol in {\em pkg}.
If a symbol is exported, it becomes accessible using a single colon ":"
as package marker, whereas unexported symbols require double colons.
In addition, exported symbols do not need colons when they are used
by {\bf use-package} or they are imported into the package.
Whether a symbol is exported or not is attributed to packages where
it is interned, not to each symbol.
So, a symbol can be internal in a package and external in another.
{\bf Export} checks {\em sym} to have name conflict with
symbols in other packages using {\em pkg}.
If there is a symbol having the same print name with {\em sym},
``symbol conflict" error is reported.}
\funcdesc{unexport}{sym \&optional pkg}{
If {\em sym} is an external symbol in {\em pkg}, it is unexported
and becomes an internal symbol.}
\funcdesc{import}{sym \&optional (pkg *package*)}{
{\em sym} is a symbol or a list of symbols.
{\bf import} makes symbols defined in other packages
visible in {\em pkg} as an internal symbol without package prefix.
If there is already a symbol that has the same print name as {\em sym},
then an ``name conflict" error is reported.}
\macrodesc{do-symbols}{(var pkg \&optional result) \&rest forms}{
repeats evaluatiing forms for each binding of {\em var}
to symbols (internal or external) in {\em pkg}.}
\macrodesc{do-external-symbols}{(var pkg \&optional result) \&rest forms}{
repeats evaluating forms for each binding of {\em var}
to external symbols in {\em pkg}.}
\macrodesc{do-all-symbols}{(var \&optional result) \&rest forms}{
repeats evaluating forms for each binding of {\em var}
to symbols in all packages.
Note that forms may be evaluated more than once to a symbol if it
appears more than one package.}
\end{refdesc}
\newpage