[plt-scheme] create complex object @ compile time but made available @ run time?
On 6/13/07, Jens Axel Søgaard <jensaxel at soegaard.net> wrote:
>
>
> > The imported names are bound to values. Somewhere and at some time
> > these values must have been evaluated. To run a piece of code,
> > it must be expanded first. Since macros and what they depend on live
> > in the transformation environment, values and structure definitions
> > are needed in the transformer environment before they are needed
> > in the runtime environment. One could argue that the values in the
> > transformer enviroment could be reused in the runtime environment
> > (that's what the defmacro system does), but that leads to a number
> > of problems. Problems that disappear, when the the runtime and the
> > transformer environment are separated.
I've seen the paper that describe this issue and the solution seems
pragmatic, but my guess is that this is an edge case where a computed struct
value is not usable - because I didn't find a disclaimer that says "don't
return struct from macro - you can't use it" ;)
> *Maybe* the following technique can be used. The example features
> > structures in structures. A square consists of four points. The
> > macro (create-square n) calculates at expansion time the coordinates
> > of the four corners of a square with side length 2*n (just to
> > show an actual computation takes place).
Thanks Jens for the novel idea - I know you are not recommending this
approach, and for now I will go back to the old way and not use macro to
return structs.
I tried another approach - i.e. returning the transformation-bound struct
functions to run-time, and it works. However, generalizing the solution
seems unwieldy, so until this is addressed at language level, the disclaimer
above is valid ;) Below is a sketch of the idea:
(module foo mzscheme
(define-struct foo (vals) (make-inspector))
(provide (all-defined)))
(require-for-syntax foo)
(define-syntax (macro-foo stx)
(syntax-case stx ()
((_ val1 val2 ...)
(with-syntax ((val (datum->syntax-object
#'_
(make-foo (syntax-object->datum #'(val1 val2
...))))))
#'val))))
;;; returns the struct functions from transform env to run-time
(define-syntax (require-foo-struct stx)
(syntax-case stx ()
((_)
(with-syntax (((struct:foo make-foo foo? foo-vals set-foo-vals!)
(datum->syntax-object
#'_
(map (lambda (name)
(datum->syntax-object #'_ name))
'(struct:foo make-foo foo? foo-vals
set-foo-vals!))))
((s make isa? vals set-vals!)
(datum->syntax-object
#'_
(list struct:foo make-foo foo? foo-vals
set-foo-vals!))))
#'(define-values (struct:foo make-foo foo? foo-vals set-foo-vals!)
(values s make isa? vals set-vals!))))))
(require-foo-struct) ; get the copy of the struct functions
(define f1 (macro-foo 1 2 3))
foo? ; #<primitive:foo?>
f1 ; #(struct:foo (1 2 3))
(foo? f1) ; #t
(foo-vals f1) ; '(1 2 3)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070613/139e2211/attachment.html>