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/ekbyseslunvmudkhl...@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!

Reply via email to