Thomas Fischbacher <[EMAIL PROTECTED]> writes:
> You might want to have a look at my with-arith-defs macro. (Just google for
> it.)
Looks interesting. I'll have to take a more careful look.
> > Added a declaration after the definition of s helps. The following
> > doesn't generate any notes:
> >
> > (defun sumn (n)
> > (declare (type (integer 0 10000) n))
> > (let ((s 0))
> > (declare (type (integer 0 200000000) s))
> > (dotimes (i n)
> > (incf s i))
> > s))
>
> Uh, shouldn't i be declared fixnum as well?
It seems that in cmucl, dotimes includes a declaration for the iteration
variable:
* (macroexpand-1 '(dotimes (i 100) (incf j i)))
(DO ((I 0 (1+ I)))
((>= I 100) NIL)
(DECLARE (TYPE (INTEGER 0 100) I))
(INCF J I))
T
* (setq n 1000)
Warning: Declaring N special.
1000
* (macroexpand-1 '(dotimes (i n) (incf j i)))
(DO ((I 0 (1+ I))
(#:G841 N))
((>= I #:G841) NIL)
(DECLARE (TYPE UNSIGNED-BYTE I))
(INCF J I))
T
Evidentally, when the number of iterations is a constant X, it
declares it to be of type (integer 0 X), and otherwise declares it to
be of type unsigned-byte. So I have to leave the decls out.
Otherwise the compiler essentially complains about an incompatible
redefinition.
This actually leads to a problem. The dotimes macro is essentially
adding an assertion about the iterator that doesn't necessarily hold,
and its existence prevents me from putting in a better declaration.
So, for example, in the bsmc function, when I declare the iterators to
be type (integer 1 1000000), I get compiler warnings that the bindings
aren't of this type. However, when I don't declare them, I instead
end up with generic comparisons:
In: DEFUN BSMC
(DOTIMES (I TRIALS)
(LET (#)
(DECLARE #)
(DOTIMES # #)
(INCF SUMVAL #)))
--> DO BLOCK LET TAGBODY UNLESS COND IF NOT IF >= IF
==>
(< I #:G0)
Note: Forced to do GENERIC-< (cost 10).
Unable to do inline fixnum comparison (cost 4) because:
The first argument is a UNSIGNED-BYTE, not a FIXNUM.
--> DO BLOCK LET TAGBODY PSETQ LET 1+
==>
(+ I 1)
Note: Forced to do GENERIC-+ (cost 10).
Unable to do inline fixnum arithmetic (cost 1) because:
The first argument is a UNSIGNED-BYTE, not a FIXNUM.
The result is a (INTEGER 1), not a FIXNUM.
Unable to do inline fixnum arithmetic (cost 2) because:
The first argument is a UNSIGNED-BYTE, not a FIXNUM.
The result is a (INTEGER 1), not a FIXNUM.
etc.
(CALLPAY (* S0 (EXP #)) K)
Note: Doing float to pointer coercion (cost 13).
[Last message occurs 2 times]
How should declarations be handled with dotimes? Or should I just
redefine it to not include a declaration? It seems like the
declaration being added isn't optimal.
--
Harvey Stein
Bloomberg LP
[EMAIL PROTECTED]