plans for macros
Steven Schveighoffer
schveiguy at yahoo.com
Thu May 15 08:32:09 PDT 2008
"janderson" wrote
> Steven Schveighoffer wrote:
>> "janderson" wrote
>>> 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.
>>
>> Lazy evaluation is already supported, and already adds the extra sugar
>> (not sure if 1.01 does though).
>
> For templates? 1.01 does support lazy for as function parameters but not
> as template parameters.
Why do you need a template? A template seems like a step backwards in ease
of use. I'd rather have just a lazy parameter where calling it is as easy
as:
LogIt("test");
>
>
>>
>> The problem I'm trying to solve is lazy evaluation of variadic arguments.
>> And in general, lazy evaluation is not as efficient as a macro would
>> be -- there would be no automatic delegate generated, especially if
>> variadic arguments need a delegate per argument, which would generate n
>> delegates.
>>
>> I really think macros are the best solution to this problem, but I was
>> wondering how easy it would be to make macros look like member functions
>> of a class, and if they will support variadic arguments.
>>
>> -Steve
>
> Templates are just as efficient as macros, particularly if u use the mixin
> syntax (ie force inlining of the template function itself).
mixin would probably work, but again, the syntax is not as appealing as a
macro:
log.formatInfo(...);
vs
mixin!(log.formatInfo, ...);
(don't know if this is right, I don't use mixins a lot)
-Steve
More information about the Digitalmars-d-learn
mailing list