Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[] reduce with anonymous function in Perl 6

We can use reduce with a sub with two arguments, putting it in double brackets:

> sub mysum { $^a + $^b }
> [[&mysum]] 1,3,5
9

But what if we want to use an anonymous function instead?

Both following variants produce a compile error:

> [[&{ $^a + $^b }]] 1,3,5
> [[{ $^a + $^b }]] 1,3,5
like image 543
Eugene Barsky Avatar asked May 06 '18 21:05

Eugene Barsky


2 Answers

You are not allowed to have any spaces in that form of reduce.

> [[&({$^a+$^b})]] 1, 3, 5
9

This is so that it is more obvious that it is a reduce, and not an array declaration.

> [ { $^a + $^b }, { $^a * $^b } ].pick.(3,5)
8 | 15

The double [[…]] is just an extension of allowing any function to be used as an infix operator.

Note that you must use &(…) in this feature, when not talking about a named function &foo, or an already existing infix operator.

> 3 [&( { $^a + $^b } )] 5
8

This is sort-of an extension of using […] for bracketing meta operators like Z and =

> @a [Z[[+]=]] 1..5
> @a Z[[+]=] 1..5
> @a Z[+=] 1..5
> @a Z+= 1..5
like image 103
Brad Gilbert Avatar answered Oct 14 '22 01:10

Brad Gilbert


Not sure why that doesn't work. But there's always:

say reduce { $^a + $^b }, 1,3,5 # 9

I'm guessing you knew that but it's all I've got for tonight. :)

I've now moved my comment here and expanded it a bit before I go to sleep.

The TTIAR error means it fails to parse the reduce as a reduce. So I decided to take a quick gander at the Perl 6 grammar.

I searched for "reduce" and quickly deduced that it must be failing to match this regex.

While that regex might be only 20 or so lines long, and I recognize most of the constructs, it's clearly not trivial. I imagine there's a way to use Grammar::Debugger and/or some other grammar debugging tool with the Perl 6 grammar but I don't know it. In the meantime, you must be a bit of a regex whiz by now, so you tell me: why doesn't it match? :)

Update

With Brad's answer to your question as our guide, the answer to my question is instantly obvious. The first line of the regex proper (after the two variable declarations) directly corresponds to the "no spaces" rule that Brad revealed:

<?before '['\S+']'>

This is an assertion that the regex engine is positioned immediately before a string that's of the form [...] where the ... is one or more non-space characters. (\s means space, \S means non-space.)

(Of course, I'd have been utterly baffled why this non-space rule was there without Brad's answer.)

like image 38
raiph Avatar answered Oct 14 '22 02:10

raiph