在 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
的行为,这在这种情况下不太可能成立,在一般情况下根本不会成立.
编译器检查函数类型是可以的,因为允许编译器抱怨或放弃。对于具有完全不同行为的运行时类型检查功能的不同实现来说,这将是完全不可移植的。
(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
的行为,这在这种情况下不太可能成立,在一般情况下根本不会成立.
编译器检查函数类型是可以的,因为允许编译器抱怨或放弃。对于具有完全不同行为的运行时类型检查功能的不同实现来说,这将是完全不可移植的。