title: Assigning variables with setf, defvar, let and scope
body: <p>So, I have read from <br>
  <a href="https://stackoverflow.com/questions/3855862/setq-and-defvar-in-lisp">setq and defvar in lisp</a>, <br>
  <a href="http://www.cs.ucf.edu/courses/cop4020/spr2006/plsetup.html" rel="nofollow noreferrer">http://www.cs.ucf.edu/courses/cop4020/spr2006/plsetup.html</a>, and <br>
  <a href="https://stackoverflow.com/questions/3860866/in-lisp-how-do-i-fix-warning-assumed-special">In Lisp, how do I fix &quot;Warning: Assumed Special?&quot;</a> <br>
  among other places about the difference between setf and defvar. So I decided to play around with the idea a bit:</p>
  
  <pre><code>CL-USER&gt; (defun foo ()
         (setf x 10)
         (print x))
  
  ; in: DEFUN FOO
  ;     (SETF X 10)
  ; ==&gt;
  ;   (SETQ X 10)
  ; 
  ; caught WARNING:
  ;   undefined variable: X
  ; 
  ; compilation unit finished
  ;   Undefined variable:
  ;     X
  ;   caught 1 WARNING condition
  FOO
  CL-USER&gt; x
  ; Evaluation aborted on #&lt;UNBOUND-VARIABLE X {10040F1543}&gt;.
  CL-USER&gt; (foo)
  
  10 
  10
  CL-USER&gt; x
  10
  </code></pre>
  
  <p>Okay, I know that setf should be used to change the value of an existing variable, but the undefined variable warning seems to be handled pretty well in SBCL (though I have read that different CL implementations may handle this differently, thus it isn't the best thing to do). </p>
  
  <p>Enter the second test:</p>
  
  <pre><code>CL-USER&gt; (defun bar ()
         (defvar y 15)
         (print y))
  
  ; in: DEFUN BAR
  ;     (PRINT Y)
  ; 
  ; caught WARNING:
  ;   undefined variable: Y
  ; 
  ; compilation unit finished
  ;   Undefined variable:
  ;     Y
  ;   caught 1 WARNING condition
  BAR
  CL-USER&gt; y
  ; Evaluation aborted on #&lt;UNBOUND-VARIABLE Y {10045033D3}&gt;.
  CL-USER&gt; (bar)
  
  15 
  15
  CL-USER&gt; y
  15
  </code></pre>
  
  <p>As per the links, I changed the setf to defvar which I think should create and bind the variable all at once. Now my undefined variable warning gets pushed into the (print y) line ... what is going on here?</p>
  
  <p>As a secondary question, I am expecting the values of any variables assinged within a funciton to be inaccessible outside of the function, as is the case in Python:</p>
  
  <pre><code>&gt;&gt;&gt; def foo():
  ...     x = 10
  ...     print x
  ... 
  &gt;&gt;&gt; foo()
  10
  &gt;&gt;&gt; x
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  NameError: name 'x' is not defined
  </code></pre>
  
  <p>I am guessing this has something to do with the way common lisp deals with scope, ie defvar creates a "global special variabe" ... So I tried one last time with (let ...)</p>
  
  <p>CL-USER> (defun baz ()
             (let ((z 10)) (print z))
             (incf z 10)
             (print z))</p>
  
  <pre><code>; in: DEFUN BAZ
  ;     (INCF Z 10)
  ; --&gt; LET* 
  ; ==&gt;
  ;   (SETQ Z #:NEW0)
  ; 
  ; caught WARNING:
  ;   undefined variable: Z
  ; 
  ; compilation unit finished
  ;   Undefined variable:
  ;     Z
  ;   caught 1 WARNING condition
  </code></pre>
  
  <p>And after reading <a href="https://stackoverflow.com/questions/8927741/whats-difference-between-defvar-defparameter-setf-and-setq">What&#39;s difference between defvar, defparameter, setf and setq</a>, this one seems to work right:</p>
  
  <pre><code>CL-USER&gt; (defun apple ()
         (defparameter x 10)
         (print 10))
  
  APPLE
  CL-USER&gt; x
  ; Evaluation aborted on #&lt;UNBOUND-VARIABLE X {1004436993}&gt;.
  CL-USER&gt; (apple)
  
  10 
  10
  CL-USER&gt; x
  10
  </code></pre>
  
  <p>Just to reiterate my questions: 
  1) what is really going on with setf, defvar and let? <br>
  2) is there a way to get common lisp to scope the variables inside a function as in the python example?</p>