2013-03-17 10 views
7

Robiłem trochę programowania genetycznego i oddzielałem funkcje na różne zestawy funkcji w oparciu o ich arytmy; to wszystko jest dość skomplikowane.Znajdź Arity funkcji w powszechnym seplenieniu

Chciałbym wiedzieć, czy jest prostszy sposób to zrobić. Na przykład, jeśli istnieje funkcja zwracająca arność danej funkcji.

Wiwaty z góry.

+2

Wydaje się być zależna od implementacji. Zobacz https://groups.google.com/forum/#!msg/comp.lang.lisp/0WoivuykcKM/0SnbqcFyNogJ –

Odpowiedz

8

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)))) 
+0

Dzięki, właśnie odkryłem, że mogę zadzwonić do 'cllist's # 'arglist, a następnie wykonaj wyszukiwanie członków na liście powraca. –

Powiązane problemy