LOOP type declaration issue

Bug #365497 reported by Nikodemus Siivola
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Confirmed
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.

Tags: loop
Changed in sbcl:
importance: Undecided → Medium
status: New → Confirmed
Revision history for this message
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.

Revision history for this message
Eugene Ossintsev (eugoss-deactivatedaccount) wrote :

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)
description: updated
Revision history for this message
Michał "phoe" Herda (phoe-krk) wrote :

----------------

(declaim (optimize (safety 0)))

(lambda ()
  (loop for x of-type fixnum
        from (1- most-positive-fixnum) to most-positive-fixnum
        do (progn)
        finally (print x)))

(compile nil *)

(funcall *)

----------------

The above loops even though it is conforming ANSI CL.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.