Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Math with undefined Perl6 values

Tags:

raku

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?

like image 220
Sean Avatar asked Jul 25 '19 22:07

Sean


1 Answers

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

like image 62
Elizabeth Mattijsen Avatar answered Nov 12 '22 15:11

Elizabeth Mattijsen