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/