2
$\begingroup$

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)

$\endgroup$
1
  • 1
    $\begingroup$ func[f_[x]] := (f[x])^2; g[y_] := Power[y, 2]; func[g[x]] $\endgroup$
    – cvgmt
    Commented Aug 8, 2020 at 3:13

2 Answers 2

2
$\begingroup$

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}  *)
$\endgroup$
1
$\begingroup$

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]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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