I'm trying to enable speed optimization is SBCL 2.3.1. Compilation of the following code:
(defun test (x y)
(declare (optimize speed))
(declare (type single-float x y))
(+ x (sqrt y)))
produces the following notes:
; processing (DEFUN TEST ...)
; file: /var/tmp/slimeftWp5F
; in: DEFUN TEST
; (SQRT RT-SPEC::Y)
;
; note: unable to
; optimize
; due to type uncertainty:
; The result is a (VALUES (OR (COMPLEX SINGLE-FLOAT) (SINGLE-FLOAT -0.0))
; &OPTIONAL), not a (VALUES FLOAT &REST T).
; (+ RT-SPEC::X (SQRT RT-SPEC::Y))
;
; note: forced to do GENERIC-+ (cost 10)
; unable to do inline float arithmetic (cost 2) because:
; The second argument is a (OR (COMPLEX SINGLE-FLOAT) (SINGLE-FLOAT -0.0)), not a SINGLE-FLOAT.
; The result is a (VALUES (OR SINGLE-FLOAT (COMPLEX SINGLE-FLOAT))
; &OPTIONAL), not a (VALUES SINGLE-FLOAT &OPTIONAL).
; unable to do inline float arithmetic (cost 3) because:
; The second argument is a (OR (COMPLEX SINGLE-FLOAT) (SINGLE-FLOAT -0.0)), not a (COMPLEX
; SINGLE-FLOAT).
; The result is a (VALUES (OR SINGLE-FLOAT (COMPLEX SINGLE-FLOAT))
; &OPTIONAL), not a (VALUES (COMPLEX SINGLE-FLOAT)
; &OPTIONAL).
;
; compilation unit finished
; printed 2 notes
If I'm understanding correctly, the generic #'sqrt
function may return values of different types. But I'm supplying a single-float
argument to it, is it possible somehow to specify what the return type must be single-float
?
If y
is negative, the square root will be a complex value:
> (test 1.5 -3.2)
#C(1.5 1.7888544)
If you want to restrict your floats to positive or zero values, you can use the compound type specifier:
single-float [single-lower-limit [single-upper-limit]]
For example, as follows:
(defun test (x y)
(declare (optimize (speed 3)))
(declare (type (single-float 0.0) x y))
(+ x (sqrt y)))
There is no warning in that case for me.