Thread overview
template recursion
Jun 26, 2018
Alex
Jun 26, 2018
ag0aep6g
Jun 26, 2018
Alex
Jun 26, 2018
Nathan S.
June 26, 2018
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." :(


June 26, 2018
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
June 26, 2018
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!
June 26, 2018
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
June 26, 2018
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".