# Strange behaviour of SubValues of a definition in a context

First we define a context:

Begin["Ctx"];

ClearAll[f];
f[m_][n_] := n // (Range /* Append[m]);

End[];


We can check that

Ctxf[2][3] == {1, 2, 3, 2} (* True *)


as expected. Now we define another function:

ClearAll[g];
g[f_] := f // (Head /* SubValues);


When we try to call g on Ctxf we get the following error:

g[Ctxf[2]]


SubValues: Argument Head[Ctxf[2]] at position 1 is expected to be a symbol.

However, Head clearly returns a Symbol. Moreover, if I define a new function h as follows:

ClearAll[h]
h[f_] := f // (Head /* {SubValues} /* Through /* First);


I get exactly what I expect from g above:

h[Ctxf[2]]

(* {HoldPattern[Ctxf[Ctxm_][Ctxn_]] :> (Range /* Append[Ctxm])[Ctxn]} *)


What am I failing to understand about contexts? Why is g not behaving like h?

• SubValues is HoldAll, so Head is not being evaluated. You could try using something like g[f_]:=f//(Head/*Evaluate/*SubValues) Jan 15, 2021 at 22:17
• @CarlWoll If you post your comment as an answer, I will accept it, because it works. Thanks! Jan 15, 2021 at 22:20

SubValues is HoldAll, so Head is not being evaluated. You could try using something like:

g[f_] := f // (Head /* Evaluate /* SubValues)


or:

g[f_] := With[{h = Head[f]}, SubValues[h]]


Then:

g[Ctxf[2]]


{HoldPattern[Ctxf[m_][n_]] :> (Range /* Append[m])[n]}