违反标识符规则的符号,例如`sub ::("☺") { }`

Symbols that break the identifier rules, e.g. `sub ::("☺") { }`

使用当前的 Rakudo 编译器 (v2021.10),symbols declared with the ::(…) form do not need to follow the rules for identifiers 即使它们声明了例程的名称。

这意味着以下代码会产生指定的输出:

class C { method ::("A method name that's also a sentence!") { say "this works"} }
sub ::("☺") { say "also works" }

C."A method name that's also a sentence!"();  # OUTPUT: «this works»
&::("☺")();                                   # OUTPUT: «also works»

我的问题是这是否有效 Raku/一个有意的特征,或者它是否是偶然的或 Rakudo 特定的。我在 Raku 文档中没有看到任何关于此语法的提及,也没有看到 Roast 测试涵盖创建这样的符号。

(关于在符号 de 引用中使用特殊字符,有一些相关的 Roast test。但是,除了不直接在点上,该测试还包含有点无用的评论“注意:我不是 100% 确定这是合法语法”。该评论(和该测试)是在 13 多年前添加的,因此该领域似乎并没有引起很多关注。 )

我问的部分原因是,如果 legal/intended,这种语法似乎在小众情况下非常有用(尤其是对于调用语法更好的方法)。这让我想起了一点 Kotlin's syntax `for allowing spaces in backtick delimited method names`。所以,如果它是 Raku 的一部分,我想使用这种语法(谨慎!)并将其添加到文档中。

简而言之,是的,这是合法的。

标识符的概念是一个句法概念:在解析Raku时,解析器需要对它看到的东西进行分类,标识符规则表示应该将哪些字符序列识别为标识符。

相比之下,存储、方法 tables 和词法作用域最终是类似于散列的数据结构:它们将字符串键映射到存储的值中。正如可以放入散列中的键没有限制一样,这里也没有。给定元对象可以由用户定义,目前还不清楚是否可以可靠地执行限制,即使它被认为是可取的。

声明性上下文中的 ::(...) 间接名称语法仅带有一个限制,即您放置在那里的内容必须是一个编译时常量。就解析而言,括号内的是一个表达式。编译器想要得到一个字符串,它可以用来在某处安装一个符号;使用标识符,它直接来自程序源文本,使用间接名称语法,通过评估在那里找到的常量。在任何一种情况下,它都用于在符号 table 中输入条目,而那些并不关心,因此在两者之间,您有办法获得符号 table 没有的条目标识符语法。