2013-03-17 37 views
7

Tôi đã thực hiện một số Lập trình di truyền và tôi đã tách các chức năng thành các bộ chức năng khác nhau dựa trên tính chất của chúng; nó khá phức tạp.Tìm tính năng của tính năng trong lisp phổ biến

Tôi muốn biết liệu có cách nào đơn giản hơn để thực hiện điều đó hay không. Ví dụ, nếu có một hàm trả về arity của một hàm đã cho.

Cổ vũ trước.

+2

Có vẻ là thực hiện phụ thuộc. Xem https://groups.google.com/forum/#!msg/comp.lang.lisp/0WoivuykcKM/0SnbqcFyNogJ –

Trả lời

8

Đối với các hàm được giải thích, bạn có thể sử dụng function-lambda-expression.

Đối với chức năng biên soạn, than ôi, chức năng này thường trả về nil, vì vậy bạn sẽ phải sử dụng một chức năng thực hiện phụ thuộc (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: lưu ý rằng arity trong CL không thực sự là số, vì hàm Lisp có thể chấp nhận các đối số optional, restkeyword ngoài các số required; đây là lý do tại sao hàm arglist ở trên trả về hàm lambda list của hàm đối số, chứ không phải một số.

Nếu bạn chỉ quan tâm đến chức năng mà chấp nhận các thông số chỉ được yêu cầu, bạn sẽ cần phải sử dụng một cái gì đó giống như

(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

Cảm ơn, tôi vừa phát hiện ra rằng tôi có thể gọi chính sách # 'arglist của chính mình, sau đó thực hiện tìm kiếm thành viên trên danh sách nó trở lại. –

Các vấn đề liên quan