
Dave Abrahams wrote:
on Wed Aug 24 2011, Eric Niebler <eric-AT-boostpro.com> wrote:
On 8/24/2011 12:55 PM, Dave Abrahams wrote:
on Wed Aug 24 2011, Eric Niebler <eric-AT-boostpro.com> wrote:
On 8/24/2011 4:28 AM, Thomas Heller wrote:
However, the problem comes with function objects having operator() overloads with different arity. Another problem I couldn't solve yet is how to decide which overload gets curryied or not. Consider:
struct foo { void operator()(int); void operator()(int, int); };
curryable<foo> f; auto curried = f(1); // To curry or not to curry, that is the question
As soon as enough arguments are collected to call the curried function, it gets called. So in this case, f(1) calls f::operator()(int).
That's an asymmetry about most currying syntax that I never liked, at least for C++.
Could you explain what you mean by asymmetry here? That my currying code prefers one function over another based on the available arguments?
I mean this, for a ternary function f:
f(x) => doesn't call f f(x)(y) => doesn't call f f(x)(y)(z) => calls f
That last step looks asymmetric to me.
In a lazy language, f(x)(y)(z) *doesn't* call f... until you actually use the result for something... which is more consistent-looking.
I suppose the symmetrical non-lazy version looks like:
f(x) => doesn't call f f(x)(y) => doesn't call f f(x)(y)(z) => doesn't call f f(x)(y)(z)() => calls f
I tend to agree, but can't we have both? What about if the lazy f implicitly converts to its return type through a casting operator? This way we can pass the return type of f(x)(y)(z) as a function object, but make lazy execution of the function object implicit. f(x) => doesn't call f f(x)(y) => doesn't call f result_type result = f(x)(y)(z) => calls f through operator(result_type) If f had a void return type I guess we would have to force it's call with operator() and use of operator() would otherwise be optional. I suppose forgetting to force would be error prone if people are used to relying on the implicit conversion to force the function call. In general I see no reason not to make a nullary function object castable to its operator() return type, does the loss of type safety hurt us in this case? I like the simplicity of not having the extra () in the simple case where I want to get its result immediately. It may be more intuitive also, but I guess it could do more harm than good if it leads to astonishment. Just thinking out loud, Luke