I want to have a function (called otimes
) with the following two properties:
- it has the attribute
OneIdentity
andFlat
- if evaluated with a single argument it returns that argument
The built-in function Times
has these properties; e.g., evaluating Times[a]
yields a
.
I am struggling with implementing my own function having the same behavior. What I tried is the obvious implementation
SetAttributes[otimes,{OneIdentity,Flat}]
otimes[a_]:=a
However this does not work and leads to an infinite recursion when I evaluate otimes[a,b]. I do not know how to implement the desired behavior consistently. Maybe somebody can help?
Answer
I see now. The problem arises with Flat
then. Just set the attributes after setting the definitions. Or at least the Flat
attribute
ClearAll[otimes];
SetAttributes[otimes, OneIdentity]
otimes[a_] := a
SetAttributes[otimes, Flat]
Check out this answer for more details on why this works.
Basically, MMA remembers if the symbol was Flat
or not at the time each DownValue
is defined. The infinite recursion is more related to this:
SetAttributes[f, Flat];
Replace[Hold@f[2], Hold@f[i_] :> Hold[i]]
So, when you did otimes[2]
and it checked the otimes[a_]:=a
downvalue, it matched a
with otimes[2]
, so you got your infinite recursion
Comments
Post a Comment