Mapped operators
SPL takes inspiration from Matlab and supports auto-vectorization or mapping of expression operators to work over lists and maps.
There are two kinds of mapped operators: non-dotted and
dotted. Non-dotted binary operators such as *
, +=
,
or -
are mapped if one operand is a scalar and the
other a list or map. Here are some examples:
void test() {
mutable list<int32> ls = [1, 2, 3];
ls = 2 * ls; // 2 * [1, 2, 3] == [2, 4, 6]
ls += 2; // [2, 4, 6] + 2 == [4, 6, 8]
ls = ls - 1; // [4, 6, 8] - 1 == [3, 5, 7]
mutable map<rstring, int32> mp = {"x":1, "y":2};
mp = 2 * mp; // 2 * {"x":1, "y":2} == {"x":2, "y":4}
mp += 2; // {"x":2, "y":4} + 2 == {"x":4, "y":6}
mp = mp - 1; // {"x":4, "y":6} - 1 == {"x":3, "y":5}
}
SPL also supports dotted mapped operators such as .+
or .*
.
If both operands are equal-length lists or maps with the same key
set, the dotted operators work on corresponding pairs of elements
at a time. For example:
[3,2] .* [5,4] == [3*5, 2*4] == [15,8] // multiply two lists
{"x":4, "y":6} .- {"x":3, "y":1} == {"x":1, "y":5} // subtract two maps
If the operands are lists of different sizes or maps with different key sets, the mapped operator triggers a runtime error. Dotted operators have the same precedence as their non-dotted counterparts.
Dotted operators | Description |
---|---|
.* ./ .% |
Mapped multiplication, division, remainder |
.+ .- |
Mapped addition, subtraction |
.<< .>> |
Mapped bitwise left-shift, right-shift |
.< .<= .> .>= .!= .== |
Mapped comparison |
.& |
Mapped and |
.^ |
Mapped xor |
.| |
Mapped or |
Mapped operators unwrap only a single dimension. For example, 2
* [[1,2],[3,4]]
is not supported, and neither is [[1,2],[3,4]]
.* [[5,6],[7,8]]
, because they both must unwrap multiple
dimensions of lists before the operators are applicable.