[racket] Lazy syntax class attributes

From: Eric Dobson (eric.n.dobson at gmail.com)
Date: Fri May 31 02:47:54 EDT 2013

I'm working on code (TR optimizer) that needs to match some
expressions and then compute an attribute based on the expression. I
would like to abstract this out as a syntax class. Example is below:

#lang racket
(require syntax/parse)

(define-syntax-class slow
  (pattern e:expr
           #:with v (begin (displayln 'slow) #''e)))

(syntax-parse #'(x 2)
  ((e:slow 1) #'(complicated (form e.v)))
  ((e:slow 2) #'(complicated (form e.v))))

The issue is that computing the attribute is slow/expensive/effectful
and so I only want to do the calculation in the case that I use the
result. One solution is to attach a thunk as the attribute value, but
this requires changing #'(complicated (form e.v)) to #`(complicated
(form #,((attribute e.v)))) which quickly becomes less readable with
many such attributes in the final syntax object. Is there a way to do
this in a lazy manner that does not complicate the use of the syntax
class? I'm fine adding complexity to the creation of the syntax class
because it is a one time cost versus the many places where the syntax
class would be used.

Posted on the users mailing list.