如果False在Perl 6 REPL中产生一个空列表,为什么命令后?

Eug*_*sky 10 perl6

如果条件ifFalse,而不是空输出,则REPL给出()(空List?)

> put 1 if True
1
> put 1 if False
()               # ? What is this?
Run Code Online (Sandbox Code Playgroud)

什么()意思?

rai*_*iph 9

在这个无休止编辑的答案的早期版本中,我写道"REPL没有做任何特别的事情".但当然我错了.REPL评估一行代码.如果它生成输出,它会显示该输出,就是这样.如果没有,那say就是最后一个语句的值.见JJ的答案.

()你指的空单.

在这个答案的早期版本中,我同意你的说法,这是空的List.但当然我错了.在这种情况下它是一个亚型List.见布拉德的回答.)


可以说我最好删除这个答案.:)

以下是对这个答案可能有价值的东西,直到有人解释我还有什么错误...

Perl 6正在做什么

语句计算为值.

陈述可以只是一种表达.

表达式可以只是一个字面值:

> 42
42
Run Code Online (Sandbox Code Playgroud)

值的文字列表评估为List:

> 42, 99
(1 99)
Run Code Online (Sandbox Code Playgroud)

空列表显示为().这可能意味着空List:

> ()
()            # <-- empty `List`
> List.new
()            # <-- empty `List`
> 'aa' ~~ m:g/b/
()            # <-- empty `List`
Run Code Online (Sandbox Code Playgroud)

或者是一个子类型的空列表List,但它重用相同的字符串,例如Slip:

> Empty
()            # <-- empty `Slip`
> Slip.new
()            # <-- empty `Slip`
Run Code Online (Sandbox Code Playgroud)

语句还可以评估为单个值:

> if True { 42 }
42
Run Code Online (Sandbox Code Playgroud)

或列表:

> if True { 42, 99 }
(42 99)
Run Code Online (Sandbox Code Playgroud)

一些语句评估为空列表.你的问题是一个这样的例子:

> if False {}
()
Run Code Online (Sandbox Code Playgroud)

正如布拉德指出的那样,这是一个空洞Slip,特别是Empty实例.


Bra*_*ert 6

实际上你的问题是不正确的.

你真正得到的是一个空滑动.
具体来说,您将获得一个名为Empty的特定实例.


什么防滑的作用是将自身插入到外listy值.

say (1, 2, 3, (4, 5)).perl;
# (1, 2, 3, (4, 5))

say (1, 2, 3, (4, 5).Slip).perl;
# (1, 2, 3, 4, 5)
Run Code Online (Sandbox Code Playgroud)

Slip存在的原因是默认情况下Perl 6不会使值变平.

sub return-list () { 4, 5 }

say (1, 2, 3, return-list()).perl;
# (1, 2, 3, (4, 5))
Run Code Online (Sandbox Code Playgroud)

(在官方发布之前,它曾经在某些情况下使值变平,并且它既困惑又难以解决)

所以Slip的特性是在你确实希望它变平的情况下引入的.

sub return-slip () { slip 4, 5 }

say (1, 2, 3, return-slip()).perl;
# (1, 2, 3, 4, 5)
Run Code Online (Sandbox Code Playgroud)

请注意,它只进行一级展平.

sub return-structured-slip () {
   slip 4, (5,)
}

say (1, 2, 3, return-structured-slip()).perl;
# (1, 2, 3, 4, (5,))
Run Code Online (Sandbox Code Playgroud)

这对于grep作为map代码的一部分来说非常有用.

say (0..10).map: { $_, $_² if .is-prime }
# ((2 4) (3 9) (5 25) (7 49))
Run Code Online (Sandbox Code Playgroud)

它还可以用于在调用例程时保留值.

my $a;
my $b = 1;

say(
  ( $a.perl if $a ),
  ( $b.perl if $b ),
)
Run Code Online (Sandbox Code Playgroud)

单数Empty的一个有用功能是,您可以匹配它.

multi sub foo ($_){.say}
multi sub foo (Empty){ say 'Hello, World' }

foo Empty; # Hello, World

foo (1 if 0); # Hello, World
Run Code Online (Sandbox Code Playgroud)

请注意,可以获得不是单数值Empty的空Slip.在这种情况下,它将不匹配.

|()
().Slip
Run Code Online (Sandbox Code Playgroud)


wam*_*mba 5

返回值为empty Slip(Empty).尝试

 say {put 1 if False}() ~~ Empty
Run Code Online (Sandbox Code Playgroud)

您可以使用… if FalseEmptyList:

 dd (2..100).map: { $_² if .is-prime }
Run Code Online (Sandbox Code Playgroud)

同样,… with NilNil andthen …返回Empty.


jjm*_*elo 5

到目前为止,所有答案都非常好,解释了幕后发生的事情。但我会尝试直接回答你的问题。

\n\n
\n

如果 if 的条件为 False,则 REPL 给出 () (一个空列表?),而不是空输出

\n
\n\n

关键是您正在开发 REPL。如果有的话,REPL 会打印块的输出;如果没有输出,它将打印表达式返回的任何内容。然后让我们将您的两个选项作为块来处理;括号内的内容是您在 REPL 中实际输入的内容:

\n\n
say (put 1 if True).^name # OUTPUT: \xc2\xab1\xe2\x90\xa4Bool\xe2\x90\xa4\xc2\xbb\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是正确的。REPL 将看到输出1并打印它。块结果,True在这种情况下,因为这就是put返回的结果)被 REPL 删除。第二种情况会发生什么?

\n\n
say (put 1 if False).^name # OUTPUT: \xc2\xabSlip\xe2\x90\xa4\xc2\xbb\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这种情况下,没有输出。REPL 将(put 1 if False)作为一个表达式并打印(),在本例中是一个 Slip。正如 @raiph 的回答所示,这就是if False {}返回的内容,所以这就是您在 REPL 中得到的内容。

\n