challenge: implement the max function

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Tue Jan 23 10:12:14 PST 2007


Donth Ave wrote:
> == Quote from Andrei Alexandrescu:
> 
>> T2.max > T1.max
>> true ? T1 : T2
>>      if (rhs > lhs) return rhs;
> 
> According to the generality of the challenge you have to admit at least
> one of the following:
> 1) On posting the challenge some of the available properties of the
> possible operands where silently dropped
> 2) The sample solution does not solve the challenge.

It does not fail in any way that you mention (see below).

> This is because in the challenge it is not required that
> a1) all involved types have a maximum at all
> a2) all involved types have the .max-property

Notice that the .max tests are guarded by if (std.is_num!(T1) && 
std.is_num(T2)). So that code is only executed for numerical types. I've 
omitted the implementation of std.is_num because it is trivial.

> b) all involved types are implicitely convertible to each other

This is a good point. In the general case (non-numeric), we can't do 
much but assume conservatively that the two types convert implicitly to 
one another.

In the numeric case, things are more interesting. With max it turns out 
that today's implicit numeric conversions do exactly as needed. (They 
will change in D 2.0, btw.) In the min case, they don't: for example, 
min(int, uint) should return int. So the body of min2 looks like:

if (rhs < lhs) return cast(ret_type) rhs;
return cast(ret_type) lhs;

Thanks for making this valuable point.

> c1) all involved values are totally ordered

Maximum implies some kind of ordering. To me using > versus <= is more 
of an academic point than a practical one. Once you have one, you can 
reasonably define all others.

> c2) none of the storageclasses is "lazy"

Lazy is never deduced, and it was not part of the requirement.

> Reason:
> Violations of a1) or a2) might break "T2.max > T1.max"
> Violations of b) might break "true ? T1 : T2"
> Violations of c1) might break "rhs > lhs"
> Violations of c2) might break "if (rhs > lhs) return rhs;" because this implies
> one more evaluation.

I refute all these on basis of what I explained above.

> Furthermore the implicite requirement of the max-function is also
> violated, which is to be usable as an rvalue.

An lvalue can always be used as an rvalue.

> This is because in the challenge it is not required that
> d) none of the involved types is a class.
> 
> Reason:
> If the types include classes as well as basic types, then it is not clear which
> one will be returned, but classes will need their opCast to be called, which might
> break "return rhs"

This is a good point. If both lhs and rhs are classes, the code works 
properly (barring a few corner cases). But the case max(obj, 4) could be 
handled better. In that case, the built-in should be explicitly 
converted to the object type.


Andrei



More information about the Digitalmars-d mailing list