[plt-scheme] Dybvig's record-case better error message

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Aug 10 23:43:08 EDT 2002

> (define-syntax (record-case stx)
>   (syntax-case stx (else)
>     [(src-record-case exp1
>                       [else exp3 ...])
>      (syntax/loc stx (begin exp3 ...))]
>     [(src-record-case exp1
>                       [key vars exp2 ...])
>      (identifier? (syntax exp1))
>      (syntax/loc stx (if (eq? (car exp1) 'key)
>                          (record vars (cdr exp1) exp2 ...)
>                          (raise-syntax-error #f "no matching clause" (syntax
src-record-case))))]
>  [...]
> 
> Although it works I am unsatisfied with the error message in the case, where
> there are no matching clause.  For example this one:
> 
> > (record-case '(- 1 2)
> [+ (a b) (+ a b)])
> . record-case: no matching clause in: record-case
> >
> 
> It catched the error alright, but it DrScheme high-lights the macro code
> in stead of the offendling expression.
> [...]
> How do I propagate the proper location, so that DrScheme highlights the
> offending use,
> in stead of code within the macro it self?

The problem is that the `syntax/loc' in the 9th line above doesn't put
any source information on the `raise-syntax-error' expression. Instead,
it just puts location info on the `if' expression.

I think `syntax/loc' probably should be changed, and we'll experiment
eventually.

Meanwhile, you'll need to do something like

   (quasisyntax/loc stx (if (eq? (car exp1) 'key)
                            (record vars (cdr exp1) exp2 ...)
                            #,(syntax/loc stx
                                 (error "no matching clause")))

FWIW, I don't think the no-matching-clause error at run time should be
a syntax error. The best solution is probably to make a new extension
struct, and then use `raise' on an instance of the struct.

Matthew




Posted on the users mailing list.