<div dir="ltr"><div><div><div><div><div><div>Roman,<br><br></div>Bear in mind that by expanding (square x) to (square x x), that means if someone writes<br><br>  (square (perform-expensive-computation))<br><br></div>then you will expand it to:<br>

<br></div>  (* (perform-expensive-computation) (perform-expensive-computation))<br><br></div><div>You have to be careful about duplicating inputs in expanded code.<br></div><div><br></div>A lot of the optimizations you are performing manually will be done by the Racket optimizer anyway; more if you use Typed Racket with optimizations on, and you can always use the Optimization Coach to find more.  A lot of the benefits you get from explicit optimization will also come from using define-inline from racket/performance-hint.<br>

<br>If you still prefer to manually expand these things, then I suggest something like the following:<br><br>(require (for-syntax syntax/parse))<br><br>(define-syntax (square stx)<br>  (define/syntax-parse body #&#39;(* x x))<br>

  (syntax-parse stx<br>    #:literals [square expt]<br>    [(square (square e:expr)) #&#39;(expt e 4)]<br>    [(square (expt e:expr n:number))<br>     (define/syntax-parse 2n (* 2 (syntax-e #&#39;n)))<br>     #&#39;(expt e &#39;2n)]<br>

    [(square (expt e:expr n:expr)) #&#39;(expt e (* n 2))]<br>    [(square e:expr) #&#39;(let ([x e]) body)]<br>    [square #&#39;(lambda (x) body)]))<br><br></div>Note that syntax-parse lets you check for numeric inputs in the pattern, and define/syntax-parse lets you bind pattern variables.  There isn&#39;t a problem with &quot;x&quot; here, because the name is not used as a pattern variable, it&#39;s a variable name introduced by the macro everywhere it occurs.<br>

<br></div>If you&#39;re unfamiliar with syntax-parse, I encourage you to learn it, but you can always use syntax-case and replace define/syntax-parse with define/with-syntax from the racket/syntax module.<br><div><div><div>

<div><div><div><div><div><div><br>On Thu, Jul 11, 2013 at 12:09 AM, Roman Klochkov <span dir="ltr">&lt;<a href="mailto:kalimehtar@mail.ru" target="_blank">kalimehtar@mail.ru</a>&gt;</span> wrote:<br><div class="gmail_extra">

<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><p>I like to make syntax-optimized functions.<br><br>(define-syntax (square stx)<br>  (syntax-case stx (square expt)<br>    [(square (square expr)) #&#39;(expt expr 4)]<br>    [(square (expt expr n)) (if (number? (syntax-e #&#39;n))<br>

                                                 #`(expt expr #,(* (syntax-e #&#39;n) 2))<br>                                                 #&#39;(expt expr (* n 2)))]<br>    [(square x) #&#39;(* x x)]<br>    [square #&#39;(lambda (x) (* x x))]))<br>

<br>So I can write  (square (expt x 5)) and have evaluate (expt x 10) and I can write (map square &#39;(1 2 3)) and it is also works.<br><br>But I dislike to repeate the body of the function in last two cases.<br><br>I tryed  <br>

<br></p><p>(define-syntax (square stx)<br>  (let ([body #&#39;(* x x)])<br>    (syntax-case stx (square expt)<br>      ...<br>      ...<br>      [(square x) body]<br>      [square #&#39;(lambda (x) #`body)]))<br><br>but hygiene prevents me from that:  x: unbound identifier in module in: x</p>

How can I bind template body with some variable? Or how to rewrite the syntax to evade duplication?<span class=""><font color="#888888"><br><br>-- <br>Roman Klochkov</font></span></div>
<br>____________________<br>
  Racket Users list:<br>
  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br></blockquote></div><br></div></div></div></div></div></div></div></div></div></div></div>