# How to give a property to a list of functions?

For example, I have defined a bunch of binary functions Sum1, Sum2, Prod1, Prod2, ... I want to make these functions associative, that is, the expression Sum1[a,b,c] will be evaluated as Sum1[Sum1[a,b],c]. I use the method here to achieve it:

Sum1[a_,b_,c__]:=Sum1[Sum1[a,b],c]

Now I want to do this to all of these binary functions without repeating it line by line (because there are too many of them). Is there a way to do it? I tried to do the following

Do[f[a_,b_,c__]:=f[f[a,b],c],{f,{Sum1,Sum2,Prod1,Prod2}}]

But after this, when I evaluate Sum1[a,b,c], it will return f[f[a,b],c]! In other words, the f after the := is not substituted by the instances from the list {Sum1,Sum2,Prod1,Prod2}.

• Do[With[{f=f}, f[a_,b_,c__]:=f[f[a,b],c]],{f,{Sum1,Sum2,Prod1,Prod2}}]
– I.M.
Jun 16 at 4:25
• @I.M. That works, but generally I think that if you feel like you need to use With[{f = f}, ...] you really should be using a Function and some mapping construct instead. Jun 16 at 8:53

Try this:

install[f_Symbol]:=(f[a_,b_,c__]:=f[f[a,b],c];);
Scan[install,{Sum1,Sum2,Prod1,Prod2}];


You may also want to have a look at Flat and OneIdentity, see here, but using them can be tricky.

• I have looked at Flat, but I am always confused about one thing - If f is flat, all it does is that f[f[a,b],c] will be converted to f[a,b,c]; I guess it is intended to be used for pattern matching and working with associative products of formal variables. However, if f is a concrete function (rather than a formal associative product), then Flat doesn't instruct f[a,b,c] to be evaluated as f[f[a,b],c]. Jun 16 at 13:34
• What precisely do you mean by a concrete function? For instance SetAttributes[f,{Flat,OneIdentity}]; f[a_,b_]:=a+b; f[3,4,5] does give 12. Jun 16 at 13:47
• Oh I see, the issue seems deeper - This example above is fine, but mine is not, probably due to the fact that it is an operator on pure functions. Let's say the objects are infinite sequences a[n] (implemented as a pure function a) and we want to define the termwise sum f[a,b]:=a[#1]+b[#1]&; SetAttributes[f,{Flat,OneIdentity}]. Then f[a,b][3]' gives a[3]+b[3] but f[a,b,c][3] just gives f[a,b,c][3] instead of the intended a[3]+b[3]+c[3]. Jun 16 at 14:06
• So f[a_,b_]:=(a[#]+b[#]&); SetAttributes[f,{Flat,OneIdentity}]; f[a,b,c][3] gives a[3]+b[3]+c[3]. You may have missed some underscores in the definition of f? Jun 16 at 14:16
• After some retest, I find that the real problem seems to be that I need to set attributes before defining the function. The parenthesis doesn't matter. I need to run f[a_,b_]:=(a[#]+b[#]&); SetAttributes[f,{Flat,OneIdentity}] twice before it to work. Alternatively, if I do SetAttributes[f,{Flat,OneIdentity}]; f[a_,b_]:=(a[#]+b[#]&)`, then once is enough. Jun 16 at 14:49