I have the following problem: I have a macro that generates code, but
now I want to call it dynamically, i.e. with arguments that aren't
static, verbatim, fixed in my code, but that are determined by function
arguments.
What is the usual Lisp way of achieving this? I've heard that EVAL
doesn't really use the lexical environment, so I couldn't call EVAL
inside a wrapper macro to eval the arguments and then `(new-macro
,evaled-arg).
Obviously, I need something just like that, because passing some Lisp
expression to the macro doesn't really do anything useful - I want the
expression's value.
--
Suffering from Gates-induced brain leakage...
Ulrich Hobelmann <···········@web.de> writes:
> I have the following problem: I have a macro that generates code, but
> now I want to call it dynamically, i.e. with arguments that aren't
> static, verbatim, fixed in my code, but that are determined by
> function arguments.
You're not quite clear here, but presumably you want to call the macro
just like a function. That's a strong indication that what you want
_is_ a function. Take a look at compiler macros, they are one way
this can be made to work nicely.
You can also do a similar sort of thing more "manually". Define a
function which does basically all the work of the macro: mac-fn.
Then, since you presumably also want to have this functionality
available at macroexpansion time, you define a macro mac which just
ends up passing all its arguments to mac-fn.
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
jayessay wrote:
> Ulrich Hobelmann <···········@web.de> writes:
>
>> I have the following problem: I have a macro that generates code, but
>> now I want to call it dynamically, i.e. with arguments that aren't
>> static, verbatim, fixed in my code, but that are determined by
>> function arguments.
>
> You're not quite clear here, but presumably you want to call the macro
> just like a function. That's a strong indication that what you want
> _is_ a function. Take a look at compiler macros, they are one way
> this can be made to work nicely.
Maybe. Thing is that I have a macro, and it *works*, so I thought I'd
just use it. The only downside is that I want to use it with different
data each time, and that data is only known at runtime.
This looks like it's calling for EVAL, but one problem I'm having with
that is that I do: (eval `(macro ,@(recursive stuff))) and that because
of side effects I don't want the recursive stuff to happen before the
eval, but in-between. When I don't quote-splice the recursive stuff
(which looks like (recur some-variable)), I get the problem that the
macro can't find the SOME-VARIABLE at runtime.
Hairy.
> You can also do a similar sort of thing more "manually". Define a
> function which does basically all the work of the macro: mac-fn.
> Then, since you presumably also want to have this functionality
> available at macroexpansion time, you define a macro mac which just
> ends up passing all its arguments to mac-fn.
Hm, worth a thought. I'm out of energy right now, but I'll consider it.
--
Suffering from Gates-induced brain leakage...
Ulrich Hobelmann <···········@web.de> writes:
> jayessay wrote:
> > Ulrich Hobelmann <···········@web.de> writes:
> >
> >> I have the following problem: I have a macro that generates code, but
> >> now I want to call it dynamically, i.e. with arguments that aren't
> >> static, verbatim, fixed in my code, but that are determined by
> >> function arguments.
> > You're not quite clear here, but presumably you want to call the
> > macro
> > just like a function. That's a strong indication that what you want
> > _is_ a function. Take a look at compiler macros, they are one way
> > this can be made to work nicely.
>
> Maybe. Thing is that I have a macro, and it *works*, so I thought I'd
Maybe. But then it doesn't do what you want when you want it.
> > You can also do a similar sort of thing more "manually". Define a
> > function which does basically all the work of the macro: mac-fn.
> > Then, since you presumably also want to have this functionality
> > available at macroexpansion time, you define a macro mac which just
> > ends up passing all its arguments to mac-fn.
>
> Hm, worth a thought. I'm out of energy right now, but I'll consider it.
...
> (let (...)
> (assemble-some-data-structures)
> `(progn ,@(fetch-code-from-those-data-structures) nil))
Since you haven't posted the actual macro, we don't know what the
interface is. Given this caveat,
(defun xxx-fn (arg1 arg2 arg3 ...)
(let (...)
(assemble-some-data-structures)
`(progn ,@(fetch-code-from-those-data-structures) nil)))
(defmacro xxx (arg1 arg2 arg3 ...)
`(xxx-fn ',arg1 ',arg2 ',arg3 ...))
Or something like that. It's hard to say since you haven't given the
interface.
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
jayessay wrote:
>> (let (...)
>> (assemble-some-data-structures)
>> `(progn ,@(fetch-code-from-those-data-structures) nil))
>
> Since you haven't posted the actual macro, we don't know what the
> interface is. Given this caveat,
Because IMHO it doesn't matter, and I don't want to argue about code
right now ;)
> (defun xxx-fn (arg1 arg2 arg3 ...)
> (let (...)
> (assemble-some-data-structures)
> `(progn ,@(fetch-code-from-those-data-structures) nil)))
>
> (defmacro xxx (arg1 arg2 arg3 ...)
> `(xxx-fn ',arg1 ',arg2 ',arg3 ...))
>
> Or something like that. It's hard to say since you haven't given the
> interface.
Yes, but even factoring the `(...) into a function doesn't evaluate it.
I'd still need to eval it somehow.
So I'm taking the other route, defining a switch variable to simply
modify the part that generates the Lisp commands to execute them :)
--
Suffering from Gates-induced brain leakage...
Ulrich Hobelmann wrote:
> jayessay wrote:
>
>>> (let (...)
>>> (assemble-some-data-structures)
>>> `(progn ,@(fetch-code-from-those-data-structures) nil))
>>
>>
>> Since you haven't posted the actual macro, we don't know what the
>> interface is. Given this caveat,
>
>
> Because IMHO it doesn't matter, and I don't want to argue about code
> right now ;)
>
>> (defun xxx-fn (arg1 arg2 arg3 ...)
>> (let (...)
>> (assemble-some-data-structures)
>> `(progn ,@(fetch-code-from-those-data-structures) nil)))
>>
>> (defmacro xxx (arg1 arg2 arg3 ...)
>> `(xxx-fn ',arg1 ',arg2 ',arg3 ...))
>>
>> Or something like that. It's hard to say since you haven't given the
>> interface.
>
>
> Yes, but even factoring the `(...) into a function doesn't evaluate it.
> I'd still need to eval it somehow.
>
> So I'm taking the other route, defining a switch variable to simply
> modify the part that generates the Lisp commands to execute them :)
>
Posting the revised version that now expands all macros recursively:
(defun apply-macro (macro &rest arguments)
(let ((expansion (apply (macro-function macro) `((,macro ,@arguments)
nil))))
(cond
((equalp (macro-function (car expansion)) nil) (apply (car
expansion) (cdr expansion)))
(t (apply #'apply-macro (append (list (car expansion)) (cdr
expansion)))))))
Ulrich Hobelmann wrote:
> Maybe. Thing is that I have a macro, and it *works*, so I thought I'd
> just use it. The only downside is that I want to use it with different
> data each time, and that data is only known at runtime.
Can you post your macro or an similar example? It sounds strange that you
want to generate code based on data at runtime, like self-modifiying
assember code I've written back in the days of the good old C64 for
impossible VIC graphics code :-)
--
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Frank Buss wrote:
> Ulrich Hobelmann wrote:
>
>> Maybe. Thing is that I have a macro, and it *works*, so I thought I'd
>> just use it. The only downside is that I want to use it with different
>> data each time, and that data is only known at runtime.
>
> Can you post your macro or an similar example? It sounds strange that you
> want to generate code based on data at runtime, like self-modifiying
> assember code I've written back in the days of the good old C64 for
> impossible VIC graphics code :-)
It's basically just
(let (...)
(assemble-some-data-structures)
`(progn ,@(fetch-code-from-those-data-structures) nil))
so it condenses its arguments down to some code. I'm thinking, maybe I
should define a special variable to tell if it should produce code, or
just execute it. Then I could factor out a separate interpretive
function and avoid the whole mess.
It's not self-modifying code, but generating code. What I'm doing is
basically wanting to call the macro with user-supplied data, but I think
I should be able to introduce that variable and change my EMIT-foo
functions to execute.
--
Suffering from Gates-induced brain leakage...
Ulrich Hobelmann wrote:
> Frank Buss wrote:
> > Ulrich Hobelmann wrote:
> >
> >> Maybe. Thing is that I have a macro, and it *works*, so I thought I'd
> >> just use it. The only downside is that I want to use it with different
> >> data each time, and that data is only known at runtime.
> >
> > Can you post your macro or an similar example? It sounds strange that you
> > want to generate code based on data at runtime, like self-modifiying
> > assember code I've written back in the days of the good old C64 for
> > impossible VIC graphics code :-)
>
> It's basically just
> (let (...)
> (assemble-some-data-structures)
> `(progn ,@(fetch-code-from-those-data-structures) nil))
Sounds like you're describing a motivation behind OOP, in which case a
serious answer is "use CLOS."
Tayssir
Tayssir John Gabbour wrote:
>> It's basically just
>> (let (...)
>> (assemble-some-data-structures)
>> `(progn ,@(fetch-code-from-those-data-structures) nil))
>
> Sounds like you're describing a motivation behind OOP, in which case a
> serious answer is "use CLOS."
I wouldn't know what for. I'm only putting Lisp statements into a
global variable, which I don't want to carry around manually. I don't
think CLOS would help (but I have a slight general bias against OOP ;) ).
--
Suffering from Gates-induced brain leakage...
In article <··············@individual.net>,
Ulrich Hobelmann <···········@web.de> wrote:
> Maybe. Thing is that I have a macro, and it *works*, so I thought I'd
> just use it. The only downside is that I want to use it with different
> data each time, and that data is only known at runtime.
If you need to do this regularly, it's usually an indication that it
shouldn't have been implemented as a macro in the first place. Perhaps
you should write a function that does this, and a macro that expands
into a call to the function. See PROCLAIM and DECLAIM for an example of
this combination -- PROCLAIM evaluates its arguments, while DECLAIM
expands into a call to PROCLAIM with a bunch of quoted arguments (as
well as using EVAL-WHEN to ensure that the compiler processes it).
--
Barry Margolin, ······@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 ***
Ulrich Hobelmann <···········@web.de> writes:
> I have the following problem: I have a macro that generates code, but
> now I want to call it dynamically, i.e. with arguments that aren't
> static, verbatim, fixed in my code, but that are determined by
> function arguments.
(apply #'macro-func stuff)
(defun macro-func (stuff)
(your-macro stuff))
Though of course one of the canonical problems with macros is that
they can't be funcalled or applied.
Or how about an approach from Norvig:
(defun macroish-function (stuff)
`(blah ,@stuff))
which will return the code template a macro would produce, but would
not execute it as a macro does. Then you could
(mapcar #'macroish-function some-list)
and be left with a list of code templates.
For example, contrast:
* (defmacro avg (&rest list)
`(/ (+ ,@list) ,(length list)))
AVG
* (avg 2 3 4 5 6)
4
with
* (defun avg (&rest list)
`(/ (+ ,@list) ,(length list)))
AVG
* (avg 2 3 4 5 6)
(/ (+ 2 3 4 5 6) 5)
--
Tiarn�n
Tiarn�n � Corr�in wrote:
> Ulrich Hobelmann <···········@web.de> writes:
>
>> I have the following problem: I have a macro that generates code, but
>> now I want to call it dynamically, i.e. with arguments that aren't
>> static, verbatim, fixed in my code, but that are determined by
>> function arguments.
>
> (apply #'macro-func stuff)
>
> (defun macro-func (stuff)
> (your-macro stuff))
I think this DEFUN would only execute my macro on STUFF, not on the
value of stuff, so it doesn't work.
> Though of course one of the canonical problems with macros is that
> they can't be funcalled or applied.
>
> Or how about an approach from Norvig:
>
> (defun macroish-function (stuff)
> `(blah ,@stuff))
>
> which will return the code template a macro would produce, but would
> not execute it as a macro does. Then you could
Yes. Not sure if I could just EVAL it then (or if I *should*, since
people keep saying that EVAL is bad). Anyway, some clauses in my
function do "normal" stuff and use recursion, but one clause using a
macro and EVAL makes the thing real ugly.
Maybe I should rewrite the macro as an interpreting function, but I
thought there should be an easier way ;)
--
Suffering from Gates-induced brain leakage...
Ulrich Hobelmann wrote:
> I have the following problem: I have a macro that generates code, but
> now I want to call it dynamically, i.e. with arguments that aren't
> static, verbatim, fixed in my code, but that are determined by function
> arguments.
>
> What is the usual Lisp way of achieving this? I've heard that EVAL
> doesn't really use the lexical environment, so I couldn't call EVAL
> inside a wrapper macro to eval the arguments and then `(new-macro
> ,evaled-arg).
>
> Obviously, I need something just like that, because passing some Lisp
> expression to the macro doesn't really do anything useful - I want the
> expression's value.
>
It's sort of ad-hoc and so far will only work for functions, but...
(defun apply-macro (macro &rest arguments)
(let ((expansion (apply (macro-function macro) `((,macro ,@arguments)
nil))))
(apply (car expansion) (cdr expansion))))
On 9377 day of my life Ulrich Hobelmann wrote:
> I have a macro that generates code, but now I want to call it
> dynamically, i.e. with arguments that aren't static, verbatim, fixed
> in my code, but that are determined by function arguments.
----------------------------------------------------------------------
Cooking Eggs in Microwave Oven FAQ
Written by Leo Kaganov, 2000.
Partially (and poorly) translated into English by I.B.
Q. How long should I cook egg in in microwave oven?
A. You can't cook egg in microwave oven because egg will explode.
Use saucepan and stove.
Q. How should I prepare an egg before cooking it in microwave oven?
A. There is no way to cook egg in microwave.
Q. How does explosion happen?
A. Egg suddenly leaves its integrity and gets shape of oven's walls.
It happen because of heating in microwave oven. Culinary science
denies doing it.
Q. I have put water into glass saucepan to compensate osmotic
pressure, put two eggs, covered saucepan and put into microwave
oven. Water haven't been boiled, but eggs exploded!
A. You forgot to add salt. Saucepan have to be metallic, and oven
have to be usual, non-microwave.
Q. I really want to cook eggs in microwave oven.
A. Cook chicken instead -- actually it is ex-egg.
Q. My mother-in-law tells me that one can't cook eggs in microwave
oven.
A. Yes.
Q. I made two holes in shell, put the egg into microwave oven, but egg
exploded.
A. Clean walls of your oven.
Q. I know personally at least three peoples who cooked eggs in
microwave oven and nothing bad happened!
A. There is nothing bad in cleaning walls of your oven.
Q. I put egg into microwave oven, but it didn't explode or heat.
A. Check oven's power cord.
Q. I put egg into microwave oven, but it didn't explode.
A. No.
Q. What kind of food does explode in microwave oven?
A. No other food explodes as spectacularly as eggs.
Q. I used your instructions from your FAQ to cook eggs in microwave
oven, but eggs exploded!
A. You should read whole FAQ. Don't stop reading just after a title.
----------------------------------------------------------------------
--
Ivan Boldyrev
Perl is a language where 2 x 2 is not equal to 4.
Ivan Boldyrev wrote:
> On 9377 day of my life Ulrich Hobelmann wrote:
>> I have a macro that generates code, but now I want to call it
>> dynamically, i.e. with arguments that aren't static, verbatim, fixed
>> in my code, but that are determined by function arguments.
>
> ----------------------------------------------------------------------
> Cooking Eggs in Microwave Oven FAQ
?
I merely asked for a way to embed dynamic values (by the user) in my
program. Ok, the above is pass�, but as you can see in another thread,
even more reasonable methods aren't without problems.
--
Suffering from Gates-induced brain leakage...