Defining the behavior of a certain function composition

I defined a function on objects of different types, u[x_] and v[y_], as

u[x_] := x^2
v[y_] := y^3
f[u[x_]] := x + 1
f[v[y_]] := y/2


When I input f[u[2]], I expect to get 5 as output. But I what I get is f[4] instead. Could someone tell me where it had gone wrong?

• u[2] becomes 2^2 = 4 immediately, before f has a chance to see the structure. And f has no rules for input that don't have head u. Look up HoldFirst – Marius Ladegård Meyer May 29 '17 at 19:23

You can get the behavior you want giving f the attribute HoldFirst, which prevents the premature evaluation of u[x] and v[x].

Remove[f, u, v]
u[x_] := x^2
v[x_] := x^3
SetAttributes[f, HoldFirst]
f[u[x_]] = 1 + u[x];
f[v[x_]] = v[x]/2;


then

{f[42], f[u[2]], f[v[3]]}


gives

{f[42], 5, 27/2}

the behavior you expected.

If you want to do function composition, I think that's not the idea way to do it. If you intent to use f[u[x]], that's another story.

In:

Clear["Global"]
u[x_] := x^2
v[y_] := y^3
f[x_] := x + 1

f@u[2]

h = f@*u;
h[2]
`

Out:

5

5