同一のインターンされないシンボルを複数個所で使う - lisp-cookbook-ja/common-lisp GitHub Wiki

シンボル

CLでは、インターンされないシンボルを記述することができ、#:fooのように記述します。 #:はリーダマクロで、リーダは#:に遭遇する度にインターンされないシンボルを新しく生成しますので、字面上同じにみえても同一のシンボルではありません

(eq '#:foo '#:foo)
;=> nil

なんらかの事情でインターンされないシンボルを複数箇所で利用したい場合は、リーダーマクロのラベル記法を用いることになります。

(eq #1='#:foo #1#)
;=> T

ラベルは複数利用することが可能です。

(let ((#1=#:foo 1)
      (#2=#:bar 2)
      #3=#:baz)
  (list #1# #2# #3#))
;=> (1 2 NIL)

また、このラベルはリードマクロであり、変数のスコープとは有効範囲が異なります。競合するとエラーになります。

(let ((#1=#:foo 1))
  (let ((#1=#:foo 2))
    #1#))
;>>> エラー
(let ((#1=#:foo 1))
  (eval 
   (read-from-string 
    "(let ((#1=#:foo 42))
      #1#)")))
;=> 42

また、インターンされないシンボルについては、インターンされないこと以外は通常のシンボルと同様です(symbol-packageはNILを返します)

(progn
  (defconstant #1=#:constant 42)
  
  (let ((#1# 44))
    #1#))
;>>> エラー

(progn
  (defvar #1=#:special)
  
  (let ((#1# 100))
    (symbol-value '#1#)))
;=> 100

議論