Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot overload logical operators (or, and) for my class

I was trying to overload the logical or operator for a custom class, but it doesn't seem to work. This is what I do:

class A { has $.a }
multi sub infix:<or> (A $a, A $b) {
    "works!({$a.a}, {$b.a})"
}
say A.new(:1a) or A.new(:2a); 

I'm expecting to get works!(1, 2) as output, but instead I get A.new(a => 1), which is the result of the standard or operator.

Other operators (except for and and xor), seem to work for me:

class A { has $.a }
multi sub infix:<anything-else> (A $a, A $b) {
    "works!({$a.a}, {$b.a})"
}
say A.new(:1a) anything-else A.new(:2a); 

results in works!(1, 2).

Am I doing something wrong or is there just no way to overload the standard or,and,xor operators?

like image 405
gmoshkin Avatar asked Jul 08 '19 19:07

gmoshkin


People also ask

Which operator we Cannot overload?

You cannot overload the following operators: . You cannot overload the preprocessor symbols # and ## . An operator function can be either a nonstatic member function, or a nonmember function with at least one parameter that has class, reference to class, enumeration, or reference to enumeration type.

Can logical operators be overloaded?

The conditional logical operators cannot be overloaded.

Which operators Cannot be overloaded and why?

Operators that cannot be overloaded in C++ For an example the sizeof operator returns the size of the object or datatype as an operand. This is evaluated by the compiler. It cannot be evaluated during runtime. So we cannot overload it.


1 Answers

Only operators that compile into a subroutine call may be overloaded. Since subroutine calls have their arguments evaluated prior to the call being made, those operators that require delayed evaluation of one of their operands are handled as special forms in the compiler.

The logical operators, like and, or, &&, and ||, are specified as only evaluating their second operand depending on the truthiness of their first operand, and so cannot be compiled into subroutine calls.

Even if they were to compile into a subroutine call that thunked the second operand, a multiple dispatch as written in the question would still not be possible on the type of the second argument, since the semantics of these operators mean we can't evaluate it right away, but that in turn means we can't find its type in order to do the dispatch.

like image 199
Jonathan Worthington Avatar answered Sep 29 '22 14:09

Jonathan Worthington