2 votes

Comment taper les variables DO en common lisp ?

Je sais que l'on peut déclarer des types de paramètres de fonctions comme

(defun add-integer (a b)
  (declare (integer a b))
  (the integer (+ a b)))

Mais qu'en est-il des variables DO ? Par exemple, je veux taper 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)))

Lorsque j'essaie de compiler avec (declaim (optimize (speed 2) (safety 0))) J'obtiens

; 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).

J'ai essayé

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

Mais ensuite, je reçois

;   Undefined variable:
;     PASSES

Je ne trouve rien à ce sujet dans les chapitres sur les types de l'HyperSpec, par exemple ( http://clhs.lisp.se/Body/04_bc.htm ). Un exemple concret serait extrêmement utile ! Merci d'avance !

6voto

Barmar Points 135986

Vous placez la déclaration au début du corps de la boucle.

(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)))

C'est ce que montre la spécification de DO :

faire ({var | (var [init-form [step-form]])}*) (end-test-form result-form*) declaration* {tag | déclaration}*

Véase declaration après (end-test-form result-form*)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X