This is because &infix:<∈>
is a multi, while &infix:<∉>
is not:
$ perl6 -e '&infix:<∈>.candidates.head.multi.say'
True
$ perl6 -e '&infix:<∉>.candidates.head.multi.say'
False
When you defined your multi &infix:<∉>
, you shadowed only &infix:<∉>
from core, and that's why you see only your candidate.
We can probably detect such a situation and require the user to provide explicit proto
to clarify what they meant. I filed that as R#1530. And I'd say such differences that one op is a multi
while another is an only
is part of a larger issue of having consistent core; I added it as a comment on RT#130020 and mentioned the problem in our docs on D#1783.
You could define your custom op like so (if the suggestion in R#1530
is implemented, the proto
would be required; currently it isn't):
proto infix:<∉> (|) {*}
multi infix:<∉> ($a, Complement:D $c) { $a ∈ $c.set }
multi infix:<∉> (|c) { &CORE::infix:<∉>(|c) }
I can only guess what you're trying to code, but thought I'd mention it, for you to account for it in your creation: negated ops are defined as not A (op) B
, not A (not(op)) B
. This small difference has impact when it comes to Junctions
:
$ perl6 -e 'say 2 ≠ 2|4'
False
If it were defined as a negated op applied to each operand, the above would be equivalent to (2 ≠ 2 or 2 ≠ 4)
and would always be True
, which is often not what the programmer would've meant, hence why it's instead computed as not (2 == 2 or 2 == 4)
To reply to Jarrod's comments on OP: subs (including grammar mutations done by declaring custom operators) are lexical, so if you wrapped the declaration into a BEGIN
block, the custom op will be scoped to just that block.
And the reason it appeared to work in REPL is because there's actually a bug (RT#131900) where custom ops are lost between REPL lines, so just as with the BEGIN
block, by the time the call came with args destined to the core candidates, the custom multi was no longer in scope.
multi infix:<∉>
is now also a multi in core. – Hadrian