Well, perhaps eval is the only way to go. There are situations where you need 
it; otherwise it wouldn't be there - Matthias



On Jul 13, 2011, at 5:30 PM, Maurizio Giordano wrote:

> Hi Matthias, hi all
> 
> 2011/7/13 Matthias Felleisen <matth...@ccs.neu.edu>
> 
> 
> [I hadn't forgotten your messages, it's just that deadlines got in the way.]
> 
> I still don't understand your desire to access the environmental variables 
> specially:
> 
> 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:
> 
> > (define-syntax-rule (mystuff y expr) (lambda (x) (displayln `(expr ,y)) (if 
> > expr x 0)))
> > [  (let ((t 333)) (mystuff t (> t 444)))   22]
> ((> t 444) 333)
> 0
> 
> See it really does get t's value from the context.
> 
> Yes it does ... I know that if the macro returns the lambda ...
> no problem, unfortunately my macro returns something like:
> (eval `(lambda ...))
> Now the question is: Can I rewrite my macro to generate the same code
> without using the "(eval `(lambda  ...))"?
> I don't know, I feel yes ... but at the moment I don't know how to
> redesign it.
> My lambda code is not a predefined template
> (the quasiquote) with some small parts to be instantiated (with unquoting).
> First, the lambda code is very large,
> Second, it is recursively produced by an expander function (used in the 
> macro).
> When you call the macro, you don't know in advance how many times 
> the expander will call itself. It is something like:
> 
> (define-syntax-rule replace
>    ...
>    (eval `(lambda (x) 
>                  ... static part ...
>                  ,(expander ...)   ; this inject a part of the lambda code   
>                  ...)))
> 
> (define (expander ...)
>   `(let ((...))
>        ... static part ...
>        ,(expander ...)             ; injection once again   
>        ...))
> 
> 2a. do you have reason to access variables other than throwing them into the 
> environment for eval? In that case your problem is solved.
>  
> 2b. if not, what are the reasons to guess at variable names in the context of 
> the macro USE (not definition)?
> 
> I try to answer to both questions:
> 
> My macro is the primitive of a new language:
> 
> < elem1, elem2, ... , (replace x y by (+ x y) if (> x othervar)) >
> 
> the replace macro has the following inputs:
> x, y = free variables to be matched on a set of elements (<...>)
> (+ x y) = a form to be inserted in the set inspite of x and y
> (> x othervar) = a conditional form: here x is matched (bound) locally,
> othervar is  a symbol "outside" the set (that is the scheme top env or
> any other inner env like a let)
> This is why I need that the produced lambda USE outside symbols.
> At the moment, in my implementation, the lambda can use outside
> symbols if they are defined in the top env ... I would like to have it also in
> inner environments. 
>  
>   
> ;; ----------------
> 
> 
> 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't perform for you?
> 
> That's an interesting question: yes ... I process A LOT the code before
> I throw it to the eval ... as I said you it is like a compiler (... my first 
> research area... many years ago!)
> First: I generate recursively the code with a my expander function (not the 
> one of racket)  
> 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.
> If you look at the generated code, you can figure out several optimizations.
> One is "inlining": 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), 
> and each time the lambda may use recursion, than, from my experience it is
> better to explode recursive calls in recursive inlining of code.
> From your question I understand that you mean "optimizations of racket
> code" that racket does not do.
> 
> Absolutely an interesting discussion... thanks.
> 
> Cheers,
> Maurizio.
>   
> -- Matthias
> 
> 
> 
> 
> 
> 
> On Jul 13, 2011, at 3:54 PM, Maurizio Giordano wrote:
> 
> > Hi all, hi Matthias,
> >
> > I would like to come back to my (still unsolved) problem I
> > proposed some days ago:
> >
> > when using define-syntax in a inner scope of bindings (like let),
> > in this example:
> >
> > (define-syntax mymacro
> >   (syntax-rules ()
> >     [(_ x)
> >       (eval `(lambda (w) (print (quote x)) (if x w #f)))]))
> >
> > (let* ((s 3) (f (mymacro (> s 0)))) (f 5))
> > reference to undefined identifier: s
> >
> > of course if you:
> >
> > (define s 3)
> >
> > in the top environment, the error will not appear.
> > This is even more clear if you expand the macro:
> >
> > (syntax->datum (expand '(mymacro (> s 0))))
> > ... you see that "s" is a %top binding.
> >
> > I know that if I make the macro to return directly the lambda,
> > it works. Nevertheless, in my implementation, I still need to use
> > the "(eval (quasiquote (lambda ...)))".
> > Why? my macro is like a compiler
> > that generates a lambda code very huge: the code  is recursive in some of 
> > its part,
> > but, for efficiency reasons, i preferred to inline all recursive calls. So 
> > I use a
> > function "expander" that makes recursive inlining (or injecting) of code).
> > It is more or less something like:
> >
> > `(lambda (...) ... static-code...  ,(expander ...) ...)
> >
> > where "expander call itself with different parameters.
> >
> > This is just to know your opinion... if the "(eval (quasiquote (lambda 
> > ...)))"
> > cannot see local bindings like in let*, than I have to choice:
> > 1) renounce to the feature.
> > 2) looking for alternative methods to generate my code with recursive 
> > inlining
> >
> > Than you,
> > Cheers,
> > Maurizio.
> 
> 


_________________________________________________
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/users

Reply via email to