[racket] help: how to make eval see local bindings?

From: Maurizio Giordano (maurizio.giorda at gmail.com)
Date: Tue Jul 12 06:41:34 EDT 2011

Hi Matthias, hi schemers,

2011/7/11 Matthias Felleisen <matthias at ccs.neu.edu>

>
> Now I don't understand at all why you want to use eval in the macro.
> If the right-hand side just returned the lambda that you have there,
> it would automatically capture the variables in the context of the
> gama rule.
>
>

> Have you tried just returning the lambda as is from the macro?
>
> I tried but it doesn't work! Here you find a sample of what you suggest:
---------------
(define-syntax mymacro
  (syntax-rules (prova)
    [(mymacro input ...)
     (lambda (z) (list input ...) (+ z extern-var))]))

> (let* ((extern-var 2) (f (mymacro x y))) (f 1))
reference to undefined identifier: extern-var
-----------------
So, it seeems that although I avoid "eval" the problem
is still there!

Just to give you more details of my implementation...
In my case things are a little more complicated:

I told you that the gamma-rule is "similar" to a lambda, not a lambda.
In order to separate gamma-rules form normal procedures I defined
a structure for gamma-rules like this:

  ; Rule datatype definition
  (define-values (s:gamma make-gamma gamma? gamma-ref gamma-set!)
     (make-struct-type 'gamma #f 3 0 #f ...))

the first field is the procedure resulted form the lambda evaluation (it is
the lambda generated by the "replace" macro, and the lambda code generation
depends on the gamma-rule inputs), the other fields are parameters of the
rule, like "active" or "inactive", etc.

so the "replace" macro does not return a lambda, but a struct whose
first field is a procedure resulting from: (eval `(lambda ...)):

(define-syntax replace-once
   (syntax-rules (replace-once)
        [(replace input ...)
         (let* (...compute some parameters "x" "y" from input...)
           (make-gamma
             (eval
                (quasiquote
                  (lambda (cntx)
                     ...unquote "x" and "y" to generate specific code ...
                     ...some references to external symbols ...
                  )))
             <field2>
             <filed3>))]))

I know that my implementation seems to be complicated,
but, since I have a "new language" running on scheme, I would like to
have multisets and (chemical) gamma rules defined as new structures
different from similar native structures of racket (i.e. vectors and
procedures).

>From what you say I understand I HAVE TO AVOID EVAL...
... and up to now I don't find another solution to generate the
lambda, other than "(eval (quasiquote (lambda (...) ...))".

Thank you for your attention.
If you mind some "eval" alternatives that are able to capture
local binding (i.e. the local environment), please let me know.
Browsing the racket documentation I found some alternative "eval"
version (r5rs):

(eval expr evironment-specific)

but it seems it allows only to capture a specified namespace
bunding... I will spend some time to look at it!

Cheers,

Maurizio.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110712/858969b5/attachment.html>

Posted on the users mailing list.