plans for macros

boyd gaboonviper at gmx.net
Thu May 15 09:53:28 PDT 2008


On Thu, 15 May 2008 17:41:55 +0200, janderson <askme at me.com> 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
--------

I use nearly that exact syntax in my project:

     debug Log(5, "blar", 10.0f);

The Log function is built using a simple template:

     void Log(T...)(T t)
     {
         writefln(t);
     }

As far as syntax goes that's in my opinion pretty nice. And the function  
isn't even called if debug is off. You can easily adapt it to work with  
debug levels:

     debug(3){
         Log(whatever);
         Log(somethingElse);
     }

So, this is in my opinion a problem that doesn't really need macro's to  
solve it.

Cheers,
Boyd


More information about the Digitalmars-d-learn mailing list