# changing number of arguments to a function in secondary evaluation

So I have a function that produces answers involving uninstantiated(?) function names, e.g.

 Out[1]= f[a,b,c,d].


I then want to evalute this leftover result by, say, replacing this f[a,b,c,d] with a defined function g[a,b,c,d,e].

I think something maybe to do with slots, but my poor attempts have still failed, eg.

 Out[1] /. f[##] &@g[##,e]

Out[1] /. f[___] -> g

Out[1] /. f[#1, #2, #3, #4] -> g[#1, #2, #3, #4, e]

• You're mixing the concepts of pure functions (# and &) with replacement (/., ->, :>). Use slots with the first one, use patterns (Pattern in the documentation, x_ or x__ for example in usage) with the second. E.g. f[a, b, c, d] /. f[x__] :> g[x, e]. Commented Aug 10, 2019 at 18:02
• Aargh. This comment is an answer! I'll accept it if you want
– nate
Commented Aug 10, 2019 at 18:06

From my own comment:

You're mixing the concepts of pure functions (# and &) with replacement (/., ->, :>). Use slots with the first one, use patterns (Pattern in the documentation, x_ or x__ for example in usage) with the second.

For this problem:

f[a, b, c, d] /. f[x__] :> g[x, e]


g[a, b, c, d, e]

Note the use of __, which is two underscores: This is a pattern which grabs 1 or more elements (see also ___ which grabs 0 or more elements), and inserts them as a Sequence when used in replacement. Thus, it doesn't get inserted as a List.

If you wanted to do this with pure functions, it becomes a bit more complicated:

g[Sequence @@ #, e] &[f[a, b, c, d]]


g[a, b, c, d, e]

But note that this isn't dependent on its argument being in the form of f[...], it will replace any functional head. To avoid that requires conditionals of some variety, e.g:

If[Head[#] === f, g[Sequence @@ #, e], Undefined] &[f[a, b, c, d]]


You can also use Apply:

g[##, e] & @@ f[a, b, c, d]


g[a, b, c, d, e]

or ReplaceAll with replacement rule f -> (g[##, e] &):

f[a, b, c, d] /.  f -> (g[##, e] &)


g[a, b, c, d, e]

There is yet another solution, using Flatten with Head f, namely

Flatten[g[f[a, b, c, d], e], 1, f]


g[a, b, c, d, e]

This assumes that g is not defined for two arguments, otherwise it will evaluate before Flatten has a chance so flatten the f. If that's not the case one can use Inactive on g, act with Flatten and then Activate again.

Activate[Flatten[Inactive[g][f[a, b, c, d], e], 1, f]]

• you can also use FlattenAt: FlattenAt[g[f[a, b, c, d], e], 1] (+1)
– kglr
Commented Aug 11, 2019 at 16:05