News for hackers. Stuff that matters.
Re:Currying by bheadmaster on Monday April 08, 2024 @05:29AM (#39967881)
Peak HN meta-argument.

It is easy to guess that the original comment meant that a manual re-write of a function:

    foo(a,b) {...}
to a class (example in pseudo-C++, since C++ supports operator() overloading):

    class Foo {
        Foo(a) {...}
        operator()(b) {...}
    }
is equivalent to currying the original function:

    // curried foo:
    foo(a)(b)

    // class-curried foo:
    Foo(a)(b)
But instead of explaining or mentioning this, you both went into a rant about intentions and motivations, which completely bored me, and informed me of nothing, as a member of the general audience.

Congratulations.

Re:Currying by whilenot-dev on Monday April 08, 2024 @06:46AM (#39968344)
Thank you for bringing the topic back on track!

Your example is currying in a manual fashion, so two questions remain for me:

1. How would you tell the compiler to do it for you, as a function transformation?

2. How would you curry a function with 3+ arguments?

Re:Currying by bheadmaster on Monday April 08, 2024 @10:17AM (#39969968)
I can answer both questions with a sprinkle of template magic:

    #include <iostream>
    #include <functional>

    template <typename Ret, typename First, typename ...Rest>
    class Curry {
        std::function<Ret(First, Rest...)> fn;
      public:
        Curry(std::function<Ret(First, Rest...)> fn): fn(fn) {};
        Curry<Ret, Rest...> operator()(First arg) {
            return Curry<Ret, Rest...>{[this, arg](Rest... args) {
                return this->fn(arg, args...);
            }};
        }
    };

    template <typename Ret, typename Arg>
    class Curry<Ret, Arg> {
        std::function<Ret(Arg)> fn;
      public:
        Curry(std::function<Ret(Arg)> fn): fn(fn) {};
        Ret operator()(Arg arg) {
            return this->fn(arg);
        }
    };


    int uncurried(int a, int b, int c) {
        return a + 2*b + 3*c;
    }

    int main() {
        auto curried = Curry<int, int, int, int>{uncurried};

        std::cout << curried(1)(2)(3) << std::endl;
    }
Re:Currying by whilenot-dev on Monday April 08, 2024 @10:58AM (#39970437)
I'm speechless, thank you very much! =)