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

Reply via email to