Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I just came across some weird behaviour. Take this function definition:

ClearAll[f]
f[vs_List : All] := "match"

The default value of vs is All. Now think about what f[] should return. Should it evaluate? You might say yes, vs will just take the default value. But you might say, wait, All doesn't even match _List so this is nonsense!

It turns out that different versions behave differently:

Version 9.0.1:

{$VersionNumber, $ReleaseNumber}
f[]
(* {9., 1} *)
(* f[] *)

Version 10.0.2:

{$VersionNumber, $ReleaseNumber}
f[]
(* {10., 2} *)
(* f[] *)

Version 10.2.0:

{$VersionNumber, $ReleaseNumber}
f[]
(* {10.2, 0} *)
(* "match" *)

Version 10.3.1:

{$VersionNumber, $ReleaseNumber}
f[]
(* {10.3, 1} *)
(* "match" *)

I don't have version 10.1.0 to try with.

Question: Is there a bug somewhere? Which should be the correct behaviour?


Ultimately this is of course a GIGO situation because the pattern arguably doesn't make sense. The solution is easy: just use f[vs : (_List | All) : All] := "match". But I made a mistake and used _List : All instead. Then much later I discovered that my test suite failed in version 10.0 while it was passing in 10.3.

What would be the most user-friendly behaviour in my opinion is for Mathematica to show a warning when it encounters this situation. Either way, it would be nice to have a mention of this behaviour in the documentation.

share|improve this question
    
Related: (4937) – Mr.Wizard Feb 29 at 11:32
    
A really interesting observation! Version 10.1.0 under Windows also gives "match". – Mr.Wizard Feb 29 at 11:33
    
Also related: (17707) – Leonid Shifrin Feb 29 at 11:42
9  
This change was intentional, and per request of the boss. – Daniel Lichtblau Feb 29 at 17:10
    
@Daniel Thanks! Could we please have this noted in the documentation somewhere, if it is not already? – Mr.Wizard Mar 1 at 2:32

Update: Daniel Lichtblau authoritatively comments:

This change was intentional, and per request of the boss.


I can find no mention of this in the documentation, though I am still looking. My guess is that the old behavior was a common source of problems and someone's fix was to implement the new behavior in version 10.1.0.

On the surface at least I like the change as it shortens and simplifies code. A notable difference is that with the new short scheme the default value is not seen as a valid explicit argument:

f[All]

   (* Out:   f[All]   -- 10.1.0 under Windows *)

I think this actually may prove useful but I can also imagine it being a new source of confusion.


Perhaps this change makes behavior more consistent than it was in the past.
Consider this behavior in older versions (here v7):

ClearAll[f, val]

f[vs_List: val] := vs
val = {1, 2, 3};
f[]

   (* Output:   f[]   -- no match *)

ClearAll[f, val]

f[vs : (_List | HoldPattern[val]) : val] := vs
val = "foo";
f[]

   (* Output:   "foo"   *)

I find both cases unexpected even if explainable. The new more permissive behavior makes these cases more similar as both evaluate using the current value of val.

share|improve this answer

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.