#### 2.11.3.3 Identifiers

This section describes the procedures that create and manipulate identifiers. The identifier data type extends the syntactic closures facility to be compatible with the high-level `syntax-rules` facility.

As discussed earlier, an identifier is either a symbol or an alias. An alias is implemented as a syntactic closure whose form is an identifier:

    (make-syntactic-closure env '() 'a) ⇒ an alias

Aliases are implemented as syntactic closures because they behave just like syntactic closures most of the time. The difference is that an alias may be bound to a new value (for example by `lambda` or `let-syntax`); other syntactic closures may not be used this way. If an alias is bound, then within the scope of that binding it is looked up in the syntactic environment just like any other identifier.

Aliases are used in the implementation of the high-level facility `syntax-rules`. A macro transformer created by `syntax-rules` uses a template to generate its output form, substituting subforms of the input form into the template. In a syntactic closures implementation, all of the symbols in the template are replaced by aliases closed in the transformer environment, while the output form itself is closed in the usage environment. This guarantees that the macro transformation is hygienic, without requiring the transformer to know the syntactic roles of the substituted input subforms.

procedure: identifier? object

  Returns `#t` if object is an identifier, otherwise returns `#f`. Examples:

      (identifier? 'a)        ⇒ #t
      (identifier? (make-syntactic-closure env '() 'a))
                              ⇒ #t

      (identifier? "a")       ⇒ #f
      (identifier? #\a)       ⇒ #f
      (identifier? 97)        ⇒ #f
      (identifier? #f)        ⇒ #f
      (identifier? '(a))      ⇒ #f
      (identifier? '#(a))     ⇒ #f

The predicate `eq?` is used to determine if two identifers are “the same”. Thus `eq?` can be used to compare identifiers exactly as it would be used to compare symbols. Often, though, it is useful to know whether two identifiers “mean the same thing”. For example, the `cond` macro uses the symbol `else` to identify the final clause in the conditional. A macro transformer for `cond` cannot just look for the symbol `else`, because the `cond` form might be the output of another macro transformer that replaced the symbol `else` with an alias. Instead the transformer must look for an identifier that “means the same thing” in the usage environment as the symbol `else` means in the transformer environment.

procedure: identifier=? environment1 identifier1 environment2 identifier2

  Environment1 and environment2 must be syntactic environments, and identifier1 and identifier2 must be identifiers. `identifier=?` returns `#t` if the meaning of identifier1 in environment1 is the same as that of identifier2 in environment2, otherwise it returns `#f`. Examples:

      (let-syntax
          ((foo
            (sc-macro-transformer
             (lambda (form env)
               (capture-syntactic-environment
                (lambda (transformer-env)
                  (identifier=? transformer-env 'x env 'x)))))))
        (list (foo)
              (let ((x 3))
                (foo))))
                              ⇒ (#t #f)

      (let-syntax ((bar foo))
        (let-syntax
            ((foo
              (sc-macro-transformer
               (lambda (form env)
                 (capture-syntactic-environment
                  (lambda (transformer-env)
                    (identifier=? transformer-env 'foo
                                  env (cadr form))))))))
          (list (foo foo)
                (foo bar))))
                              ⇒ (#f #t)

Sometimes it is useful to be able to introduce a new identifier that is guaranteed to be different from any existing identifier, similarly to the way that `generate-uninterned-symbol` is used.

procedure: make-synthetic-identifier identifier

  Creates and returns and new synthetic identifier (alias) that is guaranteed to be different from all existing identifiers. Identifier is any existing identifier, which is used in deriving the name of the new identifier.