[plt-scheme] Mutation of expansion time values not visible outside module

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Apr 5 23:44:12 EDT 2006

At Wed, 5 Apr 2006 19:28:02 -0700 (PDT), Noel Welsh wrote:
> What's going on?

The compile-time portion of the `staged' module is executed while the
module is expanded. Then, when the module is required for the
top-level, the compile-time portion is executed again (to avoid
accidental state dependencies on compilation order).

The first time around, uses of the `add-val!' within the module are
expanded, and they perform a side effect. But only the expansion result
remains, so there's no effect for future compile-time runs.

Here's the solution from the YWIW paper adapted to `add-val!':

  ;; adds a value to an entity
  (define-syntax (add-val! stx)
    (syntax-case stx ()
      ((add-val! entity val)
       ;; Don't perform side-effect directly. Instead, generate
       ;;  a compile-time expression as the expansion:
       #'(begin-for-syntax
          (set-box! (syntax-local-value (syntax entity))
                    (cons (syntax-object->datum (syntax val))
                          (unbox (syntax-local-value (syntax entity)))))))))

Matthew



Posted on the users mailing list.