plans for macros

janderson askme at me.com
Thu May 15 08:54:18 PDT 2008


janderson wrote:
> janderson wrote:
>> Steven Schveighoffer wrote:
>>> "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());
>>>>>>>
> 
> <Snip>
> 
>>>>>>> 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
>>>
>>
>> I'm not arguing against macros BTW. I do think however that templates 
>> should beable to be written as simply as:
>>
>> LogIt("test");
>>
>> or at the very least
>>
>> LogIt!("test");
>>
>> -Joel
> 
> And it would be nice if this worked:
> 
> void LogIt(lazy alias func...)()
> {
> ...
> }
> 
> LogIt(5, "blar", 10.0f);
> 
> That would be a very powerful syntax.
> 
> -Joel


Just a though.  Couldn't templates simply be extended to handle macro 
cases so that we get supper powerful templates rather then another 
feature that works independently.

ie I see macros working like:

macro void MyMacro(foo)
{
    foo;
}

MyMacro(X + 5 * 10);

Where as we could make a template do the same job,

void MyMacro(alias foo)()
{
    foo;
}

MyMacro!(X + 5 * 10);  //Compiler figures that it can drop the second () 
because its zero params.

Any cases that you need for a macro should be put into templates instead 
IMHO.  That will give up the flexibility to combine the power of the 
template with the syntax sugar of a macro.

-Joel


More information about the Digitalmars-d-learn mailing list