www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template recursion

reply Alex <sascha.orlov gmail.com> writes:
Hi all,
I have a strange case of template recursion, which I don't know 
how to solve:

´´´
import std.range;

void main()
{
	T.member.tarr.length = 42;
	//put(T.member, 4); // line 6
	T.member.put(4); // line 7
}


struct T
{
	void put(Type)(Type t){} // line 13

	static B member;
}

struct B
{
	T[] tarr;
	void put(Type)(Type t)
	{
		put(tarr[t], t); // line 23
	}
}
´´´

Line 7 complains about:
template app.B.put cannot deduce function from argument types 
!()(T, int)

So, I see, that the compiler tries to use the same put function 
in line 23, as in line 7 and fails. Instead of this, I want to 
use the one in line 13.
But I don't see any mistake at line 23...

Besides this, as a secondary question:
using line 6 does not yield any helpful debugging message. My put 
functions are templates and pretty long and branching, and I'm 
trying to debug them somehow, but using idiomatic writing all I 
get as a message is something like
"Cannot put a XX into a YY." :(
Jun 26 2018
parent reply ag0aep6g <anonymous example.com> writes:
On 06/26/2018 11:35 AM, Alex wrote:
 ´´´
 import std.range;
 
 void main()
 {
      T.member.tarr.length = 42;
      //put(T.member, 4); // line 6
      T.member.put(4); // line 7
 }
 
 
 struct T
 {
      void put(Type)(Type t){} // line 13
 
      static B member;
 }
 
 struct B
 {
      T[] tarr;
      void put(Type)(Type t)
      {
          put(tarr[t], t); // line 23
      }
 }
 ´´´
 
 Line 7 complains about:
 template app.B.put cannot deduce function from argument types !()(T, int)
 
 So, I see, that the compiler tries to use the same put function in line 
 23, as in line 7 and fails. Instead of this, I want to use the one in 
 line 13.
 But I don't see any mistake at line 23...
On line 23, you're apparently trying to call std.range.put (which would in turn call tarr[t].put). But being in a method that is itself called "put", that line is instead interpreted as a recursive call (which fails). To refer to std.range.put, you have to prepend a dot (the "module scope operator"): .put(tarr[t], t); // line 23 https://dlang.org/spec/module.html#module_scope_operators
Jun 26 2018
next sibling parent Alex <sascha.orlov gmail.com> writes:
On Tuesday, 26 June 2018 at 10:01:06 UTC, ag0aep6g wrote:
 On line 23, you're apparently trying to call std.range.put 
 (which would in turn call tarr[t].put). But being in a method 
 that is itself called "put", that line is instead interpreted 
 as a recursive call (which fails). To refer to std.range.put, 
 you have to prepend a dot (the "module scope operator"):

     .put(tarr[t], t); // line 23

 https://dlang.org/spec/module.html#module_scope_operators
Ah... that's cool :) Thanks a lot!
Jun 26 2018
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/26/18 6:01 AM, ag0aep6g wrote:

 On line 23, you're apparently trying to call std.range.put (which would 
 in turn call tarr[t].put). But being in a method that is itself called 
 "put", that line is instead interpreted as a recursive call (which 
 fails). To refer to std.range.put, you have to prepend a dot (the 
 "module scope operator"):
 
      .put(tarr[t], t); // line 23
 
 https://dlang.org/spec/module.html#module_scope_operators
Naming the hook for `put` the same thing as the global function was one of the biggest mistakes in the range library. I almost think we would be better off to deprecate that and pick another hook name. -Steve
Jun 26 2018
parent Nathan S. <no.public.email example.com> writes:
On Tuesday, 26 June 2018 at 20:47:27 UTC, Steven Schveighoffer 
wrote:
 Naming the hook for `put` the same thing as the global function 
 was one of the biggest mistakes in the range library. I almost 
 think we would be better off to deprecate that and pick another 
 hook name.
If you ever do that it would also be nice to use separate names for "put a single X into Y" and "put everything from container X into Y".
Jun 26 2018