7

It is a question about variable bind in function define:

If I define funcion "total" like this,x in "total" is bind to the local x in let.

CL-USER> (let ((x 0))
           (defun total (y)
             (incf x y)))
TOTAL
CL-USER> (defvar x 10000)
X
CL-USER> (total 1)
1

but,if I define "total" like this,x is bind to global x in defvar:

CL-USER> (defvar x 10000) 
X
CL-USER> (let ((x 0))
           (defun total (y)
             (incf x y)))
TOTAL
CL-USER> (total 1)
10001

Why this? I need an explanation to understand it. the environment is windows+emacs+slime+sbcl.Thanks.

1 Answer 1

6

DEFVAR establishes a symbol (here, X) as being a dynamic variable ("special"). Once that's been done, its dynamicity will be preserved by LET and lambda lists (this is one reason why you always name special variables with *earmuffs*). So in the second example, the X in TOTAL will be looked up in the dynamic environment of where TOTAL is called. When you call it at the top level, it sees the top-level binding of X where it has the value of 10000. You can also call TOTAL inside another LET that re-binds X and it will use that value for the duration:

* (let ((x 1000))
    (total 5)))
1005
* (total 1)
10002

In the first example, X hasn't been marked special, so LET binds it lexically, as normal. The subsequent DEFVAR doesn't retroactively affect TOTAL because the DEFUN has grabbed the lexical environment that LET created, and will use that for a reference to X (basically, hiding it from the DEFVAR.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.