Next: Type specifiers, Previous: Declarations, Up: Declarations
ECL recognizes all declaration specifiers defined in [see Steele:84].
The syntax of each such declaration specifier is exactly the same as defined in
[see Steele:84]. In addition, ECL recognizes the object
declaration specifier which is specific to ECL.
The interpreter and the compiler of ECL both treat special declarations exactly as described in [see Steele:84].
A
typeproclamation(typetype var1 var2...)specifies that the dynamic values of the named variables are of the type type. A localtypedeclaration specifies that the variables mentioned are bound by the surrounding construct and have values of the type type during execution of the surrounding construct. The compiler issues a warning if one of the named variables is not bound by the surrounding construct. The information given bytypedeclarations is used by the compiler to optimize the compiled code. The behavior of the compiled code is unpredictable if a wrongtypedeclaration is supplied. The compiler detects certain wrongtypedeclarations at compile time.
For example,
>(defun foo (x y) (declare (fixnum x) (character y)) (setq x y) ...)) foo >(compile 'foo) ; (defun foo ...) is being compiled. ;; Warning: Type mismatches between x and y.
See Section 7.3 for further information on type declarations.
(type var1 var2 ...) is equivalent to
(typetype var1 var2...), provided that type is one of the symbols in Table 4-1 of [see Steele:84], other thanfunction. Declaration specifications that begin withfunctionare regarded asfunctiondeclarations (see below).
A
functiondeclaration is used to obtain type information for function call forms. That is, afunctiondeclaration specifies the argument and the return types of each form that calls the named function.
(defun foo ()
(declare (function bar (character) fixnum))
(+ (bar (atcholi1)) (bar (atcholi2))))
In this example, the function declaration specifies that the two
functions atcholi1 and atcholi2 both return character objects
when called within the body of foo, and that the function bar returns
fixnum objects when called within the body of foo. The type information
given by function declarations is used by the compiler to optimize the compiled
code. The behavior of the compiled code is unpredictable if a wrong
function declaration is supplied. The compiler detects certain wrong
function declarations at compile time.
For example,
>(defun foo (x)
(declare (fixnum x)
(function bar (character) fixnum))
(bar x))
foo
>(compile 'foo)
; (defun foo ...) is being compiled.
;; Warning: The type of the form x is not character.
However, the compiler does not check the number of arguments, and thus, the following function definition will be compiled successfully without any warnings.
(defun foo ()
(declare (function bar (character character) fixnum))
(+ (bar (atcholi1)) (bar (atcholi2) (atcholi3) (atcholi4))))
For this definition, the compiler assumes that the three functions
atcholi1, atcholi2, and atcholi3 will return fixnum
objects. The return type of atcholi4 is unknown at compile time.
The complete syntax of a function declaration is:
(function function-name
({type}* [{&optional | &rest | &key} {thing}*])
{(values {type}* ) | {type}*}
)
Although &optional, &rest, and &key markers may appear in the list of
argument types, only those types are recognized that appear before any
such markers and the rest of the list is simply ignored. Note that functions
with &optional, &rest, or &key parameters may still be declared by
function declarations because of the use of function declarations
mentioned above.
The values construct in the specification of return types is almost
useless: (function function-name argument-types (values
type1 type2 ...)) is equivalent to (function
function-name argment-types type1 type2 ...).
See Section 7.3 for further information on function declarations.
function-type must be a list whose first element is the symbol
function.(ftype (function .rest)function-name-1...function-name-n)is equivalent to n consecutivefunctiondeclarations(functionfunction-name-1.rest)...(functionfunction-name-n.rest).
(notinlinefunction1 function2...)specifies that the compiler should not compile the named functions in-line. Calls to the named functions can be traced and an event (see Section 5.4) is pushed on the event stack when any one of the named functions is invoked.
An
inlineproclamation cancels currently effectivenotinlineproclamations, and a localinlinedeclaration locally shadows currently effectivenotinlinedeclarations.
>(defun foo (x)
(cons (car x)
(locally (declare (inline car)) (car x))))
foo
>(defun bar (x)
(cons (car x)
(locally (declare (inline car)) (car x))))
foo
>(proclaim '(notinline car))
nil
>(compile 'foo)
...
>(proclaim '(inline car))
nil
>(compile 'bar)
...
Usually, primitive functions such as car are compiled in-line.
Therefore, in this example, only the first call to car within foo
is compiled not in-line.
In general, the ECL compiler compiles functions in-line whenever possible.
Thus an inline declaration (inline function1 function2 ...)
is worthless if none of the named functions have previously been declared to be
notinline.
Usually, the compiler issues a warning if a lexical variable is never referred to.
(ignorevar1 ... varn)causes the compiler not to issue a warning even if the named variables are never referred to. The compiler issues a warning if one of the named variables is not bound by the surrounding construct, or if a named variable is actually referred to.ignoreproclamations are simply ignored.
ECL supports the four
optimizequalities listed in the [see Steele:84].
speedandcompilation-speedare used to set up the optimization switch of the C language compiler which is invoked to compile the C-language code generated by the ECL compiler (see Chapter 6).(optimize (speedn))and(optimize (compilation-speedm))are equivalent, where n and m are integers between 0 and 3, and m is equal to 3-n. When a ECL session is started, thespeedquality is set to 3. That is, by default, the compiler generates the fastest code in the longest compilation time. Thespacequality specifies whether the code size is important or not: The compiled code is a little bit larger and faster when compiled with the space quality 0, than when compiled with the space quality 1, 2, or 3. When a ECL session is started, thespacequality is set to 0. Thesafetyquality determines how much runtime error checking code should be embedded in the compiled code. If thesafetyquality is 0, the compiled code scarcely does runtime error checking. If thesafetyquality is 1, then the compiled code for a function will check the number of arguments to the function at runtime. If thesafetyquality is 2 or 3, then the compiled code does full runtime error checking. In addition, the highest quality value 3 causes the compiler to treat all functions as if they were declared to benotinline. When a ECL session is started, thesafetyquality is set to 0.
A
declarationdeclaration is used exactly as specified in the [see Steele:84].
This is the only declaration specifier that is specific to ECL.
(objectvar1 ... varn)affects only variable bindings and specifies that the named variables can be allocated in the C stack (see Section 7.3). The compiler issues a warning if one of the named variables is not bound by the surrounding construct.objectproclamations are simply ignored.