
Kirit Sælensminde wrote:
shunsuke wrote:
Kirit Sælensminde wrote:
And finally, does the curry function itself need to be a macro? When you need static-initialization. BOOST_EGG_CURRY2(..) is, in fact, a knotty braced initializer, which guarantees static-initialization.
Of course, Egg supports also:
typedef boost::result_of<T_curry2(int(*)(int,int))>::type T_curried_plus; T_curried_plus curried_plus = curry2(&::plus);
No macros. But there is a function-call, which incurs dynamic-initialization. You might notice that "static form" using macro and "dynamic form" using function is nicely symmetric.
So the macro removed the first function call and actually writes a function which is the curried version rather than perform the currying at runtime? Now that *is* cool and seems to be a good enough reason to have a macro (to me at least)! :)
Here is my implementation of curry2. I'd always assumed that a complete implementation would overload on the relevant "callable" types: As mentioned above, non-numbered form `curry` might support the famous "callables". It seems difficult to define "what is famous", though.
There is another Boost library out in 1.35, Boost.FunctionTypes, which might be able to help as it has decomposition functions that work with a wider range of callable function than for example Boost.Function does. Maybe that can be leveraged against? I've not had a chance to delve into it myself yet though, but Tobias Schwinger seemed to think it would handle the higher order requirements I was playing with last time I raised it on the list.
No. It's basically just type traits to adapt built-in, Callable types to sequential interfaces (so they can be handled regardless of their arity without using preprocessor metaprogramming). Further, as mentioned in my post you cited, it provides a workaround for certain strange portability issues. Regards, Tobias