[plt-scheme] Creating new syntax for decision tables

From: Alex Shinn (alexshinn at gmail.com)
Date: Wed Feb 14 03:02:59 EST 2007

On 2/10/07, Daniel Yoo <dyoo at cs.wpi.edu> wrote:
> 
> Another similar approach might be to do what you're thinking, building a 
> function that remembers what it returns, so that we avoid evaluation 
> unless absolutely necessary.

For this case, DELAY and FORCE work nicely.  A small refinement only
optionally uses them if the value is an application:

(define-syntax table
  (syntax-rules ()
    ((table e ...)
     (table-let () () e ...))
    ))

(define-syntax table-let
  (syntax-rules (:)
    ((table-let (vars ...) (rows ...) ((app ...) : c1 ...) e2 ...)
     (table-let (vars ... (tmp (delay (app ...)))) (rows ... ((force tmp) : c1 ...)) e2 ...))
    ((table-let (vars ...) (rows ...) (x : c1 ...) e2 ...)
     (table-let (vars ...) (rows ... (x : c1 ...)) e2 ...))
    ((table-let (vars ...) (rows ...))
     (let (vars ...)
       (table-expand rows ...)))
    ))

(define-syntax table-expand
  (syntax-rules (:)
    ;; note error checking should come before default actions
    [(table-expand (e1 : c1 c2 ...) (e2 :) e3 ...)
     (error "Table mismatch for rows"
            (quote e1) 'and (quote e2))]
    [(table-expand (e1 :) (e2 : c1 c2 ...) e3 ...)
     (error "Table mismatch for rows"
            (quote e1) 'and (quote e2))]
    [(table-expand (e : c1 c2 ...) ...)
     (or (and (clause-transform c1 e) ...)
         (table-expand (e : c2 ...) ...))]
    [(table-expand (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]
    [(clause-transform other e)
     (error "Unknown flag: " (quote other))]))

The laziness is needed if you want any kind of short-circuit logic in
the table, since unlike AND or OR, values can be referred to from
multiple execution paths.

-- 
Alex


Posted on the users mailing list.