forked from filonenko-mikhail/cltl2-doc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
dtspec.tex
1618 lines (1399 loc) · 81 KB
/
dtspec.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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%Part{Dtspec, Root = "CLM.MSS"}
%Chapter of Common Lisp Manual. Copyright 1984, 1988, 1989 Guy L. Steele Jr.
\clearpage\def\pagestatus{FINAL PROOF}
\ifx \rulang\Undef
\chapter{Type Specifiers} % Avoid ligature
\label{DTSPEC}
In Common Lisp, types are named by Lisp objects, specifically symbols and lists,
called \emph{type specifiers}. Symbols name predefined classes of objects,
whereas lists usually indicate combinations or
specializations of simpler types.
Symbols or lists may also be abbreviations for types that could
be specified in other ways.
\section{Type Specifier Symbols}
The type symbols defined by the system include those shown in
table~\ref{TYPE-SYMBOLS-TABLE}.
In addition, when a structure type is defined using \cdf{defstruct},
the name of the structure type becomes a valid type symbol.
\section{Type Specifier Lists}
If a type specifier is a list, the \emph{car}
of the list is a symbol, and the rest of the list is subsidiary
type information. In many cases a subsidiary item may be
\emph{unspecified}. The unspecified subsidiary item is indicated
by writing \cd{*}. For example, to completely specify
a vector type, one must mention the type of the elements
and the length of the vector, as for example
\begin{lisp}
(vector double-float 100)
\end{lisp}
To leave the length unspecified, one would write
\begin{lisp}
(vector double-float *)
\end{lisp}
To leave the element type unspecified, one would write
\begin{lisp}
(vector * 100)
\end{lisp}
One may also leave both length and element type unspecified:
\begin{lisp}
(vector * *)
\end{lisp}
Suppose that two type specifiers are the same except that the first
has a \cdf{*} where the second has a more explicit specification.
Then the second denotes a subtype of the type denoted by the first.
\begin{table}[t]
\caption{Standard Type Specifier Symbols}
\label{TYPE-SYMBOLS-TABLE}
\divide\tabcolsep by 2\relax
\begin{flushleft}
\cf
\begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}l@{\extracolsep{\fill}}l@{\extracolsep{\fill}}l@{}}
array&fixnum&package&simple-string \\
atom&float&pathname&simple-vector \\
bignum&function&random-state&single-float \\
bit&hash-table&ratio&standard-char \\
bit-vector&integer&rational&stream \\
character&keyword&readtable&string \\
&list&sequence& \\
compiled-function&long-float&short-float&symbol \\
complex&nil&signed-byte&t \\
cons&null&simple-array&unsigned-byte \\
double-float&number&simple-bit-vector&vector
\end{tabular*}
\end{flushleft}
\end{table}
As a convenience, if a list
has one or more unspecified items at the end, such items
may simply be dropped rather than writing an explicit \cd{*} for each one.
If dropping all occurrences of \cd{*} results in a singleton list,
then the parentheses may be dropped as well (the list may be replaced
by the symbol in its \emph{car}). For example,
\cd{(vector double-float *)} may be abbreviated to \cd{(vector double-float)},
and \cd{(vector * *)} may be abbreviated to \cd{(vector)} and then to
simply \cdf{vector}.
\section{Predicating Type Specifiers}
\label{PREDICATING-TYPE-SPECIFIERS-SECTION}
A type specifier list \cd{(satisfies \emph{predicate-name})} denotes
the set of all objects that satisfy the predicate named by \emph{predicate-name},
which must be a symbol whose global function definition is a one-argument
predicate.
(A name is required; lambda-expressions are disallowed in order to avoid
scoping problems.) For example, the type \cd{(satisfies numberp)} is the
same as the type \cdf{number}.
The call \cd{(typep x '(satisfies p))} results in applying \cdf{p} to \cdf{x}
and returning \cdf{t} if the result is true and {\nil} if the result is false.
It is not a good idea for
a predicate appearing in a \cdf{satisfies} type specifier to
cause any side effects when invoked.
\section{Type Specifiers That Combine}
The following type specifier lists define a type in terms of
other types or objects.
\begin{flushdesc}
\item[\cd{(member \emph{object1} \emph{object2} ...)}]
This denotes the set
containing precisely those objects named. An object is of
this type if and only if it is \cdf{eql} to one of the specified objects.
\end{flushdesc}
\begin{flushdesc}
\item[\cd{(eql \emph{object})}]
It may be used as a parameter specializer for CLOS methods
(see section~\ref{Introduction-to-Methods-SECTION}
and \cdf{find-method}).
It denotes the set of the one object named; an object is of
this type if and only if it is \cdf{eql} to \emph{object}. While
\cd{(eql \emph{object})} denotes the same type as \cd{(member \emph{object})},
only \cd{(eql \emph{object})} may be used as a CLOS parameter specializer.
\end{flushdesc}
\begin{flushdesc}
\item[\cd{(not \emph{type})}]
This denotes the set of all those objects that
are \emph{not} of the specified type.
\item[\cd{(and \emph{type1} \emph{type2} ...)}]
This denotes the intersection of
the specified types.
When \cdf{typep} processes an \cdf{and} type specifier, it always
tests each of the component types in order from left to right
and stops processing as soon as one component of the intersection has
been found to which the object in question does not belong.
In this respect an \cdf{and} type specifier is similar to an
executable \cdf{and} form. The purpose of this similarity is to allow
a \cdf{satisfies} type specifier to depend on filtering by previous
type specifiers. For example, suppose there were a function \cdf{primep}
that takes an integer and says whether it is prime. Suppose also that
it is an error to give any object other than an integer to \cdf{primep}.
Then the type specifier
\begin{lisp}
(and integer (satisfies primep))
\end{lisp}
is guaranteed never to result in an error because the function \cdf{primep}
will not be invoked unless the object in question has already been
determined to be an integer.
\item[\cd{(or \emph{type1} \emph{type2} ...)}]
This denotes the union of the
specified types. For example, the type \cdf{list} by definition is the same as
\cd{(or null cons)}. Also, the value returned by the function
\cdf{position} is always of type \cd{(or null (integer 0 *))}
(either {\nil} or a non-negative integer).
As for \cdf{and},
when \cdf{typep} processes an \cdf{or} type specifier, it always
tests each of the component types in order from left to right
and stops processing as soon as one component of the union has
been found to which the object in question belongs.
\end{flushdesc}
\section{Type Specifiers That Specialize}
\label{SPECIALIZED-TYPE-SPECIFIER-SECTION}
Some type specifier lists denote \emph{specializations} of
data types named by symbols. These specializations may be
reflected by more efficient representations in the underlying
implementation. As an example, consider the type \cd{(array short-float)}.
Implementation A may choose to provide a specialized representation
for arrays of short floating-point numbers, and implementation B
may choose not to.
If you should want to create an array for the
express purpose of holding only short-float objects, you may
optionally specify to \cdf{make-array} the element type
\cdf{short-float}. This does not \emph{require} \cdf{make-array} to create
an object of type \cd{(array short-float)}; it merely \emph{permits} it. The
request is construed to mean ``Produce the most specialized array
representation capable of holding short-floats that the implementation
can provide.'' Implementation A will then produce a specialized
array of type \cd{(array short-float)}, and implementation B
will produce an ordinary array of type \cd{(array t)}.
If one were then to ask whether the array were actually of type
\cd{(array short-float)}, implementation A would say ``yes,'' but
implementation B would say ``no.'' This is a property of \cdf{make-array}
and similar functions: what you ask for is not necessarily what you get.
\begin{new}
X3J13 voted in January 1989
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS}
to eliminate the differing treatment of types
when used ``for discrimination'' rather than ``for declaration'' on the grounds
that implementors have not treated the distinction consistently
and (which is more important) users have found the distinction confusing.
As a consequence of this change, the behavior of \cdf{typep} and \cdf{subtypep}
on \cdf{array} and \cdf{complex} type specifiers must be modified.
See the descriptions of those functions. In particular, under their new
behavior, implementation B would say ``yes,'' agreeing with implementation A,
in the discussion above.
Note that the distinction between declaration and discrimination remains
useful, if only so that we may remark that the specialized (list)
form of the
\cdf{function} type specifier may still be used only for declaration and
not for discrimination.
\end{new}
\begin{new}
X3J13 voted in June 1988 \issue{FUNCTION-TYPE} to clarify that
while the specialized form of the \cdf{function} type specifier
(a list of the symbol \cdf{function} possibly followed by
argument and value type specifiers)
may be used only for declaration, the symbol form (simply the name
\cdf{function}) may be used for discrimination.
\end{new}
The valid list-format names for data types are as follows:
\begin{flushdesc}
\item[\cd{(array \emph{element-type} \emph{dimensions})}]
This denotes the set
of specialized arrays
whose elements are all members of the type \emph{element-type}
and whose dimensions match \emph{dimensions}.
For declaration purposes, this type encompasses those arrays
that can result by specifying \emph{element-type} as the element type
to the function \cdf{make-array}; this may be different
from what the type means for discrimination purposes.
\emph{element-type} must be a valid type specifier or unspecified.
\emph{dimensions} may be a non-negative integer, which is the number
of dimensions, or it may be a list of non-negative integers
representing the length of each dimension (any dimension
may be unspecified instead), or it may be unspecified.
For example:
\begin{lisp}
(array integer 3)~~~~~~~~~~~;\textrm{Three-dimensional arrays of integers} \\
(array integer (* * *))~~~~~;\textrm{Three-dimensional arrays of integers} \\
(array * (4 5 6))~~~~~~~~~~~;\textrm{4-by-5-by-6 arrays} \\
(array character (3 *))~~~~~;\textrm{Two-dimensional arrays of characters} \\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~;~\textrm{that have exactly three rows} \\
(array short-float {\emptylist})~~~~~~;\textrm{Zero-rank arrays of short-format} \\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~;~\textrm{floating-point numbers}
\end{lisp}
Note that \cd{(array~t)} is a proper subset of \cd{(array~*)}.
The reason is that \cd{(array~t)} is the set of arrays that can
hold any Common Lisp object (the elements are of type \cdf{t},
which includes all objects). On the other hand, \cd{(array~*)}
is the set of all arrays whatsoever, including, for example,
arrays that can hold only characters. Now
\cd{(array character)} is not a subset of \cd{(array~t)}; the two sets
are in fact disjoint because \cd{(array character)} is not the
set of all arrays that can hold characters but rather the set of
arrays that are specialized to hold precisely characters and no
other objects. To test whether an array \cdf{foo} can hold a character,
one should not use
\begin{lisp}
(typep foo '(array character))
\end{lisp}
but rather
\begin{lisp}
(subtypep 'character (array-element-type foo))
\end{lisp}
See \cdf{array-element-type}.
\begin{new}
X3J13 voted in January 1989
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS}
to change \cdf{typep} and \cdf{subtypep}
so that the specialized \cdf{array} type specifier
means the same thing for discrimination
as for declaration: it encompasses those arrays
that can result by specifying \emph{element-type} as the element type
to the function \cdf{make-array}.
Under this interpretation \cd{(array character)} might be
the same type as \cd{(array t)}
(although it also might not be the same).
See \cdf{upgraded-array-element-type}.
However,
\begin{lisp}
(typep foo '(array character))
\end{lisp}
is still not a legitimate test of whether the array
\cdf{foo} can hold a character; one must still say
\begin{lisp}
(subtypep 'character (array-element-type foo))
\end{lisp}
to determine that question.
X3J13 also voted in January 1989
\issue{DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES}
to specify that within the lexical scope of an array type declaration,
it is an error for an array element, when referenced, not to be
of the exact declared element type. A compiler may, for example,
treat every reference to an element of a declared array as if
the reference were surrounded by a \cdf{the} form mentioning the
declared array element type (\emph{not} the upgraded array element type). Thus
\begin{lisp}
(defun snarf-hex-digits (the-array) \\*
~~(declare (type (array (unsigned-byte 4) 1) the-array)) \\*
~~(do ((j (- (length array) 1) (- j 1)) \\*
~~~~~~~(val 0 (logior (ash val 4) \\*
~~~~~~~~~~~~~~~~~~~~~~(aref the-array j)))) \\*
~~~~~~((< j 0) val)))
\end{lisp}
may be treated as
\begin{lisp}
(defun snarf-hex-digits (the-array) \\*
~~(declare (type (array (unsigned-byte 4) 1) the-array)) \\*
~~(do ((j (- (length array) 1) (- j 1)) \\*
~~~~~~~(val 0 (logior (ash val 4) \\*
~~~~~~~~~~~~~~~~~~~~~~(the (unsigned-byte 4) \\*
~~~~~~~~~~~~~~~~~~~~~~~~~~~(aref the-array j))))) \\*
~~~~~~((< j 0) val)))
\end{lisp}
The declaration amounts to a promise by the user that the \cdf{aref}
will never produce a value outside the interval 0 to 15, even if
in that particular implementation the array element type
\cd{(unsigned-byte 4)} is upgraded to, say, \cd{(unsigned-byte 8)}.
If~such upgrading does occur, then values outside that range may in fact
be stored in \cdf{the-array}, as long as the code in \cdf{snarf-hex-digits}
never sees them.
As a general rule, a compiler would be justified in transforming
\begin{lisp}
(aref (the (array \emph{elt-type} ...) \emph{a}) ...)
\end{lisp}
into
\begin{lisp}
(the \emph{elt-type} (aref (the (array \emph{elt-type} ...) \emph{a}) ...)
\end{lisp}
It may also make inferences involving more complex functions,
such as \cdf{position} or \cdf{find}.
For example, \cdf{find} applied to an array always returns either \cdf{nil}
or an object whose type is the element type of the array.
\end{new}
\begin{new}
X3J13 voted in January 1989
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS}
to change \cdf{typep} and \cdf{subtypep}
so that the specialized \cdf{array} type specifier
means the same thing for discrimination
as for declaration: it encompasses those arrays
that can result by specifying \emph{element-type} as the element type
to the function \cdf{make-array}.
Under this interpretation \cd{(array character)} might be
the same type as \cd{(array t)}
(although it also might not be the same).
See \cdf{upgraded-array-element-type}.
However,
\begin{lisp}
(typep foo '(array character))
\end{lisp}
is still not a legitimate test of whether the array
\cdf{foo} can hold a character; one must still say
\begin{lisp}
(subtypep 'character (array-element-type foo))
\end{lisp}
to determine that question.
As a general rule, a compiler would be justified in transforming
\begin{lisp}
(aref (the (array \emph{elt-type} ...) \emph{a}) ...)
\end{lisp}
into
\begin{lisp}
(the \emph{elt-type} (aref (the (array \emph{elt-type} ...) \emph{a}) ...)
\end{lisp}
It may also make inferences involving more complex functions,
such as \cdf{position} or \cdf{find}.
For example, \cdf{find} applied to an array always returns either \cdf{nil}
or an object whose type is the element type of the array.
\end{new}
\item[\cd{(simple-array \emph{element-type} \emph{dimensions})}]
This is equivalent
to \cd{(array \emph{element-type} \emph{dimensions})} except that it additionally
specifies that objects of the type are \emph{simple} arrays
(see section~\ref{ARRAY-TYPE-SECTION}).
\item[\cd{(vector \emph{element-type} \emph{size})}]
This denotes the set of
specialized one-dimensional arrays whose elements are all of type \emph{
element-type} and whose lengths match \emph{size}. This is entirely equivalent to
\cd{(array \emph{element-type} (\emph{size}))}.
For example:
\begin{lisp}
(vector double-float)~~~~~;\textrm{Vectors of double-format} \\
~~~~~~~~~~~~~~~~~~~~~~~~~~;~\textrm{floating-point numbers} \\
(vector * 5)~~~~~~~~~~~~~~;\textrm{Vectors of length 5} \\
(vector t 5)~~~~~~~~~~~~~~;\textrm{General vectors of length 5} \\
(vector (mod 32) *)~~~~~~~;\textrm{Vectors of integers between 0 and 31}
\end{lisp}
Type \cdf{string} is the union of one or more specialized vector
types, the types of whose elements are subtypes of the type \cdf{character}.
\item[\cd{(simple-vector \emph{size})}]
This is the same
as \cd{(vector t \emph{size})} except that it additionally specifies
that its elements are \emph{simple} general vectors.
\item[\cd{(complex \emph{type})}]
Every element of this type is a
complex number whose real part
and imaginary part are each of type \emph{type}.
For declaration purposes, this type encompasses those complex numbers
that can result by giving numbers of the specified type
to the function \cdf{complex}; this may be different
from what the type means for discrimination purposes.
As an example, Gaussian integers might be
described as \cd{(complex integer)}, even in implementations
where giving two integers to the function \cdf{complex} results
in an object of type \cd{(complex rational)}.
\begin{new}
X3J13 voted in January 1989
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS}
to change \cdf{typep} and \cdf{subtypep}
so that the specialized \cdf{complex}
type specifier means the same thing for discrimination purposes
as for declaration purposes.
See \cdf{upgraded-complex-part-type}.
\end{new}
\item[\cd{(function (\emph{arg1-type} \emph{arg2-type} ...) \emph{value-type})}]
\relax This type may be used only for declaration and not for
discrimination; \cdf{typep} will signal an error if it encounters a specifier of
this form. Every element of this type is
a function that accepts arguments at \emph{least} of the
types specified by the \emph{argj-type} forms and returns a value that is a
member of the types specified by the \emph{value-type} form. The
\cd{\&optional}, \cd{\&rest}, and \cd{\&key} markers
may appear in the list of argument types.
The \emph{value-type} may be a \cdf{values} type specifier
in order to indicate the types of multiple values.
The \emph{arg-type} that
follows a \cd{\&rest} marker indicates the type of each actual argument
that would be gathered into the list for a \cd{\&rest} parameter,
and not the type of the \cd{\&rest} parameter itself (which is always
\cdf{list}). Thus one might declare the function \cdf{gcd} to
be of type \cd{(function (\&rest~integer) integer)}, or
the function \cdf{aref} to be of type
\cd{(function (array \&rest fixnum) t)}.
A declaration specifier of the form
\begin{lisp}
(ftype (function (\emph{arg1-type} \emph{arg2-type} ... \emph{argn-type}) \emph{value-type}) \emph{fname})
\end{lisp}
implies that any function call of the form
\begin{lisp}
(\emph{fname} \emph{arg1} \emph{arg2} ...)
\end{lisp}
within the scope of the declaration can be treated as if it were
rewritten to use \cdf{the}-forms in the following manner:
\begin{lisp}
(the \emph{value-type} \\*
~~~~~(\emph{fname} \=(the \emph{arg1-type} \emph{arg1}) \\*
\>(the \emph{arg2-type} \emph{arg2}) \\*
\>... \\*
\>(the \emph{argn-type} \emph{argn})))
\end{lisp}
That is, it is an error for any of the actual arguments not to be of
its specified type \emph{arg-type} or for the result not to be of the specified
type \emph{value-type}. (In particular, if any argument is not of
its specified type, then the result is not guaranteed to be of the
specified type---if indeed a result is returned at all.)
Similarly, a declaration specifier of the form
\begin{lisp}
(type (function (\emph{arg1-type} \emph{arg2-type} ... \emph{argn-type}) \emph{value-type}) \emph{var})
\end{lisp}
is interpreted to mean that any reference to the variable \emph{var}
will find that its value is a function, and that
it is an error to call this function with any actual argument not of
its specified type \emph{arg-type}.
Also, it is an error for the result not to be of the specified
type \emph{value-type}.
For example, a function call of the form
\begin{lisp}
(funcall \emph{var} \emph{arg1} \emph{arg2} ...)
\end{lisp}
could be rewritten to use \cdf{the}-forms as well.
If any argument is not of
its specified type, then the result is not guaranteed to be of the
specified type---if indeed a result is returned at all.
Thus, a \cdf{type} or \cdf{ftype} declaration specifier describes type
requirements imposed on calls to a function
as opposed to requirements imposed on the definition of the function.
This is analogous to the treatment of type declarations of variables
as imposing type requirements on references to variables, rather than
on the contents of variables. See the vote of X3J13 on \cdf{type}
declaration specifiers in general, discussed
in section~\ref{DECLARATION-SPECIFIERS-SECTION}.
In the same manner as for variable type declarations in general,
if two or more
of these declarations apply to the same function call (which can
occur if declaration scopes are suitably nested), then they all apply;
in effect, the types for each argument or result are intersected.
For example, the code fragment
\begin{lisp}
(locally (declare (ftype (function (biped) digit) \\*
~~~~~~~~~~~~~~~~~~~~~~~~~butcher-fudge)) \\*
~~(locally (declare (ftype (function (featherless) opposable) \\*
~~~~~~~~~~~~~~~~~~~~~~~~~~~butcher-fudge)) \\*
~~~~(butcher-fudge sam)))
\end{lisp}
may be regarded as equivalent to
\begin{lisp}
(the opposable \\*
~~~~~(the digit (butcher-fudge (the featherless \\*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(the biped sam)))))
\end{lisp}
or to
\begin{lisp}
(the (and opposable digit) \\*
~~~~~(butcher-fudge (the (and featherless biped) sam)))
\end{lisp}
That is, \cdf{sam} had better be both \cdf{featherless} and a \cdf{biped},
and the result of \cdf{butcher-fudge} had better be both
\cdf{opposable} and a \cdf{digit}; otherwise the code is in error.
Therefore a compiler may generate code that relies on these type assumptions,
for example.
\item[\cd{(values \emph{value1-type} \emph{value2-type} ...)}]
This type specifier is extremely restricted: it may be used \emph{only}
as the \emph{value-type} in a \cdf{function} type specifier or in
a \cdf{the} special operator. It is used to specify individual types when
multiple values are involved.
The
\cd{\&optional}, \cd{\&rest}, and \cd{\&key} markers may appear in the
\emph{value-type} list;
they thereby indicate the parameter list of a
function that, when given to \cdf{multiple-value-call} along with
the values, would be suitable for receiving those values.
\end{flushdesc}
\section{Type Specifiers That Abbreviate}
The following type specifiers are, for the most part,
abbreviations for other type specifiers that would be far too
verbose to write out explicitly (using, for example, \cdf{member}).
\begin{flushdesc}
\item[\cd{(integer \emph{low} \emph{high})}]
Denotes the integers between
\emph{low} and \emph{high}. The limits \emph{low} and \emph{high}
must each be an integer, a list of an integer, or unspecified.
An integer is an inclusive limit,
a list of an integer is an exclusive limit, and
\cd{*} means that a limit does not exist
and so effectively denotes minus or plus infinity, respectively.
The type \cdf{fixnum} is simply a name
for \cd{(integer \emph{smallest} \emph{largest})} for implementation-dependent
values of \emph{smallest} and \emph{largest}
(see \cdf{most-negative-fixnum} and \cdf{most-positive-fixnum}).
The type \cd{(integer 0 1)}
is so useful that it has the special name \cdf{bit}.
\item[\cd{(mod \emph{n})}]
Denotes the set of non-negative integers less than \emph{n}.
This is equivalent to \cd{(integer 0 $n-1$)}
or to \cd{(integer 0 (\emph{n}))}.
\item[\cd{(signed-byte \emph{s})}]
Denotes the set of integers that can be represented
in two's-complement form in a byte of \emph{s} bits. This is
equivalent to
\cd{(integer $-2^{s-1}$ $2^{s-1}-1$)}.
Simply \cdf{signed-byte} or \cd{(signed-byte *)} is the same as \cdf{integer}.
\item[\cd{(unsigned-byte \emph{s})}]
Denotes the set of non-negative integers that can be
represented in a byte of \emph{s} bits. This is equivalent to \cd{(mod
$2^{s}$)}, that is, \cd{(integer 0 $2^{s}-1$)}.
Simply \cdf{unsigned-byte} or \cd{(unsigned-byte *)} is the same as
\cd{(integer 0 *)}, the set of non-negative integers.
\item[\cd{(rational \emph{low} \emph{high})}]
Denotes the rationals between
\emph{low} and \emph{high}. The limits \emph{low} and \emph{high}
must each be a rational, a list of a rational, or unspecified.
A rational is an inclusive limit,
a list of a rational is an exclusive limit, and
\cd{*} means that a limit does not exist
and so effectively denotes minus or plus infinity, respectively.
\item[\cd{(float \emph{low} \emph{high})}]
Denotes the set of floating-point numbers between
\emph{low} and \emph{high}. The limits \emph{low} and \emph{high}
must each be a floating-point number, a list of a floating-point number,
or unspecified; a floating-point number is an inclusive limit, a list of a
floating-point number is an exclusive limit, and
\cd{*} means that a limit does not exist
and so effectively denotes minus or plus infinity, respectively.
In a similar manner, one may use:
\begin{lisp}
(short-float \emph{low} \emph{high}) \\
(single-float \emph{low} \emph{high}) \\
(double-float \emph{low} \emph{high}) \\
(long-float \emph{low} \emph{high})
\end{lisp}
In this case, if a limit is a floating-point
number (or a list of one), it must be one of the appropriate format.
\item[\cd{(real \emph{low} \emph{high})}]
Denotes the real numbers between
\emph{low} and \emph{high}. The limits \emph{low} and \emph{high}
must each be a real, a list of a real, or unspecified.
A real is an inclusive limit,
a list of a real is an exclusive limit, and
\cd{*} means that a limit does not exist
and so effectively denotes minus or plus infinity, respectively.
\item[\cd{(base-string \emph{size})}]
Means the same as
\cd{(vector base-char \emph{size})}: the set of base
strings of the indicated size.
\item[\cd{(simple-base-string \emph{size})}]
Means the same
as \cd{(simple-array base-char (\emph{size}))}: the set of simple base
strings of the indicated size.
\item[\cd{(bit-vector \emph{size})}]
Means the same as \cd{(array bit (\emph{size}))}:
the set of bit-vectors of the indicated size.
\item[\cd{(simple-bit-vector \emph{size})}]
This means the same as
\cd{(simple-array bit (\emph{size}))}: the set of bit-vectors of
the indicated size.
\end{flushdesc}
\section{Defining New Type Specifiers}
New type specifiers can come into existence in two ways.
First, defining a new structure type with \cdf{defstruct} automatically
causes the name of the structure to be a new type specifier symbol.
Second, the \cdf{deftype} special operator can be used to define new type-specifier
abbreviations.
\begin{defmac}
deftype name lambda-list <{declaration}* | doc-string> {form}*
This is very similar to a \cdf{defmacro} form: \emph{name} is the
symbol that identifies the type specifier being defined, \emph{lambda-list} is
a lambda-list (and may contain \cd{\&optional} and \cd{\&rest}
markers), and
the \emph{forms} constitute the body of the expander function. If we view a
type specifier list as a list containing the type specifier name and some argument forms,
the argument forms (unevaluated) are bound to the corresponding
parameters in \emph{lambda-list}. Then the body forms are evaluated
as an implicit \cdf{progn}, and the value of the last form
is interpreted as a new type specifier for which the original specifier
was an abbreviation. The \emph{name} is returned as the value of the
\cdf{deftype} form.
\cdf{deftype} differs from \cdf{defmacro} in that if no \emph{initform}
is specified for an \cd{\&optional} parameter, the default value
is \cd{*}, not {\nil}.
If the optional documentation string \emph{doc-string} is present,
then it is attached to the \emph{name}
as a documentation string of type \cdf{type}; see \cdf{documentation}.
Here are some examples of the use of \cdf{deftype}:
\begin{lisp}
(deftype mod (n) {\Xbq}(integer 0 (,n))) \\
\\
(deftype list () '(or null cons))
\end{lisp}
%manual
\begin{lisp}
(deftype square-matrix (\cd{\&optional} type size) \\*
~~"SQUARE-MATRIX includes all square two-dimensional arrays." \\*
~~{\Xbq}(array ,type (,size ,size))) \\
\\
(square-matrix short-float 7) \textrm{means} (array short-float (7 7)) \\
\\
(square-matrix bit) \textrm{means} (array bit (* *))
\end{lisp}
\begin{lisp}
(deftype square-matrix (\cd{\&optional} type size) \\*
~~"SQUARE-MATRIX includes all square two-dimensional arrays." \\*
~~{\Xbq}(array ,type (,size ,size))) \\
\\
(square-matrix short-float 7) \textrm{означает} (array short-float (7 7)) \\
\\
(square-matrix bit) \textrm{означает} (array bit (* *))
\end{lisp}
If the type name defined by \cdf{deftype} is used simply as a type
specifier symbol, it is interpreted as a type specifier list with
no argument forms. Thus, in the example above, \cdf{square-matrix}
would mean \cd{(array * (* *))}, the set of two-dimensional arrays.
This would unfortunately fail to convey the constraint that the two
dimensions be the same; \cd{(square-matrix bit)} has the same problem.
A better definition is
\begin{lisp}
(defun equidimensional (a) \\
~~(or (< (array-rank a) 2) \\
~~~~~~(apply \#'= (array-dimensions a)))) \\
\\
(deftype square-matrix (\cd{\&optional} type size) \\
~~{\Xbq}(and (array ,type (,size ,size)) \\
~~~~~~~~(satisfies equidimensional)))
\end{lisp}
The body of the expander function defined
by \cdf{deftype} is implicitly enclosed in a \cdf{block} construct
whose name is the same as the \emph{name} of the defined type.
Therefore \cdf{return-from} may be used to exit from the function.
While defining forms normally appear at top level,
it is meaningful to place them in non-top-level contexts;
\cdf{deftype} must define the expander function
within the enclosing lexical environment, not within the global
environment.
\end{defmac}
\section{Type Conversion Function}
The following function may be used to convert an object to an
equivalent object of another type.
\begin{defun}[Function]
coerce object result-type
The \emph{result-type} must be a type specifier; the \emph{object} is converted
to an ``equivalent'' object of the specified type.
If the coercion cannot be performed, then an error is signaled.
In particular, \cd{(coerce x 'nil)} always signals an error.
If \emph{object} is already of the specified type, as determined
by \cdf{typep}, then it is simply returned.
It is not generally
possible to convert any object to be of any type whatsoever; only certain
conversions are permitted:
\begin{itemize}
\item
Any sequence type may be converted to any other sequence type, provided
the new sequence can contain all actual elements of the old sequence
(it is an error if it cannot). If the \emph{result-type} is specified as
simply \cdf{array}, for example, then \cd{(array t)} is assumed. A
specialized type such as \cdf{string} or \cd{(vector (complex short-float))}
may be specified; of course, the result may be of either that type or
some more general type, as determined by the implementation.
Elements of the new sequence will be \cdf{eql} to corresponding elements
of the old sequence.
If the
\emph{sequence} is already of the specified type, it may be returned without
copying it; in this, \cd{(coerce \emph{sequence} \emph{type})} differs from
\cd{(concatenate \emph{type} \emph{sequence})}, for the latter is required to
copy the argument \emph{sequence}. In particular, if one specifies
\cdf{sequence}, then the argument may simply be returned if it already is
a \cdf{sequence}.
\begin{lisp}
(coerce '(a b c) 'vector) \EV\ \#(a b c)
\end{lisp}
\cdf{coerce} should signal an error if the new sequence type specifies the
number of elements and the old sequence has a different length.
If the \emph{result-type} is \cdf{string}
then it is understood to mean \cd{(vector character)},
and \cdf{simple-string} is understood to mean \cd{(simple-array character (*))}.
\item
Any non-complex number can be converted to a \cdf{short-float},
\cdf{single-float}, \cdf{double-float}, or \cdf{long-float}. If simply \cdf{float}
is specified, and \emph{object} is not already a \cdf{float} of some kind, then
the object is converted to a \cdf{single-float}.
\begin{lisp}
(coerce 0 'short-float) \EV\ 0.0S0 \\
(coerce 3.5L0 'float) \EV\ 3.5L0 \\
(coerce 7/2 'float) \EV\ 3.5
\end{lisp}
\item
Any number can be converted to a complex number.
If the number is not already complex, then a zero imaginary part
is provided by coercing the integer zero to the type of the given real part.
(If the given real part is rational, however, then the rule of
canonical representation for complex rationals will result
in the immediate re-conversion of the result from type \cdf{complex}
back to type \cdf{rational}.)
\begin{lisp}
(coerce 4.5s0 'complex) \EV\ \#C(4.5S0 0.0S0) \\
(coerce 7/2 'complex) \EV\ 7/2 \\
(coerce \#C(7/2 0) '(complex double-float)) \\
~~~\EV\ \#C(3.5D0 0.0D0)
\end{lisp}
\item
Any object may be coerced to type \cdf{t}.
\begin{lisp}
(coerce x 't) \EQ\ (identity x) \EQ\ x
\end{lisp}
\item
A symbol or lambda-expression can be converted to a function.
A symbol is coerced to type \cdf{function} as if by applying
\cdf{symbol-function} to the symbol; an error is signaled if the predicate
\cdf{fboundp} is not true of
the symbol or if the symbol names a macro or special operator.
A list \emph{x} whose \emph{car} is the symbol \cdf{lambda}
is coerced to a function as if by execution of \cd{(eval {\Xbq}\#',\emph{x})},
that is, of \cd{(eval (list 'function~\emph{x}))}.
\end{itemize}
Coercions from floating-point numbers to rationals and from ratios
to integers are purposely \emph{not} provided because of rounding
problems. The functions \cdf{rational}, \cdf{rationalize},
\cdf{floor}, \cdf{ceiling}, \cdf{truncate}, and \cdf{round} may be used for
such purposes. Similarly, coercions from characters to integers
are purposely not provided; \cdf{char-code} or \cdf{char-int} may be
used explicitly to perform such conversions.
\end{defun}
\section{Determining the Type of an Object}
The following function may be used to obtain a type specifier
describing the type of a given object.
\begin{defun}[Function]
type-of object
There are the following constraints on \cdf{type-of}:
\begin{itemize}
\item
Let \emph{x} be an object such that \cd{(typep~\emph{x}~\emph{type})}
is true and \emph{type} is one of the following:
\begin{flushleft}
\cf
\begin{tabular}{@{}llll@{}}
array & float & package & sequence \\
bit-vector & function & pathname & short-float \\
character & hash-table & random-state~~ & single-float \\
complex & integer & ratio & stream \\
condition & long-float~~ & rational & string \\
cons & null & readtable & symbol \\
double-float~~ & number & restart & vector
\end{tabular}
\end{flushleft}
Then
\cd{(subtypep (type-of \emph{x}) \emph{type}))}
must return the values \cdf{t} and \cdf{t}; that is, \cdf{type-of} applied
to \emph{x} must return either \emph{type} itself or a subtype of \emph{type}
that \cdf{subtypep} can recognize in that implementation.
\item
For any object \emph{x}, \cd{(subtypep (type-of \emph{x}) (class-of \emph{x}))}
must produce the values \cdf{t} and \cdf{t}.
\item
For every object \emph{x}, \cd{(typep \emph{x} (type-of \emph{x}))}
must be true. (This implies that \cdf{type-of} can never return \cdf{nil},
for no object is of type \cdf{nil}.)
\item
\cdf{type-of} never returns \cdf{t} and never uses
a \cdf{satisfies}, \cdf{and}, \cdf{or}, \cdf{not},
or \cdf{values} type specifier in its result.
\item
For objects of CLOS metaclass \cdf{structure-class} or of \cdf{standard-class},
\cdf{type-of} returns the proper name of the class returned by \cdf{class-of}
if it has a proper name, and otherwise returns the class itself.
In particular,
for any object created by a \cdf{defstruct} constructor function,
where the \cdf{defstruct} had the name \emph{name} and no \cd{:type} option,
\cdf{type-of} will return \emph{name}.
\end{itemize}
As an example, \cd{(type-of "acetylcholinesterase")}
may return \cdf{string} or \cdf{simple-string} or \cd{(simple-string ~20)},
but not \cdf{array} or \cdf{simple-vector}.
As another example, it is permitted for
\cd{(type-of 1729)} to return
\cdf{integer} or \cdf{fixnum} (if it is indeed a fixnum) or
\cd{(signed-byte 16)} or \cd{(integer 1729 1729)} or \cd{(integer 1685 1750)}
% Bach's "St. Matthew Passion"
or even \cd{(mod 1730)}, but not \cdf{rational} or \cdf{number}, because
\begin{lisp}
(typep (+ (expt 9 3) (expt 10 3)) 'integer)
\end{lisp}
is true, \cdf{integer} is in the list of types mentioned above, and
\begin{lisp}
(subtypep (type-of (+ (expt 1 3) (expt 12 3))) 'integer)
\end{lisp}
would be false if \cdf{type-of} were to return \cdf{rational} or \cdf{number}.
% Ramanujan and Hardy?
\end{defun}
\section{Type Upgrading}
There are functions by which a program
can determine, in a given Common Lisp implementation, how that
implementation will \emph{upgrade} a type when constructing an array
specialized to contain elements of that type,
or a complex number specialized to contain parts of that type.
\begin{defun}[Function]
upgraded-array-element-type type
A type specifier is returned, indicating the element type
of the most specialized array representation capable of holding
items of the specified argument \emph{type}.
The result is necessarily a supertype of the given \emph{type}.
Furthermore, if a type \emph{A} is a subtype of type \emph{B}, then
\cd{(upgraded-array-element-type \emph{A})} is a subtype of
\cd{(upgraded-array-element-type \emph{B})}.
The manner in which an array element type is upgraded depends
only on the element type as such and not on any other property of
the array such as size, rank, adjustability,
presence or absence of a fill pointer, or displacement.
\beforenoterule
\begin{rationale}
If upgrading were allowed to depend on any of these properties,
all of which can be referred to, directly or indirectly, in the
language of type specifiers, then it would not be possible
to displace an array in a consistent and dependable manner
to another array created with the same \cd{:element-type} argument
but differing in one of these properties.
\end{rationale}
\afternoterule
Note that \cdf{upgraded-array-element-type} could be defined as
\begin{lisp}
(defun upgraded-array-element-type (type) \\
~~(array-element-type (make-array 0 :element-type type)))
\end{lisp}
but this definition has the disadvantage of allocating an array and
then immediately discarding it. The clever implementor surely can
conjure up a more practical approach.
\end{defun}
\begin{defun}[Function]
upgraded-complex-part-type type
A type specifier is returned, indicating the element type
of the most specialized complex number representation capable of having
parts of the specified argument \emph{type}.
The result is necessarily a supertype of the given \emph{type}.
Furthermore, if a type \emph{A} is a subtype of type \emph{B}, then
\cd{(upgraded-complex-part-type \emph{A})} is a subtype of
\cd{(upgraded-complex-part-type \emph{B})}.
\end{defun}
\else %RUSSIAN
\chapter{Спецификаторы типов} % Avoid ligature
\label{DTSPEC}
В Common Lisp'е типы указываются с помощью символов и списков. Они называются
\emph{спецификаторами типов}. Символы задают
предопределённые классы объектов, тогда как списки обычно указывают на
комбинации или уточнения простых типов.
Символы и списки могут быть также аббревиатурами для других типов.
\section{Символы как спецификаторы типов}
Символы для типов жестко заданы системой, включая те, что перечислены в
таблице~\ref{TYPE-SYMBOLS-TABLE}.
Когда определяется структура с использованием \cdf{defstruct}, имя
структуры также автоматически становиться типом.
\section{Списки как спецификаторы типов}
Если типа задаётся списком, \emph{car} элемент данного списка является
символом, и остаток списка --- вспомогательной информацией. В большинстве случаев
вспомогательная информация может быть \emph{неопределена}. Неопределённая
дополнительная информация указывается с помощью \cd{*}. Например, для полного
описания векторного типа, должны быть указаны тип элементов и их количество: