Aby zinterpretować funkcje, powinieneś móc używać function-lambda-expression
.
Dla skompilowanych funkcji, niestety, funkcja ta często zwraca nil
, więc trzeba będzie użyć funkcji zależna od implementacji (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)))
EDIT: Uwaga arity w CL nie jest tak naprawdę liczbą, ponieważ funkcje Lisp mogą akceptować argumenty: optional, rest i keyword oprócz required; dlatego powyższa funkcja arglist
zwraca lambda list funkcji argumentu, a nie liczbę.
Jeśli jesteś zainteresowany tylko w funkcji, które akceptują tylko wymagane parametry, trzeba by użyć czegoś jak
(defun arity (fn)
(let ((arglist (arglist fn)))
(if (intersect arglist lambda-list-keywords)
(error "~S lambda list ~S contains keywords" fn arglist)
(length arglist))))
Wydaje się być zależna od implementacji. Zobacz https://groups.google.com/forum/#!msg/comp.lang.lisp/0WoivuykcKM/0SnbqcFyNogJ –