Transform a function's body into a string for mixing in

Emmanuelle VuLXn6DBW at PPtUm7TvV6nsw.com
Fri Jun 21 21:34:26 UTC 2019


On Friday, 21 June 2019 at 15:54:35 UTC, Adam D. Ruppe wrote:
> On Friday, 21 June 2019 at 15:42:56 UTC, Emmanuelle wrote:
>> [...]
>
> This sounds very similar to something I hacked together a while 
> ago and recently wrote about making cleaner code:
>
> https://forum.dlang.org/post/ekbyseslunvmudkhlhoh@forum.dlang.org
>
> The idea here was to do a pass-by-value lambda. Usage:
>
> ---
>     auto bar(T)(T x) @nogc
>     {
>         return x(10);
>     }
>
>     auto foo(int x) @nogc
>     {
> 	auto f = lambda!(x, q{ (int y) { return x + y; } });
> 	return f;
>     }
>
>     void main()
>     {
>     	import std.stdio;
> 	writeln(foo(15)(10));
>     }
> ---
>
> Magic implementation:
>
> ---
>     template lambda(Args...) {
> 	static struct anon {
> 		static foreach(i; 0 .. Args.length - 1)
> 			mixin("typeof(Args[i]) " ~ __traits(identifier, Args[i]) ~ 
> ";");
> 		auto opCall(T...)(T t) {
> 			return mixin(Args[$-1])(t);
> 		}
> 		this(T...)(T t) {
> 			this.tupleof = t;
> 		}
> 	}
>
> 	anon lambda() {
> 		anon a;
> 		// copy the values in
> 		a.tupleof = Args[0 .. $-1];
> 		return a;
> 	}
>     }
> ---
>
>
>
> You could convert that into a regular delegate too, so it works 
> with non-template consumers, by generating a non-templated 
> opCall and taking its address.

Oh wow, that's pretty awesome. Too bad it seems the token string 
around the lambda is unavoidable, but it's not a big deal I 
think. In any case thanks, you snippet helped me figure out the 
template I wanted without overuse of strings!


More information about the Digitalmars-d-learn mailing list