Re: infix via code walker hook.

Liste des GroupesRevenir à cl lisp 
Sujet : Re: infix via code walker hook.
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.lisp
Date : 04. Apr 2025, 20:35:28
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20250404112007.58@kylheku.com>
References : 1 2 3 4
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2025-04-04, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
  1> (parse-infix '(sin a + b + c + d))
  (sin (+ (+ (+ a b) c)
          d))
>
But, if we put parentheses on the operand of sin, then it's no longer
the unary sin, but a function call with that argument:
>
  2> (parse-infix '(sin (a) + b + c + d))
  (+ (+ (+ (sin a) b)
c)
     d)
>
For someone coming from "statically typed functional programming", this
is *very* weird.
All those languages (Haskell/OCaml/SML/Coq/Idris/Agda/...) treat
>
    (sin a + b + c + d)
>
the same as
>
    (sin (a) + b + c + d)

Ah, but how about higher precedence operators?

Would you want

  sin a * b * c

to be

  sin (a) * b *c

If not, you're asking for the operator version of sin to be
a unary operator with a higher precedence than plus or minus,
but lower than multiplication.

In math boox and papers, you certainly see expression like

  sin 2cx

I believe I have also seen

  sin t + 1

But also:

  (sin t - cos t)**2

It seems that a useful behavior to have would be for the
range of the unary operator to stop when we encounter
another such unary operator; i.e.

  sin a + b + c + sin d + e + f
                ^  ^

Suppose that when the binary + is adjacent to a unary operator as above,
we pretend that the + has a lower precedence.

Ooh, that seems to nicely for all unary operators.

I put into the parser a couple of hack lines which look like this:

         (iflet ((o3 [ifx-uops (car rest)]))
           (if (eq o1.arity :infix)
             (set o1 (copy o1)
                  o1.prec (pred o3.prec))))

When about to process an infix operator o1, we first peek at the rest of the
input. If it starts with a prefix operator, which we call o3, (since o2 is
being used for a previous operator pushed onto the operator stack) then we
duplicate the current o1 operator object, and give it a precedence that is one
lower than the infix.

(A better implementation would be to have a lexical variable here holding
a copy of the precedence, and just adjust the lexical, so as not to copy
the operator object.)

Bam:

What we want works:

  2> (parse-infix '(sin x + x + cos y + y))
  (+ (sin (+ x x))
     (cos (+ y y)))

Also the higher precedence unary minus now does
the right thing, syntactically, FWIW:

  3> (parse-infix '(- x * x * - y * y))
  (* (- (* x x))
     (- (* y y)))

The rule is easy to understand and leads to intuitive, symmetric treatment of
symmetric-looking formulas.

A lower precedence prefix operator suddenly appearing in a chain of higher
precedence operators should interrupt that chain, and begin a new chain piece
at the same level of depth.

Say, I wonder whether this logic could be nicely expressed in LAR(1) anymore.
I have a feeling that not, because LALR(1) makes only simple shift or reduce

Next question: should the precedence-lowering propagate thorugh stacks
of prefix operators?

Like here:

  5> (parse-infix '(sin x + x + - cos y + y))
  (sin (+ x (+ x (- (cos (+ y y))))))

When we are processing (+ - cos y ...), looking at the binarry +, should we
take into consideration all the consecutive unary operators that prefix the
rest of the input? In this case (- cos).  And should we then take their lowest
precedence? The idea being that cos propagates its low precedence to the higher
precedence -, which propagates it to + (decremeted by 1).

Then we could get the parse

  (+ (sin (+ x x))
     (- (cos (+ y y))))

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Date Sujet#  Auteur
31 Mar 25 * infix via code walker hook.9Kaz Kylheku
2 Apr 25 `* Re: infix via code walker hook.8Kaz Kylheku
4 Apr 25  `* Re: infix via code walker hook.7Kaz Kylheku
4 Apr 25   `* Re: infix via code walker hook.6Stefan Monnier
4 Apr 25    `* Re: infix via code walker hook.5Kaz Kylheku
4 Apr 25     `* Re: infix via code walker hook.4Stefan Monnier
5 Apr 25      +- Re: infix via code walker hook.1Kaz Kylheku
5 Apr 25      `* Re: infix via code walker hook.2Stefan Ram
5 Apr 25       `- Re: infix via code walker hook.1Kaz Kylheku

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal