<br><div><span class="gmail_quote">On 6/13/07, <b class="gmail_sendername">Jens Axel Søgaard</b> &lt;<a href="mailto:jensaxel@soegaard.net">jensaxel@soegaard.net</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>&gt; The imported names are bound to values. Somewhere and at some time<br>&gt; these values must have been evaluated. To run a piece of code,<br>&gt; it must be expanded first. Since macros and what they depend on live
<br>&gt; in the transformation environment, values and structure definitions<br>&gt; are needed in the transformer environment before they are needed<br>&gt; in the runtime environment. One could argue that the values in the
<br>&gt; transformer enviroment could be reused in the runtime environment<br>&gt; (that&#39;s what the defmacro system does), but that leads to a number<br>&gt; of problems. Problems that disappear, when the the runtime and the
<br>&gt; transformer environment are separated.</blockquote><div><br>I&#39;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&#39;t find a disclaimer that says &quot;don&#39;t return struct from macro - you can&#39;t use it&quot; ;)
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">&gt; *Maybe* the following technique can be used. The example features<br>&gt; structures in structures. A square consists of four points. The
<br>&gt; macro (create-square n) calculates at expansion time the coordinates<br>&gt; of the four corners of a square with side length 2*n (just to<br>&gt; show an actual computation takes place).</blockquote><div><br>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.
<br><br>I tried another approach - i.e. returning the transformation-bound struct functions to run-time, and it works.&nbsp; However, generalizing the solution seems unwieldy, so until this is addressed at language level, the disclaimer above is valid ;)&nbsp; Below is a sketch of the idea:
<br><br>(module foo mzscheme <br>&nbsp; (define-struct foo (vals) (make-inspector))<br>&nbsp; (provide (all-defined)))<br>(require-for-syntax foo)<br>(define-syntax (macro-foo stx)<br>&nbsp; (syntax-case stx ()<br>&nbsp;&nbsp;&nbsp; ((_ val1 val2 ...)
<br>&nbsp;&nbsp;&nbsp;&nbsp; (with-syntax ((val (datum-&gt;syntax-object<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&#39;_<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (make-foo (syntax-object-&gt;datum #&#39;(val1 val2 ...))))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&#39;val))))<br>;;; returns the struct functions from transform env to run-time 
<br>(define-syntax (require-foo-struct stx) <br>&nbsp; (syntax-case stx ()<br>&nbsp;&nbsp;&nbsp; ((_)<br>&nbsp;&nbsp;&nbsp;&nbsp; (with-syntax (((struct:foo make-foo foo? foo-vals set-foo-vals!)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (datum-&gt;syntax-object <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&#39;_
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (map (lambda (name)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (datum-&gt;syntax-object #&#39;_ name))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#39;(struct:foo make-foo foo? foo-vals set-foo-vals!))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((s make isa? vals set-vals!)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (datum-&gt;syntax-object<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&#39;_<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (list struct:foo make-foo foo? foo-vals set-foo-vals!))))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #&#39;(define-values (struct:foo make-foo foo? foo-vals set-foo-vals!)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (values s make isa? vals set-vals!))))))<br>(require-foo-struct) ; get the copy of the struct functions <br>(define f1 (macro-foo 1 2 3))<br>foo? ; #&lt;primitive:foo?&gt;<br>f1 ; #(struct:foo (1 2 3))<br>(foo? f1) ; #t 
<br>(foo-vals f1) ; &#39;(1 2 3)<br><br></div></div>