Overlapping functionality: IFTI, templates, is-expressions

Russell Lewis webmaster at villagersonline.com
Wed Mar 19 17:25:52 PDT 2008


Jason House wrote:
> Defining template specialization in terms of a single template with static
> if's would be a breaking change.  Two reasons come to mind:
>   1. Template instantiation changes from "best match" to "first match".
>   2. SFINAE is no longer true.
> 
> #1 This would shift the work of template matching from the compiler writer
> to the programmer.  Ordering of templates would become important to the
> programmer.  The viability of this will partially depend on if someone come
> up with an example where no single template ordering would work properly. 
> If there's no examples or only pathological examples (that may break many
> implementations anyway), I'd be fine with the loss of functionality.

I miscommunicated.  I didn't mean that templates would be dropped into 
the is-expression template in lexical order.  I was assuming that the 
complier would generate them in the correct order to maintain "best 
match."  So the most restrictive cases would be handled first, getting 
less and less restrictive as you go.

And before you wonder, "how will we ever specify the right order to put 
things in?" remember that we need just that sort of language 
specification if anybody else is ever going to write another D compiler. 
  That is, we *must* have some strict, duplicatable definition of "best 
match" if we will ever have any D compiler other than dmd.

> #2 I know from past discussions that C++ programmers hold this very near and
> dear to their heart.  Personally, it seems like a back door to long
> compilation times.  I don't have any problem with enforcing criteria for
> templates to be defined up front, but I'm certain others don't agree with
> me.  Does the loss of SFINAE make templates too close to generics?  I know
> C# will refuse to compile code if the up-front criteria for a generic type
> isn't specific enough.

(quoting the Joker) "I have a name for my pain, and it is SFINAE!"

Now I understand why dmd works (or actually, fails to work) the way it 
does.  When I have some deeply-nested set of templates, and there is 
some quirkly little problem deep within them, then dmd will often give 
me some totally useless error:
	foo.d: 25: template "wrapper_way_on_the_outside" has an error

GRRRR!!!!  I thought that this was a bug in the compiler...

The only way to debug these problems is to unwrap the template, by hand, 
using repeated aliases over and over and over, dozens of compiles, until 
you finally find the problem.  It's usually that some minor template way 
off in the bowels of my library wasn't properly overloaded for some 
specific case.

	void myFunctionThatWillNotCompile()
	{
		alias deepestNestedTemplate!(ARGS) a1;
		alias nextLevel!(deepestNestedTemplate!(ARGS)) a2;
		alias adNauseum!(...) a3;
	/+
		... this code commented out because SFINAE makes
		... dmd produce error messages that don't tell me
		... what I need to know
	+/
	}

Worse, it means that if I have a properly-specialized template for some 
case, but the implementation within it has a small error, my code is 
going to get routed to the general, catch-all template (which it never 
should have hit), and the errors that I actually *do* see won't make any 
sense.

EEEK!!!

I know that there must be a reason why people argue for SFINAE, but, 
from my recent experience, I have to disagree.  I will say (with all 
modestly and readiness to learn otherwise) that "SFINAE IS EVIL."

Here's my modest proposal:
* If there is a "best match," force the code to use it.  Don't ignore 
the best match because of internal compilation errors.
* If people really need SFINAE, then give them a way to express it 
explicitly.  Something like:
	template foo(int n)
	{
		static if(n == 0)
			try_next_best_specialization;
	}



More information about the Digitalmars-d mailing list