我想告诉 sbcl,以下函数只会使用结果适合 fixnum 的 fixnum 值调用:
(defun layer (x y z n)
(+ (* 2 (+ (* x y) (* y z) (* x z)))
(* 4 (+ x y z n -2) (1- n))))
我的第一次尝试是做
(defun layer (x y z n)
(declare (fixnum x y z n))
(the fixnum
(+ (* 2 (+ (* x y) (* y z) (* x z)))
(* 4 (+ x y z n -2) (1- n))))
但是该返回类型声明并不能保证所有中间结果也将是 fixnums,正如我通过查看 sbcl 生成的非常有用的编译注释发现的那样。所以我这样做了:
(defmacro fixnum+ (&rest args)
(reduce
(lambda (x y) `(the fixnum (+ ,x ,y)))
args))
(defmacro fixnum* (&rest args)
(reduce
(lambda (x y) `(the fixnum (* ,x ,y)))
args))
(defun layer (x y z n)
(declare (fixnum x y z n))
(fixnum+ (fixnum* 2 (fixnum+ (fixnum* x y) (fixnum* y z) (fixnum* x z)))
(fixnum* 4 (fixnum+ x y z n -2) (the fixnum (1- n)))))
这工作得很好。我的问题是:有没有更简单、更惯用的方法来做到这一点?
例如,也许我可以重新声明 +、-、*、1- 的类型来承诺 fixnum 结果?(我知道这通常是个坏主意,但我可能想在某些程序中这样做。) CHICKEN 方案(declare (fixnum-arithmetic))
可以满足我的要求:它(不安全地)假设所有对 fixnums 的算术运算的结果都是 fixnums。