<div dir="ltr"><div class="gmail_extra"><div><div><div><div><div><div>Scott,<br><br></div>I see what you're doing now.  You're not actually trying to use macro expansion at all; you're just using local-expand to substitute the definition of pred? where it occurs, so that you can make its macro definition also serve as its DSL definition.  That's sensible, but local-expand is still doing more than you want it to.  That's why I put in all the expansion caveats -- not because you necessarily meant to do full expansion, but because local-expand is pretty explicitly built for full expansion, and always tries to push as far as it can.  Any time the caveats about expansion don't apply, local-expand is probably a bigger gun than you need.<br>

<br></div>Where local-expand is going to bite you is when the definition of pred? uses a macro at its top level.  For instance:<br><br></div>  (define-syntax-rule (pred? x) (or (< x 3) (> x 7)))<br><br></div>Here, local-expand is going to expand the use of (or ...), and any macro that (or ...) produces at its top level, until you reach a core form as the main expression, or something you've put in an explicit stop list.  That's not what you want, as I understand it -- you only want to expand pred?.<br>

<br></div>So what to do when you want to apply one macro, but not perform general expansion?  Extract its transformer using syntax-local-value, and apply it to the expression.  You probably also want to apply a syntax mark before and after transformation, just to simulate the base level of hygiene the macro may be relying on.  It might not be necessary for simple definitions, but it can't hurt.<br>

<br></div>I wrote up some code that does this, along with a test showing that it won't expand "or" too far.  It's also reasonably hygienic -- it won't be confused if someone defines a different macro named "pred?", for example.  I don't know if that's a concern, but again, it can't hurt.  Anyway, you can find what I wrote here: <a href="https://gist.github.com/carl-eastlund/8626893">https://gist.github.com/carl-eastlund/8626893</a><br>

<br clear="all"><div>Carl Eastlund</div>
<br><div class="gmail_quote">On Fri, Jan 24, 2014 at 1:30 PM, Scott Klarenbach <span dir="ltr"><<a href="mailto:scott@pointyhat.ca" target="_blank">scott@pointyhat.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div dir="ltr"><div>Just an update, I was able to make this work.</div><div><br></div><div>#lang racket</div><div>(require (for-syntax racket/syntax syntax/stx))</div><div><br></div><div>(define-syntax-rule (pred? x) (> 3 x))</div>

<div class="im">
<div><br></div><div>(define-for-syntax (recursive-expand stx)</div><div>  (let loop ([l (syntax->list stx)])</div><div><span style="white-space:pre-wrap">  </span>(cond [(stx-null? l) l]</div><div><span style="white-space:pre-wrap">          </span>  [(stx-pair? (stx-car l))</div>


<div><span style="white-space:pre-wrap">          </span>   (cons (loop (stx-car l)) (loop (stx-cdr l)))]</div></div><div><span style="white-space:pre-wrap">            </span>  [(equal? 'pred? (syntax->datum (stx-car l)))</div><div>


<span style="white-space:pre-wrap">             </span>   (local-expand (cons (stx-car l) (loop (stx-cdr l))) 'expression #f)] ;; this works</div><div class="im"><div><span style="white-space:pre-wrap">               </span>  [else</div><div>

<span style="white-space:pre-wrap">             </span>   (cons (stx-car l) (loop (stx-cdr l)))])))</div>
<div><br></div><div>(define-syntax (test stx)</div><div>  (syntax-case stx ()</div><div><span style="white-space:pre-wrap">    </span>[(_ x)</div></div><div><span style="white-space:pre-wrap">       </span> (with-syntax ([expanded (recursive-expand #'x)])</div>


<div><span style="white-space:pre-wrap">  </span>   #''expanded)]))</div><div><br></div><div>(module+ test</div><div>  (require rackunit)</div><div>  (check-equal? (test (or (< 10 x) (pred? y)))</div><div><span style="white-space:pre-wrap">                            </span>'(or (< 10 x) (> 3 y))))</div>


<div><br></div><div>The code I couldn't figure out last night was:</div><div>(local-expand (cons (stx-car l) (loop (stx-cdr l))) 'expression #f)]<br></div><div class="im"><div><br></div><div>Thanks.</div><div><br>

</div>-- <br>Talk to you soon,<br>
<br>Scott Klarenbach<br><br>PointyHat Software Corp.<br><a href="http://www.pointyhat.ca" target="_blank">www.pointyhat.ca</a><br>p <a href="tel:604-568-4280" value="+16045684280" target="_blank">604-568-4280</a><br>e <a href="mailto:scott@pointyhat.ca" target="_blank">scott@pointyhat.ca</a><br>


<span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">200-1575 W. Georgia</span><br>Vancouver, BC <span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">V6G2V3</span><br>
<br>_______________________________________<br>To iterate is human; to recur, divine
</div></div>
</blockquote></div><br></div></div>