我正在编写一个常见的lisp程序,我有一个可以包含字符串或函数的变量。我想调用函数,如果它是一个并返回该字符串。如何测试变量是否为函数?
到目前为止代码:
(defun string-or-function (var)
(if (typep var 'simple-array)
var
(if "Function equivalent of typep goes here."
(setf temp (fn-that-does-something))
(string-or-function temp)
编辑:有效的代码:
(defun string-or-function (var)
(let ((s-or-f (type-of var)))
(if (equal s-or-f 'function)
(print "function")
(if (equal (car s-or-f) 'simple-array)
(print "string")))))
有更好的方法吗?
答案 0 :(得分:7)
Common Lisp有一个预测型系统。一个值具有“主体”类型的概念在Lisp中没有那么多意义。 type-of
函数实际上很少被使用,因为询问“X的类型是什么”并且更有意义地问“Y是X的类型”是没有意义的。这可以使用typep
完成,或者更简洁地使用typecase
,这只是类型的案例陈述。
(defun string-or-function (var)
(typecase var
(string (format t "string"))
(function (format t "function"))
(t (format t "something else"))))
答案 1 :(得分:2)
我想调用该函数,如果它是一个并返回该函数以及字符串。
我认为你的意思是这样的:
(defun evaluate (arg)
"Returns something from evaluating ARG in some manner. If ARG is a string,
return it. If ARG is a function, call it with no arguments and return its
return value(s)."
(ctypecase arg
(string arg)
(function (funcall arg))))
如果您需要可扩展性:
(defgeneric evaluate (arg)
(:documentation "Returns something from evaluating ARG in some manner."))
(defmethod evaluate ((arg string))
arg)
(defmethod evaluate ((arg function))
(funcall arg))
答案 2 :(得分:0)
以下是其他一些方法:
(check-type place (or string function))
...但是您也可以使用check-type,它不是谓词,而是一个检查,如果值不满足类型规范,则表示可重新启动的条件:
(deftype string-or-fun () '(or string function))
如果您碰巧经常使用此类型,请定义自定义类型:
(defgeneric execute (object)
(:method ((s string)) (eval (read-from-string s)))
(:method ((f function)) (funcall f)))
当然,您也可以根据需要使用通用功能(愚蠢的例子):
{{1}}
但请注意,类上的泛型函数调度,而不是类型,它们是不同的东西。
答案 3 :(得分:-1)
(eq (type-of var) 'function)
但是,请记住,Common Lisp将变量和函数名称保存在不同的名称空间中,因此(var 1 2 3)和(cons var 1)会在两个不同的位置查找。您可能无法调用var like(var),而是需要使用(funcall var),具体取决于它所在的命名空间。
基本上,你可能不应该将一个函数或者一个字符串填充到一个变量中。