MathGroup Archive 1997

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

Search the Archive

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


  • Prev by Date: Re: Partition List
  • Next by Date: Loading Standard Packages
  • Previous by thread: RE: Flat: Problems & Workarounds Sweden.
  • Next by thread: Re: Flat: Problems & Workarounds Sweden.