MathGroup Archive 1997

[Date Index] [Thread Index] [Author Index]

Search the Archive

Flat: Problems & Workarounds

  • To: mathgroup at
  • Subject: [mg8418] Flat: Problems & Workarounds
  • From: Johan Gunnarsson <johan at>
  • Date: Sat, 30 Aug 1997 00:42:25 -0400
  • Organization: Link√∂ping University, Sweden
  • Sender: owner-wri-mathgroup at

This is the result from my work trying to construct a associative
Assume I want a associative function h[] which treats numerical
specially. Starting from the template in Roman Maeders "Programming in
Mathematica", 3rd ed. I define h[] as

In[3]:= SetAttributes[h,{Flat,OneIdentity}]
h[x_,y_?NumericQ] := f[y,x]
h[x_?NumericQ,y_] := f[x,y]
h[x_] := x
h[] = 1

Now we try this out by

In[8]:= h[2,a,3]

Out[8]= f[3,f[2,a]]

which is what I want, but if none of the arguments are numeric we get

In[9]:= h[a,b]
$IterationLimit::"itlim": "Iteration limit of \!\(20\) exceeded."
Out[9]= Hold[h[a,b]]

This result is reasonable since none of the binary definitions match in
case and we therefore get an infinite loop from the rule h[x_]:=x
since the Flat attribute makes h[h[a,b]] equal to h[a,b]. To call this
a longstanding bug might be wrong, even though this is certainly a

Roman Maeder suggest to move the attribute definition after the rules.
way I understood this was the following

In[10]:= ClearAll[h]
h[x_,y_?NumericQ] := f[y,x]
h[x_?NumericQ,y_] := f[x,y]
h[x_] := x
h[] = 1

This gives the following results

In[16]:= h[2,a,3]

Out[16]= h[2,a,3]

Surprisingly enough it seems that by putting the SetAttributes at the
makes the attributes inactive. Is this the correct behavior?
The second test shows that the infinite loop is gone.

In[17]:= h[a,b]

Out[17]= h[a,b]


By searching for my workaround, I found the peculiar behavior
of Mathematica conditions which I use in the following

In[18]:= ClearAll[h]
h[x_,y_?NumericQ] := f[y,x]
h[x_?NumericQ,y_] := f[x,y]
h[x_] /; Head[Unevaluated[x]]=!=h := x
h[] /; True= 1

This gives the following results

In[24]:= h[2,a,3]

Out[24]= f[3,f[2,a]]

In[25]:= h[a,b]

Out[25]= h[a,b]

which is the behavior I want.
The defintion
  h[] /; True = 1
which seams to be nonsense, prevents the pattern matcher from the
infinite loop. Otherwise we would get the tests
    h[a,b], h[1,a,b], h[1,1,a,b], h[1,1,1,a,b] and so on since
h[] is interpreted as the neutral element.

Note that the condition must be placed outside the list of arguments.
The reason for this is exemplified by the following.

test[___] := False

In[36]:= SetAttributes[g,{Flat,OneIdentity}]
g[args__] /; test[args] := foo[args]

In[38]:= Trace[g[a,b,c],test[___]]

Out[38]= {{test[a,b,c]}}

In the case above the condition is outside the arguments
and the pattern matcher try once with all the arguments.
If we place the condition inside we get

In[39]:= ClearAll[g]
g[args__ /; test[args]] := foo[args]

In[42]:= Trace[g[a,b,c],test[___]]


which shows that all combinations of the arguments are tested. This is
only giving bad performance. It is also a completely different behavior
of the
pattern matcher.

Is this a feature or a bug?
Is it documented?
Is it possible to make a nice design of an associative function?


/Johan Gunnarsson
  Johan Gunnarsson
     |     Division of Automatic Control
    /|\    Dept. of EE, Linkoping University
    \|/    S-581 83 Linkoping, Sweden
    /|\    Tel:  +46 13 282913
   / | \   Fax:  +46 13 282622
 ()  |  () Email:  johan at

  • Prev by Date: Integrate[x^x,x]??
  • Next by Date: Re: Mma 2.2: Display and PostScript Question
  • Previous by thread: Integrate[x^x,x]??
  • Next by thread: Flat: Problems & Workarounds