8
$\begingroup$

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?

$\endgroup$

4 Answers 4

6
$\begingroup$

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]

$\endgroup$
3
  • $\begingroup$ 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? $\endgroup$
    – MaPo
    Commented Sep 20, 2016 at 9:32
  • $\begingroup$ @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. $\endgroup$
    – Karsten7
    Commented Sep 20, 2016 at 9:56
  • $\begingroup$ @MaPo What's the difference between Inactive and HoldForm?. For your case I don't see a practical difference between them. $\endgroup$
    – Karsten7
    Commented Sep 20, 2016 at 9:58
6
$\begingroup$
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.

$\endgroup$
3
$\begingroup$

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]

$\endgroup$
3
$\begingroup$

... 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]

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.