函数调用中的优先级

Precedence inside a function call

在函数调用中使用 defined-or operator ( // ) 会产生我期望的结果:

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)»

关于优先级的工作原理,我遗漏了什么?

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

我会说,这是一个语法错误,因为

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

有效。

TL;DR 我超级有用的 naanswer(not-an-answer / non-authoritative 答案/深思)它可能是一个错误,也可能不是. :)


其他示例:

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

产生同样的错误。

What am I missing about how precedence works?

也许没什么。也许修复语法是可取的并且是可能的,因此这些 function-call-arg-list-signifying parens 决定优先级就像普通表达式 parens 所做的那样。

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


或者出于良好的可用性等原因,它可能会一直保持原样(尽管最初是“嗯?”)and/or 权宜之计 and/or single-pass 解析 and/or随便。


我搜索了一下,看看是否能找到相关的评论。这里有一些(有趣的?)位:

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

(来自 a comment on #perl6

如果你从 Larry 的评论向后滚动,你会看到他是在 Raku 非凡的 无缝 解析(没有引入分隔符)的上下文中说的 single nested sub-languages 的 pass 每个都可以有 任意 语法。

(顺便说一句,我有一个想法:std 解析 say(42 and 42) 好吗?我不确定这些天是否有 运行 std。)

虽然我们确实完全控制了 stock Raku,但我不相信有什么值得向后弯腰修复这种类型的皱纹(foo(... op ...)在这种情况下)当 general 情况(..... 其中 .s 外对中的中间 ... 具有任意语法)意味着我们'当 userland/module space 中出现大量混乱的语言/语法混合时,我会在未来几年内出现的情况下达到“完美”程度的极限。

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


也许结合上述内容考虑:

Raku borrows many concepts from human language ...

(来自 the doc

结合:

☞ Self-clocking code produces better syntax error messages

(来自 Seeing Wrong Right

结合:

Break that clock and your error messages will turn to mush

(来自 a mailing list comment

但话说回来:

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

你是这个意思,也许...?

> 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 的观点,即编译器中存在语法错误。