-->

查找Common Lisp中函数的参数数量(Find function's arity in

2019-07-21 19:38发布

我一直在做一些遗传编程和我已经分离功能基于其元数不同的功能集; 这一切都相当复杂。

我想知道如果有一个简单的做到这一点的方式。 例如,如果有一个返回给函数的参数数量的函数。

干杯提前。

Answer 1:

为了解释的功能,你应该能够使用function-lambda-expression

对于编译功能,唉,这个功能经常返回nil ,所以你必须使用一个实现相关的功能( clocc / 端口 / 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即元数是不是一个真正的数字,因为Lisp函数可以接受可选休息关键字除了参数需要的人; 这就是为什么上面arglist函数返回拉姆达清单参数的功能,不是一个数字的。

如果你只在其中只接受所需的参数的功能感兴趣的话,您将需要使用像

(defun arity (fn)
  (let ((arglist (arglist fn)))
    (if (intersect arglist lambda-list-keywords)
        (error "~S lambda list ~S contains keywords" fn arglist)
        (length arglist))))


Answer 2:

还有就是给出了函数的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)

它返回完整的拉姆达列表, &optional之类的东西,所以我们不能只拿到length的结果的元数的。



文章来源: Find function's arity in Common Lisp