晃来晃去的主题(或任何其他)变量不会失败

时间:2019-06-29 08:38:01

标签: syntax perl6

这有效:

$_ =

say "hi";

也就是说,您可以在任务和后面的内容之间放置任意数量的空格,它只会忽略它。您也可以使用任何变量(带有my)。实际上,将为$ _分配say的结果,即True

这是令人惊讶的,但是符合规范,还是仅仅是令人惊讶?

2 个答案:

答案 0 :(得分:8)

运算符的两边可能有任意数量的空格。因此:

say 1
    + 2

    + 3;
就编译器而言,

完全相同:

say 1 + 2 + 3;

分配(=)只是另一个运算符,因此也要遵循这些规则。

此外,say只是一个普通的内置子例程,因此就像:

my $answer = flip '24';
say $answer; # 42

除了具有更多的空格:

my $answer = 

    flip '24';
say $answer; # 42

在Perl 6中有 some 个空格,空格很大,但是中缀运算符之间的空格不是其中之一。

答案 1 :(得分:4)

TL; DR P6语法是自由格式。

  

悬挂主题(或任何其他)变量不会失败

您描述的问题是一个非常普遍的问题。绝对不只是关于变量声明/赋值!

在P6中,对语句(单个命令单元(“执行此操作”)的解析)通常会一直进行下去,直到到达显式语句分隔符(;)为止,该分隔符将一条语句带到就像这个英语句子结尾处的句点(也称为句号)一样。

  

您可以放置​​任意数量的空格

与许多编程语言一样,标准P6通常为freeform。也就是说,只要 some 空格有效,那么通常任何数量的空格-水平和垂直空格-在语法上都是等效的。

$_ =

say "hi";

以上内容的工作原理完全与预期的一致,如果有人采用自由格式原理,这是将say的值分配给$_变量的单个语句。

  

这是令人惊讶的,但是符合规范,还是仅仅是令人惊讶?

我喜欢发明(希望是愚蠢的)俗语。我刚刚发明了“惊喜跟随惊喜”。

由规格决定。我知道可以期待。这并不令我惊讶。

如果有人接受P6通常是自由格式并且具有分号语句分隔的事实,那么我预测,(最终-可能很快)它将不再令人惊讶。


以上内容是您问题的直接答案。同样,请参见乔纳森的答案以获取更多信息。随意忽略此答案的其余部分。

对于此答案的其余部分,我使用“自由格式”来指代P6的自由格式语法,分号语句分隔和大括号({...})的组合。

此答案的其余部分分为三个部分:

  • 自由格式语法的P6例外

  • 自由格式vs面向行

  • 自由格式面向行?

自由格式语法的P6例外

@Larry总结说,在某些情况下,直觉,美观,方便和/或其他因素证明了标准P6中纯自由格式语法的例外。

如果满足以下条件,则语句可以省略结尾的分号

  • 是源文件或块中的最后一条语句;

  • 以一个结尾的块结尾,该块的结尾卷曲后跟换行符(忽略注释)。

因此下面的三个语句(if和两个say)都不需要以分号结尾:

if 42 {
  say 'no semicolon needed before the closing curly'
}    # no semicolon needed after the closing curly
say   'no semicolon needed if last statement in source file'

有时候这可能不是想要的:

{ ... }   # the closing } ends the statement (block)
.()       # call is invoked on $_

一种更改方法是使用括号:

({ ... })
.()       # calls the block on prior line

对于某些构造,空格是必需的或不允许的。例如,某些后缀必须直接跟随它们所应用的值,而某些后缀则不能。这些都是语法错误:

foo ++
foo«+»bar

自由格式vs面向行

对于某些编码方案,P6的自由格式语法可以说是强大的净肯定值,例如:

  • 一个衬里可以使用块;

  • FP代码是自然的(一个人可以编写非平凡的闭包);

  • 更直接的编辑/重构/复制/粘贴。

但是有缺点:

  • 自由格式语法(分号和大括号)的读写开销。

  • 无视可能导致您提出问题的直觉。

后者很有效。以下所有内容可能会使某人认为您的示例中的say是新语句的一部分,而不是$_ =语句的延续:

  • =之后的换行符;

  • 此后的空白行;

  • 相对于say行,在$_ =行的开头没有缩进;

  • say的性质(似乎say必须是新语句的开始)。

上述直觉的结果是某些编程语言采用"line-oriented" syntax而不是自由格式的语言,其中最著名的是Python。 1

自由格式面向行的语法

某些语言,例如Haskell,允许使用 面向行的自由格式语法(至少对于 some 语言构造而言)。

P6支持slangs,这是一种会改变语言的用户界面模块。想象一下同时支持自由格式面向行代码的语:

  • 那些学习P6的人在学习基于Pem的 面向行的自由格式代码以学习该语言的基础知识时,会遇到更多的熟悉和更少的惊喜;

  • 熟悉P6的人可以通过使用 面向行的自由格式语法编写更好的代码。

冒着使事情变得过于复杂的风险,想象一个既采用行定向又采用Python支持的the off-side rule的语,并为无类型的无sigil变量实现no strict;(它会删除声明符和嘲笑并促进不变性。这是几周前我在a reddit comment中发布的用想象的语编写的一些代码片段:

sub egg(bar)
  put bar

data = ["Iron man", "is", "Tony Stark"]
callbacks = []

也许上面的东西很难实现? (我目前不知道为什么。)

脚语

1 本节的其余部分使用Programming language statements上的Wikipedia部分作为指南来比较P6和Python:

  

语句分隔符用于划分两个单独的语句之间的边界。

在P6中,它是;或块末。

在Python中,;可用于单独的语句。但这主要是面向行的。

  

将行尾解释为语句结尾的语言称为“面向行”语言。

在Python中,除非适当地缩进了下一行(在这种情况下,这是相关子块的开始)或在行的末尾出现了显式的行继续符,否则行末会终止一条语句。

P6不是 面向行的。 (至少不是标准的P6。我将在此答案的末尾放置一个P6 s语,该语言同时支持自由格式和面向行的语法。)

  

“行继续”是面向行的语言的约定,它允许单个语句跨越多个行。

Python具有行继续功能;有关详细信息,请参见Wikipedia文章。

尽管不面向行,标准P6也具有行连续功能。 2

2 P6支持行继续。继续引用维基百科的话:

  

换行符通常会导致将令牌添加到令牌流中,除非检测到行连续。

(令牌是代码的最小片段-除了单个字符之外,解析器将其视为原子单位。)

如果标准P6遇到换行符,则总是假定令牌中断,唯一的例外是跨这样的行写入字符串:

say
'The
 quick
 fox';

这将编译OK,并在三行中分别显示Thequickfox

Python中的等效项将生成语法错误。

  

反斜杠作为行的最后一个字符

在P6中,反斜杠:

  • 不能出现在令牌的中间;

  • 可用于在解析器忽略的源代码中引入空格,以避免语法错误。例如:

        say @foo\
            »++
  • 实际上是"unspace"的更笼统的概念,可以在一行中的任何地方使用,而不仅仅是在结尾处使用
        say @foo\            »++
  

内联注释的某些形式可以作为行的延续

这有效:

say {;}#`( An embedded
comment ).signature

嵌入的评论:

  • 不能出现在令牌的中间;

  • 不像反斜杠那样普遍(say @foo#`[...]»++不起作用)。