Template condition evaluation (shortcircuit)

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Mar 21 18:14:33 UTC 2018


On Wed, Mar 21, 2018 at 05:42:34PM +0000, rumbu via Digitalmars-d-learn wrote:
> I tried to define a template:
> 
> enum isFoo(alias T) =
>     T.stringof.length >= 3 && T.stringof[0..3] == "abc";
> 
> int i;
> pragma(msg, isFoo!i);
> 
> Error: string slice [0 .. 3] is out of bounds
> Error: template object.__equals cannot deduce function from argument types
> !()(string, string), candidates are:
> [...]
> 
> Is it normal that the condition is not short circuited at first test?
> Of course, I can throw there a bunch of static ifs in an eponymous
> template, but I don't see the point of this verbosity.
[...]

The reason it's not short-circuited is because T.stringof[0..3] is
processed *before* the && is evaluated.  Basically, this:

	enum isFoo(alias T) = T.stringof.length >= 3 && T.stringof[0..3] == "abc";

is a shorthand for this:

	template isFoo(alias T)
	{
		enum isFoo = T.stringof.length >= 3 && T.stringof[0..3] == "abc";
	}

T.stringof[0..3] is actually evaluated during AST expansion time,
because it's slicing a template argument list, but && isn't evaluated
until CTFE-time.

See: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time


Now, arguably, we *could* make it so that && is also shortcircuited at
AST expansion time, i.e., basically lower && in this context into a
series of nested static if's instead of a CTFE expression.  But that
would probably involve some extensive changes in the compiler.


T

-- 
The trouble with TCP jokes is that it's like hearing the same joke over and over.


More information about the Digitalmars-d-learn mailing list