I'm a little perplexed with how math works with undefined values. My Perl 5 intuition tells me that such values are equivalent to zero in most circumstances, for example:
> my $x
(Any)
> $x += 5
5
As expected.
> my $x
(Any)
> $x *= 3
3
Wait, what? Now it's as if the undefined value was interpreted as 1
.
I know that Perl6 has some notion of the identity element for some operators:
> [*] ()
1
Maybe multiplying an undefined value is related to that somehow...?
How does this work, exactly?
Operators are just (multi) subs with special names. The behaviour you see is because &infix:<*>
(the name of the sub for *
) has a no-argument and a one argument candidate:
$ perl6 -e 'say infix:<*>()'
1
$ perl6 -e 'say infix:<*>(42)'
42
$ perl6 -e 'say infix:<*>(6,7)'
42
When you do [*] ()
, you hit the no-argument candidate. This works similarly for other infixes:
$ perl6 -e 'say infix:<+>()'
0
$ perl6 -e 'say infix:<+>(666)'
666
For some operators, like /
, this does not work:
$ perl6 -e 'say infix:</>()'
No zero-arg meaning for infix:</>
But that is to be expected, mathematically speaking :-)
Getting back to the *=
: metaops are essentially taking the operator and create a new operator (Callable
) out of that. So, in this example, +=
, basically does sub metaop(&op) {(-> \a, \b { a = a.DEFINITE ?? op(a,b) !! op(b) } }; metaop([+])($x,3)
. Note that a special check is added for the first parameter (aka the left hand side) to handle the case it is undefined. That's why there is no warning there. So it is pretty deliberate, otherwise the generated code would have been -> \a, \b { a = op(a,b) }
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