函数调用内的优先级

发布于 2025-01-11 14:24:46 字数 594 浏览 0 评论 0原文

使用定义或运算符 ( // )在函数调用中产生我期望的结果:

say( 'nan'.Int // 42); # OUTPUT: «42»

但是,使用较低优先级的orelse运算符反而会引发错误:

say( 'nan'.Int orelse 42); 
# OUTPUT: «Error: Unable to parse expression in argument list; 
#                 couldn't find final ')' 
#                 (corresponding starter was at line 1)»

关于优先级的工作原理,我缺少什么?

(或者这个错误是一个错误,我只是想太多了?)

Using the defined-or operator ( // ) in a function call produces the result I'd expect:

say( 'nan'.Int // 42); # OUTPUT: «42»

However, using the lower-precedence orelse operator instead throws an error:

say( 'nan'.Int orelse 42); 
# OUTPUT: «Error: Unable to parse expression in argument list; 
#                 couldn't find final ')' 
#                 (corresponding starter was at line 1)»

What am I missing about how precedence works?

(Or is the error a bug and I'm just overthinking this?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼眸里的那抹悲凉 2025-01-18 14:24:46

我想说,这是一个语法错误,确实

say ("nan".Int orelse 42);  # 42

如此。

I'd say, it's a grammar bug, as

say ("nan".Int orelse 42);  # 42

works.

抚笙 2025-01-18 14:24:46

TL;DR 我的超级有用的 naanswer(非答案/非权威答案/深思熟虑)是它可能是一个错误,也可能不是。 :)


其他示例:

say(42 and 42);
say(42 ==> 99);

产生相同的错误。

关于优先级的工作原理,我缺少什么?

也许什么也没有。也许修复语法是可取的并且是可能的,以便这些函数调用参数列表表示括号确定优先级,就像普通表达式括号一样。

如果是这样,也许修复它最好等待,或者实际上必须等待,直到 RakuAST 登陆时或之后(6.e?)。或者甚至更晚,lf/when Grammar cleanup/slangs lands (6.f?)。


或者,出于诸如良好的可用性(尽管最初的“嗯?”)和/或权宜之计和/或单遍解析和/或其他原因等原因,它可能会始终保持原样。


我进行了一些挖掘,看看是否能找到相关的评论。这里有一些(有趣的?):

OPP 比标准二元运算符 OPP 稍微复杂一点

(来自 对 #perl6 的评论

如果你从 Larry 的评论向后滚动,你会看到他在 Raku 非凡的背景下说了这句话在嵌套子语言的单次中进行无缝解析(不引入分隔符),每种子语言都可以具有任意语法。

(顺便说一句,我有一个想法:std 解析 say(42 和 42) 没问题吗?我不确定是否有正在运行的 std 虽然我们确实完全控制了 Raku stock,但

我不相信有什么令人信服的办法来解决这类问题(foo(... op ...) 在这种情况下)当一般情况时(.....,其中中间的...位于外部的对内。 s 具有任意语法)意味着当用户空间/模块空间中存在大量无政府语言/语法混合时,我们将达到“完美”程度的极限,正如我预计将在未来几年出现的那样。

所以,在我看来,如果它相当容易修复,并且不会过度限制或增加用户俚语自由的负担,那就太好了。如果没有,我认为目前的情况足够公平(尽管也许改进错误消息是可取的、可行的和合理的)。


或许可以将上述内容与以下内容结合起来考虑:

Raku 借用了人类语言的许多概念......

(来自文档

并结合:

☞ 自计时代码产生更好的语法错误消息

(来自 见错了)

结合:

打破这个时钟,你的错误消息就会变成糊状

(来自 邮件列表评论

但是话又说回来:

请不要认为 rakudo 的特质和设计化石是规范的。

TL;DR My super useful naanswer (not-an-answer / non-authoritative answer / food for thought) is it might be a bug or it might not. :)


Other examples:

say(42 and 42);
say(42 ==> 99);

yield the same error.

What am I missing about how precedence works?

Perhaps nothing. Perhaps it will be desirable and possible to fix the grammar so these function-call-arg-list-signifying parens determine precedence just like plain expression parens do.

If so, perhaps fixing it would best wait, or perhaps realistically must wait, until when or after RakuAST lands (6.e?). Or perhaps even later, lf/when grammar cleanup/slangs lands (6.f?).


Or perhaps it's going to always stay as it is for reasons such as good usability (despite the initial "huh?") and/or expediency and/or single-pass parsing and/or whatever.


I've dug a little to see if I could find relevant commentary. Here are some (juicy?) bits:

the OPP is a bit more complex than a standard binary-operator OPP

(from a comment on #perl6)

If you scroll backwards from Larry's comment you'll see he said this in the context of Raku's extraordinary seamless parsing (no delimiters introduced) in a single pass of nested sub-languages that each can have arbitrary grammars.

(Btw, one thought I had: did std parse say(42 and 42) fine? I'm not sure if there's a running std anywhere these days.)

While we do have complete control of stock Raku, I'm not convinced there's anything compelling about bending over backwards to fix every wrinkle of this sort (foo(... op ...) in this case) when the general case (..... where the middle ... inside the outer pair of .s has arbitrary syntax) means we'll be hitting limits in how "perfect" it can all be when there's a huge amount of anarchic language / syntax mixing going on in userland/module space, as I anticipate will emerge in years to come.

So, imo, if it's reasonably easy to fix, without unduly cramping or burdening user slang freedom, great. If not, I think the current situation is fair enough (though perhaps it'll be desirable, viable and reasonable to improve the error message).


Perhaps consider the foregoing in combination with:

Raku borrows many concepts from human language ...

(from the doc)

in combination with:

☞ Self-clocking code produces better syntax error messages

(from Seeing Wrong Right)

in combination with:

Break that clock and your error messages will turn to mush

(from a mailing list comment)

But then again:

Please don't assume that rakudo's idiosyncracies and design fossils are canonical.

淡淡的优雅 2025-01-18 14:24:46

你的意思是这个,也许……?

> say ( NaN.Int orelse 42 )
42

因为

> say( NaN.Int orelse 42 )
===SORRY!=== Error while compiling:
Unable to parse expression in argument list; couldn't find final ')' (corresponding starter was at line 1)
------> say( '42'.Int⏏ orelse 42 )
    expecting any of:
        infix
        infix stopper

我倾向于同意 @lizmat 的观点,即编译器中存在语法错误。

Do you mean this, maybe...?

> say ( NaN.Int orelse 42 )
42

since

> say( NaN.Int orelse 42 )
===SORRY!=== Error while compiling:
Unable to parse expression in argument list; couldn't find final ')' (corresponding starter was at line 1)
------> say( '42'.Int⏏ orelse 42 )
    expecting any of:
        infix
        infix stopper

I would tend to agree with @lizmat that there is a grammar bug in the compiler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文