Subject: Re: Avoiding unintentional variable capture
From: rpw3@rigden.engr.sgi.com (Rob Warnock)
Date: 1999/09/27
Newsgroups: comp.lang.lisp
Message-ID: <7smo4l$ac898@fido.engr.sgi.com>
Erik Naggum  <erik@naggum.no> wrote:
+---------------
| * Ben Goetter
| | Of course a Lisp programmer always uses gensym where appropriate to write
| | a safe macro; thus also with Scheme, as any environment with defmacro
| | will also have gensym.  (If the Scheme lacks defmacro, how can it be
| | unsafe?  Unuseful, maybe, but unsafe?)
| 
|   as I understand this, Scheme cannot generate symbols on the fly in code
|   in the first place, since the language is not defined in terms of sexprs...
+---------------

But it can! The following is pure R4RS Scheme:

(define gensym
  (let ((count 0))
    (lambda rest  
      (define (normalize-arg x)
        (cond
          ((null? x) "g")
          ((string? (car x)) (car x))
          ((symbol? (car x)) (symbol->string (car x)))
          (else (error "gensym: expects symbol/string/(), given: " (car x)))))
      (let ((prefix (normalize-arg rest)))
        (set! count (+ count 1))
        (string->symbol
          (string-append prefix (number->string count)))))))

> (gensym)
g1
> (symbol? (gensym))
#t
> (gensym)
g3
> (gensym 'foo-)
foo-4
> (gensym 'foo-)
foo-5
> (gensym (string-append "foo-" (symbol->string (gensym 'bar-)) "-"))
foo-bar-6-7
> (gensym (string-append "foo-" (symbol->string (gensym 'bar-)) "-"))
foo-bar-8-9
> 


-Rob

-----
Rob Warnock, 8L-846		rpw3@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		FAX: 650-933-0511
Mountain View, CA  94043	PP-ASEL-IA