Take the 2-minute tour ×

Suppose we're given the expression f*g+h, where f,g,h are all pure functions. How can we evaluate this expression on some x? If there were only one operation, say f+g, we could simply use Through[(f+g)[x]], but Through only deals with one operation, as far as I can see. How is this done?

share|improve this question
To clarify, you are asking for through to apply the pure functions at the most nested level to x? Your example is Plus[Times[f,g],h], so the functions you want applied to x are Level[f*g + h, {-1}]? –  VF1 Jul 4 '13 at 6:44
Apply[(f[##] g[##] + h[##]) &, {arguments}], crude version of what Mr. Wizard have showed. –  Kuba Jul 4 '13 at 6:57
Ah, yes, that is what I want @VF1 –  Nilay Kumar Jul 4 '13 at 7:03

3 Answers 3

up vote 9 down vote accepted


Mr.Wizard helped to refine my old function to:

SetAttributes[Through2, HoldFirst]
Through2[head_[args___]] := Replace[head, s : _Function | _Symbol :> s[args], -1]

This locates the most nested functions and symbols and evaluates their value for the parameter arguments.

Below is my older, less robust function:

SetAttributes[Through2, HoldFirst]
Through2[expr_] := 
 With[{head = Head@expr, arg = First@expr}, 
  With[{funcs = Cases[head, _Function | _Symbol, -1]}, 
   head /. Thread[funcs -> Through[funcs[arg]]]]]
Through2[(f*g + h)[x]]
(* f[x] g[x] + h[x] *)
Through2[(f*g + (h*Minus)^2)[x]]
(* f[x] g[x] + x^2 h[x]^2 *)
Through2[{Re, Im + Re}[x]]
(* {Re[x], Im[x] + Re[x]} *)
share|improve this answer
Interesting interpretation. +1 I still wonder what the OP actually wants however. –  Mr.Wizard Jul 4 '13 at 7:00
This works great, thanks! –  Nilay Kumar Jul 4 '13 at 8:07

Perhaps you want something like this?

apply = (# /. s_Symbol /; Context[s] =!= "System`" :> s[##2]) &;

apply[f*g + h, x]

This is a limited implementation but it can be extended if this is in fact the kind of operation you desire. The idea is to recognize any Symbol not belonging to the System` context as a function to apply to x. Alternatively one could apply only symbols in the Global` context using Context[s] === "Global`".

share|improve this answer
Yes, I'd say that our functions do the same thing (with yours being more elegant and direct). In hindsight, Cases and then ReplaceAll does seem a bit redundant - and dangerous, too, if one of the pure functions is used on a higher level in the expression. Your solution will be more robust. –  VF1 Jul 4 '13 at 7:13
@VF1 Thanks for the check. If you'd like to put this in your answer instead that's fine with me; it was your idea to look at the levelspec. –  Mr.Wizard Jul 4 '13 at 7:22
Will do. Thanks. –  VF1 Jul 4 '13 at 7:24
@VF1 It just occurred to me that my {-1} code is broken for Function as that will not be found at level {-1}; Please use the Heads -> False code, assuming that isn't broken. –  Mr.Wizard Jul 4 '13 at 7:26
Is there a difference between Yours apply and @VF1 's Through2 exept that the latter works for 1 argument only (after edit it works for many) and Yours can not handle Minus and other System context functions? –  Kuba Jul 4 '13 at 7:29

For example...


Using substitution rule...

f*g+h /. z:(f|g|h)->z[3]


share|improve this answer

Your Answer


