From: "Juanma Barranquero" <laley-actualidad.es at barranquero>
On 03 May 1999 17:04:39 UT, Erik Naggum wrote:
> (INTEGER 0 10) is actually a very specific subtype of FIXNUM.
Yes, you're right, of course.
> try (setq excl::*loop-real-data-type* 'fixnum) and see if you win.
Yes, that works for fixnum loop counters (as is the case in "repeat"
loops). Thanks.
I recommend against playing with this internal parameter! Changing it
as Eric recommends would likely cause certain other legal loop forms
to miscompile.
Yes, I've looked into it. What I find surprising is that I'd suppose
(loop for i from 1 to n do...)
or
(loop repeat n do...)
with a (fixnum-sized) integer "n" are a lot more usual than
(loop for i from 1.0 to 10.0 do...)
or
(loop repeat 10.0 do...)
or similar. So I would've expected for the loop macro to detect if
it's using statically defined fixnum constants and act as appropriate.
Yes, it should. Ideally, the compiler's type propagator (which
happens long after macroexpansion) would be able to infer the correct
type limits, in in fact the current propagator is not strong enough.
So, instead the LOOP repeat handler could be tweaked (IMO quite safely
and efficiently) to recognize the common case of an integer constant
in a repeat clause. If, as Erik suggests, you have the sources, you
could accomplish this by adding the capitalized form below. However,
it would be better for you to pass this suggestion on to
<franz.com at bugs> so the suggested change can be checked and integrated
into the official sources.
(defun loop-do-repeat ()
(let ((form (loop-get-form))
(type (loop-check-data-type (loop-optional-type) *loop-real-data-type*)))
(when (and (consp form) (eq (car form) 'the) (subtypep (second form) type))
(setq type (second form)))
(multiple-value-bind (number constantp value)
(loop-constant-fold-if-possible form type)
(cond ((and constantp (<= value 1)) `(t () () () ,(<= value 0) () () ()))
(t (WHEN (AND CONSTANTP (INTEGERP VALUE)) ; smh 4May99
(SETQ TYPE `(INTEGER 0 ,VALUE)))
(let ((var (loop-make-variable (loop-gentemp 'loop-repeat-) number type)))
(if constantp
`((not (plusp (setq ,var (1- ,var)))) () () () () () () ())
`((minusp (setq ,var (1- ,var))) () () ()))))))))