使用exclusive-or或sbcl类型声明

Dan*_*ogh 1 sbcl common-lisp

对于像这样的功能:

(defun test (x y)
   (declare (optimize (speed  3)))
   (< x y))
Run Code Online (Sandbox Code Playgroud)

我看到一个警告,其中包含:

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.
Run Code Online (Sandbox Code Playgroud)

如果我知道要么两个参数都是RATIONAL xor FLOAT,那么是否有一个声明提示我可以给sbcl这个?

cor*_*ump 5

你不能在类型之间声明那种关系,但你可以做的是定义一些辅助函数,其中类型被断言但没有被检查:

(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))
Run Code Online (Sandbox Code Playgroud)

然后,你只需要检查第一个参数,因为你知道第二个参数必然是相同的类型(这就是声明所说的,并且你要求编译器信任你).

(defun test (x y)
  (etypecase x
    (float (test-float x y))
    (fixnum (test-fixnum x y))
    (rational (test-rational x y))))
Run Code Online (Sandbox Code Playgroud)