| Deutsch English Français Italiano |
|
<20250404112007.58@kylheku.com> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail
From: Kaz Kylheku <643-408-1753@kylheku.com>
Newsgroups: comp.lang.lisp
Subject: Re: infix via code walker hook.
Date: Fri, 4 Apr 2025 19:35:28 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 126
Message-ID: <20250404112007.58@kylheku.com>
References: <20250331141507.905@kylheku.com>
<20250401201007.528@kylheku.com> <20250403192220.35@kylheku.com>
<jwvldsfrecv.fsf-monnier+comp.lang.lisp@gnu.org>
Injection-Date: Fri, 04 Apr 2025 21:35:29 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="0acdb8a9a9b6b4fb3b99d09777fb4d36";
logging-data="310197"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/qB2EFvA04mPlK2aSW+iMd/xN7nOY8Xh4="
User-Agent: slrn/pre1.0.4-9 (Linux)
Cancel-Lock: sha1:MUJgaVLJ2loekxTDom1HE7LOi2A=
Bytes: 4705
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