私はいくつかの遺伝的プログラミングを行っており、それらのアリティに基づいて関数を異なる関数セットに分離しています。それはすべてかなり複雑です。
もっと簡単な方法があるかどうか知りたいのですが。たとえば、特定の関数のアリティを返す関数があるとします。
よろしくお願いします。
私はいくつかの遺伝的プログラミングを行っており、それらのアリティに基づいて関数を異なる関数セットに分離しています。それはすべてかなり複雑です。
もっと簡単な方法があるかどうか知りたいのですが。たとえば、特定の関数のアリティを返す関数があるとします。
よろしくお願いします。
インタプリタ関数については、を使用できるはずです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)))
編集:Lisp関数は必須の引数に加えてオプションの引数、rest引数、キーワード引数を受け入れることができるため、CLのアリティは実際には数値ではないことに注意してください。これが、上記の関数が数値ではなく引数関数のラムダリストを返す理由です。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))))
関数のラムダリストを提供するポータブルライブラリがあります: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