WhateverStar `&&` Perl 6 中的 WhateverStar

WhateverStar `&&` WhateverStar in Perl 6

* > 20 && * %% 5grep 中使用似乎是错误的,是否等于带有 2 个参数的 WhateverCode lambda?正如在

上解释的那样
> my @a = 1,12,15,20,25,30,35,37;

> @a.grep: * > 20 && * %% 5 # The result seems strange, expected (25 30 35)
(15 20 25 30 35)

> @a.grep: * %% 5 && * > 20
(25 30 35 37)

> @a.grep: { $_>20 && $_ %% 5 }
(25 30 35)

> @a.grep: all(* > 20, * %% 5)
(25 30 35)

> @a.grep: -> $a { all($a > 20, $a %% 5) }
(25 30 35)

> @a.grep: -> $a {$a > 20 && $a %% 5}
(25 30 35)

打高尔夫球

my &or  = * == 1 || * == 2 ;
my &and = * == 1 && * == 2 ;

say .signature, .(1), .(2)
  for &or, ∧

显示:

(;; $whatevercode_arg_1 is raw)TrueFalse
(;; $whatevercode_arg_4 is raw)FalseTrue

我仍然不知道发生了什么事[ed: 也就是说,我在写这一段的时候还不知道;随着谜团的展开],我保留了我在这个答案中写的内容],但很明显签名只是一个 arg,结果只是 &and 的右手表达式和 &and 的左手表达式=14=] 这意味着代码似乎没有,呃,结果是,呃,正确的。调查仍在继续......(不,我不是 det remiker)。

谜底已解

因此,看起来逻辑操作(&&||andor 等)不执行 Whatever -柯里化。考虑到 "not all operators and syntactic constructs curry * (or Whatever-stars) to WhateverCode",这很公平。考虑到它们的性质,甚至是合乎逻辑的。不过,它们可能应该添加到该页面的 table 异常中。

同时,== do Whatever curry 等运算符。同样,考虑到 "subexpressions may impose their own Whatever star rules".

,这很公平

所以 &or&and 变成...

是有道理的

啊哈!知道了。 * == 1* == 2 在编译时计算并变成 WhateverCode。作为 WhateverCodes 它们只是一些代码。它们被定义。他们是True。 (这忽略了在 运行 时调用它们。)然后是 && 并评估到右手 WhateverCode。 (|| 将计算为左手 WhateverCode。)

因此我们看到了行为。

一个解决方案

根据@HåkonHægland 的提示, 工作的代码因此是不依赖于逻辑运算 Whatever-currying 的代码,即:

my @a = 1,12,15,20,25,30,35,37;

say @a.grep: { $_ > 20 && $_ %% 5 } # (25 30 35)

现在怎么办?

现在我们必须弄清楚要建议的文档编辑...

实际上,在我们这样做之前,确认逻辑操作不应该 Whatever-curry...

为了开始滚动,我只是搜索了搜索 TimToady comments on #perl6 about "currying" 的结果(#perl6-dev 上有 none),寻找与我们的案例相关的结果这里。

首先,来自 2017 年的一篇可以说与任何文档编辑相关的文章:

the design docs actually try to avoid the word "currying" ... but it's hard to get people to use words differently than they do

接下来,2015 年的一篇关于 &&|| 等等:

|| and && and such are really control flow operators, turned rather rapidly into 'if' and 'unless' ... those ops can be curried with .assuming, I assume

最后是 2010 年的一对似乎也可能很重要(尽管可能有一个或多个不再适用?):

all operators autocurry a WhateverCode, whether or not they curry a Whatever

I think we can keep the current mechanism as a fallback for operators that still want to curry at run time

> my $d = * + * + * 
> $d.arity
3
> my $e = * == 1 || * == 2 || * == 3 
> $e.arity
1

正如 doc 所说:

Returns the minimum number of positional arguments that must be passed in order to call the code object.

所以我认为 * == 1 || * == 2 || * == 3 中的所有三颗星都是一样的。

> my $e = * == 1 && * == 2 && * > 3 
> $e(1)
False
> $e(2)
False
> $e(3)
False
> $e(4)
True