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

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Fri Aug 9 15:46:19 EDT 2002

Hi everone,

I read Dybvig's dissertation "Three Implemention Models  of Scheme" from
    http://www.cs.indiana.edu/~dyb/pubs.html
and wanted to try the interpreters. For that purpose I wrote this
macro for record-case (I don't know whether it is the same as the one
in Chez Scheme), which dispatches on the first symbol on a list,
naming the remaining variables in the :

 > (record-case '(- 1 2)
     [+ (a b) (+ a b)]
     [- (a b) (- a b)])
-1


This macro works:

(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))))]
    [(src-record-case exp1
                      [key vars exp2 ...]
                      clause
                      ...)
     (identifier? (syntax exp1))
     (syntax/loc stx (if (eq? (car exp1) 'key)
                         (record vars (cdr exp1) exp2 ...)
                         (record-case exp1
                                      clause
                                      ...)))]
    [(src-record-case exp1
                      clause
                      ...)
     (not (identifier? (syntax exp1)))
     (let ([r (car (generate-temporaries (datum->syntax-object (syntax
src-record-case) '(q))))])
       (quasisyntax/loc (syntax src-record-case)
                        (let ([(unsyntax r) exp1])
                          (record-case (unsyntax r)
                                       clause
                                       ...))))]))

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.

The macro is recursive so it is the "leaf" record-case in the expansion
that reports the error, and thus the wrong place in code is highlighted.
I tried to use an exception-handler to propagate the syntax-error excpetion
to the
original use of the macro, but I couldn't make it work. But I'm also a
little unsure
whether it actually was supposed to work, since the error occurs on
macro-expansion-time.

How do I propagate the proper location, so that DrScheme highlights the
offending use,
in stead of code within the macro it self?

--
Jens Axel Søgaard





Posted on the users mailing list.