<HTML><BODY>Thank you. You answer is very useful.<br><br>> 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 <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> in Racket?<br><br>> 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 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 <cce@ccs.neu.edu>:<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> (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 #'(* x x))<br>
(syntax-parse stx<br> #:literals [square expt]<br> [(square (square e:expr)) #'(expt e 4)]<br> [(square (expt e:expr n:number))<br> (define/syntax-parse 2n (* 2 (syntax-e #'n)))<br> #'(expt e '2n)]<br>
[(square (expt e:expr n:expr)) #'(expt e (* n 2))]<br> [(square e:expr) #'(let ([x e]) body)]<br> [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. 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"><<a href="sentmsg?mailto=mailto%3akalimehtar@mail.ru" target="_blank">kalimehtar@mail.ru</a>></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> (syntax-case stx (square expt)<br> [(square (square expr)) #'(expt expr 4)]<br> [(square (expt expr n)) (if (number? (syntax-e #'n))<br>
#`(expt expr #,(* (syntax-e #'n) 2))<br> #'(expt expr (* n 2)))]<br> [(square x) #'(* x x)]<br> [square #'(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 '(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 #'(* x x)])<br> (syntax-case stx (square expt)<br> ...<br> ...<br> [(square x) body]<br> [square #'(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><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>
</div>
                        
                
                <base target="_self" href="https://e.mail.ru/">
        </div>
        
</div>
</div>
</blockquote>
<br>
<br>--
<br>Roman Klochkov<br></BODY></HTML>