[racket] exn:fail:contract:variable id field
On Fri, Apr 1, 2011 at 7:45 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
> At Fri, 1 Apr 2011 04:10:19 -0500, Casey Klein wrote:
>> What exactly is in the `id' field of a `exn:fail:contract:variable'
>> structure? It doesn't seem to be the symbolic name of the
>> not-yet-defined variable.
>
> It's the real symbolic name --- the one that would work with
> `namespace-variable-value' and similar reflective operations.
>
> In this case, you get `x.6', because the original symbolic name `x' was
> introduced by a macro; the variable name can't be just 'x, since it
> must be renamed for hygiene. Also, the symbol that prints as 'x.6' in
> this case is a kind of gensym --- not the result of `(string->symbol
> "x.6")'.
>
> The mismtach between `x' and `x.6' reflects is a mismatch between
> identifiers (the modern Scheme way of binding) and symbols (the
> traditional Lisp way of binding, on which the identifier layer is
> currently built and that sometimes shows through in the reflection
> API).
>
Thanks, that makes sense.
I asked this question because I'm having trouble getting Redex to
produce a good error message when you use a metafunction before its
definition. For example, the program
#lang racket
(require redex)
(define-language L)
(apply-reduction-relation
(reduction-relation L (--> (any ...) ((f any) ...)))
'(a b c))
(define-metafunction L
[(f any) (any)])
raises the error "reference to an identifier before its definition:
f3.18". I know how to get the error to say "f.18", but I don't know
how to get it to say just "f".
The problem is the expansion of metafunction definitions. The
definition of f expands into something roughly like
(begin
(define f.18 ---)
(define-syntax f (make-term-fn #'f.18)))
and the reduction-relation macro walks over the rules' right-hand
sides, looking for identifiers bound to term-fns and constructing
appropriate calls to the underlying functions. With this approach, the
apply-reduction-relation call ends up referencing f.18 (in this case,
before it's defined).
Maybe mine is a weird case, but it has me wondering why it's better
for the exn:fail:variable:contract message to use the real symbolic
name. These names are never known to programmers, since they don't
appear in source programs, right?