4

I'm having trouble with a function which is supposed to work on another function. Simplified version:

one[x_] := 1 (* the argument *)
problem[f_] := Integrate[f[t], {t, 0, #}] & (* the function doing the work *)

Simple enough, right? But when I pass

problem[one] // InputForm (* to paste into se *)

I get

Integrate[one[t], {t, 0, #1}] &

and even

FullSimplify[problem[one]] // InputForm

just gives

Integrate[one[t], {t, 0, #1}] &

But I know that the function is there, since if I evaluate

problem[one][17]

it (properly) gives

17

How do I get Mathematica to substitute the function's definition for its name so it can simplify the result (in this case, evaluate the integral)?

(System details: 64-bit Mathematica 10.0.2.0, Windows 7 Pro SP1, i7-4770.)

Charles
  • 1,359
  • 8
  • 13
  • So what you've defined with problem is what's called an anonymous or inline function. It's a function waiting to take arguments which will replace the #. That's why you don't get a result until you feed it the upper bound of your integral (17 in your example). Until then, it's just a function waiting for an argument to evaluate. What is it that you expect problem[one] to look like instead? – IPoiler Jul 30 '15 at 13:50
  • Try Evaluate @@ problem[one] – Dr. belisarius Jul 30 '15 at 13:54
  • Proposed duplicate: (41950). Also related: (30205) – Mr.Wizard Jul 31 '15 at 05:03

1 Answers1

8

The problem is that the function name f is substituted into Function (&) which is HoldAll. This means f[t] will not be evaluated until the Function is evaluated, such as in the OP's example problem[one][17].

So the trick is to evaluate the integrand before inserting it into the Function. Here is one way.

one[x_] := 1 (*the argument*)
problem[f_] := With[{integrand = f[\[FormalT]]},
  Integrate[integrand, {\[FormalT], 0, #}] & 
  ]

problem[one]
(*  Integrate[1, {\[FormalT], 0, #1}] &  *)

Mathematica graphics

As @Guess who it is pointed out, the use of \[FormalT] or Esc$tEsc is safer way to define problem. If ones uses a simple t instead and t already has a value, say t = 2, then the evaluation of f[t] will substitute the value of t, and we would get f[2] for the integrand instead of a function of t. Since formal symbols cannot be assigned a value, this problem cannot occur with \[FormalT].

However, if for some reason the definition of f contained \[FormalT], say as a parameter, then we run into trouble. So maybe a better way is to use Module to localize t. This should offer even more protect at the expense of having a slightly unreadable module variable:

problem[f_] := Module[{t},
  With[{integrand = f[t]}, Integrate[integrand, {t, 0, #}] &]
  ]

problem[one]
(*  Integrate[1, {t$64741, 0, #1}] &  *)

Within one's own project, one should be able to pick a formal symbol that is never used as a parameter. So practically the first answer above should suffice.

Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • 2
    Additional note: for full safety, one should consider using a formal symbol for the dummy variable. – J. M.'s missing motivation Jul 30 '15 at 14:06
  • @Guesswhoitis.: Can you explain how to do this? I recognized the (potential) problem of clashing variables but don't know how to handle this in Mathematica. (I can handle it in other languages, but my Math'ca isn't so good yet.) – Charles Jul 30 '15 at 14:54
  • 1
    @Charles, the idea is to use the formal symbols, \[FormalA] to \[FormalZ] (there are also upper-case versions, if needed) if you want to ensure that any dummy variable, as with sums and integrals, does not have a prior value that may have been set many cells ago. (They don't format nicely here on SE, but you should be able to see what they actually look like on the front end.) The keyboard shortcut for entering them in is Esc+$+(letter here)+Esc. – J. M.'s missing motivation Jul 30 '15 at 15:05
  • @Charles I changed my answer to fit the comment. – Michael E2 Jul 30 '15 at 15:11
  • I noted a proposed duplicate in the comments above. I also note that this answer is more thorough than those. Would you review the case and give your recommendation? – Mr.Wizard Jul 31 '15 at 05:04
  • @Mr.Wizard The principle issues are the same. The danger of unwanted evaluation is clearer in this question than in the proposed duplicate. That seems main distinction. I could vote for the duplicate and we could let the community decide whether it's distinctive enough to keep open. Or did you have something else in mind? – Michael E2 Jul 31 '15 at 10:37
  • I am not sure how to handle this so I asked. At the very least they need to be linked, and now they are. I could merge but that will cost you an Accept and require extensive rewriting; not ideal. I always hesitate to close an older question in favor of a newer one but that too is an option. Maybe I should leave well enough alone. – Mr.Wizard Jul 31 '15 at 23:10