www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Recursive templated structs disallowed?

reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
struct bar( T ) {
     auto baz( U )( U arg ) {
         bar!( typeof( this ) ) tmp;
         return tmp;
     }
}

void main( ) {
     bar!int n;
     n.baz( 3 );
}

This code fails with
Error: recursive template expansion for template argument bar!(int)
Now, I agree it is recursive, but it is not infinitely recursive, so
there shouldn't really be a problem.
Is this a bug? Is there a workaround?

-- 
Simen
Aug 04 2010
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 04 Aug 2010 15:37:32 -0400, Simen kjaeraas  
<simen.kjaras gmail.com> wrote:

 struct bar( T ) {
      auto baz( U )( U arg ) {
          bar!( typeof( this ) ) tmp;
          return tmp;
      }
 }

 void main( ) {
      bar!int n;
      n.baz( 3 );
 }

 This code fails with
 Error: recursive template expansion for template argument bar!(int)
 Now, I agree it is recursive, but it is not infinitely recursive, so
 there shouldn't really be a problem.
 Is this a bug? Is there a workaround?

It's lazily recursive. Meaning, it *is* infinitely recursive, but the compiler does not have to evaluate all the recursions until they are used. I'm not sure it should be disallowed, but it's definitely on the edge. Do you have some real-world case for this? If you want to get something like this fixed, you'll need a good example, not an academic one. -Steve
Aug 04 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Steven Schveighoffer <schveiguy yahoo.com> wrote:

 On Wed, 04 Aug 2010 15:37:32 -0400, Simen kjaeraas  
 <simen.kjaras gmail.com> wrote:

 struct bar( T ) {
      auto baz( U )( U arg ) {
          bar!( typeof( this ) ) tmp;
          return tmp;
      }
 }

 void main( ) {
      bar!int n;
      n.baz( 3 );
 }

 This code fails with
 Error: recursive template expansion for template argument bar!(int)
 Now, I agree it is recursive, but it is not infinitely recursive, so
 there shouldn't really be a problem.
 Is this a bug? Is there a workaround?

It's lazily recursive. Meaning, it *is* infinitely recursive, but the compiler does not have to evaluate all the recursions until they are used. I'm not sure it should be disallowed, but it's definitely on the edge. Do you have some real-world case for this? If you want to get something like this fixed, you'll need a good example, not an academic one.

I sorta do. I have a struct that keeps track of the operations performed on it, to create a template stack for calculating stuff at the end. Basically, I build a function by performing the operations on the struct. Not sure if this is an expression template, but possibly related. -- Simen
Aug 04 2010
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--0015174befdce75b88048d061453
Content-Type: text/plain; charset=ISO-8859-1

On Wed, Aug 4, 2010 at 22:06, Steven Schveighoffer <schveiguy yahoo.com>wrote:

 On Wed, 04 Aug 2010 15:37:32 -0400, Simen kjaeraas <simen.kjaras gmail.com>
 wrote:

  struct bar( T ) {
     auto baz( U )( U arg ) {
         bar!( typeof( this ) ) tmp;
         return tmp;
     }
 }

 void main( ) {
     bar!int n;
     n.baz( 3 );
 }

 This code fails with
 Error: recursive template expansion for template argument bar!(int)
 Now, I agree it is recursive, but it is not infinitely recursive, so
 there shouldn't really be a problem.
 Is this a bug? Is there a workaround?

It's lazily recursive. Meaning, it *is* infinitely recursive, but the compiler does not have to evaluate all the recursions until they are used. I'm not sure it should be disallowed, but it's definitely on the edge. Do you have some real-world case for this? If you want to get something like this fixed, you'll need a good example, not an academic one. -Steve

I could get this to work, using a factory function: import std.stdio; struct Bar( T ) { auto baz( U )( U arg ) { return bar(this); } } Bar!T bar(T)(T t) { return Bar!T(); } void main( ) { Bar!int n; auto nn = n.baz( 3 ); writeln(typeof(n).stringof); writeln(typeof(nn).stringof); } It's... fragile. Changes a few things here and there, and it's back to infinite recursion. Philippe --0015174befdce75b88048d061453 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Wed, Aug 4, 2010 at 22:06, Steven Sch= veighoffer <span dir=3D"ltr">&lt;<a href=3D"mailto:schveiguy yahoo.com">sch= veiguy yahoo.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote"= style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> <div><div></div><div class=3D"h5">On Wed, 04 Aug 2010 15:37:32 -0400, Simen= kjaeraas &lt;<a href=3D"mailto:simen.kjaras gmail.com" target=3D"_blank">s= imen.kjaras gmail.com</a>&gt; wrote:<br> <br> <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex"> struct bar( T ) {<br> =A0 =A0 auto baz( U )( U arg ) {<br> =A0 =A0 =A0 =A0 bar!( typeof( this ) ) tmp;<br> =A0 =A0 =A0 =A0 return tmp;<br> =A0 =A0 }<br> }<br> <br> void main( ) {<br> =A0 =A0 bar!int n;<br> =A0 =A0 n.baz( 3 );<br> }<br> <br> This code fails with<br> Error: recursive template expansion for template argument bar!(int)<br> Now, I agree it is recursive, but it is not infinitely recursive, so<br> there shouldn&#39;t really be a problem.<br> Is this a bug? Is there a workaround?<br> </blockquote> <br></div></div> It&#39;s lazily recursive. =A0Meaning, it *is* infinitely recursive, but th= e compiler does not have to evaluate all the recursions until they are used= .<br> <br> I&#39;m not sure it should be disallowed, but it&#39;s definitely on the ed= ge. =A0Do you have some real-world case for this? =A0If you want to get som= ething like this fixed, you&#39;ll need a good example, not an academic one= .<br> <br> -Steve<br> </blockquote></div><br><div>I could get this to work, using a factory funct= ion:</div><div><br></div><div><div>import std.stdio;</div><div><br></div><d= iv>struct Bar( T ) {</div><div>=A0=A0 auto baz( U )( U arg ) {</div><div>= =A0=A0 =A0 =A0 return bar(this);</div> <div>=A0=A0 }</div><div>}</div><div><br></div><div>Bar!T bar(T)(T t)</div><= div>{</div><div>=A0=A0 =A0return Bar!T();</div><div>}</div><div><br></div><= div>void main( ) {</div><div>=A0=A0 Bar!int n;</div><div>=A0=A0 auto nn =3D= n.baz( 3 );</div> <div>=A0=A0 writeln(typeof(n).stringof);</div><div>=A0=A0 writeln(typeof(nn= ).stringof);</div><div>}</div></div><div><br></div><div>It&#39;s... fragile= . Changes a few things here and there, and it&#39;s back to infinite recurs= ion.=A0</div> <div><br></div><div><br></div><div><br></div><div>Philippe</div> --0015174befdce75b88048d061453--
Aug 04 2010
prev sibling parent Don <nospam nospam.com> writes:
Simen kjaeraas wrote:
 struct bar( T ) {
     auto baz( U )( U arg ) {
         bar!( typeof( this ) ) tmp;
         return tmp;
     }
 }
 
 void main( ) {
     bar!int n;
     n.baz( 3 );
 }
 
 This code fails with
 Error: recursive template expansion for template argument bar!(int)
 Now, I agree it is recursive, but it is not infinitely recursive, so
 there shouldn't really be a problem.
 Is this a bug? Is there a workaround?
 

Aug 05 2010