challenge: implement the max function

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Wed Jan 24 08:44:19 PST 2007


Don Clugston wrote:
> Andrei Alexandrescu (See Website for Email) wrote:
>> Andrei Alexandrescu (See Website For Email) wrote:
>>> Here's a simple challenge: implement the max function. Requirements:
>>>
>>> a) generic
>>> b) efficient
>>> c) preserve lvalueness when possible such that one can write e.g.
>>>
>>> max(arr[0], arr[1]) *= 0.9;
>>>
>>> d) should accept two or more arguments
>>> e) should return the "smartest" type, e.g. max of an unsigned int and 
>>> unsigned long should return unsigned long
>>> f) short and easy to understand
>>>
>>> I don't think it's possible to implement the function to the spec in 
>>> current D, so designs are allowed to invent new features, as long as 
>>> they define them thoroughly.
>>
>> Thanks to all for the great replies. I am glad there is consensus that
>> max is a good exercise to test a language's expressive power.
>>
>> Below is an implementation of max that uses some in-design language
>> features.
>>
>> template max
>> {
>> private:
>>   template maxtype(storageof(T1) T1, storageof(T2) T2)
>>   {
>>     static if (storageof(T1) T1 == storageof(T2) T2)
>>       alias storageof(T1) T1 maxtype;
>>     else
>>       static if (std.is_num!(T1) && std.is_num!(T2))
>>         static if (T2.max > T1.max)
>>           alias T2 maxtype;
>>         else
>>           alias T1 maxtype;
>>       else
>>         alias typeof(true ? T1 : T2) maxtype;
>>   }
> 
> Surely this should be:
> 
>    else
>      static if (std.is_num!(T1) && std.is_num!(T2))
>         static if (T2.max > T1.max)
>           alias storageof(T2) T2 maxtype;
>         else
>           alias storageof(T1) T1 maxtype;
> 
>       else
>         alias storageof(true ? T1 : T2) typeof(true ? T1 : T2) maxtype;

Au contraire, your code will not compile. We are already past type 
equality, so we don't want to preserve the lvalueness anymore. For 
example, T1 may be unsigned and T2 unsigned long. You can't then return 
an inout value, even though both were inout.

> Seems as though "storageof(X) X" will be an extremely common idiom -- 
> far more common than "storageof(Y) X".

Yah. Walter thinks $T could be used as storageof(T) T.

> In fact, if there was a way to copy storage from one type to another, 
> and check if two types have identical storage, a simpler syntax might be 
> possible (just as a special syntax for the sign of a number is not 
> required).

This will definitely be possible.

>> * A minor point is that the code assumes a future feature of D: if a
>> template only defines a public member and that member is homonym with
>> the template name, that member gets automatically promoted as a synonim
>> for the template name. (This is a relaxation of the existing rule.)
> 
> This has been proposed many times. It would greatly simplify a lot of 
> complex code.

Well it saves an extra symbol, which is a good thing.


Andrei



More information about the Digitalmars-d mailing list