Real World usage of D, Today (was Re: challenge #2: implement the varargs_reduce metafunction)

Sean Kelly sean at f4.ca
Fri Jan 26 09:03:06 PST 2007


Frits van Bommel wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> The syntax that I am proposing does away with storageof and is very 
>> much in spirit with the current D:
>>
>> S int foo(S, T)(S T t) { }
>>
>> It does exactly what it says it does, in a clear and terse manner, and 
>> is 100% within the spirit of existing D:
>>
>> * It's customized on symbols S and T
>>
>> * It's matching (by sheer position of S and T) the storage (i.e., all 
>> of the gooey fuzzy nice information about the argument passed) and the 
>> type of the incoming argument
>>
>> * In this example it uses the storage in the result type (e.g. const 
>> goes to const)
>>
>> * Inside the function can easily use either T separately or S T as a 
>> group that transports the storage around. You have total flexibility 
>> (and don't forget that juxtaposition is always easier than extraction).
>>
>> So far we're only thinking of storage-like attributes, but a good deal 
>> of information can be encoded under the loose declaration of "storage".
> 
> Would it also be possible to 'cherry-pick' attributes?
> So that e.g something like S.constness expands to either 'const' or ''?
> 
> And would this mean 'raw' storage attributes would be valid template 
> parameters? So that something like foo!(const) would be valid syntax?

This gets into something that would be nice to have in D: some sort of 
concept checking.  The easiest method would be something like this:

     alias Tuple!(int,char) A;
     void fnA( T in A )( T val ) {}

     void fnB( T : is( T == int ) || is( T == char ) )( T val ) {}

The ':' currently suggests type matching so perhaps the operator would 
need to be changes.  An alternate for the above which would work is:

     template fnC( T )
     in
     {
         this = is( T == int ) || is( T == char );
     }
     body
     {

     }

Which would be equivalent to:

     template fnC( T, bool match : true = Test!(T) )
     {

     }

     template Test( T )
     {
         const Test = is( T == int ) || is( T == char );
     }

The problem is that it's awkward to overload templates on concepts 
now--the C++ approach is just about the only way.  However, since 
templates can not be overloaded across module boundaries, this is also 
currently an option:

     template fnD( T )
     {
         static if( is( T == int ) || is( T == char ) )
         {
             ...
         }
         else
         {
             static assert( false );
         }
     }

It works just fine, but requires all overloads to exist within the same 
template block, and this isn't terribly readable with a large number of 
conditions.


Sean



More information about the Digitalmars-d mailing list