On Wednesday, 8 July 2015 at 18:31:00 UTC, Steven Schveighoffer wrote:

You can use a function lambda:

auto fp = (real a) => cos(a);

Note, I had to put (real a) even though I would have expected "a => cos(a)" to work.

-Steve

I've been playing around with this a little more. I wrote this function to encapsulate a simple operation on arrays.

U array_fun(T, U)(T fp, U x)
        if (isFunctionPointer!(T) && isArray!(U))
{
        return x.map!(a => fp(a)).array;
}

Then I wrote a cos function that calls it on using a function pointer.

T cos(T : U[], U)(T x)
        if (isArray!(T))
{
        auto fp = (U a) => cos(a);
        return array_fun(fp, x);
}

This seems to work just fine, but for some reason this only seems to work when I import std.math : cos. It doesn't work when I just do import std.math. Bug?

Nevertheless, if I want to implement it for another function, then I have to write it all over again. So I wrote a mixin that would encapsulate that idea (I put in the \n, \t for formatting purposes because I like to be able to writeln it out and see that it matches the original).

template mixin_builder(string function_name)
{
        const char[] mixin_builder =
                "T " ~ function_name ~ "(T : U[], U)(T x)\n" ~
                        "\tif (isArray!(T))\n" ~
                "{\n" ~
                        "\tauto fp = (U a) => " ~ function_name ~ "(a);\n" ~
                        "\treturn array_fun(fp, x);\n" ~
                "}";
}

Then I can just call
mixin(mixin_builder!("cos"));
mixin(mixin_builder!("sin"));

While it works, it feels a bit hackish. I'm not sure I can think of a generic way to do this without mixins.

Reply via email to