我一直在做一些遗传编程,我一直在根据它们的数量将函数分成不同的函数集;这一切都相当复杂。
我想知道是否有更简单的方法可以做到这一点。例如,如果有一个函数返回给定函数的数量。
提前喝彩。
我一直在做一些遗传编程,我一直在根据它们的数量将函数分成不同的函数集;这一切都相当复杂。
我想知道是否有更简单的方法可以做到这一点。例如,如果有一个函数返回给定函数的数量。
提前喝彩。
对于解释函数,您应该能够使用function-lambda-expression
.
对于编译函数,唉,这个函数经常返回nil
,所以你必须使用一个依赖于实现的函数(clocc / port / sys.lisp):
(defun arglist (fn)
"Return the signature of the function."
#+allegro (excl:arglist fn)
#+clisp (sys::arglist fn)
#+(or cmu scl)
(let ((f (coerce fn 'function)))
(typecase f
(STANDARD-GENERIC-FUNCTION (pcl:generic-function-lambda-list f))
(EVAL:INTERPRETED-FUNCTION (eval:interpreted-function-arglist f))
(FUNCTION (values (read-from-string (kernel:%function-arglist f))))))
#+cormanlisp (ccl:function-lambda-list
(typecase fn (symbol (fdefinition fn)) (t fn)))
#+gcl (let ((fn (etypecase fn
(symbol fn)
(function (si:compiled-function-name fn)))))
(get fn 'si:debug))
#+lispworks (lw:function-lambda-list fn)
#+lucid (lcl:arglist fn)
#+sbcl (sb-introspect:function-lambda-list fn)
#-(or allegro clisp cmu cormanlisp gcl lispworks lucid sbcl scl)
(error 'not-implemented :proc (list 'arglist fn)))
编辑:注意 CL 中的arity并不是一个真正的数字,因为 Lisp 函数除了需要的参数之外,还可以接受optional、rest和keyword参数;这就是为什么上面的函数返回参数函数的lambda 列表,而不是数字。arglist
如果您只对只接受必需参数的函数感兴趣,则需要使用类似
(defun arity (fn)
(let ((arglist (arglist fn)))
(if (intersection arglist lambda-list-keywords)
(error "~S lambda list ~S contains keywords" fn arglist)
(length arglist))))
有一个提供函数的 lambda 列表的可移植库:https ://github.com/Shinmera/trivial-arguments
(ql:quickload "trivial-arguments")
例子:
(arg:arglist #'gethash)
;; => (sb-impl::key hash-table &optional sb-impl::default)
(defun foo (a b c &optional d) nil)
(arglist #'foo) ;; => (a b c &optional d)
它返回完整的 lambda 列表,带有&optional
和东西,所以我们不能只得到length
arity 的结果。