Lisp warning: xx is not declared and not bound, it will be processed as if it were declared SPECIAL

I am new to lisp and am writing some simple programs to get to know him. One of the things I do is write a recursive and iterative version of the factorial. However, I ran into a problem and cannot solve it.

I saw a similar error with Lisp: CHAR was not declared and not bound, but the solution was not really reached, except that the OP realized that it made a "input error". In REPL, I can use the setf function, and it works fine. I also use LispBox with emacs. I would be grateful for any suggestions!

(defun it-fact(num) (setf result 1) (dotimes (i num) (setf result (* result (+ i 1))) ) ) 

WARNING in IT-FACT: A RESULT is not declared and not linked, it will be processed as if it had been declared SPECIAL.

+7
scope lisp lexical-scope
source share
3 answers

You need to bind the variable 'result' - using, for example, 'let' - before you start using it:

 (defun it-fact(num) (let ((result 1)) (dotimes (i num) (setf result (* result (+ i 1)))))) 

For more details you can read this ...

+5
source share

There are a few wrong or not-so-good Lisp styles:

 (defun it-fact(num) ; style: use a space before ( (setf result 1) ; bad: variable result is not introduced (dotimes (i num) (setf result (* result (+ i 1))) ; bad: extra addition in each iteration ) ; style: parentheses on a single line ) ; bad: no useful return value 

Possible version:

 (defun it-fact (num) (let ((result 1)) ; local variable introduced with LET (loop for i from 1 upto num ; i starts with 1, no extra addition do (setf result (* result i))) result)) ; result gets returned from the LET 
+6
source share

In Lisp, local variables must be explicitly declared using LET or other forms that create local variables. This is different from, for example, Python or JavaScript, where assigning a variable creates a variable in the current lexical domain.

Your example can be rewritten as follows:

 (defun it-fact(num) (let ((result 1)) (dotimes (i num) (setf result (* result (+ i 1)))))) 

An off-topic comment: it makes no sense to put closing parentheses on separate lines.

+5
source share

All Articles