【问题标题】:Find function's arity in Common Lisp在 Common Lisp 中查找函数的数量
【发布时间】:2013-03-17 19:23:42
【问题描述】:

我一直在做一些遗传编程,我一直在根据它们的数量将函数分成不同的函数集;这一切都相当复杂。

我想知道是否有更简单的方法可以做到这一点。例如,如果有一个函数返回给定函数的元数。

提前干杯。

【问题讨论】:

标签: common-lisp arity parameter-list


【解决方案1】:

对于解释函数,您应该能够使用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 并不是一个真正的数字,因为除了 required 之外,Lisp 函数还可以接受 optionalrestkeyword 参数;这就是为什么上面的arglist 函数返回参数函数的lambda list,而不是数字。

如果您只对只接受必需参数的函数感兴趣,则需要使用类似

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

【讨论】:

  • 谢谢,我刚刚发现可以调用clisp自己的#'arglist,然后在它返回的列表上进行成员搜索。
  • 这是一个很好的答案,但也请查看“琐碎参数”下面的答案!超级轻量级​​的库,你可以简单的调用(arglist fn),方便携带。
  • 对于CCL,有ccl:arglist,应该将其添加到上面的可移植arglist 定义中(理想情况下也可以在CLOCC)。
【解决方案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)

它返回完整的 lambda 列表,包含 &optional 和其他东西,所以我们不能只获取 arity 结果的 length

【讨论】:

  • 很棒的图书馆!一直在使用它进行一些便携式元编程!再简单不过了。
猜你喜欢
  • 2020-08-16
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多