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.


Subscript[g1, n_] := bad[n]
Subscript[g2, n_] := bad[n] 

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:


    {HoldPattern[Subscript[g1, n_]] :> bad[n], 
    HoldPattern[Subscript[g2, n_]] :> bad[n]}

Is this at all possible?

  • $\begingroup$ @kglr Actually the "inner" arguments aren't declared verbatim (see my motivation) $\endgroup$
    – Anti Earth
    Jul 3 '18 at 14:24
  • $\begingroup$ @kglr Pardon the over-simplicity in the original statement of my problem - please see 'my motivation' $\endgroup$
    – Anti Earth
    Jul 3 '18 at 14:35
  • $\begingroup$ 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 $\endgroup$
    – rhermans
    Jul 4 '18 at 8:18
  • $\begingroup$ 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 $\endgroup$
    – Anti Earth
    Jul 4 '18 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.

  • $\begingroup$ Works fantastic. I'll hopelessly wait a little longer for I accept this answer :) $\endgroup$
    – Anti Earth
    Jul 4 '18 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.