plans for macros
janderson
askme at me.com
Thu May 15 00:10:18 PDT 2008
Steven Schveighoffer wrote:
> I just found a very good use for macros, and I was wondering how they could
> be used to help in this situation.
>
> If I have a log object, and that log object is supposed to evaluate its
> arguments only if the logging level allows it, checked at runtime.
>
> So this is the ideal usage in the calling function:
>
> if(log.isEnabledAtLevel(Information))
> log.output(someExpensiveStringBuild());
>
> This is ideal because it only outputs at the appropriate level, and it only
> evaluates the expensive function if the log level is enabled.
>
> However, this is very verbose, and is prone to errors. Many log systems use
> the following method:
>
> log.outputInformation(someExpensiveStringBuild());
>
> Which does the if-statement for you. However, they warn you to write your
> logging code in the first form if the code to build the output is expensive
> to avoid building the output even when it is not output. But D has a better
> way:
>
> class Log
> {
> void outputInformation(lazy string x)
> {
> if(isEnabledAtLevel(Information))
> output(x);
> }
> }
>
> Now, we can still use the second form, even when building the string is
> expensive. But there are issues with this solution. For one, lazy
> evaluation adds delegate functions wherever the logging is required, adding
> to runtime and code bloat. Second, variadic functions would be nice for
> logging, especially with formatting, but the only way to do lazy variadic
> functions is with template tuples, so there is another lot of generated
> code, and is even more inefficient.
>
> But a macro would solve the problem quite nicely. A macro would evaluate
> the if statement in the calling function, and so would prevent evaluation of
> the expensive string building unless necessary, AND would require no
> delegates to do it.
>
> The question I have is, when macros are implemented, can I have a 'class
> scoped' macro? That is, a macro that knows what context it is supposed to
> be in, and is passed a 'this' pointer? And will macros support variadic
> arguments?
>
> For example, I'd like to have a macro to output formatted log information
> only if the log is enabled, but I want to call it like a member function of
> the log.
>
> -Steve
>
>
I'm not sure if this solves your problem. Here's an interesting syntax
I discovered in 1.01 (haven't checked other versions).
void LogIt(alias func)()
{
if (true)
{
printf(func());
}
}
LogIt!( { char[] test = "test"; return test.ptr; } )();
LogIt!( { return "test"; } )(); //You couldn't do this.
Unfortunately I don't want to update my compiler at this time to see if
this would work in new versions.
I also wonder if it could be simpled by wrapping it in something else ->
thoughts? Its a pretty cool technique, essentially a inlined function
pointer.
If alias could be replaced with the word lazy string and have D add the
extra sugar we'd be set.
-Joel
More information about the Digitalmars-d-learn
mailing list