www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - SFINAE

reply Jason House <jason.james.house gmail.com> writes:
Now that we're all talking about templates and Andrei is participating on
this list, I figure it's a good time to bring this topic up again.

(brief background: SFINAE = substitution failure is not an error.  Commonly
used when selecting which templated definition to apply.  Most uses in C++
are tricks to determine info available in D is expressions)

SFINAE causes debugging nightmares with template based code when a
specialization fails to compile as expected.  When I challenged people in
the past to provide real examples of template code that would require
SFINAE in D, nobody could come up with one.  The template declaration and
constraints in D seem to be enough.

I think we should try removing SFINAE from D 2.x while it's still considered
experimental/alpha.  I expect a lack of SFINAE to make the compiler simpler
and ensure D preserves its fast compile times.

If it does turn out that SFINAE does provide unique functionality, I think
it may be better to enhance existing generic programming techniques than to
keep SFINAE.  The further SFINAE gets pushed out of normal use (through
constraints and detailed type declarations), the more of a corner case
SFINAE becomes.  The more this happens, the more this "feature" will bite
developers instead of helping them.

PS: This is basically a rehash of what I typed in
http://d.puremagic.com/issues/show_bug.cgi?id=1951

It's also based on the past newsgroup thread at
http://digitalmars.com/d/archives/digitalmars/D/SFINAE_is_Evil_67995.html
Oct 05 2008
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jason House wrote:
 Now that we're all talking about templates and Andrei is participating on
 this list, I figure it's a good time to bring this topic up again.
 
 (brief background: SFINAE = substitution failure is not an error.  Commonly
 used when selecting which templated definition to apply.  Most uses in C++
 are tricks to determine info available in D is expressions)
 
 SFINAE causes debugging nightmares with template based code when a
 specialization fails to compile as expected.  When I challenged people in
 the past to provide real examples of template code that would require
 SFINAE in D, nobody could come up with one.  The template declaration and
 constraints in D seem to be enough.
 
 I think we should try removing SFINAE from D 2.x while it's still considered
 experimental/alpha.  I expect a lack of SFINAE to make the compiler simpler
 and ensure D preserves its fast compile times.
 
 If it does turn out that SFINAE does provide unique functionality, I think
 it may be better to enhance existing generic programming techniques than to
 keep SFINAE.  The further SFINAE gets pushed out of normal use (through
 constraints and detailed type declarations), the more of a corner case
 SFINAE becomes.  The more this happens, the more this "feature" will bite
 developers instead of helping them.
 
 PS: This is basically a rehash of what I typed in
 http://d.puremagic.com/issues/show_bug.cgi?id=1951
 
 It's also based on the past newsgroup thread at
 http://digitalmars.com/d/archives/digitalmars/D/SFINAE_is_Evil_67995.html
I think conditional templates obviate most, if not all, of the need for sfinae. There need to be some more steps taken, most importantly unification of regular functions with template functions. Andrei home
Oct 05 2008
parent reply Jason House <jason.james.house gmail.com> writes:
Andrei Alexandrescu wrote:

 I think conditional templates obviate most, if not all, of the need for
 sfinae. There need to be some more steps taken, most importantly
 unification of regular functions with template functions.
 
 Andrei home
Can you expand on the "unification of regular functions with template functions"?
Oct 05 2008
next sibling parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Sun, Oct 5, 2008 at 7:15 PM, Jason House <jason.james.house gmail.com> wrote:
 Andrei Alexandrescu wrote:

 I think conditional templates obviate most, if not all, of the need for
 sfinae. There need to be some more steps taken, most importantly
 unification of regular functions with template functions.

 Andrei home
Can you expand on the "unification of regular functions with template functions"?
So you can do i.e. void foo(int x) {} void foo(T)(T t) {} foo(5) calls the int overload and foo(3.4) calls foo!(typeof(3.4))(3.4).
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 7:15 PM, Jason House <jason.james.house gmail.com>
wrote:
 Andrei Alexandrescu wrote:

 I think conditional templates obviate most, if not all, of the need for
 sfinae. There need to be some more steps taken, most importantly
 unification of regular functions with template functions.

 Andrei home
Can you expand on the "unification of regular functions with template functions"?
So you can do i.e. void foo(int x) {} void foo(T)(T t) {} foo(5) calls the int overload and foo(3.4) calls foo!(typeof(3.4))(3.4).
Thunder theft. Andrei
Oct 05 2008
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jason House wrote:
 Andrei Alexandrescu wrote:
 
 I think conditional templates obviate most, if not all, of the need for
 sfinae. There need to be some more steps taken, most importantly
 unification of regular functions with template functions.

 Andrei home
Can you expand on the "unification of regular functions with template functions"?
This is a large subject and I don't want to spread myself too thin. In short: void fun(int a, char[] b); should be treated as if it were declared: void fun(T, U)(T a, U b) if (is(T == int) && is(U == char[])); In other words: a regular function is nothing but an "infinitely specialized" template function. Once that's in place, they'll all play rather nicely together. But there are some more things to change, such as behavior of template functions with implicit conversions. Andrei
Oct 05 2008
next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Sun, Oct 5, 2008 at 7:45 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 Jason House wrote:
 Andrei Alexandrescu wrote:

 I think conditional templates obviate most, if not all, of the need for
 sfinae. There need to be some more steps taken, most importantly
 unification of regular functions with template functions.

 Andrei home
Can you expand on the "unification of regular functions with template functions"?
This is a large subject and I don't want to spread myself too thin. In short: void fun(int a, char[] b); should be treated as if it were declared: void fun(T, U)(T a, U b) if (is(T == int) && is(U == char[])); In other words: a regular function is nothing but an "infinitely specialized" template function. Once that's in place, they'll all play rather nicely together. But there are some more things to change, such as behavior of template functions with implicit conversions.
I was figuring this was how it would be unified. Template specialization has more than enough power to do function overloading.
Oct 05 2008
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 void fun(int a, char[] b);
 should be treated as if it were declared:
 void fun(T, U)(T a, U b) if (is(T == int) && is(U == char[]));
 
 In other words: a regular function is nothing but an "infinitely
 specialized" template function.
So you can also take a delegate/function pointer of that fun() template. Bye, bearophile
Oct 05 2008
parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Sun, Oct 5, 2008 at 8:21 PM, bearophile <bearophileHUGS lycos.com> wrote:
 Andrei Alexandrescu:
 void fun(int a, char[] b);
 should be treated as if it were declared:
 void fun(T, U)(T a, U b) if (is(T == int) && is(U == char[]));

 In other words: a regular function is nothing but an "infinitely
 specialized" template function.
So you can also take a delegate/function pointer of that fun() template.
There's nothing stopping you from taking the address of templated functions now, as long as they're fully specified. Unless you're only talking about the syntactic benefits of being able to write &fun instead of &fun!(int, char[]).
Oct 05 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Sun, Oct 5, 2008 at 8:21 PM, bearophile <bearophileHUGS lycos.com> wrote:
 Andrei Alexandrescu:
 void fun(int a, char[] b);
 should be treated as if it were declared:
 void fun(T, U)(T a, U b) if (is(T == int) && is(U == char[]));

 In other words: a regular function is nothing but an "infinitely
 specialized" template function.
So you can also take a delegate/function pointer of that fun() template.
There's nothing stopping you from taking the address of templated functions now, as long as they're fully specified. Unless you're only talking about the syntactic benefits of being able to write &fun instead of &fun!(int, char[]).
Yah, that's part of "But there are some more things to change". Ahem. Andrei
Oct 05 2008
prev sibling next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Andrei Alexandrescu Wrote:
 
 I think conditional templates obviate most, if not all, of the need for 
 sfinae. 
Which is it? Most or all? If it's not all, what's missing?
 There need to be some more steps taken, most importantly 
 unification of regular functions with template functions.
Why would having or not having that change the need for SFINAE?
Oct 05 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jason House wrote:
 Andrei Alexandrescu Wrote:
  
 I think conditional templates obviate most, if not all, of the need for 
 sfinae. 
Which is it? Most or all? If it's not all, what's missing?
 There need to be some more steps taken, most importantly 
 unification of regular functions with template functions.
Why would having or not having that change the need for SFINAE?
I don't know; we haven't thought all of that through. Andrei
Oct 05 2008
parent Don Clugston <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 Jason House wrote:
 Andrei Alexandrescu Wrote:
  
 I think conditional templates obviate most, if not all, of the need 
 for sfinae. 
Which is it? Most or all? If it's not all, what's missing?
 There need to be some more steps taken, most importantly unification 
 of regular functions with template functions.
Why would having or not having that change the need for SFINAE?
I don't know; we haven't thought all of that through. Andrei
I've never seen any D code which used SFINAE. Why not simply disable it, see if anything breaks, and _then_ look for alternatives for anything which actually requires it? I strongly suspect that SFINAE is an obselete coding style in D. There's a decent chance that nobody is using it.
Oct 06 2008
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Jason House wrote:
 Now that we're all talking about templates and Andrei is participating on
 this list, I figure it's a good time to bring this topic up again.
 
 (brief background: SFINAE = substitution failure is not an error.  Commonly
 used when selecting which templated definition to apply.  Most uses in C++
 are tricks to determine info available in D is expressions)
 
 SFINAE causes debugging nightmares with template based code when a
 specialization fails to compile as expected.  When I challenged people in
 the past to provide real examples of template code that would require
 SFINAE in D, nobody could come up with one.  The template declaration and
 constraints in D seem to be enough.
 
 I think we should try removing SFINAE from D 2.x while it's still considered
 experimental/alpha.  I expect a lack of SFINAE to make the compiler simpler
 and ensure D preserves its fast compile times.
SFINAE means backtracking. You can substitute it with templates that manually select the appropriate other template to instantiate, which is hella easier to work with. While this doesn't solve naming collisions, we have other methods for doing that already.
Oct 08 2008