11

Just check

i_: 0 | 1 // FullForm

In v12.0 or earlier the output is

Alternatives[Optional[Pattern[i, Blank[]], 0], 1]

enter image description here

But in v12.1 the output becomes

Optional[Pattern[i, Blank[]], Alternatives[0, 1]]

enter image description here

Seems that the precedence between : and | varies in v12.1. Is this an intentional change, or a bug?


Some more observations. Behavior in v3:

enter image description here

Behavior in v2.1:

enter image description here

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
xzczd
  • 65,995
  • 9
  • 163
  • 468
  • 2
    I suspect that this was a bugfix. Try running the same in command-line mode, or try ToExpression["i_: 0 | 1 // FullForm"]. It parses the same way as in 12.1.1. I expect this fixed an inconsistency between the FE's and the kernel's parser. – Szabolcs Jun 30 '20 at 06:14
  • 3
    I wonder how you came across this example. I can't see a reasonable use for either (i_ : 0) | 1 or i_ : (0 | 1). – Szabolcs Jun 30 '20 at 06:23
  • 1
    @Szabolcs It's a simplified example of course. I found this because it breaks my code here (see revision 6 ): https://mathematica.stackexchange.com/posts/132713/revisions . Your guess looks reasonable. Post it as an answer? – xzczd Jun 30 '20 at 06:26
  • I think it's v3 that introduced the FE as we know it today. (So it makes sense.) – Szabolcs Jun 30 '20 at 08:06
  • 1
    @sza Aha, here comes another broken example: https://mathematica.stackexchange.com/a/29366/1871 – xzczd Jun 30 '20 at 10:04
  • 1
    With respect to detoae in your first comment, it's a cute use of Times, but, imho, the kind of cute that hides a bug: (2 u)[t] /. detoae — an extremely rare bug that is hardly likely to occur since (2 u)[t] is almost certainly a mistake, though you will find Q&A on site where users want to take a linear combination of functions and plug in x (there was one yesterday or the day before). I just bite the bullet and write two rules, one for derivatives and one for functions, because it's easier to understand. – Michael E2 Jun 30 '20 at 12:01
  • @MichaelE2 Yeah the two rules solution is more stable and pellucid. (I admit my pattern is kind of ostentation :) . ) – xzczd Jun 30 '20 at 12:15
  • I have to admit I like the way you can do such things in Mathematica. But after a year or so of being pleased with myself, I tend to think a more straightforward way would be easier to deal with. :) – Michael E2 Jun 30 '20 at 12:28
  • 2
    Actually the 2.1 screenshot answers a question for me. Because when I saw the FE implementation, which dated back to the very beginning of the box parser, I couldn't figure out why it was done that way...in obvious contradiction to the docs. But your 2.1 screenshot suggests that there was actually a change to the kernel (and maybe the docs as well) from 2.1 to 3.0. Maybe the box parser, which was implemented in 3.0, was based on what would become out-of-date info from the kernel. The box parser was implemented maybe a year before I started working on the FE. – John Fultz Jul 01 '20 at 17:05

2 Answers2

9

I expect that this was a bugfix that corrected an inconsistency between how the Front End and the kernel parse this code. Here's a comparison from M12.0.0:

In[1]:= $Version
Out[1]= 12.0.0 for Mac OS X x86 (64-bit) (April 7, 2019)

In[2]:= i_: 0|1//FullForm Out[2]//FullForm= Alternatives[Optional[Pattern[i,Blank[]],0],1]

In[3]:= ToExpression["i_: 0 | 1 // FullForm"] Out[3]//FullForm= Optional[Pattern[i,Blank[]],Alternatives[0,1]]

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • 1
    Seeing the behavior of v2.1 , I'm a bit confused which change should be regarded as bug... (Check my update. ) – xzczd Jun 30 '20 at 07:09
  • 1
    @xzczd I would always give the kernel's parsing priority because that is what is being used when a package (i.e. a plain text file) is loaded. – Szabolcs Jun 30 '20 at 08:07
  • 2
    There's no need to guess here, or pick favorites between the kernel and the FE. The documentation trumps everything. Any variation from the documentation is always a bug (it might be a bug in the documentation, of course, but in practice that's pretty rare). https://reference.wolfram.com/language/tutorial/OperatorInputForms.html And, yes, it was indeed an intentional bugfix. Three external users had reported some variant of this, and IIRC it came up on the Redmine, too. – John Fultz Jul 01 '20 at 16:55
  • @JohnFultz So, the behavior of kernel is an incompatible change of kernel in v3.0, and the behavior of front end is a bug introduced in v3.0 and fixed in v12.1.0? – xzczd Jul 02 '20 at 02:22
7

I think V. 12.1.1 is correct, because the precedence of Alternatives (|) is larger than that of Optional (:)

Precedence /@ {Alternatives, Optional}
{160., 140.}

This result of Precedence is obtainable both in V. 12.1.1 and V. 12.0.0 (no V. 12.0.1 at hand). So it looks like a bug in V. 12.0.x when interpreting shorthand symbols.