Additional Details

 

 

1 Overload method tables

The overloaded operators from the ‘broadcast’ package attempts to mimic the base operators accurately, except that broadcasting is used (obviously).

The following tables overview the behaviour of the operators.

 

1.1 Regular Arithmetic operators

If both sides of the operators given here are numeric or logical, the following holds:

operator action functions like
+ add bc.d
- substract bc.d
* multiply bc.d
/ divide bc.d
^ raise to power bc.d
%/% floored integer divide bc.i
%% modulo bc.i

 

1.2 Complex Arithmetic operators

If at least one of the arguments of the operators given here are complex, the following holds:

operator action functions like
+ add bc.cplx
- substract bc.cplx
* multiply bc.cplx
/ divide bc.cplx

 

1.3 Logical Operators

If both sides of the operators given here are complex, numeric or logical, the following holds:

operator action functions like
& and bc.b
| or bc.b

 

1.4 Bit-wise operators

If both sides of the operators given here are type of raw, the following holds:

operator action functions like
& bit-wise and bc.bit
| bit-wise or bc.bit

 

1.5 Relational operators

For relational operators, ‘broadcast’ first finds the “highest” (or most complex) atomic type of both sides, coerces both sides to said type, and then performs the broadcasted relational operation. Recursive types are not supported.

The types, from complex to simple, are: character, complex, numeric (also known as double), integer, logical, and raw.

 

2 Compatibility with Custom Methods

Consider a classed vector like the following:

x <- 1:10
class(x) <- "someclass"
print(class(x))
#> [1] "someclass"

Setting a vector or array as a “broadcaster” using the broadcaster()<- function, will add the “broadcaster” class attribute;
but note that the “broadcaster” class will be placed last in the class attribute:

broadcaster(x) <- TRUE
print(class(x))
#> [1] "someclass"   "broadcaster"

Notice how the “broadcaster” class comes after the “someclass” class.

Let’s make a quick ’n dirty (and not at all smart) + method for “somceclass”, which will just print some text:

`+.someclass` <- function(e1, e2) {print("someclass method called")}

What will happen? Will the + method for the broadcaster be called, or the + method for “someclass”?
Well, since the “broadcaster” class is intentionally placed last, operator methods for the overriding classes will always “win” over the “broadcaster” class. In this case, if there are methods for the base operators (such as +, -, etc.) for the “someclass” class, the method for “someclass” will be called, rather than the broadcaster method:

y <- array(1:10, c(1, 10))
class(y) <- "someclass"
broadcaster(y) <- TRUE
x + y
#> [1] "someclass method called"
#> [1] "someclass method called"

Notice how the + method for “someclass” is called, rather than the + method for the broadcaster.

This ensures compatibility with custom classes.
After all, some classes may not be intended to be broadcasted, or they may not be compatible with the base ‘R’ way of arithmetic (which is what ‘broadcast’ mimics), or they may need careful handling of attributes.

Authors of these custom classes can make their methods use broadcasting if a broadcaster vector/array is detected, if they so choose; only they know what is appropriate for their classes and what isn’t.