Basic Concepts

Everything is a function (class actor) in the Phoenix framework that can be evaluated as f(a..n), where n is the function's arity, or number of arguments that the function expects. Operators are also functions. For example, a + b is just a function with arity == 2 (or binary). a + b is the same as plus(a, b), a + b + c is the same as plus(plus(a, b), c). plus(plus(a, b), c) is a ternary function (arity == 3).

Amusingly, even functions return functions. We shall see what this means in a short while.

Currying, named after the famous Logician Haskell Curry, is one of the important mechanisms in the programming discipline known as functional programming (or FP). There's much theory surrounding the concepts behind it, however, in the most simplest term, it is safe to assume that "currying" a function is more or less like partially evaluating a function. Take a simple pseudo C++ function:

    plus(x, y) { return x + y; }

for example. Fully evaluating the function 'plus' above is done by supplying the arguments for x and y. For example:

    plus(3, 2)

will give us 5. On the other hand, partial evaluation can be thought of as calling the function without supplying all the arguments. Here's an imaginary (non-C++) example:

    plus(?, 6)

What does this mean and what is the function's result? First, the question mark proclaims that we don't have this argument yet, let this be supplied later. We have the second argument though, which is 6. Now, while the fully evaluated function plus(3, 2) results to the actual computed value 5, the partially evaluated function plus(?, 6) results to another (unnamed) function (A higher order function. In FP, the unnamed function is called a lambda function), this time, the lambda function expects one less argument:

    plus(3, 2) --> 5
    plus(?, 6) --> unnamed_f_x_plus_6(x)

now, we can use unnamed_f_x_plus_6, which is the result of the expression plus(?, 6) just like a function with one argument. Thus:

    plus(?, 6)(3) --> 9

This can be understood as:

    | plus(?, 6) | (3) |
    |_____f1_____|     |
    |_____f2___________|

The same can be done with operators. For instance, the above example is equivalent to:

        3 + 2 --> 5
        ? + 6 --> unnamed_f_x_plus_6(x)

Obviously, partially evaluating the plus function as we see above cannot be done directly in C++ where we are expected to supply all the arguments that a function expects. Simply, currying the function plus is not possible in straight C++. That's where the Phoenix framework comes in. The framework provides the facilities to do partial function evaluation.