Hi Maurizio,<br><br>I guess what you are trying to do is possible with macros, but I could be wrong as it is difficult to understand what you are doing, because we all seem to lack a common vocabulary in this matter. Sorry if I misunderstood your intentions.<br>
<br>Your expander seems to be a function. I think you are trying to generate some syntax from a plain old function. And that is where you run into problems that you try to solve with eval. I suspect that you should program your expander as a set of utility macros. that build up the lambda you need. Perhaps no eval is needed but you do mention that you want to do certain optimizations.<br>
<br>This tutorial helped me to understand some basics of macros. For example how to generate code with them. Now Racket has lots of other facilities as well but maybe these give you ideas how to ask more precise questions?<br>
<a href="http://hipster.home.xs4all.nl/lib/scheme/gauche/define-syntax-primer.txt">http://hipster.home.xs4all.nl/lib/scheme/gauche/define-syntax-primer.txt</a><br><br>On the topic of macros, I find it a bit confusing that to metaprogram in Racket, I must use such a different language of macros (with syntax-rules et al.), instead of being able to manipulate common data structures with plain old Racket functions. The approach in Clojure, that the code is just a common data structure, easily manipulatable with Clojure code, is intriguing. What I must do with syntax-rules et al. brings me memories of template metaprogramming in C++, where I had to twist my mind in order to be able to do the most simple of things. Writing regular tree manipulation in Racket is easy, but manipulating the syntax tree with the macro support is not because of this &quot;language switch&quot;.<br>
<br>Once more, to me it seems your expander tries to use plain old Racket to come up with a list of symbols, that is what you think your expanded program should look like. And then you try to make it a macro. I think this is not what the usual Racket way of writing macros is.<br>
<br>-Markku<br><br><div class="gmail_quote">On Thu, Jul 14, 2011 at 12:30 AM, Maurizio Giordano <span dir="ltr">&lt;<a href="mailto:maurizio.giorda@gmail.com">maurizio.giorda@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Hi Matthias, hi all<br><br><div class="gmail_quote"><div class="im">2011/7/13 Matthias Felleisen <span dir="ltr">&lt;<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>&gt;</span><br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<br>
<br>
[I hadn&#39;t forgotten your messages, it&#39;s just that deadlines got in the way.]<br>
<br>
I still don&#39;t understand your desire to access the environmental variables specially:<br>
<br>
1.  if you generate a closure or a struct full of closures in your macro, the expression that you pass in captures the variables in its context:<br>
<br>
&gt; (define-syntax-rule (mystuff y expr) (lambda (x) (displayln `(expr ,y)) (if expr x 0)))<br>
&gt; [  (let ((t 333)) (mystuff t (&gt; t 444)))   22]<br>
((&gt; t 444) 333)<br>
0<br>
<br>
See it really does get t&#39;s value from the context.<br>
<br></blockquote></div><div>Yes it does ... I know that if the macro returns the lambda ...</div><div>no problem, unfortunately my macro returns something like:</div><div>(eval `(lambda ...))</div><div>Now the question is: Can I rewrite my macro to generate the same code</div>

<div>without using the &quot;(eval `(lambda  ...))&quot;?</div><div>I don&#39;t know, I feel yes ... but at the moment I don&#39;t know how to</div><div>redesign it.</div><div>My lambda code is not a predefined template</div>

<div>(the quasiquote) with some small parts to be instantiated (with unquoting).</div><div>First, the lambda code is very large,</div><div>Second, it is recursively produced by an expander function (used in the macro).</div>

<div>When you call the macro, you don&#39;t know in advance how many times </div><div>the expander will call itself. It is something like:</div><div><br></div><div>(define-syntax-rule replace</div><div>   ...</div><div>   (eval `(lambda (x) </div>

<div>                 ... static part ...</div><div>                 ,(expander ...)   ; this inject a part of the lambda code   </div><div>                 ...)))</div><div><br></div><div>(define (expander ...)</div><div>

  `(let ((...))</div><div>       ... static part ...</div><div>       ,(expander ...)             ; injection once again   </div><div>       ...))</div><div class="im"><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<br>
2a. do you have reason to access variables other than throwing them into the environment for eval? In that case your problem is solved.<br> </blockquote><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">


2b. if not, what are the reasons to guess at variable names in the context of the macro USE (not definition)?<br>
<br></blockquote></div><div>I try to answer to both questions:</div><div><br></div><div>My macro is the primitive of a new language:</div><div><br></div><div>&lt; elem1, elem2, ... , (replace x y by (+ x y) if (&gt; x othervar)) &gt;</div>

<div><br></div><div>the replace macro has the following inputs:</div><div>x, y = free variables to be matched on a set of elements (&lt;...&gt;)</div><div>(+ x y) = a form to be inserted in the set inspite of x and y</div>

<div>(&gt; x othervar) = a conditional form: here x is matched (bound) locally,</div><div>othervar is  a symbol &quot;outside&quot; the set (that is the scheme top env or</div><div>any other inner env like a let)</div><div>

This is why I need that the produced lambda USE outside symbols.</div><div>At the moment, in my implementation, the lambda can use outside</div><div>symbols if they are defined in the top env ... I would like to have it also in</div>

<div>inner environments. </div><div class="im"><div> </div><div>  </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
;; ----------------<br>
<br>
<br>
SEPARATE QUESTION: Now you also write that you process the code before you throw it to eval. Is it possible to write functions on syntax that process the code and perform the optimizations that Racket doesn&#39;t perform for you?<br>


<font color="#888888"><br></font></blockquote></div><div>That&#39;s an interesting question: yes ... I process A LOT the code before</div><div>I throw it to the eval ... as I said you it is like a compiler (... my first research area... many years ago!)</div>

<div>First: I generate recursively the code with a my expander function (not the one of racket)  </div><div>Second: I (try) to generate an efficient code to simulate the runtime of the language (the chemical language) I have implemented on top of racket.</div>

<div>If you look at the generated code, you can figure out several optimizations.</div><div>One is &quot;inlining&quot;: if I have a lambda (in my case a chemical rule) that will be executed many times (on all possible combinations of elements in a set), </div>

<div>and each time the lambda may use recursion, than, from my experience it is</div><div>better to explode recursive calls in recursive inlining of code.</div><div>From your question I understand that you mean &quot;optimizations of racket</div>

<div>code&quot; that racket does not do.</div><div><br></div><div>Absolutely an interesting discussion... thanks.</div><div><br></div><div>Cheers,</div><div>Maurizio.</div><div><div></div><div class="h5"><div>  </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<font color="#888888">
-- Matthias<br>
</font><div><div></div><div><br>
<br>
<br>
<br>
<br>
<br>
On Jul 13, 2011, at 3:54 PM, Maurizio Giordano wrote:<br>
<br>
&gt; Hi all, hi Matthias,<br>
&gt;<br>
&gt; I would like to come back to my (still unsolved) problem I<br>
&gt; proposed some days ago:<br>
&gt;<br>
&gt; when using define-syntax in a inner scope of bindings (like let),<br>
&gt; in this example:<br>
&gt;<br>
&gt; (define-syntax mymacro<br>
&gt;   (syntax-rules ()<br>
&gt;     [(_ x)<br>
&gt;       (eval `(lambda (w) (print (quote x)) (if x w #f)))]))<br>
&gt;<br>
&gt; (let* ((s 3) (f (mymacro (&gt; s 0)))) (f 5))<br>
&gt; reference to undefined identifier: s<br>
&gt;<br>
&gt; of course if you:<br>
&gt;<br>
&gt; (define s 3)<br>
&gt;<br>
&gt; in the top environment, the error will not appear.<br>
&gt; This is even more clear if you expand the macro:<br>
&gt;<br>
&gt; (syntax-&gt;datum (expand &#39;(mymacro (&gt; s 0))))<br>
&gt; ... you see that &quot;s&quot; is a %top binding.<br>
&gt;<br>
&gt; I know that if I make the macro to return directly the lambda,<br>
&gt; it works. Nevertheless, in my implementation, I still need to use<br>
&gt; the &quot;(eval (quasiquote (lambda ...)))&quot;.<br>
&gt; Why? my macro is like a compiler<br>
&gt; that generates a lambda code very huge: the code  is recursive in some of its part,<br>
&gt; but, for efficiency reasons, i preferred to inline all recursive calls. So I use a<br>
&gt; function &quot;expander&quot; that makes recursive inlining (or injecting) of code).<br>
&gt; It is more or less something like:<br>
&gt;<br>
&gt; `(lambda (...) ... static-code...  ,(expander ...) ...)<br>
&gt;<br>
&gt; where &quot;expander call itself with different parameters.<br>
&gt;<br>
&gt; This is just to know your opinion... if the &quot;(eval (quasiquote (lambda ...)))&quot;<br>
&gt; cannot see local bindings like in let*, than I have to choice:<br>
&gt; 1) renounce to the feature.<br>
&gt; 2) looking for alternative methods to generate my code with recursive inlining<br>
&gt;<br>
&gt; Than you,<br>
&gt; Cheers,<br>
&gt; Maurizio.<br>
<br>
</div></div></blockquote></div></div></div><br>
<br>_________________________________________________<br>
  For list-related administrative tasks:<br>
  <a href="http://lists.racket-lang.org/listinfo/users" target="_blank">http://lists.racket-lang.org/listinfo/users</a><br></blockquote></div><br>