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/