[racket-dev] Unique identifiers

From: Eric Dobson (eric.n.dobson at gmail.com)
Date: Fri May 31 11:58:44 EDT 2013

If you replace all of your internal definition manipulation with
(syntax-local-lift-expression #'#f), it passes your check.rkt. You
don't have control over the names, but I'm guessing you could look
into the implementation and see what it is doing to generate such
names.

On Fri, May 31, 2013 at 8:32 AM, Carl Eastlund <cce at ccs.neu.edu> wrote:
> I want a non-probabilistic guarantee of uniqueness, partly because I'd
> rather not rely on something nondeterministic, and partly because in an
> ideal solution, I'd like to have control over the printed names of these
> identifiers.
>
> Carl Eastlund
>
> On Fri, May 31, 2013 at 9:27 AM, Eric Dobson <eric.n.dobson at gmail.com>
> wrote:
>>
>> What does unique mean in this context? Does probabilistically unique
>> work? If so could you form an identifier with the symbolic form
>> "unique-id-"+UUID?
>>
>> On Fri, May 31, 2013 at 8:20 AM, Carl Eastlund <cce at ccs.neu.edu> wrote:
>> > I'm having trouble creating identifiers that are unique with respect to
>> > free-identifier=? and that survive marshaling to compiled code.  The
>> > normal
>> > source of fresh identifiers, generate-temporaries, only guarantees they
>> > are
>> > unique with respect to bound-identifier=?.  The obvious alternative,
>> > gensym,
>> > does not properly survive marshaling -- copies saved in different .zo
>> > files
>> > load as distinct identifiers.  I've tried a few alternative methods,
>> > none
>> > more successful than either of these.
>> >
>> > Below, there are a few short files that show the difficulties and can be
>> > used to test other methods.  The first, fresh.rkt, contains the
>> > procedure
>> > used to create fresh identifiers.  The file original.rkt creates a fresh
>> > identifier at compile time.  The file identical.rkt copies the
>> > identifier
>> > from original.rkt using quote-syntax.  The file different.rkt creates
>> > another fresh identifier at compile time.  The file check.rkt checks
>> > that
>> > the identifiers from original.rkt and identical.rkt are
>> > free-identifier=? to
>> > each other, and that the identifiers from original.rkt and different.rkt
>> > are
>> > not free-identifier=? to each other.  To run a test, first update
>> > fresh.rkt
>> > to use the appropriate method for creating identifiers, then run "raco
>> > make
>> > check.rkt".  Some of the methods work when simply running "racket
>> > check.rkt", but "raco make" marshals the identifiers to .zo files and
>> > exposes more problems.
>> >
>> > Can anyone suggest an implementation that would work here?
>> >
>> > ;;;;; fresh.rkt
>> > #lang racket
>> > (begin-for-syntax
>> >   (require racket/syntax)
>> >   (define (fresh)
>> >     ;; does not guarantee free-identifier=?
>> >     #;(generate-temporary)
>> >     ;; does not survive marshaling
>> >     #;(gensym)
>> >     ;; also does not survive marshaling
>> >     (begin
>> >       (define id0 (datum->syntax #false 'fresh))
>> >       (define ctx (syntax-local-make-definition-context))
>> >       (syntax-local-bind-syntaxes (list id0) #false ctx)
>> >       (internal-definition-context-seal ctx)
>> >       (internal-definition-context-apply ctx id0)))
>> >   (provide fresh))
>> >
>> > ;;;;; original.rkt
>> > #lang racket
>> > (require "fresh.rkt")
>> > (define-syntax (macro stx)
>> >   (with-syntax {[name (fresh)]}
>> >     #'(begin-for-syntax
>> >         (define original (quote-syntax name))
>> >         (provide original))))
>> > (macro)
>> >
>> > ;;;;; identical.rkt
>> > #lang racket
>> > (require "original.rkt")
>> > (define-syntax (macro stx)
>> >   (with-syntax {[orig original]}
>> >     #'(begin-for-syntax
>> >         (define identical (quote-syntax orig))
>> >         (provide identical))))
>> > (macro)
>> >
>> > ;;;;; different.rkt
>> > #lang racket
>> > (require "fresh.rkt")
>> > (define-syntax (macro stx)
>> >   (with-syntax {[name (fresh)]}
>> >     #'(begin-for-syntax
>> >         (define different (quote-syntax name))
>> >         (provide different))))
>> > (macro)
>> >
>> > ;;;;; check.rkt
>> > #lang racket
>> > (require "fresh.rkt" "original.rkt" "identical.rkt" "different.rkt")
>> > (begin-for-syntax
>> >   (unless (free-identifier=? original identical)
>> >     (error 'fresh "~v != ~v\n" original identical))
>> >   (when (free-identifier=? original different)
>> >     (error 'fresh "~v == ~v\n" original different)))
>> >
>> > --
>> > Carl Eastlund
>> >
>> > _________________________
>> >   Racket Developers list:
>> >   http://lists.racket-lang.org/dev
>> >
>>
>

Posted on the dev mailing list.