# Defining a function of a function with arbitrary variable name

Is there a way to pass a function into a function you write such that the function can be of an arbitrary variable?

What I want to do is something like...

func[f_[x]] := (f[x])^2
g[y_] := y^2
func[g[y]]

Out[]= y^4


So far I know how to square an expression, but not a function unless it explicitly uses the same var x in both func and g.

(Also as a side note, why does...

func[f_[x]] := (f[x])^2
g[y_] := Sin[y]
func[g[x]]


work, but not for non-trig functions like Exp?

Might be because of other things in my notebook, hopefully not)

• func[f_[x]] := (f[x])^2; g[y_] := Power[y, 2]; func[g[x]] Commented Aug 8, 2020 at 3:13

First, the problem is that g[x] evaluates before func is evaluated. Thus the function g disappears, and the definition of func does not apply, unless by accident, the value of g[x] has the form f[x]. To prevent this, evaluation of the argument of func must be held.

ClearAll[func];
SetAttributes[func, HoldAll];
func[f_[x_]] := (f[x])^2;

g[y_] := Power[y, 2];
func[g[x]]

(*  x^4  *)


Trace shows what happens when the argument is not held. The first thing is that g[x] is evaluated. When g[x] yield x^2, it has the internal form Power[x, 2], which has two arguments; however the pattern for func[f_[x_]] is only for when it has one argument. In the second case, Sin[x] has the form f[x], which matches the definition of func.

g[y_] := y^2;
func[g[x]] // Trace

(*  {{g[x], Power[x, 2]}, func[Power[x, 2]]}  *)

g[y_] := Sin[y];
func[g[x]] // Trace

(*  {{g[x], Sin[x]}, func[Sin[x]], Sin[x]^2}  *)


A replacement rule of this form seems to work. I hope it helps.

func[arg_] := arg /. f_[x___] :> (f[x])^2
g[y_] := y^2
func[g[y]]