在 SBCL/Common Lisp 中是否可以在运行时 check/get 函数类型或其签名?

Is it possible to check/get function type or its signature at runtime in SBCL/Common Lisp?

(deftype binary-number-func ()
  `(function (number number) number))

(declaim (ftype binary-number-func my-add))
(defun my-add (a b)
  (+ (the number a) (the number b)))

;; FAIL:
(assert (typep #'my-add 'binary-number-func))
;; Function types are not a legal argument to TYPEP:
;;  (FUNCTION (NUMBER NUMBER) (VALUES NUMBER &REST T))
;;   [Condition of type SIMPLE-ERROR]

;; FAIL:
(typep #'my-add '(function (number number) number))
;; Function types are not a legal argument to TYPEP:
;;   (FUNCTION (NUMBER NUMBER) (VALUES NUMBER &REST T))
;;    [Condition of type SIMPLE-ERROR]

有什么方法可以检查函数值的复合类型吗? (在 Common Lisp 中,我使用的是 SBCL sbcl-1.5.0-x86-64-linux)

提前致谢。

因为 Common Lisp 允许您编写函数,即使编译器无法为它们确定最小的函数类型,编译器并不总是能够检查函数是否具有特定类型。因此,唯一理智的行为是不检查类型。

其次,这样的最小类型可能不存在。考虑这个函数:

(defun foo (key)
  (getf '(:red 1 :blue 2 :green 3 :yellow 4) key))

它的类型是 (function (T) T)(function (T) (or null (integer 1 4))) 还是 (function ((member :red :blue :green :yellow)) (integer 1 4))。注意第二种和第三种类型都是正确的,但一种不是另一种的子类型。

另请注意,要检查上述第三种类型,需要准确了解 getf 的行为,这在这种情况下不太可能成立,在一般情况下根本不会成立.

编译器检查函数类型是可以的,因为允许编译器抱怨或放弃。对于具有完全不同行为的运行时类型检查功能的不同实现来说,这将是完全不可移植的。