www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Macro functions...

I know this is mostly just taking something already possible and making 
it easier, but I thought I'd post about it and see what people say. 
Probably people here won't like it, I guess.

For the record, I'm not talking about preprocessor style macro 
functions.  What I am talking about can best be described with a code 
segment:

template api_macros()
{
    void DEBUG_ARG()
    {
       writefln("arg: %d", arg);
    }
}

void api_function(int arg)
{
    mixin api_macros;

    DEBUG_ARG();
}

That's all well and good, and various macros as used by people in C 
could be done this way (because the variables only need to be there at 
time of mixin) and is indeed fairly convenient.

However, the problem comes in when you have this:

void DEBUG_ARGS2()
{
    writefln("arg1: %d, arg2: %d", arg1, arg2);
}

For functions which do not have two arguments named appropriately, this 
will give an error if it is put in the same template.  The way to fix 
this is to place it into a second mixin, obviously.  But, when you do 
that at some point you find yourself doing this:

void api_function(int x, int y, float c, float a)
{
    mixin macros_debug_xy;
    mixin macros_debug_c;
    mixin macros_debug_a;

    DEBUG_XY();
    DEBUG_X();
    DEBUG_A();
}

I'd like to, at this point, note that my example leaves a bit to be 
desired.  The point is only to be an example - I'm sure most of you have 
experience with real macros as used in most C and C++ programs, ones 
that seem more useful or which simplify things much more.

At this point, it's obviously almost worthless to bother with this style 
of macros, because you're adding so many lines of mixins and such, and 
creating so many templates.

We might as well use a variadic function or something in this case, but 
there's a reason macros are popular - again, I'm sure many of you have 
seen macros that use variables in the current scope "in the wild."

I believe the solution to this, which would be much more appealing to 
people switching from C imho, is:

macro void DEBUG_ARG()
{
    writef("arg: %d", arg);
}

Which should be exactly equivalent to creating a template with that one 
function inside it.  Calling said function would be exactly equivalent 
to a mixin (unless one has already been done) and a call to that/the 
created function.

This would also give a hint to the optimizer that you probably want this 
function inlined, even if it is longer than those functions it normally 
likes to inline.

Ideally, the function would use the same stack, allowing (just as with 
mixins iirc) the use of alloca() and similar.

Debatably, such functions could add to the stack, much like mixins can - 
although this I'm sure could be trickier, and could easily be left out 
because it's less logical in a way.

I know that in many cases macro functions are not necessary, rather they 
are just easier or simpler.  However, I again believe this would help 
people switching from other languages, and be a general benefit to the 
language.

Synonyms for the "macro" token I've mentioned might be the mentioned 
"compile_time", "static" (except that is already taken), and even 
"inline" (although imho that should be the optimizer's decision.)  That 
said, I like "macro" and think it rather unlikely such a token would 
break many identifiers in use.

Of course, this is basically just using mixins with a nicer syntax, and 
I admit that's all it is.

Thanks,
-[Unknown]
Jun 25 2005