Re: Can't parse "a # not b", but parses "a # (not b)" and prints it as "a # not b"

Brent Meeker <[email protected]> Mon, 22 Jun 2026 10:30:12 -0700
Newsgroups gmane.comp.mathematics.maxima.general
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============8048824055751807305==
Content-Type: multipart/alternative;
 boundary="------------jyjE1p31vhQBxKgfan7gU0EN"
Content-Language: en-US

This is a multi-part message in MIME format.
--------------jyjE1p31vhQBxKgfan7gU0EN
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

Hear! Hear!

Brent

On 6/21/2026 1:04 PM, Stavros Macrakis wrote:
> I strongly disagree with any change that parses *a=b>c* as 
> *(a=b)>c* or *a=(b>c) *or that interprets *a=b=c *as *(a=b)=c* or 
> *a=(b=c)*.
>
> It's not that "it's a bit of a stretch to figure out what a= 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==b==c as 
> ((a==b)==c, 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==b==c *the way a mathematician would expect: as 
> *(a==b) and (b==c)*. For mathematicians, scientists and engineers -- 
> our users -- that is the only interpretation that makes sense. 
> Similarly, the only interpretation of *a<b>=c *that makes sense is 
> (*a<b) and (b >=c)* (but only evaluating each term once).
>
> *
> *
>
> On Sun, Jun 21, 2026 at 1:21 AM Robert Dodier 
> <[email protected]> wrote:
>
>     I guess I'm a little late to the party. Anyway, about these changes.
>
>     (1) change RPOS and LPOS for = 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
>     = b > c means. By assigning binding powers, we give it an unambiguous
>     representation -- it must be a = (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 PM David Scherfgen via Maxima-discuss
>     <[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 =.)
>     >
>     > Proposed fix:
>     > In nparse.lisp, change lpos and rpos for the = and # operators
>     from $expr to $any. Also, increase the binding powers of  <, <=,
>     >= and > from 80 to 85. Note that this is in accordance with most
>     programming languages, where <, <=, >= and > have a higher binding
>     power than == and !=, 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 = not b
>     > a = b = c (parses as (a = b) = c)
>     > a > b = c (parses as (a > b) = c)
>     > c = a > b (parses as c = (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
>
>
>
> _______________________________________________
> Maxima-discuss mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/maxima-discuss

--------------jyjE1p31vhQBxKgfan7gU0EN
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#faf0b8">
    Hear! Hear!<br>
    <br>
    Brent<br>
    <br>
    <div class="moz-cite-prefix">On 6/21/2026 1:04 PM, Stavros Macrakis
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CACLVabUJ2xxgm0wOUCr-uuNe1egy04Jgh+KL3PSheV72dCd+nA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div class="gmail_default"
style="font-family:georgia,serif;font-size:small;color:#330000">I
          strongly disagree with any change that parses <b>a=b&gt;c</b> as
          <b>(a=b)&gt;c</b> or <b>a=(b&gt;c) </b>or that interprets <b>a=b=c
          </b>as <b>(a=b)=c</b> or <b>a=(b=c)</b>.</div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><font
            face="georgia, serif"><br>
          </font></div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><font
            face="georgia, serif">It's not that "<span
              style="background-color:transparent;color:rgb(34,34,34)">it's
              a bit of a stretch to figure out what a</span><span
              style="background-color:transparent;color:rgb(34,34,34)">=
              b &gt; c means." Of course users can "figure it out" in
              principle, but we should design according to the <a
href="https://en.wikipedia.org/wiki/Principle_of_least_astonishment"
                moz-do-not-send="true">principle of least surprise</a>,
              not the principle of "only your language lawyer knows for
              sure".</span></font></div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><font
            face="georgia, serif"><span
              style="background-color:transparent;color:rgb(34,34,34)"><br>
            </span></font></div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><font
            face="georgia, serif"><span
              style="background-color:transparent;color:rgb(34,34,34)">Old
              programming languages like C and PL/I parsed a==b==c as
              ((a==b)==c, notoriously leading to</span></font><span
style="background-color:transparent;color:rgb(34,34,34);font-family:georgia,serif"> counterintuitive
            behavior and bugs. Their grammar was inherited by C++ and
            Javascript. </span></div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><span
style="background-color:transparent;color:rgb(34,34,34);font-family:georgia,serif"><br>
          </span></div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><span
style="background-color:transparent;color:rgb(34,34,34);font-family:georgia,serif">Java
            and C# are more strictly typed, and give a type error. </span><span
style="font-family:georgia,serif;background-color:transparent;color:rgb(34,34,34)">Rust
            and Go also forbid it and tell the user to add parentheses,
            precisely because it is an "attractive nuisance".</span></div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><span
style="background-color:transparent;color:rgb(34,34,34);font-family:georgia,serif"><br>
          </span></div>
        <div class="gmail_default"
          style="font-size:small;color:rgb(51,0,0)"><span
style="background-color:transparent;color:rgb(34,34,34);font-family:georgia,serif">Python
            treats <b>a==b==c </b>the way a mathematician would
            expect: as <b>(a==b) and (b==c)</b>. For mathematicians,
            scientists and engineers -- our users -- that is the only
            interpretation that makes sense. Similarly, the only
            interpretation of <b>a&lt;b&gt;=c </b>that makes sense is
            (</span><b
style="background-color:transparent;color:rgb(34,34,34);font-family:georgia,serif">a&lt;b)
            and (b &gt;=c)</b><span
style="background-color:transparent;color:rgb(34,34,34);font-family:georgia,serif"> (but
            only evaluating each term once).</span></div>
        <div class="gmail_default" style="font-size:small"><br>
        </div>
        <div class="gmail_default"
style="font-family:georgia,serif;font-size:small;color:#330000"><b><br>
          </b></div>
      </div>
      <br>
      <div class="gmail_quote gmail_quote_container">
        <div dir="ltr" class="gmail_attr">On Sun, Jun 21, 2026 at
          1:21 AM Robert Dodier &lt;<a
            href="mailto:[email protected]" moz-do-not-send="true"
            class="moz-txt-link-freetext">[email protected]</a>&gt;
          wrote:<br>
        </div>
        <blockquote class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;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 = 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 what a<br>
          = b &gt; c means. By assigning binding powers, we give it an
          unambiguous<br>
          representation -- it must be a = (b &gt; c). What does that
          "mean"? We<br>
          don't need to know. If that's not suitable for some use, then
          we just<br>
          say "Don't do that." We set up the rules and let the user
          figure out<br>
          what is meaningful to them  -- 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 &amp; all the best.<br>
          <br>
          Robert<br>
          <br>
          On Tue, Jun 9, 2026 at 10:59 PM David Scherfgen via
          Maxima-discuss<br>
          &lt;<a href="mailto:[email protected]"
            target="_blank" moz-do-not-send="true"
            class="moz-txt-link-freetext">[email protected]</a>&gt;
          wrote:<br>
          &gt;<br>
          &gt; Dear all,<br>
          &gt;<br>
          &gt; as Stavros noted in this bug report, Maxima fails to
          parse this:<br>
          &gt;<br>
          &gt; a # not b<br>
          &gt; Error: "Found LOGICAL expression where ALGEBRAIC
          expression expected"<br>
          &gt;<br>
          &gt; 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 =.)<br>
          &gt;<br>
          &gt; Proposed fix:<br>
          &gt; In nparse.lisp, change lpos and rpos for the = and #
          operators from $expr to $any. Also, increase the binding
          powers of  &lt;, &lt;=, &gt;= and &gt; from 80 to 85. Note
          that this is in accordance with most programming languages,
          where &lt;, &lt;=, &gt;= and &gt; have a higher binding power
          than == and !=, for the exact same reason of being able to
          compare logical expressions. Maxima currently has them all the
          same.<br>
          &gt;<br>
          &gt; If we make this change, the following expressions will
          parse directly without requiring parentheses, building the
          exact same trees they already do:<br>
          &gt;<br>
          &gt; a # not b<br>
          &gt; a = not b<br>
          &gt; a = b = c (parses as (a = b) = c)<br>
          &gt; a &gt; b = c (parses as (a &gt; b) = c)<br>
          &gt; c = a &gt; b (parses as c = (a &gt; b), wouldn't parse
          with the original binding powers)<br>
          &gt;<br>
          &gt; Would this have any unintended side-effects?<br>
          &gt;<br>
          &gt; Best regards<br>
          &gt; David Scherfgen<br>
          &gt; _______________________________________________<br>
          &gt; Maxima-discuss mailing list<br>
          &gt; <a href="mailto:[email protected]"
            target="_blank" moz-do-not-send="true"
            class="moz-txt-link-freetext">[email protected]</a><br>
          &gt; <a
href="https://lists.sourceforge.net/lists/listinfo/maxima-discuss"
            rel="noreferrer" target="_blank" moz-do-not-send="true"
            class="moz-txt-link-freetext">https://lists.sourceforge.net/lists/listinfo/maxima-discuss</a><br>
          <br>
          <br>
          _______________________________________________<br>
          Maxima-discuss mailing list<br>
          <a href="mailto:[email protected]"
            target="_blank" moz-do-not-send="true"
            class="moz-txt-link-freetext">[email protected]</a><br>
          <a
href="https://lists.sourceforge.net/lists/listinfo/maxima-discuss"
            rel="noreferrer" target="_blank" moz-do-not-send="true"
            class="moz-txt-link-freetext">https://lists.sourceforge.net/lists/listinfo/maxima-discuss</a><br>
        </blockquote>
      </div>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <pre wrap="" class="moz-quote-pre">_______________________________________________
Maxima-discuss mailing list
<a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
<a class="moz-txt-link-freetext" href="https://lists.sourceforge.net/lists/listinfo/maxima-discuss">https://lists.sourceforge.net/lists/listinfo/maxima-discuss</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>

--------------jyjE1p31vhQBxKgfan7gU0EN--


--===============8048824055751807305==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


--===============8048824055751807305==
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

--===============8048824055751807305==--