Next: Arguments/Values passing, Previous: Variable allocations, Up: Declarations
Some built-in Common-Lisp functions can directly operate on raw data, if
appropriate declarations are supplied. The addition function +
is among
such functions.
(let ((x 1)) (declare (fixnum x)) ... (setq x (+ x 2)) ... )
In the compiled code for this let
form, the raw fixnum datum (i.e., the
32 bit signed integer) stored in x is simply incremented by 2 and the
resulting 32 bit signed integer is stored back into x. The compiler is
sure that the addition for 32 bit signed integers will be performed on the call
to +
, because the arguments are both fixnums and the return value must
be also a fixnum since the value is to be assigned to the fixnum
variable. The knowledge of both the argument types and the return type is
necessary for this decision: Addition of two fixnums may possibly produce a
bignum and addition of two bignums may happen to produce a fixnum value. If
either the argument type or the return type were not known to the compiler, the
general addition function would be called to handle the general case. In the
following form, for example, the compiler cannot be sure that the return value
of the multiplication is a fixnum or that the arguments of the addition are
fixnums.
(setq x (+ (* x 3) 2))
In order to obtain the optimal code, a the
special form should
surround the multiplication.
(setq x (+ (the fixnum (* x 3)) 2))
Built-in Common-Lisp functions that can directly operate on raw data are:
+
, -
,
1+
, 1-
, *
, floor
, mod
, /
, and
expt
.
eq
, eql
, equal
,
zerop
, plusp
, minusp
, =
, /=
, <
,
<=
, >
, >=
, char=
, char/=
, char<
,
char<=
, char>
, and char>=
.
nth
, nthcdr
, length
, and
elt
.
svref
, char
, schar
,
and aref
(see below).
char-code
, code-char
,
and float
.
As mentioned in Section 2.5.1, array elements are represented in one of six ways depending on the type of the array. By supplying appropriate array type declarations, array access and update operations can handle raw data stored in arrays. For example,
(let ((a (make-array n :element-type 'fixnum)) (sum 0)) (declare (type (array fixnum) a) (fixnum sum)) (dotimes (i n) ;;; Array initialization. (declare (fixnum i)) (setf (aref a i) i)) .... (dotimes (i n) ;;; Summing up the elements. (declare (fixnum i)) (setq sum (+ (aref a i) sum))) .... )
The setf
form replaces the i-th
element of the array a by the raw
fixnum value of i
. The aref
form retrieves the raw fixnum datum
stored in a
. This raw datum is then added to the raw fixnum value of
the fixnum variable sum
, producing the raw fixnum datum to be stored in
sum
. Similar raw data handling is possible for arrays of types
(array fixnum), (vector fixnum),
(array string-char), string,
(array short-float), (vector short-float),
(array long-float)
, and (vector long-float)
.