<br><div class="gmail_quote">On Sat, Dec 11, 2010 at 2:49 PM, YC <span dir="ltr">&lt;<a href="mailto:yinso.chen@gmail.com">yinso.chen@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br><div class="gmail_quote"><div class="im">On Sat, Dec 11, 2010 at 8:56 AM, Ryan Culpepper <span dir="ltr">&lt;<a href="mailto:ryanc@ccs.neu.edu" target="_blank">ryanc@ccs.neu.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><br></div>
If you are only supporting syntax-rules, then I recommend implementing the algorithm from &quot;Macros that Work&quot; by Clinger and Rees. Hygienic macro expansion does typically involve alpha-conversion---renaming lexical variables to fresh names. The challenge, as you mention above, is in not renaming too eagerly.</blockquote>
</div></div></blockquote><div><br></div><div>Looking at the paper, it occurred to me that one way to ensure that macro expands to the correct binding is for the macro to carry the references to the environment itself. </div>
<div><br></div><div>So for the example in the paper: </div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div class="gmail_quote"><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">(let-syntax ((push (syntax-rules </font></div>
</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                       ((push ?v ?x) </font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                        =&gt; </font></div>
</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">                        (set! ?x (cons ?v ?x))))))</font></div></div></div><div class="gmail_quote"><div>
<div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">  (let ((pros (list &quot;cheap&quot; &quot;fast&quot;))</font></div></div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">        (cons (list)))</font></div>
</div></div><div class="gmail_quote"><div><div><font class="Apple-style-span" face="&#39;courier new&#39;, monospace">    (push &quot;unreliable&quot; cons)))</font></div></div></div></blockquote><div class="gmail_quote">
<div><br></div><div>The push macro already contains the bindings to set! and cons, so the later shadowing of cons does not overwrite push&#39;s own copy of cons.  In that sense a macro transformer&#39;s job is to merge its own environment along with the call-site&#39;s environment. </div>
<div><br></div><div>The key to correctly implement macros is then to ensure that every macro holds references to a environment at the point of its definition, so it can then be used for merging during the expansion.</div>
<div><br></div><div>Is this a fair way of thinking about macro expansions? </div><div><br></div><div>Thanks,</div><div>yc</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div>