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