2013-03-17 15 views
7

Bazı Genetik Programlama yapıyorum ve işlevleri fonksiyonlarına göre farklı fonksiyonlara ayıyorum; hepsi oldukça karmaşık.Ortak lisp'de Fonksiyonun Aritesini Bul

Bunu yapmanın daha basit bir yolu olup olmadığını bilmek istiyorum. Örneğin, belirli bir işlevin aritiliğini döndüren bir işlev varsa.

Şerefe peşinen.

+2

gibi bir şey kullanmak gerekir uygulama bağımlı gibi görünüyor. Bkz. Https://groups.google.com/forum/#!msg/comp.lang.lisp/0WoivuykcKM/0SnbqcFyNogJ –

cevap

8

Yorumlanan işlevler için function-lambda-expression kullanabilmeniz gerekir.

(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))) 

DÜZENLEME: Eğer bir uygulama bağımlı fonksiyonu (clocc/port/sys.lisp) kullanmak zorunda kalacak şekilde derlenmiş işlevler için

, ne yazık ki, bu fonksiyon genellikle nil döndüren unutmayın Arity yılında Lisp işlevleri required'a ek olarak optional, rest ve keyword argümanlarını kabul edebildiğinden CL bir sayı değildir; Yukarıdaki arglist işlevinin bir sayı değil argüman işlevinin lambda list değerini döndürmesinin nedeni budur.

sadece gerekli parametreleri kabul fonksiyonlarda sadece ilgilenen varsa,

(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

Teşekkürler, sadece clisp'in kendi # arglistini arayabileceğimi keşfettim, sonra listede bir üye araması yapın döner. –