A "declare" form returned by macro
Posted: Tue Dec 30, 2008 5:23 am
After xmas, I started to write my first code in Common Lisp. I started with the following function:
Of course, the function above is supposed to make a new 1-d array of fixnum values, filled with the given initial element.
Soon it becomes obvious to me, that I'll use the declare forms a lot in my code. So, I decided to write the following macro:
Now, I could replace the form:
with the following line:
At least, I thought so... Common Lisp compiler told me I was doing something wrong:
I have to admit, that I don't get it. AFAIK (or, to be more precise, as far as I get the concept of macros in CL), the macro is expanded to some form at the compile time, and that form is then evaluated. The macro I wrote expands to the right form (I checked it with macroexpand-1), so what's the problem, mr CL compiler?
Perhaps the problem is that the "declare" form shouldn't be evaluated (it's an information for CL compiler), and CL compiler tries to evaluate it, so both "declare" and "type" are treated as functions. If this is the case, how can I define syntax for (decltype (fixnum var*))?
Code: Select all
(defun fixvect (f_len f_initEl)
(declare (type fixnum f_len)
(type fixnum f_initEl))
(make-array (list f_len) :element-type 'fixnum :initial-element f_initEl))
Soon it becomes obvious to me, that I'll use the declare forms a lot in my code. So, I decided to write the following macro:
Code: Select all
(defmacro decltype (&rest lst)
(defun type-collect (lst)
;;; (some-type a b c) -> ( (type some-type a) (type some-type b)
;;; (type some-type c) )
(let ( (typ (car lst))
(vars (cdr lst)) )
(loop for var in vars collect `(type ,typ ,var))))
(let ( (type-list nil) )
(loop for lstInt in lst do
(setf type-list (append type-list (type-collect lstInt))))
`(declare ,@type-list)))
Code: Select all
(declare (type fixnum f_len)
(type fixnum f_initEl))
Code: Select all
(decltype (fixnum f_len f_initEl))
Code: Select all
; in: LAMBDA NIL
; (DECLTYPE (FIXNUM F_LEN F_INITEL))
;
; caught STYLE-WARNING:
; (in macroexpansion of (DECLTYPE (FIXNUM F_LEN F_INITEL)))
; (hint: For more precise location, try *BREAK-ON-SIGNALS*.)
; redefining TYPE-COLLECT in DEFUN
; in: LAMBDA NIL
; (DECLTYPE (FIXNUM F_LEN F_INITEL))
; ==>
; (DECLARE (TYPE FIXNUM F_LEN) (TYPE FIXNUM F_INITEL))
;
; caught WARNING:
; There is no function named DECLARE. References to DECLARE in some contexts
; (like starts of blocks) have special meaning, but here it would have to be a
; function, and that shouldn't be right.
; --> DECLARE
; ==>
; (TYPE FIXNUM F_LEN)
;
; caught WARNING:
; undefined variable: FIXNUM
;
; caught WARNING:
; The function TYPE is undefined, and its name is reserved by ANSI CL so that
; even if it were defined later, the code doing so would not be portable.
;
; caught WARNING:
; This variable is undefined:
; FIXNUM
;
; caught STYLE-WARNING:
; These functions are undefined:
; DECLARE TYPE
;
; compilation unit finished
; caught 4 WARNING conditions
; caught 2 STYLE-WARNING conditions
Perhaps the problem is that the "declare" form shouldn't be evaluated (it's an information for CL compiler), and CL compiler tries to evaluate it, so both "declare" and "type" are treated as functions. If this is the case, how can I define syntax for (decltype (fixnum var*))?