Re: Flat: Problems & Workarounds Sweden.

*To*: mathgroup at smc.vnet.net*Subject*: [mg8493] Re: Flat: Problems & Workarounds Sweden.*From*: Robert Villegas <villegas>*Date*: Tue, 2 Sep 1997 16:15:37 -0400*Organization*: Wolfram Research*Sender*: owner-wri-mathgroup at wolfram.com

An additional note regarding the associative function that recognizes NumericQ arguments in certain positions: > This is the result from my work trying to construct a associative function. > Assume I want a associative function h[] which treats numerical arguments > 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 The problem was underspecified in that you didn't say exactly how you wanted nested h expressions treated. Here's an example using the code I supplied: In[51]:= h[h[a, 2], h[a, 3]] Out[51]= h[f[2, a], f[3, a]] It's possible that you expect In[51] to return the same result as the following, which has h pre-flattened out: In[52]:= h[a, 2, a, 3] Out[52]= f[3, h[a, 2, a]] In[51] did what it was supposed to: h isn't HoldAll, so it lets its arguments fully evaluate first. Thus, h[a, 2] ==> f[2, a] and h[a, 3] ==> f[3, a]. So the question is, which do you want to occur first: argument evaluation or argument flattening? The original code I gave you did the default: evaluation. If you want flattening to occur first, here is the same code with a couple additions -- HoldAll and an extra rule -- with the net effect that h forces its arguments to sit still only long enough to be flattened, then lets them go. ClearAll[h]; Attributes[h] = HoldAll; $hEvaluate = True; h[elems___] /; MemberQ[Unevaluated[{elems}], _h] := Flatten[Unevaluated @ h[elems], Infinity, h]; h[elems___] := Block[{$hEvaluate = False}, h @@ {elems} ] /; $hEvaluate; h[elems__, n_?NumberQ] := f[n, h[elems]]; h[n_?NumberQ, elems__] := f[n, h[elems]]; h[singleton_] := singleton; h[] = 1; It still works for the test examples, and pre-flattens nested h: In[47]:= {h[], h[1], h[a], h[1, a], h[a, 1], h[a, b], h[2, a, 3], h[2, 3, a], h[a, 2, 3]} Out[47]= {1, 1, a, f[1, a], f[1, a], h[a, b], f[3, f[2, a]], f[2, f[3, a]], f[3, f[2, a]]} In[48]:= h[h[a, 2], h[a, 3]] Out[48]= f[3, h[a, 2, a]] Robby Villegas