WhwhatStar `&&` WhwhatStar в Perl 6 - PullRequest
0 голосов
/ 10 мая 2018

* > 20 && * %% 5, используемый в grep, кажется неправильным, равно ли лямбда-коэффициенту WheverCode, принимающему 2 аргумента?Как это объяснить на SO

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

Ответы [ 2 ]

0 голосов
/ 10 мая 2018
> my $d = * + * + * 
> $d.arity
3
> my $e = * == 1 || * == 2 || * == 3 
> $e.arity
1

как документ сказать:

Возвращает минимальное количество позиционных аргументов, которое должно быть передано для вызова объекта кода.

поэтому я думаю, что все три звезды в * == 1 || * == 2 || * == 3 - это одно и то же.

> my $e = * == 1 && * == 2 && * > 3 
> $e(1)
False
> $e(2)
False
> $e(3)
False
> $e(4)
True
0 голосов
/ 10 мая 2018

Golfed

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

Я до сих пор не знаю, что происходит, но ясно, что подпись только для одного аргумента, и результат соответствует только правому выражению для &and и левой руке для &or, который означает, что код, похоже, не оставил результат, то есть, верно. Расследование продолжается ... (и нет, я не det remiker).

Тайна разгадана

Итак, похоже, что логические операции (&&, ||, and, or и т. Д.) Не выполняют Whatever -скорость. Что достаточно справедливо, учитывая, что "не все операторы и синтаксические конструкции карри * (или Whatever -звезд) до WhateverCode" . Даже логично, учитывая их природу. Однако, вероятно, их следует добавить в таблицу исключений на этой странице.

Тем временем операторы типа == do Whatever curry. Опять же, это справедливо, учитывая, что «подвыражения могут навязывать свои собственные правила Звезды» .

Так что имеет смысл, что &or и &and превращаются в ...

Aha! Понял. * == 1 и * == 2 вычисляются во время компиляции и превращаются в WhateverCode с. Как WhateverCode s, они просто биты кода. Они определены. Они True. (Это игнорирует вызов их во время выполнения.) Затем идет && и оценивается справа WhateverCode. (|| будет соответствовать левой руке WhateverCode.)

Отсюда и поведение, которое мы видим.

Решение

В соответствии с запросом @ HåkonHægland код, который будет работать , является, следовательно, кодом, который не полагается на логическое выполнение операций Whatever, то есть:

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

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

Что теперь?

Теперь мы должны выяснить, какие правки документов предложить ...

На самом деле, прежде чем мы это сделаем, подтвердите, что логические операции не должны Whatever -curry ...

И чтобы начать этот шарик, я просто просмотрел результаты поиска TimToady комментариев к # perl6 о "curry" (не было ни одного на # perl6-dev) в поисках уместно в случае у нас здесь.

Во-первых, один из 2017 года, который, возможно, имеет отношение к любым правкам документов:

дизайнерские документы на самом деле стараются избегать слова "карри" ... но трудно заставить людей использовать слова иначе, чем они делают

Далее, один из 2015 о && и || и такие:

|| и && и тому подобное - действительно операторы потока управления, довольно быстро превращенные в «если» и «если» ... эти операции могут быть каррированы с помощью .assuming, я полагаю

И, наконец, пара из 2010 года, которая также кажется потенциально важной (хотя, возможно, одна или несколько больше не применимы?):

все операторы autocurry a WhateverCode, независимо от того, карри они или нет Whatever

Я думаю, что мы можем сохранить текущий механизм в качестве запасного варианта для операторов, которые все еще хотят карри во время выполнения

...