2011-04-22 7 views
7

Es una pregunta acerca unen variable en función de definir:una pregunta sobre bind variable en Common Lisp

Si defino funcion "total" de este tipo, x en "total" se unen a los x locales en let.

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

pero, si defino "total" de este tipo, x se unen a x globales en defvar:

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

¿Por qué esto? Necesito una explicación para entenderlo. el entorno es windows + emacs + slime + sbcl.Gracias.

Respuesta

6

defvar establece un símbolo (en este caso, X) como una variable dinámica ("especial"). Una vez hecho esto, su dinamismo será preservado por listas LET y lambda (esta es una de las razones por las que siempre se nombran variables especiales con * earmuffs *). Entonces, en el segundo ejemplo, la X en TOTAL se buscará en el entorno dinámico de donde se llama TOTAL. Cuando lo llamas en el nivel superior, ve el enlace de nivel superior de X donde tiene el valor de 10000. También puedes llamar a TOTAL dentro de otro LET que vuelve a enlazar X y usará ese valor para la duración:

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

En el primer ejemplo, X no se ha marcado como especial, por lo que LET lo vincula léxicamente, como es normal. El defvar posterior no afecta de manera retroactiva total, porque la DEFUN ha agarrado el entorno léxico que le permiten crear, y utilizará para que una referencia a X (básicamente, ocultándola de la defvar.)

+0

Gracias por su ayuda! – luosha865