如何在 Common Lisp 中输入 DO 变量?

kws*_*wsp 2 common-lisp

我知道你可以声明函数参数类型,例如

(defun add-integer (a b)
  (declare (integer a b))
  (the integer (+ a b)))
Run Code Online (Sandbox Code Playgroud)

但是 DO 变量呢?例如,我想输入passes

(defun bench ()
  (do ((end (+ (get-internal-real-time) (* 5 internal-time-units-per-second)))
       (passes 0 (+ 1 passes)))
      ((> (get-internal-real-time) end)
       passes)
    (sieve 1000000)))
Run Code Online (Sandbox Code Playgroud)

当我尝试使用 进行编译时(declaim (optimize (speed 2) (safety 0))),我得到

; in: DEFUN BENCH
;     (1+ PASSES)
; 
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a UNSIGNED-BYTE, not a FIXNUM.
;       The result is a (VALUES (INTEGER 1) &OPTIONAL), not a (VALUES FIXNUM
;                                                                     &REST T).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a UNSIGNED-BYTE, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES (INTEGER 1) &OPTIONAL), not a (VALUES
;                                                              (UNSIGNED-BYTE 64)
;                                                              &REST T).
Run Code Online (Sandbox Code Playgroud)

我试过

; in: DEFUN BENCH
;     (1+ PASSES)
; 
; note: forced to do full call
;       unable to do inline fixnum arithmetic (cost 2) because:
;       The first argument is a UNSIGNED-BYTE, not a FIXNUM.
;       The result is a (VALUES (INTEGER 1) &OPTIONAL), not a (VALUES FIXNUM
;                                                                     &REST T).
;       unable to do inline (unsigned-byte 64) arithmetic (cost 5) because:
;       The first argument is a UNSIGNED-BYTE, not a (UNSIGNED-BYTE 64).
;       The result is a (VALUES (INTEGER 1) &OPTIONAL), not a (VALUES
;                                                              (UNSIGNED-BYTE 64)
;                                                              &REST T).
Run Code Online (Sandbox Code Playgroud)

但后来我明白了

;   Undefined variable:
;     PASSES
Run Code Online (Sandbox Code Playgroud)

我在 HyperSpec 的类型章节中找不到任何相关内容,例如(http://clhs.lisp.se/Body/04_bc.htm)。一个有效的例子将会非常有帮助!谢谢!

Bar*_*mar 6

您将声明放在循环体的开头。

(defun bench ()
  (do ((end (+ (get-internal-real-time) (* 5 internal-time-units-per-second)))
       (passes 0 (+ 1 passes)))
      ((> (get-internal-real-time) end)
       passes)
    (declare (type (unsigned-byte 64) passes))
    (sieve 1000000)))
Run Code Online (Sandbox Code Playgroud)

这在以下规范中有所体现DO

do ({var | (var [init-form [step-form]])}*) (end-test-form result-form*) 声明* {tag | 陈述}*

见后declaration(end-test-form result-form*)

  • 请参阅/sf/ask/3005663181/ (2认同)