1
$\begingroup$

Let's say I have an expression that in held form contains a pointer to a function.

expr = Hold[2*{"FUNCTION1"} + 5];

{"FUNCTION1"} references a pure function or combination of other functions that are verbose and would be redundant to retype. For an example, let's say the function is:

func = #^2 &

In later calculations, I want to define a new function that uses expr with the referenced function substituted:

newfunc = ReleaseHold[expr /. {"FUNCTION1"} :> func]

5 + 2 (#1^2 &)

However, this is not what I'm after as trying to evaluate newfunc reveals:

newfunc[5]

(5 + 2 (#1^2 &))[5]

What I'm really after is

(5 + 2*#1^2) &[5]

55

So, is there a pattern format that can be used to correctly splice in the pure function. This needs to be general as expr won't always have the same form.

$\endgroup$
5
  • $\begingroup$ Related: (28064) $\endgroup$
    – Mr.Wizard
    Commented Dec 29, 2014 at 23:23
  • $\begingroup$ Thanks for the Accept. I am curious to know how (where) you are using this method. $\endgroup$
    – Mr.Wizard
    Commented Dec 31, 2014 at 1:42
  • $\begingroup$ @MrWizard I'd be glad to show you, but it'll require something more substantial than a comment box to explain. I still have your email if you're that interested. $\endgroup$
    – kale
    Commented Dec 31, 2014 at 2:11
  • $\begingroup$ Go ahead; thanks. $\endgroup$
    – Mr.Wizard
    Commented Dec 31, 2014 at 5:04
  • $\begingroup$ @Mr.Wizard Email sent. $\endgroup$
    – kale
    Commented Jan 5, 2015 at 16:55

2 Answers 2

2
$\begingroup$

I seem to recall a similar question but I cannot find it now. Anyway a key detail is that the body of the function presumably should not be evaluated, meaning e.g. func = Print[#^2] & should still work.

Here is one approach:

expr = Hold[2*{"FUNCTION1"} + 5];

func = Print[#^2] &;

newfunc = Function @@ expr /. {"FUNCTION1"} -> Hold @@ func // ReleaseHold
2 Print[#1^2] + 5 &
$\endgroup$
1
$\begingroup$

Maybe these other approaches will be useful for you pointer to function problem :

1.expr[x_] := 2*func[x] + 5

You can now for example always use expr but switch func to your needs. For example :

func = Sin ; expr[hello]
func = #^2 &; {expr[hello], expr[5]} 

return

5 + 2 Sin[hello]
{5 + 2 hello^2, 55}

But if you really need to create explicitly a new function, you can do :

func = #^3 &;
expr2[x_] = expr[x]

5 + 2 x^3

(*check*)
expr2[1]
(* 7 *)

or if you prefer the Function approach :

func = Tan;
expr3 = Function[x, Evaluate@expr@x]

Function[x, 5 + 2 Tan[x]]

(*check*)
expr3[2]
(*5 + 2 Tan[2]*)

2. fexpr[func_][x_] := 2*func[x] + 5

This approach is even more useful I guess.

Then for example :

fexpr[Sin][10]

5 + 2 Sin[10]

fexpr[#^2 &][5]

55

Plot[fexpr[#^2 &][x], {x, 0, 1}]

enter image description here

If you need to create new functions, then for example :

f1 = fexpr[Cos][#] &

fexpr[Cos][#1] &

f1[Pi/3]

6

In this previous case you see that f1 is defined as a function of fexpr. This way, you can track what was your input function. But maybe this is exactly what you don't want, then you can do instead :

f2 = Function[x, Evaluate@fexpr[Tan][x]]

Function[x, 5 + 2 Tan[x]]

Here f2 is not a function of fexpr anymore (no more traces how the function was created).

(*check*)
f2[10]
(*5 + 2 Tan[10]*)

I haven't check, but there is probably here a lot of other posts and answers for this kind of problems.

$\endgroup$
1
  • $\begingroup$ I don't know if this is applicable to the OP's "template" code but it is good information so +1. Releated: (7999) $\endgroup$
    – Mr.Wizard
    Commented Dec 31, 2014 at 1:44

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.