<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Ok, I will give you more details about my project... maybe you could
be interested<br>
in it :><br>
But first I need to underline that the macro *cannot foresee* which
extern variables the<br>
lambda can reference ... so I cannot adopt your solution:<br>
<pre wrap="">(define-syntax mym
(syntax-rules ()
[(_ input ...)
(let* ([x 10]) ; at this time, I don't know if lambda will use "x", if "x" is bounded
; and (if bounded) which is the binding
(lambda (stuff)
input ... ;; line 2
x))]))</pre>
Now let's describe my project.<br>
I have defined a new language in racket, named chemical language
(HOCL).<br>
The basic data structure of HOCL is the "multiset". It is a similar
to a vector,<br>
with the difference that the elements are not ordered, but they move
stochastically<br>
inside the vector (but this is all folks!). The multiset is a sort
of chemical container<br>
(solution) of molecules.<br>
<br>
molecules can be any racket object: numbers?, strings, lists, and
"gamma-rules".<br>
A "gamma-rule" is very similar to a scheme lambda. It is a function<br>
that captures some elements (chemical molecules) of the multiset and
produces<br>
new molecules. In the chemical language, gamma-rules are the
"chemical rules"<br>
that fire reactions in the mutliset (the chemical solution), and
that transform molecules in<br>
new molecules.<br>
<br>
I implemented a reader for the multiset notation: < molecule1,
molecule2, ... ><br>
where commas separates the multiset elements, and "<" ">" are
multiset delimiters.<br>
<br>
I create and bind a multiset in this way <br>
<br>
(define m < 1,2,3,4,(replace x y by (+ x y)), 5, 6 >) ; top
level definition<br>
< 1,2,3,4, #<procedure>, 5, 6 >
<br>
; the output is a chemical container with a gamma-rule inside it
(plus other molecules)<br>
; the "x" and "y" free variables of the rule are bound to molecules
by a pattern matching<br>
mechanism, <br>
<br>
Now I have a chemical engine ("cham") that starts reactions in the
chemical solution.<br>
The gamma-rules are applied to the mutliset (with the sheme
"apply").<br>
> (cham m)<br>
< 21, #<procedure> ><br>
<br>
As you see the chemical rule (gamma-rule) applies many times, and
each time it adds <br>
pairs of molecules until one molecule (the total sum) is left (the
chemical inert state). <br>
<br>
Now let's talk about the "gamma-rule" generation: the macro "replace
... by ... "<br>
generate the gamma-rule code <br>
<pre wrap="">(define-syntax replace
(syntax-rules (replace)
[(replace input ...)
(let* (...)
(eval `(lambda (cntx) ; the code of the "gamma-rule"
...
))]))
</pre>
Now the problem... In the previous example I can define a rule like
this:<br>
<br>
(replace x y by (+ x y) if (> top (+ x y))), 5, 6 >)<br>
<br>
that is, I want the reaction to take place only if the partial sum
of molecules is not over "top",<br>
where the "top" variable may be externally defined.<br>
Now I can write the code:<br>
<br>
(let ((top 8)<br>
(m < 1,2,3,4,(replace x y by (+ x y) if (> top (+ x
y))), 5, 6 >))) ; multiset elements are evaluated after reading<br>
(cham m))<br>
reference to undefined identifier: top<br>
<br>
... I hope now it is clear that I need to generate procedures with
references to symbols that can<br>
(or cannot) have bindings when the procedure is called... in fact,
the user writes <br>
the (replace ....) form but the system cannot foresee which extern
symbols the generated procedure<br>
may use.<br>
<br>
Thank you for your attention.<br>
Sorry for a so long email... I couldn't explain my probelm with less
details.<br>
Maurizio.<br>
<br>
Il 11/07/2011 17.26, Matthias Felleisen ha scritto:
<blockquote
cite="mid:B120A844-54CF-4A0E-BAA5-408D29E7976A@ccs.neu.edu"
type="cite">
<pre wrap="">
This sounds a bit confused. Allow me to tease out a clarification.
1. If you write a macro like this:
(define-syntax mym
(syntax-rules ()
[(_ input ...)
(let* ([x 10])
(lambda (stuff)
input ... ;; line 2
x))]))
'hygiene' gives you a couple of different things:
-- the x and the stuff introduced in the macro doesn't accidentally interfere with free variables in input ... on line 2
-- the let* and the lambda are guaranteed to refer to the meaning in place where you define the macro
2. So when you run this expression in the context of mym
(let ([x 42]) ;; line 9
((mym (displayln x)) ;; line 7
'random-argumnent))
you see
-- the output 42 from the displayln on line 7
-- the result 10 from the line below line 2
3. It is rare that mym needs to generate code involving the x on line 9 WITHOUT specifying the x in an input position for mym.
QUESTION: can you explain why you'd want to do so?
POSSIBLE ANSWER: you may wish to break hygiene then.
4. It is equally rare that you want let* or lambda to mean what the context of the macro call says they are.
IF THIS IS WHAT YOU WANT, can you provide more details.
On Jul 11, 2011, at 11:04 AM, Maurizio Giordano GMAIL wrote:
</pre>
<blockquote type="cite">
<pre wrap="">On Mon, 2011-07-11 at 13:43 +0100, Noel Welsh wrote:
</pre>
<blockquote type="cite">
<pre wrap="">On Mon, Jul 11, 2011 at 1:26 PM, Maurizio Giordano GMAIL
<a class="moz-txt-link-rfc2396E" href="mailto:maurizio.giorda@gmail.com"><maurizio.giorda@gmail.com></a> wrote:
</pre>
<blockquote type="cite">
<pre wrap="">PS. my lambda is generated by a macro (define-syntax) ...
this is why I use eval to generate the corresponding procedure.
</pre>
</blockquote>
<pre wrap="">
If this is the case I don't think you need to use eval. You either
need to write your macro in a hygenic way -- it accepts as parameters
all the identifiers in the enclosing environment that is should
reference -- or you should explicitly break hygiene. If you're new-ish
to Racket the preceeding sentence probably won't make any sense, so
feel free to ask for more help!
Cheers,
N.
</pre>
</blockquote>
<pre wrap="">
Hi Nole,
Yes, I am an absolute new-ish to racket... I would like to know more
about writing a macro by "explicitly break hygiene".
I supposed I didn't need to use eval... but for me it is
the easiest way to "build" a lambda-code and then evaluate it.
I want to give you more details about my problem.
I have a macro like this:
(define-syntax mymacro
(syntax-rules (mymacro)
[(mymacro input ...)
(let* (...)
(eval `(lambda (cntx)
... ; a code generated according to macro
"input ..."
(+ x 2) ; that contains references to an outside "x"
symbol
...
))]))
Note that I cannot foresee which extern symbols are referenced by the
generated lambda.
This macro returns a procedure.
if I use my macro in a "let" construct, of course I have a "reference to
an undefined identifier":
(let* ((x 1)
(f (mymacro ...)))
(f 2))
reference to undefined identifier: x
So, coming back to my question: since the eval is called within the
"let"
scope, is it possible to make it aware of the bindings of the "let"?
Do you know alternative mechanism to do that?
TIA,
Cheers,
Maurizio.
_________________________________________________
For list-related administrative tasks:
<a class="moz-txt-link-freetext" href="http://lists.racket-lang.org/listinfo/users">http://lists.racket-lang.org/listinfo/users</a>
</pre>
</blockquote>
<pre wrap="">
</pre>
</blockquote>
<br>
<br>
<div class="moz-signature">-- <br>
<a href="http://it.linkedin.com/in/giordanomaurizio"> <img
src="cid:part1.02030506.03040308@gmail.com" alt="View Maurizio
Giordano's profile on LinkedIn" width="160" border="0"
height="25"></a><a
href="http://it.linkedin.com/in/giordanomaurizio"> </a></div>
</body>
</html>