eval form supposed to evaluate a given form in a null lexical environment, I don't get what I expect

后端 未结 2 424
谎友^
谎友^ 2021-01-11 13:23

Let\'s say I have a special var:

(defvar x 20)

then I do the following:

(let ((x 1)) (eval \'(+ x 1))

whi

相关标签:
2条回答
  • 2021-01-11 13:51

    DEFVAR declares its variables special. Globally, everywhere. You can also not remove this easily.

    That's also the reason you should never use common names like x, i, list as variable names for DEFVAR. Make sure that you use *x*, *i* and *list* instead. Otherwise all variables, even local ones, with these common names are declared special.

    0 讨论(0)
  • 2021-01-11 14:12

    in your example x is special which means it is bound in the dynamic environment

    y is not special, so it is bound in the lexical environment


    so at the time of the first eval the environments could be represented like this:

    dynamic environment:  { x : 1 } -> { x : 20, ...other global variables... } -> nil
    lexical environment:  nil
    

    the symbol x is special so eval looks up x in the current dynamic environment and finds x = 1


    assuming it was run in same lisp as the last example, the environment of your second eval looks like this:

    dynamic environment: { x : 20,  ...other global variables... } -> nil
    lexical environment: { y :  1 } -> nil
    

    the symbol y is not special so eval looks up y in the null lexical environment -- not the current lexical environment -- and finds nothing.

    this makes sense when you realize that lisp is usually compiled, and the lexical environment can be optimized down to simple mov instructions in some cases.

    0 讨论(0)
提交回复
热议问题