www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - "SFINAE is Evil"

reply Jason House <jason.james.house gmail.com> writes:
SFINAE - Substitution failure is not an error

This post is all about templates and their static if counterparts.  With the
enhanced expressiveness of D, is there a need for SFINAE from C++? 
Essentially, when a specialization exists, if the compilation of the
specialization fails, the compiler silently gives up on it and goes to the
next more general case.  In my mind, this is both dangerous and a loop hole
for long compile times (as the compiler instantiates extra template
instances).

What I want to know is this:  Who uses SFINAE in D, and why?  Is this a
matter of convenience or a requirement.  If required, I assume it's from a
lack of expressiveness in defining a template's conditions.  Could this be
overcome with use of static if's instead?

PS: Post title is a quote of Russell Lewis from another thread.
Mar 20 2008
next sibling parent "Craig Black" <craigblack2 cox.net> writes:
"Jason House" <jason.james.house gmail.com> wrote in message 
news:frv6ut$2ecv$1 digitalmars.com...
 SFINAE - Substitution failure is not an error

 This post is all about templates and their static if counterparts.  With 
 the
 enhanced expressiveness of D, is there a need for SFINAE from C++?
 Essentially, when a specialization exists, if the compilation of the
 specialization fails, the compiler silently gives up on it and goes to the
 next more general case.  In my mind, this is both dangerous and a loop 
 hole
 for long compile times (as the compiler instantiates extra template
 instances).

 What I want to know is this:  Who uses SFINAE in D, and why?  Is this a
 matter of convenience or a requirement.  If required, I assume it's from a
 lack of expressiveness in defining a template's conditions.  Could this be
 overcome with use of static if's instead?

 PS: Post title is a quote of Russell Lewis from another thread.

I get the feeling that a number of features in D can eventually be dumped in favor of others. Perhaps SFINAE is one of them. I haven't used templates in D enough to know for sure. Definitely worth discussing though IMO. Anything that reduces the complexity of D without sacrificing expressive power is a good thing. -Craig
Mar 20 2008
prev sibling next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Jason House wrote:
 SFINAE - Substitution failure is not an error
 
 This post is all about templates and their static if counterparts.  With the
 enhanced expressiveness of D, is there a need for SFINAE from C++? 
 Essentially, when a specialization exists, if the compilation of the
 specialization fails, the compiler silently gives up on it and goes to the
 next more general case.  In my mind, this is both dangerous and a loop hole
 for long compile times (as the compiler instantiates extra template
 instances).
 
 What I want to know is this:  Who uses SFINAE in D, and why?  Is this a
 matter of convenience or a requirement.  If required, I assume it's from a
 lack of expressiveness in defining a template's conditions.  Could this be
 overcome with use of static if's instead?
 
 PS: Post title is a quote of Russell Lewis from another thread.

How do I know if I'm using SFINAE or not? :-) Seriously, I might be using it. I'm not sure. I'm not sure how to go about checking. And that in and of itself seems like an undesirable quality. I will say that I have most definitely been bitten by errors that came from failure to instantiate the template I thought I was instantiating (most often due to IFTI failures). These things can usually be debugged by switching the code I suspect to specify all template arguments. Then I'll get the sensible error telling me why it doesn't match. Also I've had bugs from the is-expressions not getting triggered because I had a typo in the is-expression which wasn't a syntax error. Not sure how the compiler could help there, though. --bb
Mar 20 2008
parent Russell Lewis <webmaster villagersonline.com> writes:
Bill Baxter wrote:
 How do I know if I'm using SFINAE or not?  :-)
 
 Seriously, I might be using it.  I'm not sure.  I'm not sure how to go 
 about checking.  And that in and of itself seems like an undesirable 
 quality.

Indeed!
 I will say that I have most definitely been bitten by errors that came 
 from failure to instantiate the template I thought I was instantiating 
 (most often due to IFTI failures).  These things can usually be debugged 
 by switching the code I suspect to specify all template arguments.  Then 
 I'll get the sensible error telling me why it doesn't match.

Tuples hurt you here, because if you specify some Tuple template as a "last resort" template, you can end up using it for things you thought you'd handled. Or, at least, I think that maybe that's the case...with SFINAE, it's hard to know for sure.
Mar 21 2008
prev sibling parent reply Russell Lewis <webmaster villagersonline.com> writes:
Jason House wrote:
 SFINAE - Substitution failure is not an error
 
 This post is all about templates and their static if counterparts.  With the
 enhanced expressiveness of D, is there a need for SFINAE from C++?

Here's a classic example of how SFINAE makes things hard. Look at the code below. You'd expect the static assert to fail, right? Give you an error message at the right location, and point you towards your bug? Nope. BEGIN CODE import std.stdio; template foo(TPL...) { static assert(false); } void main() { int i; foo!(i)(); } END CODE Here's what the compiler actually says: sfinae.d(3): template sfinae.foo(TPL...) is not a function template sfinae.d(11): template sfinae.foo(TPL...) cannot deduce template function from argument types !(i)() Not even a mention of the real problem. Now imagine that you are using non-trivial templates! Russ
Mar 21 2008
parent reply Jason House <jason.james.house gmail.com> writes:
It looks like your first compiler error is correct... There is no function.

 Jason House wrote:
 SFINAE - Substitution failure is not an error
 
 This post is all about templates and their static if counterparts.  With the
 enhanced expressiveness of D, is there a need for SFINAE from C++?

Here's a classic example of how SFINAE makes things hard. Look at the code below. You'd expect the static assert to fail, right? Give you an error message at the right location, and point you towards your bug? Nope. BEGIN CODE import std.stdio; template foo(TPL...) { static assert(false); } void main() { int i; foo!(i)(); } END CODE Here's what the compiler actually says: sfinae.d(3): template sfinae.foo(TPL...) is not a function template sfinae.d(11): template sfinae.foo(TPL...) cannot deduce template function from argument types !(i)() Not even a mention of the real problem. Now imagine that you are using non-trivial templates! Russ

Mar 21 2008
parent Russell Lewis <webmaster villagersonline.com> writes:
Jason House wrote:
 It looks like your first compiler error is correct... There is no 

You were right. I've seen that error so many times before, in cases, where a function did exist, that I didn't look closely enough. Here's a better example. The following code will produce useless "not a function template errors." Obviously, if you comment out the "static assert(false);", it works just fine. BEGIN dmd OUTPUT sfinae.d(3): template sfinae.foo(int I) is not a function template sfinae.d(22): template sfinae.foo(int I) cannot deduce template function from argument types !(5)() END OUTPUT BEGIN CODE import std.stdio; template foo(int I) { static if(I == 1) { void foo() {}; } else { void foo() { static assert(false); foo!(1)(); foo!(I-1)(); } } } void main() { foo!(5)(); } END CODE
Mar 24 2008