<HTML><BODY>Thank you. You answer is very useful.<br><br>&gt; You have to be careful about duplicating inputs in expanded code.<br><br>I thought, that hygiene implies not only cl:gensym, but also once-only. Is there something like&nbsp;<a href="http://common-lisp.net/project/cl-utilities/doc/once-only.html" data-mce-href="http://common-lisp.net/project/cl-utilities/doc/once-only.html">http://common-lisp.net/project/cl-utilities/doc/once-only.html</a>&nbsp;in Racket?<br><br>&gt;&nbsp;A lot of the benefits you get from explicit optimization will also come from using define-inline from racket/performance-hint.<br><br>Do you think, that Racket will do pure calculations in compile-time?<br><br>For example, if I write<br><br>(+ x (* 2 3 4) (sin 20))<br><br>will it be optimized to <br><br>(+ x &nbsp;24.912945250727628) ?<br><br>Or I have to use define-syntax to do it?<br><br><br>Четверг, 11 июля 2013, 0:26 -04:00 от Carl Eastlund &lt;cce@ccs.neu.edu&gt;:<br>
<blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;" class="mailru-blockquote">
        <div id="">
        



    






        

        
        
        
        
        

        



<div class="js-helper js-readmsg-msg">
        <style type="text/css"></style>
        <div id="style_13735168580000000523" class="mr_read__body">
                <base target="_self" href="https://e.mail.ru/">
                
                        <div id="style_13735168580000000523_BODY"><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>&nbsp; (square (perform-expensive-computation))<br><br></div>then you will expand it to:<br>

<br></div>&nbsp; (* (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.&nbsp; 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>&nbsp; (define/syntax-parse body #'(* x x))<br>

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

&nbsp;&nbsp;&nbsp; [(square (expt e:expr n:expr)) #'(expt e (* n 2))]<br>&nbsp;&nbsp;&nbsp; [(square e:expr) #'(let ([x e]) body)]<br>&nbsp;&nbsp;&nbsp; [square #'(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.&nbsp; There isn't a problem with "x" here, because the name is not used as a pattern variable, it's a variable name introduced by the macro everywhere it occurs.<br>

<br></div>If you'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="sentmsg?mailto=mailto%3akalimehtar@mail.ru" target="_blank">kalimehtar@mail.ru</a>&gt;</span> wrote:<br><div>

<div><blockquote 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>&nbsp; (syntax-case stx (square expt)<br>&nbsp; &nbsp; [(square (square expr)) #'(expt expr 4)]<br>&nbsp; &nbsp; [(square (expt expr n)) (if (number? (syntax-e #'n))<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;#`(expt expr #,(* (syntax-e #'n) 2))<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;#'(expt expr (* n 2)))]<br>&nbsp; &nbsp; [(square x) #'(* x x)]<br>&nbsp; &nbsp; [square #'(lambda (x) (* x x))]))<br>

<br>So I can write &nbsp;(square (expt x 5)) and have evaluate (expt x 10) and I can write (map square '(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 &nbsp;<br>

<br></p><p>(define-syntax (square stx)<br>&nbsp; (let ([body #'(* x x)])<br>&nbsp; &nbsp;&nbsp;(syntax-case stx (square expt)<br>&nbsp; &nbsp; &nbsp; ...<br>&nbsp; &nbsp; &nbsp; ...<br>&nbsp; &nbsp; &nbsp; [(square x) body]<br>&nbsp; &nbsp; &nbsp; [square #'(lambda (x) #`body)]))<br><br>but hygiene prevents me from that: &nbsp;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><font color="#888888"><br><br>-- <br>Roman Klochkov</font></span></div>
<br>____________________<br>
&nbsp; Racket Users list:<br>
&nbsp; <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>

</div>
                        
                
                <base target="_self" href="https://e.mail.ru/">
        </div>

        
</div>


</div>
</blockquote>
<br>
<br>-- 
<br>Roman Klochkov<br></BODY></HTML>