[racket] generate-temporaries, gensym, etc.
What's the current preferred way to generate unique identifiers in
syntax transformers? "generate-temporaries"?
Rest of this email is a long example that might not be relevant to the
answer, so please disregard if it's not.
In the below example (which is an abstracted tiny piece of a real
program), I'm introducing one identifier that I programmatically paste
into two parts of the syntax. In this case, I need only one variable,
so I didn't need something "gensym"-like. If, however, I wanted "foo"
to put each "BAR.CODE" forms in its own binding clause of a single
"let*" (or something like that), should I be generating multiple
identifiers, and if so, should I be using "generate-temporaries" or
something else?
#lang racket/base
(require (for-syntax racket/base
syntax/parse)
syntax/parse)
(begin-for-syntax
(define-syntax-class bar-sc
#:attributes (CODE)
(pattern EXPR
#:attr CODE #'(lambda (x) (cons EXPR x)))))
(provide foo)
(define-syntax (foo stx)
(syntax-parse stx
((_ BAR:bar-sc ...+)
(let ((new-id #'top-arg))
#`(lambda (#,new-id)
#,(let loop ((bar-codes (attribute BAR.CODE))
(last-expr new-id))
(if (null? bar-codes)
last-expr
(loop (cdr bar-codes)
#`(#,(car bar-codes) #,last-expr)))))))))
;; Example:
;; ((foo "arg1" "arg2" "arg3") "seed")
;;=expand=>
;; ((lambda (top-arg)
;; ((lambda (x) (cons "arg3" x))
;; ((lambda (x) (cons "arg2" x))
;; ((lambda (x) (cons "arg1" x))
;; top-arg))))
;; "seed")
;;=result=> ("arg3" "arg2" "arg1" . "seed")
Thanks,
Neil V.