I'm trying to construct a macro called memory. The syntax is memory (&rest body) and doing (memory form) should expand to
(SYMBOL-MACROLET ((CELL XXX)) form)
where XXX should be replaced by the number of surrounding memory invocations. So for example
(memory (format t "CELL has value ~a~%" cell) (memory (format t "CELL has value ~a~%" cell)) (format t "CELL has value ~a~%" cell))
should expand to
(SYMBOL-MACROLET ((CELL 1)) (FORMAT T "CELL has value ~a~%" CELL) (SYMBOL-MACROLET ((CELL 2)) (FORMAT T "CELL has value ~a~%" CELL)) (FORMAT T "CELL has value ~a~%" CELL))
and produce CELL has value 1 CELL has value 2 CELL has value 1
Note how in the second invocation of memory, CELL is assigned the form 2 because it is inside 2 nested invocations of memory. No matter how deeply nested (within reason) the invocations of memory are CELL should get the correct value. Below are my efforts but they have not met with success.
With the test I gave above it produces CELL has value 1 CELL has value 1 CELL has value 1
So the second invocation of memory in the test does not increase by 1 the value of CELL.
The second attempt wouldn't be completely satisfactory even if it worked because it exposes to the outside world an internal part of the implementation , the variable B. But it doesn't work.
(defparameter b 0)
(defmacro memory2 (&rest body) (prog2 (defparameter b (+ b 1)) `(symbol-macrolet ((cell ,b)) ,@body) (defparameter b (- b 1))))
Once again doing
(memory2 (format t "CELL has value ~a~%" cell) (memory2 (format t "CELL has value ~a~%" cell)) (format t "CELL has value ~a~%" cell))
produces CELL has value 1 CELL has value 1 CELL has value 1
I tried some variations of the above but no luck. So first why do my attempts above not work ? I assume that by the time the code generated from the macro expansion gets compiled the statement (decf a) has already been executed. Am I right ?
It would be convenient if Lisp had some kind of minimal-compile function so that you could do (minimal-compile form) and it would return what results after minimal compilation of the form. With such a thing one could define memory as
Does anyone know an implementation with such a facility ? Any other solutions to the problem ?
-- Shakespeare also predicted structured programming: "Go to, go to, thou are a foolish fellow. Let me be clear of thee." Twelfth Night, Act IV, Scene 1.
C/USER[100]> (memory (format t "CELL has value ~a~%" cell) (memory (format t "CELL has value ~a~%" cell)) (format t "CELL has value ~a~%" cell)) CELL has value 1 CELL has value 2 CELL has value 1 NIL
> I'm trying to construct a macro called memory. The syntax is > memory (&rest body) and doing (memory form) should expand to
> (SYMBOL-MACROLET ((CELL XXX)) > form)
> where XXX should be replaced by the number of surrounding memory > invocations. So for example
> (memory > (format t "CELL has value ~a~%" cell) > (memory (format t "CELL has value ~a~%" cell)) > (format t "CELL has value ~a~%" cell))
> should expand to
> (SYMBOL-MACROLET ((CELL 1)) > (FORMAT T "CELL has value ~a~%" CELL) > (SYMBOL-MACROLET ((CELL 2)) > (FORMAT T "CELL has value ~a~%" CELL)) > (FORMAT T "CELL has value ~a~%" CELL))
> and produce > CELL has value 1 > CELL has value 2 > CELL has value 1
Why does cell have to be a symbol macro? How about simply generating:
(let ((cell (1+ cell)) ...)
Take advantage of the LET scoping rule which allows you to shadow an outer variable, but use its avlue to initialize the shadowing one.
You just need to bootstrap this somehow for the outermost invocation. Here is where a symbol macro comes in: a global one made with define-symbol-macro, to avoid introducing cell as a dynamic variable.
Spiros Bousbouras wrote: > I'm trying to construct a macro called memory. The syntax is > memory (&rest body) and doing (memory form) should expand to
> (SYMBOL-MACROLET ((CELL XXX)) > form)
> where XXX should be replaced by the number of surrounding memory > invocations. So for example
> (memory > (format t "CELL has value ~a~%" cell) > (memory (format t "CELL has value ~a~%" cell)) > (format t "CELL has value ~a~%" cell))
> should expand to
> (SYMBOL-MACROLET ((CELL 1)) > (FORMAT T "CELL has value ~a~%" CELL) > (SYMBOL-MACROLET ((CELL 2)) > (FORMAT T "CELL has value ~a~%" CELL)) > (FORMAT T "CELL has value ~a~%" CELL))
> and produce > CELL has value 1 > CELL has value 2 > CELL has value 1
What do you want the following to evaluate to?
(setq f (memory (lambda () (memory (print cell)))))
(funcall f)
If you want this to evaluate to 1, the other Pascal's solution is fine.
IF you want this to evaluate to 2, here is another solution:
One important thing to keep in mind: Don't use side effects in macro definitions. In both your solutions, you tried to achieve the result by assigning to a local or global variable as part of the macroexpansion process. However, you cannot predict whether or when, and how often, a particular macro will be invoked. For example, development environments may offer users to expand macros on demand, compilers may expand macros several times for analysis, higher-order macros may expand inner macro for analysis as well, etc., etc. So make sure that your macros are always side-effect-free (unless you really know what you're doing).
On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:
> I'm trying to construct a macro called memory. The syntax is > memory (&rest body) and doing (memory form) should expand to > (SYMBOL-MACROLET ((CELL XXX)) > form) > where XXX should be replaced by the number of surrounding memory > invocations.
Surrounding how? Lexically or dynamically?
---Vassil.
-- "Even when the muse is posting on Usenet, Alexander Sergeevich?"
It makes cell only available within body not everywhere. A difference from my vision is that in the code above cell expands to a variable instead of a numerical constant but that's fairly unimportant. I'm a bit more annoyed by the fact that your solution also exposes an implementation detail to the world. I would prefer a 100% clean solution like what we would have if memory were a function when we would use closures.
On 7 Nov, 18:53, Kaz Kylheku <kkylh...@gmail.com> wrote:
> Why does cell have to be a symbol macro? How about simply generating:
> (let ((cell (1+ cell)) ...)
> Take advantage of the LET scoping rule which allows you to shadow an outer > variable, but use its avlue to initialize the shadowing one.
It doesn't have to be a symbol macro. The point of the exercise is to investigate methods by which different invocations of the same macro can share information. Many of the technical details are unimportant. Having said that , it would be nice to have a way for this sharing of information to happen through objects only the macro knows about.
> You just need to bootstrap this somehow for the outermost invocation. Here is > where a symbol macro comes in: a global one made with define-symbol-macro, > to avoid introducing cell as a dynamic variable.
It would be good if this bootstrapping could be done through the macro definition itself.
-- To have absolutely if l' this large Mister is loved! Translation on 2-11-2009 by http://uk.babelfish.yahoo.com/translate_txt of "A posséder absolument si l'on aime ce grand monsieur!
On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote:
> On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:
> > I'm trying to construct a macro called memory. The syntax is > > memory (&rest body) and doing (memory form) should expand to > > (SYMBOL-MACROLET ((CELL XXX)) > > form) > > where XXX should be replaced by the number of surrounding memory > > invocations.
> Surrounding how? Lexically or dynamically?
Lexically. See the examples above. I'm not even sure what a dynamic surrounding would be.
* Kaz Kylheku <20091107104314....@gmail.com> : Wrote on Sat, 7 Nov 2009 18:44:28 +0000 (UTC):
| On 2009-11-07, Spiros Bousbouras <spi...@gmail.com> wrote: |> It would be convenient if Lisp had some kind of minimal-compile |> function ... | | Indeed, it would help a certain troll in another thread to have a | fraction of a valid point.
Assuming you are baiting me here by calling me a troll, I think you are rather sore for pointing out you had no clue what minimal compilation was and its implications to symbol macro-expansion
In article <52b2c0f6-8c87-498c-a716-11efaf7a0...@o10g2000yqa.googlegroups.com>, Spiros Bousbouras <spi...@gmail.com> wrote:
> On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote: > > On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:
> > > I'm trying to construct a macro called memory. The syntax is > > > memory (&rest body) and doing (memory form) should expand to > > > (SYMBOL-MACROLET ((CELL XXX)) > > > form) > > > where XXX should be replaced by the number of surrounding memory > > > invocations.
> > Surrounding how? Lexically or dynamically?
> Lexically. See the examples above. I'm not even sure what a > dynamic surrounding would be.
When PRINT in FUN2 is called, there's one lexical surrounding invocation, two dynamic ones.
-- Barry Margolin, bar...@alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
On Sat, 7 Nov 2009 14:23:36 -0800 (PST), Spiros Bousbouras <spi...@gmail.com> said:
> On 7 Nov, 19:55, Vassil Nikolov <vniko...@pobox.com> wrote: >> On Sat, 07 Nov 2009 18:18:19 GMT, Spiros Bousbouras <spi...@gmail.com> said:
>> > I'm trying to construct a macro called memory. The syntax is >> > memory (&rest body) and doing (memory form) should expand to >> > (SYMBOL-MACROLET ((CELL XXX)) >> > form) >> > where XXX should be replaced by the number of surrounding memory >> > invocations.
>> Surrounding how? Lexically or dynamically? > Lexically.
Then a solution cannot be based on a special variable (at least not a naïve solution; and even if a complicated solution could, I don't think it would be worth the candles).
---Vassil.
-- "Even when the muse is posting on Usenet, Alexander Sergeevich?"
Let me see if I understand the reason for the difference between memory and memory2. The first call to the two macros expands to the same thing and places what follows in the scope of (after expansions) (symbol-macrolet ((cell 1)) The difference lies in the behaviour of the line (let ((new-cell-value (1+ (macroexpand 'cell env)))) vs (let ((new-cell-value (1+ (macroexpand 'cell)))) in the second call to the macros. There (macroexpand 'cell env) evaluates to 1 whereas (macroexpand 'cell) evaluates to 0. The reason is the following excerpt in the macroexpand page in the HS:
In addition to macro definitions in the global environment, any local macro definitions established within env by macrolet or symbol-macrolet are considered. If only form is supplied as an argument, then the environment is effectively null, and only global macro definitions as established by defmacro are considered.
I assume the last line should actually read "defmacro or define-symbol-macro are considered".
Is my understanding correct ?
-- <Khassaki> HI EVERYBODY!!!!!!!!!! <Judge-Mental> try pressing the the Caps Lock key <Khassaki> O THANKS!!! ITS SO MUCH EASIER TO WRITE NOW!!!!!!! <Judge-Mental> fuck me http://www.bash.org/?835030
On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote:
> One important thing to keep in mind: Don't use side effects in macro > definitions. In both your solutions, you tried to achieve the result by > assigning to a local or global variable as part of the macroexpansion > process. However, you cannot predict whether or when, and how often, a > particular macro will be invoked. For example, development environments > may offer users to expand macros on demand, compilers may expand macros > several times for analysis, higher-order macros may expand inner macro > for analysis as well, etc., etc. So make sure that your macros are > always side-effect-free (unless you really know what you're doing).
So you're saying that setq (or setf) should not appear in the code of the macroexpansion function ? Why , what could go wrong ?
>> One important thing to keep in mind: Don't use side effects in macro >> definitions. In both your solutions, you tried to achieve the result by >> assigning to a local or global variable as part of the macroexpansion >> process. However, you cannot predict whether or when, and how often, a >> particular macro will be invoked. For example, development environments >> may offer users to expand macros on demand, compilers may expand macros >> several times for analysis, higher-order macros may expand inner macro >> for analysis as well, etc., etc. So make sure that your macros are >> always side-effect-free (unless you really know what you're doing).
> So you're saying that setq (or setf) should not appear in the code of > the macroexpansion function ? Why , what could go wrong ?
(defvar *c* 0)
(defmacro m () (incf *c*) `',*c*)
(defun f () (list (m) (m)))
(f) --> (1 2) ; or --> (42 87) ; or anything else.
(f) --> (1 2) ; or --> (3 4) ; or --> (36 99) ; or anything else.
For example, here is what you get with clisp:
C/USER[5]> (f) ; interpreted (1 2) C/USER[6]> (f) ; minimal compilation is cached. (1 2) C/USER[7]> (compile 'f) ; execute minimal compilation once again F ; NIL ; NIL C/USER[8]> (f) ; hence the new result (3 4) C/USER[9]> (f) (3 4)
> Let me see if I understand the reason for the difference between > memory and memory2. The first call to the two macros expands to the > same thing and places what follows in the scope of (after expansions) > (symbol-macrolet ((cell 1)) > The difference lies in the behaviour of the line > (let ((new-cell-value (1+ (macroexpand 'cell env)))) > vs > (let ((new-cell-value (1+ (macroexpand 'cell)))) > in the second call to the macros. There > (macroexpand 'cell env) evaluates to 1 whereas > (macroexpand 'cell) evaluates to 0. > The reason is the following excerpt in the macroexpand page in > the HS:
> In addition to macro definitions in the global environment, > any local macro definitions established within env by > macrolet or symbol-macrolet are considered. If only form is > supplied as an argument, then the environment is effectively > null, and only global macro definitions as established by > defmacro are considered.
> I assume the last line should actually read "defmacro or > define-symbol-macro are considered".
> Is my understanding correct ?
Yes, this is correct. The Common Lisp environment objects effectively give you a first-class representation of (compile-time) lexical environments.
Spiros Bousbouras wrote: > On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote: >> One important thing to keep in mind: Don't use side effects in macro >> definitions. In both your solutions, you tried to achieve the result by >> assigning to a local or global variable as part of the macroexpansion >> process. However, you cannot predict whether or when, and how often, a >> particular macro will be invoked. For example, development environments >> may offer users to expand macros on demand, compilers may expand macros >> several times for analysis, higher-order macros may expand inner macro >> for analysis as well, etc., etc. So make sure that your macros are >> always side-effect-free (unless you really know what you're doing).
> So you're saying that setq (or setf) should not appear in the code of > the macroexpansion function ? Why , what could go wrong ?
As I said, a macro may be expanded more than once. For example, in the LispWorks IDE (and others), I can right-click on an s-expression and macroexpand it, to see what the result of macroexpansion will be. This will trigger any side effects the macro definition may produce.
Here is another example: Assume you have a 'with-locked macro that supposedly takes a lock on an object and then executes some code. Since taking locks is expensive, it may want to avoid doing so. So it does something like this:
(defmacro with-lock (object &body body &environment env) (if (contains object (walk body env)) `(call-with-locked-object ,object (lambda () ,@body)) `(progn ,@body)))
(defun contains (object expanded-body) ... some form of membership test ...)
(defun walk (code env) ... something that repeatedly calls (macroexpand code env) to expand all macros in code ...)
> Who's your mama ?
I don't know why that would be relevant in this thread.
> >> One important thing to keep in mind: Don't use side effects in macro > >> definitions. In both your solutions, you tried to achieve the result by > >> assigning to a local or global variable as part of the macroexpansion > >> process. However, you cannot predict whether or when, and how often, a > >> particular macro will be invoked. For example, development environments > >> may offer users to expand macros on demand, compilers may expand macros > >> several times for analysis, higher-order macros may expand inner macro > >> for analysis as well, etc., etc. So make sure that your macros are > >> always side-effect-free (unless you really know what you're doing).
> > So you're saying that setq (or setf) should not appear in the code of > > the macroexpansion function ? Why , what could go wrong ?
> (defvar *c* 0)
> (defmacro m () > (incf *c*) > `',*c*)
If that's what Pascal meant I'm not surprised. But he referred to the code in my first post, for example
His phrasing above and the example gave me the impression that he was saying that all assignments are dangerous even if the effects of the assignment do not persist after the macroexpansion function has finished executing. If that's what he meant then I do find it surprising. For example I don't see what could go wrong with my code above regardless of how many times the macro gets expanded.
In any case, it seems that if one wants to have macros share information (apart from trivial cases perhaps) then this cannot be achieved behind the scenes so to speak. What I mean behind the scenes is the way you would do it with functions:
(let ((a)) (defun foo ... (defun bar ...)
Any changes to a one function makes the other knows about but the rest of the code is ignorant about a. With macros however one has to put any changes to the shared information in the code the macro produces thereby leaking what ought to be internal implementation. I consider this a blemish in Lisp.
-- Capitalization is the difference between "I had to help my uncle Jack off a horse.." and "I had to help my uncle jack off a horse.." http://www.bash.org/?367896
Spiros Bousbouras wrote: > On 10 Nov, 01:40, p...@informatimago.com (Pascal J. Bourguignon) > wrote: >> Spiros Bousbouras <spi...@gmail.com> writes: >>> On 7 Nov, 19:04, Pascal Costanza <p...@p-cos.net> wrote: >>>> One important thing to keep in mind: Don't use side effects in macro >>>> definitions. In both your solutions, you tried to achieve the result by >>>> assigning to a local or global variable as part of the macroexpansion >>>> process. However, you cannot predict whether or when, and how often, a >>>> particular macro will be invoked. For example, development environments >>>> may offer users to expand macros on demand, compilers may expand macros >>>> several times for analysis, higher-order macros may expand inner macro >>>> for analysis as well, etc., etc. So make sure that your macros are >>>> always side-effect-free (unless you really know what you're doing). >>> So you're saying that setq (or setf) should not appear in the code of >>> the macroexpansion function ? Why , what could go wrong ? >> (defvar *c* 0)
>> (defmacro m () >> (incf *c*) >> `',*c*)
> If that's what Pascal meant I'm not surprised. But he referred to the > code in my first post, for example
> His phrasing above and the example gave me the impression that he was > saying that all assignments are dangerous even if the effects of the > assignment do not persist after the macroexpansion function has > finished executing. If that's what he meant then I do find it > surprising. For example I don't see what could go wrong with my code > above regardless of how many times the macro gets expanded.
I didn't read your code carefully enough, so I indeed didn't notice that the side effect didn't persist. However, this code could still create problems, for example when a user tries to macroexpand some particular form while some other code is compiled in a background thread, and two invocations of 'memory are thus expanded at the same time. You would either need to synchronize the accesses to the 'a variable, for example by using locks or STM (har :P ), or you should just use local bindings for 'a.
> In any case, it seems that if one wants to have macros share > information (apart from trivial cases perhaps) then this cannot be > achieved behind the scenes so to speak. What I mean behind the scenes > is the way you would do it with functions:
> (let ((a)) > (defun foo ... > (defun bar ...)
> Any changes to a one function makes the other knows about but the > rest of the code is ignorant about a. With macros however one has to > put any changes to the shared information in the code the macro > produces thereby leaking what ought to be internal implementation. I > consider this a blemish in Lisp.
Spiros Bousbouras <spi...@gmail.com> writes: > If that's what Pascal meant I'm not surprised. But he referred to the > code in my first post, for example
> His phrasing above and the example gave me the impression that he was > saying that all assignments are dangerous even if the effects of the > assignment do not persist after the macroexpansion function has > finished executing. If that's what he meant then I do find it > surprising. For example I don't see what could go wrong with my code > above regardless of how many times the macro gets expanded.
Well, I'm not convinced that this has to work the way you may wish it to. In particular, the expansion of macros inside BODY doesn't have to occur in the dynamic scope of the expansion of MEMORY.
So, for example, it seems to me it is perfectly permissible, and in fact the most likely implementation, that when macros are being expanded the following happens:
The macro MEMORY is encountered by the code walker or compiler. It is expanded, and given the BODY contents. The BODY contents are not evaluated, but merely returned inside the SYMBOL-MACROLET form. The macroexpansion function for MEMORY returns the new form.
This new form is now walked by the code walker, so if there is any macros in the newly returned form, they will also be properly expanded. But since the macro-expansion function has already returned, the value of variable A has been restored. So the next expansion doesn't see any dynamic change.
In fact, I'm pretty sure it has to work this way, since otherwise macros that expand into code headed by other macros would not work properly. There will not be any invocation of macro-expansion functions during the invocation of a macro-expansion function.
You could probably observe this by tracing the macro-expansion function that corresponds to your macro. I would expect to see it return before any other macro expansion occurs.
-- Thomas A. Russ, USC/Information Sciences Institute
> In any case, it seems that if one wants to have macros share > information (apart from trivial cases perhaps) then this cannot be > achieved behind the scenes so to speak. What I mean behind the scenes > is the way you would do it with functions:
> (let ((a)) > (defun foo ... > (defun bar ...)
> Any changes to a one function makes the other knows about but the > rest of the code is ignorant about a. With macros however one has to > put any changes to the shared information in the code the macro > produces thereby leaking what ought to be internal implementation.
Where is it leaking? Because you can introspectively look at a macro's expansion? Do you consider reflection to be "blemish" in general?
> I consider this a blemish in Lisp.
Impenetrable encapsulation is only longed for by the timid. :-)
> > His phrasing above and the example gave me the impression that he was > > saying that all assignments are dangerous even if the effects of the > > assignment do not persist after the macroexpansion function has > > finished executing. If that's what he meant then I do find it > > surprising. For example I don't see what could go wrong with my code > > above regardless of how many times the macro gets expanded.
> I didn't read your code carefully enough, so I indeed didn't notice that > the side effect didn't persist. However, this code could still create > problems, for example when a user tries to macroexpand some particular > form while some other code is compiled in a background thread, and two > invocations of 'memory are thus expanded at the same time.
Is there any established way for how such parallel expansion/compilation is supposed to work ? Intuitively it seems to me that in the scenario you're describing the implementation ought to create one copy of a for the compilation and another for any expansions which are not part of the compilation. If it doesn't do that what makes you think that even your code will work correctly ? There may be clashes with the use of new-cell-value.
> > In any case, it seems that if one wants to have macros share > > information (apart from trivial cases perhaps) then this cannot be > > achieved behind the scenes so to speak. What I mean behind the scenes > > is the way you would do it with functions:
> > Any changes to a one function makes the other knows about but the > > rest of the code is ignorant about a. With macros however one has to > > put any changes to the shared information in the code the macro > > produces thereby leaking what ought to be internal implementation. I > > consider this a blemish in Lisp.
> You can hide the shared information in a package.
You can but still I find it kludgy. You already have the datum in a variable i.e. in memory but in order to share it with a different invocation of the macro you have to "print" it and then read it back in again. Very ugly. Apart from aesthetics there's another issue : "Practical Common Lisp" says in footnote 4 of chapter 4 : "Not all Lisp objects can be written out in a way that can be read back in". What if it is such an object you want to share ?
-- Never attribute to conspiracy what can adequately be explained by shared attitudes.
On Nov 10, 4:36 pm, Spiros Bousbouras <spi...@gmail.com> wrote: [...]
> In any case, it seems that if one wants to have macros share > information (apart from trivial cases perhaps) then this cannot be > achieved behind the scenes so to speak. What I mean behind the scenes > is the way you would do it with functions: > (let ((a)) > (defun foo ... > (defun bar ...) > Any changes to a one function makes the other knows about but the > rest of the code is ignorant about a.
This is a trick I've used once or twice in the past, and I'm just submitting it as an idea in part because I'd like to see if there are problems with it that I haven't considered up until now. It's hardly something I do every day, and I know this corner of macrology is generally riddled with pitfalls.
The idea is that you have easy access to uninterned symbols, and those symbols not only have their value cells, but also function cells and property lists to play with. You could do something like this:
> Spiros Bousbouras <spi...@gmail.com> writes: > > If that's what Pascal meant I'm not surprised. But he referred to the > > code in my first post, for example
> > His phrasing above and the example gave me the impression that he was > > saying that all assignments are dangerous even if the effects of the > > assignment do not persist after the macroexpansion function has > > finished executing. If that's what he meant then I do find it > > surprising. For example I don't see what could go wrong with my code > > above regardless of how many times the macro gets expanded.
> Well, I'm not convinced that this has to work the way you may wish it > to.
I would be surprised if you or anyone else were convinced since I already said in my opening post that I tested it and it doesn't work.
> The macro MEMORY is encountered by the code walker or compiler. It is > expanded, and given the BODY contents. The BODY contents are not > evaluated, but merely returned inside the SYMBOL-MACROLET form. The > macroexpansion function for MEMORY returns the new form.
> This new form is now walked by the code walker, so if there is any > macros in the newly returned form, they will also be properly expanded. > But since the macro-expansion function has already returned, the value > of variable A has been restored. So the next expansion doesn't see any > dynamic change.
Or as I said in my OP : "I assume that by the time the code generated from the macro expansion gets compiled the statement (decf a) has already been executed."
-- The worst part of living on the West Coast is having to remember to say "no mayonnaise" when ordering a burger. tinyurl.com/mayo-quote
On Nov 17, 9:48 am, Pillsy <pillsb...@gmail.com> wrote: [...]
> (let ((closed (closed "BACKING-"))) > (defmacro foo (name &rest args) > (setf (get closed name) (stuff-from-foo-args args)) > (generate-foo-expansion name args closed)) > (defmacro bar (name &rest args) > (setf (get closed name) (stuff-from-bar-args args)) > (generate-bar-expansion name args closed))) > Is there something horribly wrong with this approach?
Well, one thing that's potentially horribly wrong with the approach is its dependence on compile-time side-effects. This problem seems pretty avoidable if all you want to do is establish a private chanell that can be accessed by your expansions; that may not be enough for your purposes. But if it is, there's always