The last line here results in a incorrect signature to the map call:
my @array=[0,1,2];
say "String Repetition";
say @array.map({($_ x 2)});
say @array.map: * x 2;
say "\nCross product ";
say @array.map({($_ X 2)});
say @array.map: * X 2;
say "\nList Repetition";
say @array.map({$_ xx 2});
say @array.map: * xx 2;
The output being:
String Repetition
(00 11 22)
(00 11 22)
Cross product
(((0 2)) ((1 2)) ((2 2)))
(((0 2)) ((1 2)) ((2 2)))
List Repetition
((0 0) (1 1) (2 2))
Cannot resolve caller map(Array:D: Seq:D); none of these signatures match:
($: Hash \h, *%_)
(\SELF: █; :$label, :$item, *%_)
The x operator returns a Str, the X returns a List of Lists and the xx return a List.
Is this changed somehow using the Whatever. Why is this error happening? Thanks in advance
Let me see if I can get this through clearly. If I don't, please ask.
Short answer: xx
has a special meaning together with Whatever
, so it's not creating a WhateverCode
as in the rest of the examples.
Let's see if I can get this straight with the long answer.
First, definitions. * is called Whatever
. It's generally used in situations in which it's curried
I'm not too happy with this name, which points at functional-language-currying, but does not seem to be used in that sense, but in the sense of stewing or baking. Anyway.
Currying it turns it into WhateverCode
. So an * by itself is Whatever, * with some stuff is WhateverCode, creating a block out of thin air.
However, that does not happen automatically, because some times we need Whatever just be Whatever. You have a few exceptions listed on Whatever
documentation. One of them is using xx
, because xx
together with Whatever
should create infinite lists.
But that's not what I'm doing, you can say. *
is in front of the number to multiply. Well, yes. But this code in Actions.nqp (which generates code from the source) refers to infix xx
. So it does not really matter.
So, back to the short answer: you can't always use *
together with other elements to create code. Some operators, such as that one, .. or ... will have special meaning in the proximity of *, so you'll need to use something else, like placeholder arguments.
The xx
operator is “thunky”.
say( rand xx 2 );
# (0.7080396712923503 0.3938678220039854)
Notice that rand
got executed twice. x
and X
don't do that.
say( rand x 2 );
0.133525574759261740.13352557475926174
say( rand X 1,2 );
((0.2969453468495996 1) (0.2969453468495996 2))
That is xx
sees each side as something sort of like a lambda on their own.
(A “thunk”)
say (* + 1 xx 2);
# ({ ... } { ... })
say (* + 1 xx 2)».(5);
# (6 6)
So you get a sequence of *
repeated twice.
say (* xx 2).map: {.^name}
# (Whatever Whatever)
(The term *
, is an instance of Whatever)
This also means that you can't create a WhateverCode closure with &&
/ and
, ||
/ or
, ^^
/ xor
, or //
.
say (* && 1);
# 1
Note that *
also does something different on the right side of xx
.
It creates an infinite sequence.
say ( 2 xx * ).head(20);
# (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
If xx
wasn't “thunky”, then this would also have created a WhateverCode lambda.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With