# What are Flat Attribute best practices? [duplicate]

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.

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]