对于像这样的功能:
(defun test (x y)
(declare (optimize (speed 3)))
(< x y))
我看到一个警告,其中包含:
note:
unable to
open-code FLOAT to RATIONAL comparison
due to type uncertainty:
The first argument is a REAL, not a FLOAT.
The second argument is a REAL, not a RATIONAL.
如果我知道要么两个参数都是RATIONAL xor FLOAT,那么是否有一个声明提示我可以给sbcl这个?
你不能在类型之间声明那种关系,但你可以做的是定义一些辅助函数,其中类型被断言但没有被检查:
(macrolet ((defexpansion (name type)
`(progn
(declaim (inline ,name))
(defun ,name (x y)
(declare (type ,type x y)
(optimize (safety 1)
(speed 3)))
(< x y)))))
(defexpansion test-fixnum fixnum)
(defexpansion test-float float)
(defexpansion test-rational rational))
然后,你只需要检查第一个参数,因为你知道第二个参数必然是相同的类型(这就是声明所说的,并且你要求编译器信任你)。
(defun test (x y)
(etypecase x
(float (test-float x y))
(fixnum (test-fixnum x y))
(rational (test-rational x y))))
您可以向sbcl
提供有关数据类型的一些信息:
(defun test (x y)
(declare (optimize (speed 3))
(type rational x y))
(< x y))
您应该决定是否可以在任何情况下判断x
和y
的类型。
您可以在hyperspec和sbcl的manual中找到有关类型声明的更多信息。
编辑
我不知道它是否有意义,但人们可以考虑另一个层来决定调用哪个函数:
(defun test% (x y)
(declare (optimize (speed 3)))
(if (and (typep x 'rational) (typep y 'rational))
(test-rational x y)
(test-float x y)))
(defun test-rational (x y)
(declare (optimize (speed 3))
(type rational x y))
(< x y))
(defun test-float (x y)
(declare (optimize (speed 3))
(type float x y))
(< x y))
我想使用typecase
进行进一步优化还是有空间,或者使用CLOS
为每种类型定义方法。