ID:2878157
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Varadic macros are cool, but they are held back massively by not having a way to decompose them.
They feel very tied to either list or proc uses, which is fine but being able to use them to properly expand code would be very nice.

Like, if I wanted to print all the strings passed into a macro, I want to do something like this
#define PRINT(print, rest...) world.log << print; PRINT(##rest)
PRINT("a", "b", "c", "d")

with a desired output of
world.log << "a";
world.log << "b";
world.log << "c";
world.log << "d";

That won't work however, because of course ## only trims ,s (from what I understand it literally just directly inserts the below, commas and all)
"a", "b", "c"


This is understandable, but prevents recursive macros which is a significant loss of power in terms of reducing runtime work.

There's at least 2 ways you could go about expanding this, by my reckoning.

You could allow #if inside #define (maybe with {} to note scope? or just going to the next #if like) with #if defined(empty_varadic) resolving to nothing
#define PRINT(first, rest...) world.log << first: #if defined(rest) PRINT(rest) #endif


Could differentiate between different argument counts for macros, which would let me do something like this
#define PRINT(first) world.log << first;
#define PRINT(first, rest...) PRINT(first); PRINT(rest)
PRINT("a", "b", "c", "d")

I realize this is unlikely, since it changes how define resolution works at least potentially, and fucks with #undef

Not really sure how valid either of these are, but it's a problem I really wish I could solve, so I thought I'd put this out there.
Discussed with lummox some, he's a bit antsy about recursive macros but was semi receptive to something like c++'s __VA_OPT__(), which only compiles what it wraps if the macro's varadic arg has something inside it.