Can’t wait for the next post 🙂
]]>In reply to ciber.
Clever! I like that variadic compose function you have there.
]]>In reply to dzada.
I did a bit of poking around, dealing with primitives with cps and crazy lambdas in general tends to give you the exact same code as if you just wrote something like std::cout << whateverl since lambdas inline quite well. STL functions are a special objects so they take a fair bit more overhead in general.
I'm trying to learn assembly just so I can better comment on performance stuff, but I'm far from expert at it.
I work in gcc 4.9 your mileage may vary.
Thanks for reading!
]]>Sorry for the code: it does not display well. Better, see this answer http://stackoverflow.com/a/27727236/286335
]]>// g++ -std=c++1y composition.cpp
#include
using namespace std;
// ———————————————————
// ———————————————————
template
class Composite;
// ———————————————————
// ———————————————————
template
Composite compose2 (F1 f, F2 g) {
return Composite {f,g};
}
// ———————————————————
// ———————————————————
template
auto compose (F1 f, F2 g) -> decltype(compose2 (f, g))
{
return compose2 (f, g);
}
template
decltype(auto) compose (F1 f, Fs … args)
{
return compose2 (f, compose(args…));
}
// ———————————————————
// ———————————————————
template
class Composite{
private:
F1 f1;
F2 f2;
public:
Composite(F1 f1, F2 f2) : f1(f1), f2(f2) { }
template
auto operator() (IN i) -> decltype(f2(f1(i)))
{
return f2 ( f1(i) );
}
};
// ———————————————————
// ———————————————————
int f(int a) { return 2*a; }
double g(int a) { return a+2.5; }
double h(double a) { return 2.5*a; }
double i(double a) { return 2.5-a; }
class Functor {
double x;
public:
Functor (double x_) : x(x_) { }
double operator() (double a) { return a*x; }
};
// ———————————————————
// ———————————————————
int main () {
auto l1 = [] (double a) { return a/3; };
auto l2 = [] (double a) { return 3.5+a; };
Functor fu {4.5};
auto compos1 = compose (f, g, l1, g, h, h, l1, l2);
auto compos2 = compose (compos1, l1, l2, fu);
auto x = compos2 (3);
cout << x << endl;
cout << compos2(3) << endl;
cout << fu(l2(l1(l2(l1(h(h(g(l1(g(f(3))))))))))) << endl;
} // ()
]]>I’m surprised your vector monoid uses a loop and push_back. Depending on the size of the rhs it could involve multiple allocations. Why not something like:
using namespace std;
lhs.insert( end(lhs), begin(rhs), end(rhs) )
Additionally that would work for any container type that has insert, not just vector.
]]>You might enjoy http://coliru.stacked-crooked.com/a/fec4013aff8f8214 — a *then* operator that converts a function returning an element or a tuple into a continuation call. func(a,b,c) *then* [&]( int x, int y ){ std::cout << x << "," << y <Z ) would require a bit more work, and dealing with the issue that function names are not passable objects in C++ (as they represent entire overload sets). I also threw in std::future support for giggles.
]]>Hello
Nice and clear article, thank you. (really makes me think of the waterfall Js)
Also I wondered if in you next articles you could mention about the possible performance overhead.
From what I’ve done with lambdas and std::function, I would say: low overhead with Lambdas, and heavy with std::functions on MSVC, quite heavy for both on CLang (3.1 if i remember well). Which was a bit sad.
Maybe this will change as compilers are evolving quite fast and probably just starting on these. Although I can imagine it to be easier to optimize for a compiler when simply written with ad hoc code.
Best
]]>How can you declare template function pointer f like R(C::*f)() with no arguments and still be able to call it with Args…?
]]>It isn’t hard to write `*then*` which takes a usual function (non-cps) on the left hand side, and a continuation on the right, unpacking tuples if the right hand side will take them. You should also be able to kill the std function overhead in your recursive example and make it returnable with a y combinator (as it stands that callable is only valid within its own scope) — in C++14 the y is even elegant (at least I think that is what I wrote…)
]]>