Sean
Sean

Reputation: 29790

Math with undefined Perl6 values

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?

Upvotes: 11

Views: 174

Answers (1)

Elizabeth Mattijsen
Elizabeth Mattijsen

Reputation: 26969

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

Upvotes: 9

Related Questions