Re: Can't parse "a # not b", but parses "a # (not b)" and prints it as "a # not b"
Stavros Macrakis <[email protected]> Sun, 21 Jun 2026 16:04:45 -0400
| Newsgroups | gmane.comp.mathematics.maxima.general |
|---|---|
| Message-ID | <CACLVabUJ2xxgm0wOUCr-uuNe1egy04Jgh+KL3PSheV72dCd+nA@mail.gmail.com> |
--===============0518475629018155427== Content-Type: multipart/alternative; boundary="0000000000006c08460654c90a8e" --0000000000006c08460654c90a8e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable I strongly disagree with any change that parses *a=3Db>c* as *(a=3Db)>c* or *a=3D(b>c) *or that interprets *a=3Db=3Dc *as *(a=3Db)=3Dc* or *a=3D(b=3Dc)*. It's not that "it's a bit of a stretch to figure out what a=3D b > c means.= " Of course users can "figure it out" in principle, but we should design according to the principle of least surprise <https://en.wikipedia.org/wiki/Principle_of_least_astonishment>, not the principle of "only your language lawyer knows for sure". Old programming languages like C and PL/I parsed a=3D=3Db=3D=3Dc as ((a=3D= =3Db)=3D=3Dc, notoriously leading to counterintuitive behavior and bugs. Their grammar was inherited by C++ and Javascript. Java and C# are more strictly typed, and give a type error. Rust and Go also forbid it and tell the user to add parentheses, precisely because it is an "attractive nuisance". Python treats *a=3D=3Db=3D=3Dc *the way a mathematician would expect: as *(= a=3D=3Db) and (b=3D=3Dc)*. For mathematicians, scientists and engineers -- our users = -- that is the only interpretation that makes sense. Similarly, the only interpretation of *a<b>=3Dc *that makes sense is (*a<b) and (b >=3Dc)* (but only evaluating each term once). On Sun, Jun 21, 2026 at 1:21=E2=80=AFAM Robert Dodier <robert.dodier@gmail.= com> wrote: > I guess I'm a little late to the party. Anyway, about these changes. > > (1) change RPOS and LPOS for =3D and #. > > (2) change RBP and LBP for inequality operators. > > These are both OK by me. These both make it possible to parse some > expressions which trigger errors now, and don't change any existing > expressions which don't trigger an error (right?). > > It doesn't bother me that it's a bit of a stretch to figure out what a > =3D b > c means. By assigning binding powers, we give it an unambiguous > representation -- it must be a =3D (b > c). What does that "mean"? We > don't need to know. If that's not suitable for some use, then we just > say "Don't do that." We set up the rules and let the user figure out > what is meaningful to them -- that is, I claim, the mathematical > approach. > > I think (1) was somewhat less controversial than (2). Maybe if we > can't get everybody on board for (2), we can still consider (1). > > FWIW & all the best. > > Robert > > On Tue, Jun 9, 2026 at 10:59=E2=80=AFPM David Scherfgen via Maxima-discus= s > <[email protected]> wrote: > > > > Dear all, > > > > as Stavros noted in this bug report, Maxima fails to parse this: > > > > a # not b > > Error: "Found LOGICAL expression where ALGEBRAIC expression expected" > > > > However, a # (not b) with parentheses parses perfectly, but is printed > without parentheses. This means that Maxima cannot parse its own output. > (The same for =3D.) > > > > Proposed fix: > > In nparse.lisp, change lpos and rpos for the =3D and # operators from > $expr to $any. Also, increase the binding powers of <, <=3D, >=3D and > = from > 80 to 85. Note that this is in accordance with most programming languages= , > where <, <=3D, >=3D and > have a higher binding power than =3D=3D and != =3D, for the > exact same reason of being able to compare logical expressions. Maxima > currently has them all the same. > > > > If we make this change, the following expressions will parse directly > without requiring parentheses, building the exact same trees they already > do: > > > > a # not b > > a =3D not b > > a =3D b =3D c (parses as (a =3D b) =3D c) > > a > b =3D c (parses as (a > b) =3D c) > > c =3D a > b (parses as c =3D (a > b), wouldn't parse with the original > binding powers) > > > > Would this have any unintended side-effects? > > > > Best regards > > David Scherfgen > > _______________________________________________ > > Maxima-discuss mailing list > > [email protected] > > https://lists.sourceforge.net/lists/listinfo/maxima-discuss > > > _______________________________________________ > Maxima-discuss mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/maxima-discuss > --0000000000006c08460654c90a8e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-family:georgia,= serif;font-size:small;color:#330000">I strongly disagree with any change th= at parses <b>a=3Db>c</b>=C2=A0as <b>(a=3Db)>c</b>=C2=A0or <b>a=3D(b&g= t;c) </b>or that interprets <b>a=3Db=3Dc </b>as <b>(a=3Db)=3Dc</b>=C2=A0or = <b>a=3D(b=3Dc)</b>.</div><div class=3D"gmail_default" style=3D"font-size:sm= all;color:rgb(51,0,0)"><font face=3D"georgia, serif"><br></font></div><div = class=3D"gmail_default" style=3D"font-size:small;color:rgb(51,0,0)"><font f= ace=3D"georgia, serif">It's not that "<span style=3D"background-co= lor:transparent;color:rgb(34,34,34)">it's a bit of a stretch to figure = out what a</span><span style=3D"background-color:transparent;color:rgb(34,3= 4,34)">=3D b > c means." Of course users can "figure it out&qu= ot; in principle, but we should design according to the <a href=3D"https://= en.wikipedia.org/wiki/Principle_of_least_astonishment">principle of least s= urprise</a>, not the principle of "only your language lawyer knows for= sure".</span></font></div><div class=3D"gmail_default" style=3D"font-= size:small;color:rgb(51,0,0)"><font face=3D"georgia, serif"><span style=3D"= background-color:transparent;color:rgb(34,34,34)"><br></span></font></div><= div class=3D"gmail_default" style=3D"font-size:small;color:rgb(51,0,0)"><fo= nt face=3D"georgia, serif"><span style=3D"background-color:transparent;colo= r:rgb(34,34,34)">Old programming languages like C and PL/I parsed a=3D=3Db= =3D=3Dc as ((a=3D=3Db)=3D=3Dc, notoriously leading to</span></font><span st= yle=3D"background-color:transparent;color:rgb(34,34,34);font-family:georgia= ,serif">=C2=A0counterintuitive behavior and bugs. Their grammar was inherit= ed by C++ and Javascript.=C2=A0</span></div><div class=3D"gmail_default" st= yle=3D"font-size:small;color:rgb(51,0,0)"><span style=3D"background-color:t= ransparent;color:rgb(34,34,34);font-family:georgia,serif"><br></span></div>= <div class=3D"gmail_default" style=3D"font-size:small;color:rgb(51,0,0)"><s= pan style=3D"background-color:transparent;color:rgb(34,34,34);font-family:g= eorgia,serif">Java and C# are more strictly typed, and give a type error.= =C2=A0</span><span style=3D"font-family:georgia,serif;background-color:tran= sparent;color:rgb(34,34,34)">Rust and Go also forbid it and tell the user t= o add parentheses, precisely because it is an "attractive nuisance&quo= t;.</span></div><div class=3D"gmail_default" style=3D"font-size:small;color= :rgb(51,0,0)"><span style=3D"background-color:transparent;color:rgb(34,34,3= 4);font-family:georgia,serif"><br></span></div><div class=3D"gmail_default"= style=3D"font-size:small;color:rgb(51,0,0)"><span style=3D"background-colo= r:transparent;color:rgb(34,34,34);font-family:georgia,serif">Python treats = <b>a=3D=3Db=3D=3Dc </b>the way a mathematician would expect: as <b>(a=3D=3D= b) and (b=3D=3Dc)</b>. For mathematicians, scientists and engineers -- our = users -- that is the only interpretation that makes sense. Similarly, the o= nly interpretation of <b>a<b>=3Dc </b>that makes sense is (</span><b = style=3D"background-color:transparent;color:rgb(34,34,34);font-family:georg= ia,serif">a<b) and (b >=3Dc)</b><span style=3D"background-color:trans= parent;color:rgb(34,34,34);font-family:georgia,serif">=C2=A0(but only evalu= ating each term once).</span></div><div class=3D"gmail_default" style=3D"fo= nt-size:small"><br></div><div class=3D"gmail_default" style=3D"font-family:= georgia,serif;font-size:small;color:#330000"><b><br></b></div></div><br><di= v class=3D"gmail_quote gmail_quote_container"><div dir=3D"ltr" class=3D"gma= il_attr">On Sun, Jun 21, 2026 at 1:21=E2=80=AFAM Robert Dodier <<a href= =3D"mailto:[email protected]">[email protected]</a>> wrote:<= br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e= x;border-left:1px solid rgb(204,204,204);padding-left:1ex">I guess I'm = a little late to the party. Anyway, about these changes.<br> <br> (1) change RPOS and LPOS for =3D and #.<br> <br> (2) change RBP and LBP for inequality operators.<br> <br> These are both OK by me. These both make it possible to parse some<br> expressions which trigger errors now, and don't change any existing<br> expressions which don't trigger an error (right?).<br> <br> It doesn't bother me that it's a bit of a stretch to figure out wha= t a<br> =3D b > c means. By assigning binding powers, we give it an unambiguous<= br> representation -- it must be a =3D (b > c). What does that "mean&qu= ot;? We<br> don't need to know. If that's not suitable for some use, then we ju= st<br> say "Don't do that." We set up the rules and let the user fig= ure out<br> what is meaningful to them=C2=A0 -- that is, I claim, the mathematical<br> approach.<br> <br> I think (1) was somewhat less controversial than (2). Maybe if we<br> can't get everybody on board for (2), we can still consider (1).<br> <br> FWIW & all the best.<br> <br> Robert<br> <br> On Tue, Jun 9, 2026 at 10:59=E2=80=AFPM David Scherfgen via Maxima-discuss<= br> <<a href=3D"mailto:[email protected]" target=3D"_blan= k">[email protected]</a>> wrote:<br> ><br> > Dear all,<br> ><br> > as Stavros noted in this bug report, Maxima fails to parse this:<br> ><br> > a # not b<br> > Error: "Found LOGICAL expression where ALGEBRAIC expression expec= ted"<br> ><br> > However, a # (not b) with parentheses parses perfectly, but is printed= without parentheses. This means that Maxima cannot parse its own output. (= The same for =3D.)<br> ><br> > Proposed fix:<br> > In nparse.lisp, change lpos and rpos for the =3D and # operators from = $expr to $any. Also, increase the binding powers of=C2=A0 <, <=3D, &g= t;=3D and > from 80 to 85. Note that this is in accordance with most pro= gramming languages, where <, <=3D, >=3D and > have a higher bin= ding power than =3D=3D and !=3D, for the exact same reason of being able to= compare logical expressions. Maxima currently has them all the same.<br> ><br> > If we make this change, the following expressions will parse directly = without requiring parentheses, building the exact same trees they already d= o:<br> ><br> > a # not b<br> > a =3D not b<br> > a =3D b =3D c (parses as (a =3D b) =3D c)<br> > a > b =3D c (parses as (a > b) =3D c)<br> > c =3D a > b (parses as c =3D (a > b), wouldn't parse with th= e original binding powers)<br> ><br> > Would this have any unintended side-effects?<br> ><br> > Best regards<br> > David Scherfgen<br> > _______________________________________________<br> > Maxima-discuss mailing list<br> > <a href=3D"mailto:[email protected]" target=3D"_bla= nk">[email protected]</a><br> > <a href=3D"https://lists.sourceforge.net/lists/listinfo/maxima-discuss= " rel=3D"noreferrer" target=3D"_blank">https://lists.sourceforge.net/lists/= listinfo/maxima-discuss</a><br> <br> <br> _______________________________________________<br> Maxima-discuss mailing list<br> <a href=3D"mailto:[email protected]" target=3D"_blank">M= [email protected]</a><br> <a href=3D"https://lists.sourceforge.net/lists/listinfo/maxima-discuss" rel= =3D"noreferrer" target=3D"_blank">https://lists.sourceforge.net/lists/listi= nfo/maxima-discuss</a><br> </blockquote></div> --0000000000006c08460654c90a8e-- --===============0518475629018155427== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline --===============0518475629018155427== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Maxima-discuss mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/maxima-discuss --===============0518475629018155427==--