www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - functors with template lambdas

reply "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
I think this code should be allowed, but it isn't:

	struct Functor (T)
	{
		T a;

		auto ref fmap (alias f)()
		{
			return Functor (f(a));
		}
	}

	auto ref identity (T)(auto ref T a)
	{
		return a;
	}

	void main()
	{
		Functor!int a;

		static auto id (T)(T x)
		{return x;}

		a.fmap!identity; // ok

		a.fmap!id; // ok

		a.fmap!((int x) => x); // ok

		a.fmap!(x => x); // Error: template instance fmap!((x) => x) 
cannot use local '__lambda1' as parameter to non-global template 
fmap(alias f)()
	}

This seems like one of those things that doesn't work because of 
some compiler implementation detail rather than a consequence of 
the language rules but I'm not sure. Opinion?
May 15 2015
parent reply "weaselcat" <weaselcat gmail.com> writes:
On Saturday, 16 May 2015 at 02:04:39 UTC, Vlad Levenfeld wrote:
 I think this code should be allowed, but it isn't:

 	struct Functor (T)
 	{
 		T a;

 		auto ref fmap (alias f)()
 		{
 			return Functor (f(a));
 		}
 	}

 	auto ref identity (T)(auto ref T a)
 	{
 		return a;
 	}

 	void main()
 	{
 		Functor!int a;

 		static auto id (T)(T x)
 		{return x;}

 		a.fmap!identity; // ok

 		a.fmap!id; // ok

 		a.fmap!((int x) => x); // ok

 		a.fmap!(x => x); // Error: template instance fmap!((x) => x) 
 cannot use local '__lambda1' as parameter to non-global 
 template fmap(alias f)()
 	}

 This seems like one of those things that doesn't work because 
 of some compiler implementation detail rather than a 
 consequence of the language rules but I'm not sure. Opinion?
very long standing compiler bug https://issues.dlang.org/show_bug.cgi?id=3051
May 15 2015
parent reply "weaselcat" <weaselcat gmail.com> writes:
On Saturday, 16 May 2015 at 02:06:45 UTC, weaselcat wrote:
 very long standing compiler bug
 https://issues.dlang.org/show_bug.cgi?id=3051
see also https://issues.dlang.org/show_bug.cgi?id=5710 unsure if they're duplicate bugs, never really looked into it.
May 15 2015
parent "Vlad Levenfeld" <vlevenfeld gmail.com> writes:
On Saturday, 16 May 2015 at 02:08:09 UTC, weaselcat wrote:
 On Saturday, 16 May 2015 at 02:06:45 UTC, weaselcat wrote:
 very long standing compiler bug
 https://issues.dlang.org/show_bug.cgi?id=3051
see also https://issues.dlang.org/show_bug.cgi?id=5710 unsure if they're duplicate bugs, never really looked into it.
Yeah it looks like the bugs come from the same root cause. http://wiki.dlang.org/DIP30 Also, this came up during the discussion of the latter bug. Its still in "Draft" status. Haven't read it carefully enough yet to tell whether or not it would be helpful. GDC rejects this code as well. I dunno about LDC. BUT!! I found a way to make this pattern, at least, work as intended. I expected a symbol resolution error from the following code but was very pleased to find that it compiles: module ffunc; struct F (T) { T a; } auto ref fmap (alias f, T)(auto ref F!T x) { return F!T (f(x.a)); } --- module gfunc; struct G (T) { T a; } auto ref fmap (alias f, T)(auto ref G!T x) { return G!T (f(x.a)); } --- import ffunc; import gfunc; auto ref identity (T)(auto ref T a) { return a; } void main () { F!int a; G!int b; a.fmap!identity; b.fmap!identity; static auto id (T)(T x) {return x;} a.fmap!id; b.fmap!id; a.fmap!((int x) => x); b.fmap!((int x) => x); a.fmap!(x => x); b.fmap!(x => x); } Frankly this is even better than the original code, because now fmap can be defined after the functor, as a UFCS extension. Awesome!!
May 15 2015