# Evaluate arguments in a curried function left to right

I have an inner pattern

f[g, n_] := inner

and I want to define an outer curried pattern

f[h, m_][f[g, n_]] := ...

which has unrelated behaviour to f[g,n] and so should receive expression f[g,n] rather than inner. Alas, f[h,m][f[g,n]] is undesiredly first evaluated as f[h,m][inner]. How can I prevent Mathematica from evaluating the inner f[g,n] whilst still recognising a pattern for f[h,m_][..] without having to explicitly insert Hold into the outermost expression?

Of course SetAttribute[f, HoldAll] doesn't work, and I can't exactly set an attribute for the experssion f[h].

My motivation: I'm creating inner "functions" with subscript "arguments", and I want to define an outer "functional" which also has subscript "arguments" which should start evaluating before the passed inner functions are evaluated.

E.g.

...

Subscript[h, m_][ Subscript[g_,n_] ] := good[g,m,n]

I want the behaviourwhere $g1_n$ gives bad[n], but $h_m[g1_n]$ gives good[g1,m,n]. The above code instead gives $h_m[bad[n]]$.

I notice that the last line of the above code doesn't affect the DownValues of Subscript:

DownValues[Subscript]

Is this at all possible?

• @kglr Actually the "inner" arguments aren't declared verbatim (see my motivation) Jul 3, 2018 at 14:24
• @kglr Pardon the over-simplicity in the original statement of my problem - please see 'my motivation' Jul 3, 2018 at 14:35
• Some of us here think that using Subscript while defining symbols (variables) should be avoided. Subscript[x, 1] is not a symbol, but a composite expression where Subscript is an operator without built-in meaning. You expect to do $x_1=2$ but you are actually doing Set[Subscript[x, 1], 2] which is to assign a DownValues to the operator Subscript and not an OwnValues to an indexed x as you may intend. Read how to properly define indexed variables here Jul 4, 2018 at 8:18
• I agree, but I'm still looking to do it :) I can use /: to attach an OwnValues to x if that was really a problem Jul 4, 2018 at 13:19

When I run into problems like this, I workaround it by using ReplaceAll like so:

rules = {
f[g, n_] :> inner,
f[h, m_][f[g, n_]] :> outer
};

f[h, m][f[g, n]] //. rules

(* outer *)

That's because while the standard evaluation procedure looks at elements before moving up, ReplaceAll works by first trying to match the whole expression before going deeper.

• Works fantastic. I'll hopelessly wait a little longer for I accept this answer :) Jul 4, 2018 at 16:30