# Using With[] vs. Using a Pure Function for Constants

There are many cases where I am conflicted over using With[] versus using pure functions when dealing with constants, knowing the output is the same either way. For example, consider

f1[input_] := With[{const = g[input]},h[const]]

f2[input_] := h[#] &@g[input]


where g and h are complicated functions defined inline – not defined elsewhere using set delayed.

Of course, the output is the same...

f1[3]
(*h[g[3]]*)

f2[3]
(*h[g[3]]*)

1. Is there a general rule about which paradigm is faster or uses less memory?

2. Are there any general major considerations I should be making in determining when to use one over the other?

• Why not simply writing: f[g[input]] ? Or the same more cryptical: (f@*g)[x] Commented Mar 30, 2021 at 18:44
• @DanielHuber I am trying to be as pure as possible, so I mean to have g and h be inline. This usually makes for better performance. Also, doing as you suggest is messy when h refers to its input many times. (I am a bit confused though. It seems you are using f the way I am using h.) Commented Mar 30, 2021 at 18:57
• MMA evaluates function arguments before a function sees it. So, even if h refers to its input many times, this input is only evaluated once. Sorry, no need for confusion, I simply picked some characters, use h instead of f. Commented Mar 30, 2021 at 19:08
• @DanielHuber But h is inline. So what I mean is that h[g[input]] is literally, something like g[input]^g[input]+Range[1,g[input], not defined elsewhere with set delayed. In this example, g[input] is evaluated 3 times. Commented Mar 30, 2021 at 19:45
• I've never noticed a difference in speed (which I've tested) or memory (which I haven't). The main differences are that the functional way is usually shorter, but with With I can use a variable name to help me remember what it stands for as well as break up a really long composition of operations into pieces. Generally speaking, readibility is worth valuing over insignificant speed advantages. Commented Mar 30, 2021 at 20:18

You have several choices with variations:

With[{a = (g1[i]; g2[i])}, h1[a]; h2[a]]
(g1[i]; g2[i]) // Function[i, h1[i]; h2[i]]
Function[i, h1[i]; h2[i]][g1[i]; g2[i]]
(h1[#]; h2[#]) & [g1[i]; g2[i]]
(g1[i]; g2[i]) // (h1[#]; h2[#]) &