Am I missing some important fact about interning symbols in LISP?

有些话、适合烂在心里 提交于 2019-12-02 02:28:17

Your problem has nothing to do with interning.

The first problem is indeed causes by the fact that the reader will always uppercase the symbols, so you need to call (intern "FOO") in order to get the same result as 'foo.

The problem with EVAL is caused by the fact that LET introduces a lexical binding which is not visible inside EVAL. If you really want this to work you'd have to declare abc to be special, like so:

(let ((abc 2))
    (declare (special abc))
    (eval '(1+ abc)))

A special declaration will cause the variable to have dynamic binding, instead of lexical binding (the latter means that the binding is limited to the local lexical context, i.e. within the LET form. With the special declaration the variable is available to anything that is called by from that form).

Note that the use of both special declarations and eval is something you should be very careful about and you should probably rethink your use of EVAL in the first place. It is very rare that you actually need to use it. In most cases you're actually looking for the use of lambda functions instead.

Eval evaluates the form in the null lexical environment, i.e. with no lexical bindings. That has nothing to do with the interning of symbols.

The case-sensitivity of the Common Lisp reader is determined by the readtable:

(readtable-case *readtable*)

Typically the reader will initially intern symbols in uppercase (unless you explicitly escape characters). Hence:

(eq (intern "foo") 'foo) => NIL

(eq (intern "FOO") 'foo) => T

(eq (intern "FOo") 'fo\o) => T

You can use backquote syntax to build the form for eval:

(let ((abc 2))
  (eval `(+ 2 ,abc)))

=> 4

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!