[racket-dev] Unique identifiers

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Fri May 31 11:56:42 EDT 2013

Even worse, I can't even reliably make identifiers that are unique with
respect to bound-identifier=?, because marks don't survive marshaling any
better than other "unique" values like internal definition contexts or
uninterned symbols.  I checked this by changing fresh to run
generate-temporary and check.rkt to use bound-identifier=?.

The problem is pretty clearly that I'm using these identifiers without
binding them to anything, and that's not what identifiers are for.  I
either need a way to actually bind these things to _something_, or I need
to give up on identifiers for this purpose.  So unless someone has a
breakthrough and can solve this problem purely using identifiers, I'll look
to other kinds of solutions for now.

Carl Eastlund

On Fri, May 31, 2013 at 9: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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/dev/archive/attachments/20130531/09393012/attachment.html>

Posted on the dev mailing list.