Next: , Previous: , Up: iklib   [Index]


6.38 Gensyms

Gensym stands for generated symbol—a fresh symbol that is generated at run time and is guaranteed to be not eq? to any other symbol present in the system. Gensyms are useful in many applications including expanders, compilers, and interpreters when generating an arbitrary number of unique names is needed.

Vicare is similar to Chez Scheme in that the readers (including the read procedure) and writers (including write and pretty-print) maintain the read/write invariance on gensyms. When a gensym is written to an output port, the system automatically generates a random unique identifier for the gensym. When the gensym is read back though the #{gensym} read syntax, a new gensym is not regenerated, but instead, it is looked up in the global symbol table.

A gensym’s name is composed of two parts: a pretty string and a unique string. The Scheme procedure symbol->string returns the pretty string of the gensym and not its unique string. Gensyms are printed by default as #{pretty-string unique-string}.

The reader supports special syntaxes to generate symbols, iklib reader misc.

Procedure: gensym
Procedure: gensym string
Procedure: gensym symbol

Construct a new gensym. If passed no arguments, construct a gensym with no pretty name. The pretty name is constructed when and if the pretty name of the resulting gensym is needed. If gensym is passed a string, that string is used as the pretty name. If gensym is passed a symbol, the pretty name of the symbol is used as the pretty name of the returned gensym. See gensym-prefix and gensym-count for details.

> (gensym)
#{g0 |y0zf>GlFvcTJE0xw|}
> (gensym)
#{g1 |U%X&sF6kX!YC8LW=|}
> (eq? (gensym) (gensym))
#f

(gensym string) constructs a new gensym with string as its pretty name. Similarly, (gensym symbol) constructs a new gensym with the pretty name of symbol, if it has one, as its pretty name.

> (gensym "foo")
#{foo |>VgOllCM&$dSvRN=|}
> (gensym 'foo)
#{foo |!TqQLmtw2hoEYfU>|}
> (gensym (gensym 'foo))
#{foo |N2C>5O0>C?OROUBU|}
Procedure: gensym? x

Return #t if its argument is a gensym, return #f otherwise.

> (gensym? (gensym))
#t
> (gensym? 'foo)
#f
> (gensym? 12)
#f
Procedure: gensym->unique-string gensym

Return the unique name associated with the gensym argument.

> (gensym->unique-string (gensym))
"YukrolLMgP?%ElcR"

An example

The (rnrs syntax-case) library provides a generate-temporaries procedure, which takes a syntax object (representing a list of things) and returns a list of fresh identifiers. Using gensym, that procedure can be defined as follows:

(define (generate-temporaries* stx)
  (syntax-case stx ()
    [(x* ...)
     (map (lambda (x)
            (datum->syntax #'unimportant
              (gensym
                (if (identifier? x)
                    (syntax->datum x)
                    't))))
          #'(x* ...))]))

The above definition works by taking the input stx and destructuring it into the list of syntax objects x* .... The inner procedure maps each x into a new syntax object (constructed with datum->syntax). The datum is a gensym, whose name is the same name as x if x is an identifier, or the symbol t if x is not an identifier. The output of generate-temporaries* generates names similar to their input counterpart:

> (print-gensym #f)
> (generate-temporaries* #'(x y z 1 2))
(#<syntax x> #<syntax y> #<syntax z> #<syntax t> #<syntax t>)

Next: , Previous: , Up: iklib   [Index]