Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

RepeatedNull appears to be buggy (versions 8.0, and 9.0).

Define f as follows:

In[1]:= f@s:{h_@___...} := List @@@ s

f is intended to accept (possibly empty) List of non-atomic (possibly empty) expressions with the same head and change that head to List. It seems to work properly at first:

In[2]:= f@{g[x], g[y]}
Out[2]= {{x}, {y}}

(Calculates as intended.)

In[3]:= f@{g[x], h[y]}
Out[3]= f[{g[x], h[y]}]

(Pattern does not match.)

However, f behaves unexpectedly on an empty List:

In[4]:= f@{}
Out[4]= {1}

The pattern does match, as it should, but the appearance of 1 is a complete mystery. I expected f@{} to be List @@@ {}, which is {}. Tracing didn't tell me anything:

In[5]:= Trace[f@{}, TraceInternal -> True]
Out[5]= {f[{}], List@@{1}, {1}}

It's probably a bug. Defining f@{} as a special case seems to fix the problem. However, 1) it's not actually a special case, and 2) I'm not sure in the correctness of the definition since there may be something wrong with the pattern I picked.

  1. Was {h_@___...} the right choice of pattern for “(possibly empty) List of non-atomic (possibly empty) expressions with the same head”?

  2. Is there a plausible explanation where does 1 come from?

UPD:

To clear things up I'll elaborate on a test example by @m_goldberg (from the answer) and a note by @sebhofer (from a comment):

In[6]:= ReleaseHold[ClearAll /@ Hold[test1, test2]];
In[7]:= test1[patt1: {h_@___ ...}] := Row@{"With named head: ", patt1}
        test2[patt2: {_@___ ...}] := Row@{"Without named head: ", patt2}

Results vary with use of named vs unnamed pattern. That's one aspect convincing me to calssify the issue as bug:

In[9]:= {test1@{}, test2@{}} // Column
Out[9]= "With named head:" 
        "Without named head:" {}

(Here and after, output formatting is adjusted manually.)

What also concerns me is that existing definitions don't get overwritten:

In[10]:= ClearAll@test
In[11]:= test[patt1 : {h_@___ ...}] := Row@{"With named head: ", patt1}
         test[patt2 : {_@___ ...}] := Row@{"Without named head: ", patt2}
         DownValues@test
Out[13]= {HoldPattern[test[patt2:{_[___]...}]]  :> "Without named head:" patt2,
          HoldPattern[test[patt1:{h_[___]...}]] :> "With named head:" patt1}
In[14]:= test@{}
Out[14]= "Without named head:" {}

DownValues is prepended with the subsequent ones:

In[15]:= test[patt1 : {h_@___ ...}] := Row@{"Newdef, with named head: ", patt1}
         test[patt2 : {_@___ ...}] := Row@{"Newdef, without named head: ", patt2}
         DownValues@test
Out[17]= {HoldPattern[test[patt2:{_[___]...}]]  :> "Newdef, without named head:" patt2,
          HoldPattern[test[patt1:{h_[___]...}]] :> "Newdef, with named head:" patt1,
          HoldPattern[test[patt2:{_[___]...}]]  :> "Without named head:" patt2,
          HoldPattern[test[patt1:{h_[___]...}]] :> "With named head:" patt1}
In[18]:= test@{}
Out[18]= "Newdef, without named head:" {}

While output satisfactorily corresponds to new definition, this probably should not happen due to 1) unpredictability; 2) garbage accumulation.

(Additional examples of unstable pattern matching with RepeatedNull may be found in comments.)

share|improve this question
3  
That's not a problem with the pattern. Try List @@@ Sequence[] –  sebhofer Nov 11 '13 at 23:30
1  
@rm-rf Can do, I thought we might want to keep the OP puzzling for a bit :) –  sebhofer Nov 11 '13 at 23:36
7  
Ok, I vote for bug. Smallest example {} /. s : {h_ ...} :> s gives Sequence[] –  Rojo Nov 12 '13 at 3:21
1  
@Rojo, good example. Interesting that both {} /. s : {h ...} :> s and {} /. s : {_ ...} :> s behave as expected –  Simon Woods Nov 12 '13 at 14:10
4  
@RolfMertig The bug woundn't that it matches, but what the label s matches to –  Rojo Nov 12 '13 at 15:06
show 12 more comments

1 Answer 1

up vote 9 down vote accepted

Here is some evidence concerning what is going wrong.

ff[arg : {(h : _)@___ ...}] := Row @ {h, " : ", arg}

ff @ {u[x]}
u : {u[x]}
ff @ {{x}}
List : {{x}}
ff @ {{}}
List : {{}}

All the above show what one would expect, but

ff @ {}
{} : 

In this last case, I conclude that h has been matched with {} and arg has been matched with Sequence[]. I can not but think that this is a bug.

share|improve this answer
    
Perhaps I misunderstood your last phrase. If arg had been matched with {} and h with Sequence[] everything would be fine. But it was the other way around, and that's the bug. –  Rojo Nov 12 '13 at 5:38
    
@Rojo. Good catch, I corrected my typo. –  m_goldberg Nov 12 '13 at 5:43
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.