[racket-dev] certificates and phases question

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Wed Sep 8 15:40:15 EDT 2010

Sam Tobin-Hochstadt wrote:
> I'm puzzled by the behavior of the below program.  In particular,
> `get' doesn't work, but `get2' does, even though the only difference
> is the phase at which they're executed.  `get' produces the
> certificate error:
>   compile: access from an uncertified context to unexported variable
> from module: 'm1 in: x
> Is there a way around this?  Working at phase 1 has become inconvenient for me.
> #lang racket/load
> (module m1 racket
>   (define x 1)
>   (define-syntax (m stx) #'(list x))
>   (provide m))
> (module m2 racket
>   (require 'm1 (for-syntax syntax/parse))
>   (define-syntax (get stx)
>     (syntax-parse stx
>       [(_ nm)
>        (with-syntax ([(app lst val) (local-expand #'(m) 'expression null)])
>          #'(define nm #'val))]))
>   (define-syntax (get2 stx)
>     (syntax-parse stx
>       [(_ nm)
>        (with-syntax ([(app lst val) (local-expand #'(m) 'expression null)])
>          #'(define-for-syntax nm #'val))]))
>   (get2 z))
> (require 'm2)

Replace #'val with (quote-syntax val). Syntax (#') checks every 
identifier in its template to see if it's a pattern variable. That check 
counts as a reference, which is prohibited in this case by the 
certificate system.

The reason get2 works is that x isn't bound at phase 1, so the access 
control check doesn't kick in.


Posted on the dev mailing list.