On 12/10/11 12:11 PM, Walter Bright wrote:
That's because
Matrix!(int, cast(int)1)
is considered a different template instantiation (and hence a different
type) from
Matrix!(int, cast(uint)1)
Instantiation types are based on the arguments' types, not the
parameters' types.
Which is, in my not-so-humble opinion, just plain broken. Template value
parameters are, well, values, and there shouldn't ever be a difference
between whether a value of an integral type represents 1 or 1u (if it
accepts both).
This is a long-standing bug, and makes unsigned template value
parameters and, to a lesser extent, integral template value parameters
in general virtually unusable, because you hit hard to debug issues with
confusing error messages all over the place.
It gets even worse once CTFE comes into play (or compile-time values in
general, as opposed to directly passing number literals) for two
reasons: First, the error messages become totally useless, i.e. in most
cases something similar to »Foo!(n) can't be implicitly converted to
Foo!(n)«. Second, even if you litter your code with explicit casts all
over the place, it is not always possible to get it to behave like
intended because of what I presume are issues with constant folding.
I know this first hand, because I worked on a units-of-measurement
library which relies on units being uniquely represented as types,
because the unit type becomes part of the type of quantities as a
template parameter (I presented it at the NG a while back, by the way:
http://www.digitalmars.com/d/archives/digitalmars/D/RFC_Units_of_measurement_for_D_Phobos_134590.html).
For derived units (e.g. kg m/s^2), you need to »normalize« the exponents
using compile time rational arithmetic, which was really hard to get to
work because of the issue discussed here (I don't even remember all the
details). But even with my own unit tests passing, I now once in a while
get a message saying something like: »Hey, I checked out your units
library prototype, and while it works nice for most cases, I encountered
this situation where … [some situation in which 1 != 1 for DMD]«. I
tried hard to work around this, but I couldn't find a reliable solution.
Also, I'd like to note that I am not alone with this opinion; Don, Kenji
and Jonathan, among others, agree that the current behavior is
confusing. A few reports of this issue (and related ones):
http://d.puremagic.com/issues/show_bug.cgi?id=3467
http://d.puremagic.com/issues/show_bug.cgi?id=2257
http://d.puremagic.com/issues/show_bug.cgi?id=2550
Kenji even came up with a fix in form of a pull request, which you
turned down without further explanation:
https://github.com/D-Programming-Language/dmd/pull/449
So, could you please at least elaborate on why you think the current
behavior is correct, and how its advantages outweigh the massive
confusion it causes?
Thanks,
David