On 28/10/2015 8:29 AM, tsbockman wrote:
On Tuesday, 27 October 2015 at 21:14:26 UTC, Timon Gehr wrote:
On 10/27/2015 09:18 PM, tsbockman wrote:
I don't think any dead code is being generated,

This seems to be a misunderstanding. I mean generated using mixins or
template instantiation. Sure, it will usually be removed, but why
generate and semantically analyze it in the first place.

Forcing me to add `static if`s with redundant and potentially complex
predicates just to make my code do the exact same thing it would have
done anyway is a violation of "Don't Repeat Yourself", with all of the
usual consequences:

* The more places the same logic is expressed, the more chances I have
to get it wrong and cause a bug.

* Even if I get it right the first time, a redundant predicate could get
out of sync with the rest of the code later, causing a bug.

* It's a waste of my time, which is more valuable than my computer's time.

* It clutters up the code with statements which add little (useful)
information.


I personally like the style of that code, and agree that it allows less repetition. But it does this at the cost of intentionally introducing dead code in some instantiations. If you enable the compiler warnings about dead code, they have to trigger here because it doesn't know if you introduced dead code intentionally or not. As is often the case with warnings, if you want your code to compile with them you sometimes need to avoid otherwise completely valid constructs.

Here's a similar example:

bool func(T, T val)()
{
    if (val < 0)
        return true;
    return false;
}

func!(uint, 7);
func!(int, 7);

When instantiated with uint, the first return is unreachable because unsigned numbers cannot be negative. When val == 7, it's also unreachable because 7 is not less than 0. Which instantiations should give the warning?

> Another perspective, though, which I picked up from someone (Andrei
> Alexandrescu, I think?) in the D community, is to consider template
> parameters simply as additional function arguments, which happen to
> be evaluated at compile time. In many cases, the timing of their
> evaluation is just an implementation detail - a performance
> optimization (or de-optimization, as the case may be).

This is a great way to learn how to use templates, but there are limits to how well this simplification corresponds to reality and this is one of them. Parameters inhibit optimizations and analysis in ways that compile-time constants do not.

Reply via email to