17
$\begingroup$

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.)

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

1 Answer 1

9
$\begingroup$

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.

$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$
    – Rojo
    Commented Nov 12, 2013 at 5:38
  • $\begingroup$ @Rojo. Good catch, I corrected my typo. $\endgroup$
    – m_goldberg
    Commented Nov 12, 2013 at 5:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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