# Elegant Replace Hold combination?

I would like to define an distributive function like this:

com[x__Plus, y_] := c @@@ Distribute[c[x, y]];


which is Ok. I know that it's possible to define it simply exploiting the fact that Plus is Flat, but consider what I wrote just as a toy model of a more refined example.

Here the point is that I cannot write

com[x__Plus, y_] :=  Distribute[com[x, y]];


since I would have an infinite recursion. But is there a way to obtain the result I got in the first example without using that trick, just with Hold and ReleaseHold commands?

With

com[x__Plus, y_] := Distribute[Inactive[com][x, y]] // Activate


you get, for example,

com[Plus[a, b], c]


com[a, c] + com[b, c]

• I noticed that another solution can be com[x__Plus, y_] := Distribute[HoldForm[com][x, y]] '. Do you have any suggestion when one has to choose between these two ways?
– MaPo
Commented Sep 20, 2016 at 9:32
• @MaPo When using com[x__Plus, y_] := Distribute[HoldForm[com][x, y]] the output is displayed as com[a, c] + com[b, c], but its FullForm is Plus[HoldForm[com][a,c],HoldForm[com][b,c]]. One can get rid of these HoldForms (assuming that's wanted) using ReleaseHold. I think you should add the HoldForm version as a self-answer. Commented Sep 20, 2016 at 9:56
• @MaPo What's the difference between Inactive and HoldForm?. For your case I don't see a practical difference between them. Commented Sep 20, 2016 at 9:58
com[x__Plus, y_] := Block[{com}, Distribute[com[x, y]]]


This Blocks the evaluation of com until after Distribute has done its work by momentarily treating com as a variable local to the Block scoping construct and hence momentarily losing all of its definitions and Attributes.

I think you can just use Unevaluated here:

com[x__Plus, y_] := Distribute[Unevaluated @ com[x, y]]


Examples:

com[a+b, c]
com[a+b, c+d+e, f]


com[a, c] + com[b, c]

com[a, c, f] + com[a, d, f] + com[a, e, f] + com[b, c, f] + com[b, d, f] + com[b, e, f]

... just with Hold and ReleaseHold commands

ClearAll[com]
com[x__Plus, y_] := ReleaseHold @ Distribute[Hold[com][x, y]]

com[a + b, c]


com[a, c] + com[b, c]

com[a + b + c, d + e, f]
`

com[a, d, f] + com[a, e, f] + com[b, d, f] + com[b, e, f] + com[c, d, f] + com[c, e, f]