Executing multiple steps to handle a purchase using currying Is doing something like this utilizing currying in a practical sense?

function processOneClickPurchase(item) {
    let context = { step: 0 }

    let addItemToCart = item =&gt; {
        let cart = getSession().cart
        cart.items.push(item)
        log('Cart items', cart.items)
        return cart
    }

    ...

    let purchase = generate([
        addItemToCart,
        makePurchase,
        processBilling,
        setupShipping,
        sendPurchaseAndShippingNotification,
    ], null, cleanup)

    return purchase(item)

    function generate(steps, before, after) {
        const takeStep = (incoming, outgoing) =&gt; {
            let message = {
                step: ++context.step,
                incoming: incoming,
                outgoing: outgoing
            };

            log('step #'+(context.step), message)

            return outgoing
        }
        const walk = value =&gt; {
            return steps.reduce((from, to) =&gt; {
                return takeStep(from, to(from))
            }, value)
        }

        (before &amp;&amp; steps.push(before)) + (after &amp;&amp; steps.push(after))

        return function invoke(state) {
            const hasItems = Array.isArray(state) || !(state = [state])
            const processed = state.map(walk)
            return hasItems ? processed : processed[0]
        }
    }
}


https://jsfiddle.net/f7mdak6z/25/

I realize there's algebra going on with currying and maybe this is nonsensical, so we're not talking rigid math concepts. However, it seems to me this pattern is rudimentary and it feels like an application of currying over an input to achieve an output. takeStep() almost seems like a monad, etc.

I think it would definitely start to sound like a fit if the methods passed to generate() simply modified the stream, and perhaps the takeStep() function handled side-effects.
I take it here that you mean “algebra” to mean lambda calculus and by extension, combinatory logic.

The takeStep function is essentially (disregarding side-effects): $$
\lambda ab.b
$$ in lambda calculus, or in JS in terms of identity (using Haskell Curry’s combinator naming):

I = a =&gt; a
K = a =&gt; b =&gt; a
KI = K(I)


So as the takeStep function is simply disregarding the first argument, and the walk function calling the second argument with the previous (/initial) value there and then, I’m wondering if you would really be after the B-combinator $$
   \lambda fga.f(ga)
$$ (or, as JS: B = f =&gt; g =&gt; a =&gt; f(g(a)), often named compose) with possibly the C-combinator $$
   \lambda fab.fba
$$ (C = f =&gt; a =&gt; b =&gt; f(b)(a)) for reversing the arguments (often named pipe or sequence for f =&gt; g =&gt; a =&gt; g(f(a))).

(I’m not sure if the commutativity of the functions or JS evaluation strategy plays a role here.)

Regarding currying, I wonder if you were thinking of partial application instead.