MathGroup Archive 2003

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

Search the Archive

Re: Re: New version, new bugs

  • To: mathgroup at smc.vnet.net
  • Subject: [mg42869] Re: [mg42817] Re: New version, new bugs
  • From: Andrzej Kozlowski <andrzej at platon.c.u-tokyo.ac.jp>
  • Date: Thu, 31 Jul 2003 01:47:55 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

On Wednesday, July 30, 2003, at 10:07 AM, Maxim wrote:

> I think it should be mentioned that there are some things that probably
> aren't errors but still can be considered as major drawbacks. Consider 
> four
> nearly identical expressions:
>
> In[1]:=
> f[a] + f[b] + 1 /. HoldPattern[Plus][f[_] ..] /; True :> 0
> f[a] + f[b] + 1 /. HoldPattern[Plus[f[_] ..]] /; True :> 0
> f[a] + f[b] + 1 /. HoldPattern[Plus][f[_] ..] :> 0 /; True
> f[a] + f[b] + 1 /. HoldPattern[Plus[f[_] ..]] :> 0 /; True
>
> Exactly one of them evaluates to 1. This is something from Who Wants 
> to Be a
> Millionaire, not a programming language.
>
>


Pattern matching is of course a very delicate technique, its not at all 
surprising that "very similar" patterns match different expressions. 
(Actually the patterns are no longer so similar if you look at their 
full form).
The cases involving HoldPattern[Plus] are obviously nonsense and the 
fact that they do not work is quite consistent with the description of 
HoldPattern in the Mathematica book. The only thing about this supposed 
problem that deserves any comment is the observation that:

> f[a] + f[b] + 1 /. HoldPattern[Plus[f[_] ..]] /; True :> 0

does not work and

> f[a] + f[b] + 1 /. HoldPattern[Plus[f[_] ..]] :> 0 /; True

  does.

This is indeed rather subtle. To see what happens more clearly, let us 
consider a head h instead of Plus:

In[1]:=
h[1, f[b], f[c]] /. HoldPattern[h[f[_]..]] /; True :> 0

Out[1]=
h[1, f[b], f[c]]


In[2]:=
h[1, f[b], f[c]] /. HoldPattern[h[f[_]..]] :> 0 /; True

Out[2]=
h[1, f[b], f[c]]

We see no difference. Now give h the attribute Flat:

SetAttributes[h, {Flat}]

In[4]:=
h[1, f[b], f[c]] /. HoldPattern[h[f[_]..]] /; True :> 0

Out[4]=
h[1, f[b], f[c]]


In[5]:=
h[1, f[b], f[c]] /. HoldPattern[h[f[_]..]] :> 0 /; True

Out[5]=
h[1,0]

You get the difference you observed with Plus.
As you can see clearly, in order for the match to take place the Flat 
property of h needs to be used. This is done in the second case with 
h[1, f[b], f[c]] being first replaced by h[h[1], h[f[b], f[c]]] and not 
done in the first case. The reasons are basically to do with the order 
of pattern matching and evaluation (and are closely related to the so 
called Trott-Strzebonski method of partial evaluation of expressions). 
However, this matter, which has been discussed on this list before, is 
not important here. The important thing here is that the mechanism 
responsible for this behaviour is both subtle and powerful, although 
admittedly not very transparent. It may sometimes be confusing but it 
also underlies lots of very convenient patterns matching constructions 
many of us use all the time. If you know of a way to achieve all of 
that in a simple and transparent way I am sure Wolfram Research would 
be interested. But unlike some of your earlier criticism I can see 
nothing constructive not in any way valuable in this one. The same, I 
am afraid, applies to the rest of your posting.

Andrzej Kozlowski
Yokohama, Japan
http://www.mimuw.edu.pl/~akoz/
http://platon.c.u-tokyo.ac.jp/andrzej/


  • Prev by Date: RE: How to multiply two matrix simply?
  • Next by Date: Re: Series
  • Previous by thread: Re: New version, new bugs
  • Next by thread: Re: New version, new bugs