<div dir="ltr"><font face="courier new, monospace">By the way, I found that this also works - applying the lexical context of the dog-unit syntax-object to the dog^ identifier:</font><div><font face="courier new, monospace"><br>
</font></div><div><div><font face="courier new, monospace">(define-syntax (use-dog stx)</font></div><div><font face="courier new, monospace"> (syntax-case stx ()</font></div><div><font face="courier new, monospace"> ([_ dog-unit]</font></div>
<div><font face="courier new, monospace"> #`(define-values/invoke-unit dog-unit</font></div><div><font face="courier new, monospace"> (import)</font></div><div><font face="courier new, monospace"> (export #,(datum->syntax #'dog-unit 'dog^))))))</font></div>
</div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">Again, many thanks.</font></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Aug 6, 2013 at 2:32 PM, Carl Eastlund <span dir="ltr"><<a href="mailto:cce@ccs.neu.edu" target="_blank">cce@ccs.neu.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div>Nick,<br><br></div>The unit system has some non-hygienic behavior, by design. That is, it introduces names that aren't part of its input, which isn't the default behavior of hygienic macros. Of course we want this -- we want the macro use-dog to bind the names woof and bark, which aren't directly part of its input. But getting the context right, and still "playing nice" with other hygienic macros, is slightly tricky.<br>
<br></div>So in this context, what's the trick? The names bound by define-values/invoke-unit are bound in the context that the interface names are written in. Note that the interface names in use-dog are written inside the macro definition. The macro system assumes anything from inside a macro is a local or "temporary" name that should be hidden from the rest of the program. You can fix this with the syntax-local-introduce function, which (basically) toggles the context of a given syntax object between the current macro expansion step and its call site.<br>
<br></div>So right now you are getting two definitions each for woof and bark, one visible by the main module and one only visible from the expansion of the use-dog macro. If you call use-dog multiple times, you'll get more, separate, unique contexts.<br>
<br>You can fix it like this, to make use-dog bind things in the context where it is called:<br><br> (define-syntax (use-dog stx)<br> (syntax-case stx ()<br> ([_ dog-unit]<br> #`(define-values/invoke-unit dog-unit<br>
(import)<br> (export #,(syntax-local-introduce #'dog^))))))<span class="HOEnZb"><font color="#888888"><br><br clear="all"></font></span><div class="gmail_extra"><span class="HOEnZb"><font color="#888888"><div>
Carl Eastlund</div>
<br></font></span><div class="gmail_quote"><div class="im">On Tue, Aug 6, 2013 at 5:11 PM, Nick Main <span dir="ltr"><<a href="mailto:david.nick.main@gmail.com" target="_blank">david.nick.main@gmail.com</a>></span> wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
<div dir="ltr"><font face="courier new, monospace">I am attempting to write a macro to clean up the use of define-values/invoke-unit and finding some confusing behavior.</font><div><font face="courier new, monospace"><br>
</font></div>
<div><font face="courier new, monospace">My macros module is:</font></div><div><font face="courier new, monospace"><br></font></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><font face="courier new, monospace">#lang racket</font></div>
</div><div><div><font face="courier new, monospace">(provide (all-defined-out))</font></div></div><div><div><font face="courier new, monospace"><br></font></div></div><div><div><font face="courier new, monospace">(define-signature dog^</font></div>
</div><div><div><font face="courier new, monospace"> (woof</font></div></div><div><div><font face="courier new, monospace"> bark))</font></div></div><div><div><font face="courier new, monospace"><br></font></div></div>
<div><div><font face="courier new, monospace">(define mutt@</font></div></div><div><div><font face="courier new, monospace"> (unit</font></div></div><div><div><font face="courier new, monospace"> (import)</font></div>
</div><div><div><font face="courier new, monospace"> (export dog^)</font></div></div><div><div><font face="courier new, monospace"> (define (woof) (printf "Wuf !!\n"))</font></div></div><div><div><font face="courier new, monospace"> (define (bark) (printf "RarRarRar !!\n"))))</font></div>
</div><div><div><font face="courier new, monospace"><br></font></div></div><div><div><font face="courier new, monospace">(define-syntax use-dog</font></div></div><div><div><font face="courier new, monospace"> (syntax-rules ()</font></div>
</div><div><div><font face="courier new, monospace"> ([_ dog-unit]</font></div></div><div><div><font face="courier new, monospace"> (define-values/invoke-unit dog-unit</font></div></div><div><div><font face="courier new, monospace"> (import)</font></div>
</div><div><div><font face="courier new, monospace"> (export dog^)))))</font></div></div></blockquote><font face="courier new, monospace"><br></font><div><font face="courier new, monospace">..and the module using it is:</font></div>
<div><font face="courier new, monospace"><br></font></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="courier new, monospace"><div>#lang racket</div></font></div><div><font face="courier new, monospace"><div>
(require "macros.rkt")</div></font></div><div><font face="courier new, monospace"><div><br></div></font></div><div><font face="courier new, monospace"><div>(define-values/invoke-unit mutt@</div></font></div><div>
<font face="courier new, monospace"><div> (import)</div></font></div><div><font face="courier new, monospace"><div> (export dog^))</div></font></div><div><font face="courier new, monospace"><div><br></div></font></div>
<div>
<font face="courier new, monospace"><div>(use-dog mutt@)</div></font></div><div><font face="courier new, monospace"><div><br></div></font></div><div><font face="courier new, monospace"><div>(woof)</div></font></div><div>
<font face="courier new, monospace"><div>
(woof)</div></font></div><div><font face="courier new, monospace"><div>(bark)</div></font></div><div><font face="courier new, monospace"><div>(woof)</div></font></div></blockquote><div><font face="courier new, monospace"><div>
<br></div><div>I am trying to make the "use-dog" macro expand to the equivalent define-values/invoke-unit form as shown.</div><div>If I comment out the define-value/invoke-unit form I get warning about unbound identifier woof - implying that the (use-dog dog^) form is not doing the job. Moreover, the second module as it stands does not give a warning about duplicate definitions for woof or bark (as it does if I duplicate the define-values/invoke-unit form) - further indicating the non-action of use-dog.</div>
<div><br></div><div>The macro stepper shows use-dog expand exactly as expected, but it then seems to be ignored without any warnings.</div><div><br></div><div>Is there something I am misunderstanding here, or is this a bug ?</div>
</font></div></div>
<br></div></div><div class="im">____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></div></blockquote></div><br></div></div>
</blockquote></div><br></div>