Steel Bank Common Lisp

LOOP type declaration issue

Reported by Nikodemus Siivola on 2009-04-23
2
Affects Status Importance Assigned to Milestone
SBCL
Medium
Unassigned

Bug Description

Reported by Stas Boukarev on sbcl-devel.

(loop for i from most-negative-fixnum to most-positive-fixnum
      count i))

expands into

(BLOCK NIL
  (LET ((I MOST-NEGATIVE-FIXNUM))
    (DECLARE (TYPE (AND REAL NUMBER) I))
    (LET ((#:LOOP-SUM-899 0))
      (DECLARE (TYPE FIXNUM #:LOOP-SUM-899))
      (SB-LOOP::LOOP-BODY NIL
                          (NIL NIL
                           (WHEN (> I '536870911) (GO SB-LOOP::END-LOOP)) NIL)
                          ((WHEN I (SETQ #:LOOP-SUM-899 (1+ #:LOOP-SUM-899))))
                          (NIL (SB-LOOP::LOOP-REALLY-DESETQ I (1+ I))
                           (WHEN (> I '536870911) (GO SB-LOOP::END-LOOP)) NIL)
                          ((RETURN-FROM NIL #:LOOP-SUM-899))))))

Where counter has type FIXNUM even though the count becomes a bignum.

Note also the (AND REAL NUMBER) declaration for I: smarter placement of the termination test would allow a FIXNUM declaration there.

Changed in sbcl:
importance: Undecided → Medium
status: New → Confirmed
Nikodemus Siivola (nikodemus) wrote :

CLHS says about LOOP COUNT:

"The count construct counts the number of times that the supplied form returns true. The argument var accumulates the number of occurrences; if var is supplied, loop does not return the final count automatically. The var argument is bound as if by the construct with to a zero of the appropriate type. Subsequent values (including any necessary coercions) are computed as if by the function 1+. If into var is used, a type can be supplied for var with the type-spec argument; the consequences are unspecified if a nonnumeric type is supplied. If there is no into variable, the optional type-spec argument applies to the internal variable that is keeping the count. The default type is implementation-dependent; but it must be a supertype of type fixnum."

So FIXNUM appears to be a legal assumption, actually. Suboptimal, but legal.

By the way, in Clozure CL 1.4 it's also FIXNUM.

(BLOCK NIL
  (LET ((I MOST-NEGATIVE-FIXNUM))
    (DECLARE (TYPE NUMBER I))
    (LET ((#:LOOP-SUM-0 0))
      (DECLARE (TYPE FIXNUM #:LOOP-SUM-0))
      (ANSI-LOOP::LOOP-BODY NIL
                            (NIL NIL NIL NIL)
                            ((WHEN I (SETQ #:LOOP-SUM-0 (1+ #:LOOP-SUM-0))))
                            (NIL (ANSI-LOOP::LOOP-REALLY-DESETQ I (1+ I))
                                 (WHEN (> I '1152921504606846975)
                                   (GO ANSI-LOOP::END-LOOP))
                                 NIL)
                            ((RETURN-FROM NIL #:LOOP-SUM-0))))))

Stas Boukarev (stassats) on 2010-01-18
description: updated
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers