Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
660 views
in Technique[技术] by (71.8m points)

lambda - Installing a Recursive Function Using symbol-function

A function can be installed programmatically in Common Lisp using symbol-function (instead of defun):

* (setf (symbol-function 'factorial)
    (compile nil (lambda (n) 
                   (if (= n 1) 
                     1 
                     (* n (factorial (- n 1)))))))

; in: SETF (SYMBOL-FUNCTION 'FACTORIAL)
;     (FACTORIAL (- N 1))
;
; caught STYLE-WARNING:
;   undefined function: COMMON-LISP-USER::FACTORIAL
;
; compilation unit finished
;   Undefined function:
;     FACTORIAL
;   caught 1 STYLE-WARNING condition
#<FUNCTION (LAMBDA (N)) {1003F2222B}>

But as above, if the function is recursive, a warning is issued by SBCL because the function is anonymous.

This problem is not encountered when using defun, since, as the hyperspec says: "Evaluating defun causes function-name to be a global name for the function specified by the lambda expression".

Can the warning be averted by providing the proper function name when using symbol-function?

(PS: At first, I thought the compile function could be given the function name, but that is only for macros.)

question from:https://stackoverflow.com/questions/65931001/installing-a-recursive-function-using-symbol-function

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Declaring that factorial is fbound is enough to remove the warning:

(compile nil 
         (lambda (n) 
           (declare (ftype function factorial)) 
           (if (= n 1) 
               1 
               (* n (factorial (- n 1))))))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...