问题
What is the difference between an "interned" and an "uninterned" symbol. Is it only Racket that has uninterned symbols or do other dialects of scheme or lisp have them?
回答1:
Interned symbols are eq?
if and only if they have the same name. Uninterned symbols are not eq?
to any other symbol, so they are a kind of unique token with an attached string. Interned symbols are the kind that are produced by the default reader. Uninterned symbols can be used as identifiers when generating code in a macro, such an identifier cannot be shadowed by any other identifier. Most Lisp dialects have this concepts, in Scheme it is rarer, since hygienic macros are supposed to reduce its usefulness.
回答2:
Common Lisp has uninterned symbols. As Juho's answer says, an uninterned symbol is guaranteed not to be equal to any other value.
Common Lisp-style requires uninterned symbols in order to write many macros correctly (particularly macros whose expansion requires introducing and binding new variables), because any interned symbol you use in a macro expansion might capture or shadow a binding in its expansion site.
Scheme's hygienic macro systems, on the other hand, do not have this problem, so a Scheme system does not need to provide uninterned symbols. Still, many of them do. Why? Several reasons:
- Some Scheme systems offer a Common Lisp-style
defmacro
capability. - In others, the hygienic macro system's implementation may use uninterned symbols internally, but the concept of an uninterned symbol may be exposed.
- Uninterned symbols can be useful in many programs that use s-expressions to represent a language, and transform this language into another s-expr language. These sorts of tasks often benefit from an ability to generate an identifier guaranteed to be new.
回答3:
The other two excellent answers nevertheless fail to mention the virtue of interned values generally, which is that they can be compared in constant time. This typically means that these values are represented as pointers to a table without duplicates. In Racket, as of a few months ago[*], other values--floating point values and strings used as literals, for instance--will also be interned. In addition to allowing faster comparisons, I believe that this enables better compile-time optimizations, because these values can be compared for equality without running the code.
Are there other systems that do things like this? I bet there are.
[*] I'm sure someone will correct me if I'm wrong :).
来源:https://stackoverflow.com/questions/8855592/what-is-the-difference-between-an-interned-and-an-uninterned-symbol