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.
"match"
. $\endgroup$.m
file to be linted. Things likeBegin["cont`"]
would have to be parsed manually and applied to subsequent symbols ...Import[..., {"Package", "HeldExpressions"}]
(understandably) won't be able to get this right. $\endgroup$