macro chain

L

luser- -droog

I remember reading something from Knuth to the effect that you don't
really need multiple argument macros because you can yield a macro
name from the macro expansion and call that with a new argument.

So I tried a little experiment:

#define A(x) x + B
#define B(y) y y y
A(2)(3)

And I'll be darned if gcc -E doesn't produce:

2 + 3 3 3

But I'm not really doing this right, am I? Does anyone have
suggestions for where I could learn more? (more Knuth?)
 
B

Ben Bacarisse

luser- -droog said:
I remember reading something from Knuth to the effect that you don't
really need multiple argument macros because you can yield a macro
name from the macro expansion and call that with a new argument.

So I tried a little experiment:

#define A(x) x + B
#define B(y) y y y
A(2)(3)

And I'll be darned if gcc -E doesn't produce:

2 + 3 3 3

But I'm not really doing this right, am I? Does anyone have
suggestions for where I could learn more? (more Knuth?)

Not all macro processors are created equal. The big difference between
C's macro processor and many others (TeX, m4, Lisp, TRAC, ...) is that a
macro expansion can't define new macros (in fact they can't generate
*any* macro processing directives).

Knuth's remark may well be about macro systems that can mirror what
functional languages often do for multiple-argument functions (looking
up Currying and partial application may give you more about this -- it's
off topic enough that I don't want to go into it here). Though I don't
know the Knuth document in question, I suspect he is referring to macros
that work in a similar way.

In C+ it might look a bit like this:

#define ADD(x) #define ADD_(y) x + y \
ADD_

An invocation of ADD(3) produces a new definition of a macro called
ADD_ which generates code to add 3 to its argument along with a call to
this macro left "hanging". ADD(3)(4) would then yield 3 + 4.

To do this properly, you'd want ADD_ to remove its own definition and
you'd want definitions to "stack" so that the new (temporary) definition
does not interfere with any existing one, and some macro systems allow
new, unique, names to be generated thus avoiding the need to pick
a name for the temporary macro.
 
E

Eric Sosman

I remember reading something from Knuth to the effect that you don't
really need multiple argument macros because you can yield a macro
name from the macro expansion and call that with a new argument.

So I tried a little experiment:

#define A(x) x + B
#define B(y) y y y
A(2)(3)

And I'll be darned if gcc -E doesn't produce:

2 + 3 3 3

But I'm not really doing this right, am I? Does anyone have
suggestions for where I could learn more? (more Knuth?)

This should work, but only for "tail-chaining" expansions,
that is, where the very last thing in the first macro's replacement
list is the name of the second macro.

For example, to put parentheses around the entire expansion
you could not just change A to

#define A(x) ( x + B )

.... but you'd have to change both macros, something like

#define A(x) ( x + B
#define B(y) y y y )

If the first macro's argument must expand after the second
macro, I think even this won't suffice. For example, consider
a simple two-argument macro like

#define MAX(x,y) ( (x) > (y) ? (x) : (y) )
int max = MAX(42,17);

.... and try to build an equivalent "chain" of one-argument macros:

#define AMAX(x) // your answer here
#define BMAX(y) // your answer here
int max = AMAX(42)(17);

I think the fact that the 42 must appear both before and after
the 17 means you're sunk.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top