[plt-scheme] Creating new syntax for decision tables

From: Andrew Gacek (andrew.gacek at gmail.com)
Date: Fri Feb 9 08:58:49 EST 2007

Thanks for the quick and helpful responses. Jacob's code is very
similar to how I expected this macro to look. I was also able to add
some basic error checks as well

(define-syntax table
   (syntax-rules (:)
     [(table (e : c1 c2 ...) ...)
      (or (and (clause-transform c1 e) ...)
          (table (e : c2 ...) ...))]
     [(table (e :) ...)
      #f]
     [(table (e1 : c1 c2 ...) (e2 :))
      (error "Table mismatch for rows"
             (quote e1) 'and (quote e2))]
     [(table (e1 :) (e2 : c1 c2 ...))
      (error "Table mismatch for rows"
             (quote e1) 'and (quote e2))]))

(define-syntax clause-transform
  (syntax-rules (T F *)
    [(clause-transform T e) e]
    [(clause-transform F e) (not e)]
    [(clause-transform * e) #t]
    [(clause-transform other e)
     (error "Unknown flag: " (quote other))]))

Now it checks that each row has the same number of flags and that each
flag is either T, F, or *.

I have two remaining questions for this example:

1. If I want to prevent the expressesions on the left side of the
colons from being evaluated more than once, what is the best way to do
this? My initial thought it to make another macro which passes those
expressions into a function call so that they are evaluated just once.

2. Is there a way to show the expansion of these macros? So that I can
see what expression is being generated for a particular table.

Thanks,
Andrew

On 2/8/07, Robby Findler <robby.findler at gmail.com> wrote:
> Oh! Nice use of the ellipses.
>
> That trick can be adapted to my verison below to get rid of the use of
> transpose (if you want to improve the error reporting, you'll probably
> want to use the syntax-case version).
>
> Robby
>
> On 2/8/07, Jacob Matthews <jacobm at cs.uchicago.edu> wrote:
> > This can also be done pretty nicely using syntax-rules. Here's a
> > version that uses only pattern matching:
> >
> > (module a mzscheme
> >
> >   (define-syntax table
> >     (syntax-rules (:)
> >       [(table (e : c1 c2 ...) ...)
> >        (or (and (clause-transform c1 e) ...)
> >            (table (e : c2 ...) ...))]
> >       [(table (e :) ...)
> >        #f]))
> >
> >   (define-syntax clause-transform
> >     (syntax-rules (T F *)
> >       [(clause-transform T e) e]
> >       [(clause-transform F e) (not e)]
> >       [(clause-transform * e) #t])))
> >
> >
> > Examples:
> >
> > > (let ([a #t] [b #f] [c #t])
> >     (table
> >      (a : T T T)
> >      (b : T F *)
> >      (c : T F F)))
> > #f
> > > (let ([a #t] [b #f] [c #t])
> >     (table
> >      (a : T T *)
> >      (b : T F *)
> >      (c : T F F)))
> > #f
> > > (let ([a #t] [b #f] [c #t])
> >     (table
> >      (a : T T *)
> >      (b : * F *)
> >      (c : T F F)))
> > #t
> >
> >
> > Notes:
> >   - not thoroughly tested
> >   - as written it will evaluate each e several times, this can be
> > changed easily enough
> >   - of course there's no syntax error checking
> >
> > -jacob
> >
> >
> >
> > On 2/8/07, Robby Findler <robby.findler at gmail.com> wrote:
> > > Oops, left in a silly bug. Here you go:
> > >
> > > (module m mzscheme
> > >
> > >   (define-syntax (table stx)
> > >     (syntax-case stx (:)
> > >       [(_ clauses ...)
> > >        (let* ([transpose (λ (l) (apply map list l))]
> > >               [rewrite-clauses
> > >                (λ (clause)
> > >                  (syntax-case clause (:)
> > >                    [(var : tfs ...)
> > >                     (map
> > >                      (λ (tf)
> > >                        (syntax-case tf (T F)
> > >                          [T #'var]
> > >                          [F #'(not var)]
> > >                          [* #'#t]))
> > >                      (syntax->list (syntax (tfs ...))))]))])
> > >          (with-syntax ([((item ...) ...)
> > >                         (transpose (map rewrite-clauses
> > >                                         (syntax->list (syntax (clauses
> > > ...)))))])
> > >            #'(or (and item ...) ...)))]))
> > >
> > >   (λ (a b c)
> > >     (table
> > >      (a : T T F)
> > >      (b : F * F)
> > >      (c : * F T))))
> > >
> > > _________________________________________________
> > >   For list-related administrative tasks:
> > >   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> > >
> > >
> >
>

Posted on the users mailing list.