4
$\begingroup$

I would like, as an example, to build a Times-like function. Take the following example

SetAttributes[f, OneIdentity];
f[] := 1;
f[a_] := a;
SetAttributes[f, Flat];
f[a_ + b_, c_] := f[a, c] + f[b, c];

This works perfectly. Notice that had I grouped the Attributes, an infinite recursion would have happened:

SetAttributes[f, {OneIdentity,Flat}];
f[] := 1;
f[a_] := a;
f[a_ + b_, c_] := f[a, c] + f[b, c];

The reason why it happens is explained in several posts (for instance here). However in Mathematica guide for Flat there is written:

The Flat attribute must be assigned before defining any values for a Flat function.

My (first) example does not respect this principle but works. I would like to know if there exist an "official" best practice to implement function with Flat attributes. It would be nice to see the implementation of Times, but of course it must be hard-coded.

$\endgroup$
2
$\begingroup$

Per the linked question, you could do:

SetAttributes[f, {Flat, OneIdentity}];
Verbatim[f][] := 1
Verbatim[f][a_] := a
f[a_ + b_, c_] := f[a, c] + f[b, c]

Then, there are no iteration/recursion errors:

f[]
f[a]
f[x, y]
f[x + y, z]

1

a

f[x, y]

f[x, z] + f[y, z]

| improve this answer | |
$\endgroup$

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