Download CMUCL User`s Manual - Common

Transcript
CHAPTER 4. THE COMPILER
4.5
69
Types in Python
A big difference between Python and all other Common Lisp compilers is the approach to type checking and
amount of knowledge about types:
• Python treats type declarations much differently that other Lisp compilers do. Python doesn’t blindly
believe type declarations; it considers them assertions about the program that should be checked.
• Python also has a tremendously greater knowledge of the Common Lisp type system than other compilers. Support is incomplete only for the not, and and satisfies types.
See also sections 5.2 and 5.3.
4.5.1
Compile Time Type Errors
If the compiler can prove at compile time that some portion of the program cannot be executed without a type
error, then it will give a warning at compile time. It is possible that the offending code would never actually
be executed at run-time due to some higher level consistency constraint unknown to the compiler, so a type
warning doesn’t always indicate an incorrect program. For example, consider this code fragment:
(defun raz (foo)
(let ((x (case foo
(:this 13)
(:that 9)
(:the-other 42))))
(declare (fixnum x))
(foo x)))
Compilation produces this warning:
In: DEFUN RAZ
(CASE FOO (:THIS 13) (:THAT 9) (:THE-OTHER 42))
--> LET COND IF COND IF COND IF
==>
(COND)
Warning: This is not a FIXNUM:
NIL
In this case, the warning is telling you that if foo isn’t any of :this, :that or :the-other, then x will be initialized
to nil, which the fixnum declaration makes illegal. The warning will go away if ecase is used instead of case,
or if :the-other is changed to t.
This sort of spurious type warning happens moderately often in the expansion of complex macros and in
inline functions. In such cases, there may be dead code that is impossible to correctly execute. The compiler
can’t always prove this code is dead (could never be executed), so it compiles the erroneous code (which will
always signal an error if it is executed) and gives a warning.
extensions:required-argument
[Function]
This function can be used as the default value for keyword arguments that must always be supplied. Since it
is known by the compiler to never return, it will avoid any compile-time type warnings that would result from
a default value inconsistent with the declared type. When this function is called, it signals an error indicating
that a required keyword argument was not supplied. This function is also useful for defstruct slot defaults
corresponding to required arguments. See section 5.2.5, page 80.
Although this function is a CMUCL extension, it is relatively harmless to use it in otherwise portable code,
since you can easily define it yourself:
(defun required-argument ()
(error "A required keyword argument was not supplied."))