带位置信息的符号(symbol with position) 由一个被称为 原始符号(bare symbol) 的符号,加上一个非负的定长整数( 称为 位置(position))组成。 尽管带位置信息的符号在多数行为上与原始符号一致,但它本身并不是符号:它是一种同时包含原始符号和位置信息的对象。因为带位置信息的符号并非真正的符号,所以它们不在符号表(obarray)中登记,不过它们对应的原始符号通常会登记(see 创建与编入符号)。
字节编译器会使用带位置信息的符号,在其中记录每个符号出现的位置,并在警告和错误信息中使用这些位置。正常情况下不应该在其他场景使用它们,否则在使用 eq、equal 等 Emacs 基础函数时可能会产生意料之外的结果。
带位置信息的符号的打印形式采用 打印表示与读入语法 中描述的井号标记格式,形如 ‘#<symbol foo at 12345>’。它没有对应的读取语法。如果你希望在打印时只输出原始符号,可以在打印操作周围将变量 print-symbols-bare 绑定为非 nil。字节编译器在将输出写入编译后的 Lisp 文件之前会执行这一操作。
当标志变量 symbols-with-pos-enabled 的值为非 nil 时,带位置信息的符号在常规情况下的行为等同于其原始符号。例如,表达式 ‘(eq (position-symbol 'foo 12345) 'foo)’ 的返回值为 t,而 equal 函数也会将带位置信息的符号视作其原始符号来处理。
当 symbols-with-pos-enabled 的值为 nil 时,带位置信息的符号会以自身的身份(而非符号身份)表现行为。例如,表达式 ‘(eq (position-symbol 'foo 12345) 'foo)’ 的返回值为 nil,equal 函数也会判定带位置信息的符号与其原始符号不相等。
在 Emacs 中,绝大多数情况下 symbols-with-pos-enabled 的值都是 nil;但字节编译器和原生编译器在运行时会将其绑定为 t,这种情况下 Emacs 的运行速度会略微变慢。
通常,带位置信息的符号是由字节编译器调用读取器函数 read-positioning-symbols 创建的(see 输入函数)。也可以通过函数 position-symbol 来创建带位置信息的符号。
该变量会影响带位置信息的符号在非打印状态下、且并非本节后续定义函数的参数时的行为。当该变量值为非 nil 时,此类带位置信息的符号表现得与其原始符号一致;否则,它会以自身的身份(而非符号身份)表现行为。
当该变量被绑定为非 nil 时,Lisp 打印器仅打印带位置信息的符号的原始符号,忽略其位置信息。反之,带位置信息的符号会按自身形式打印,而非以符号形式打印。
若 object 是带位置信息的符号,该函数返回 t,否则返回 nil。与 symbolp 不同,该函数不受 symbols-with-pos-enabled 变量的影响。
该函数返回带位置信息的符号 sym 对应的原始符号;若 sym 本身已是普通符号,则直接返回其自身。如果传入的是其他类型的对象,该函数会触发错误。此函数不受 symbols-with-pos-enabled 变量的影响。
该函数从带位置信息的符号 sympos 中提取位置信息(一个非负的定长整数)并返回。如果传入的是其他类型的对象,该函数会触发错误。此函数不受 symbols-with-pos-enabled 变量的影响。
创建一个新的带位置信息的符号。新对象的原始符号取自 sym: 若 sym 是普通符号,则直接使用该符号; 若 sym 是带位置信息的符号,则使用其对应的原始符号。
新对象的位置信息取自 pos: 若 pos 是一个非负的定长整数,则直接使用该数值; 若 pos 是带位置信息的符号,则使用其对应的位置信息。
如果任一参数无效,Emacs 会触发错误。此函数不受 symbols-with-pos-enabled 变量的影响。