Equivalent functions exist to apply all of the relational, logical and arithmetic operators described above,
as well as the math routines described in
Library Routines, to entire
sequences as
well as to single numbers (
atoms).
The sq_uminus() function applies the unary (one operand) minus operator to each element of a sequence to yield
a sequence of results of the same length. If one of these elements is itself a sequence then the same rule
is applied again recursively. e.g.
x = sq_uminus({1, 2, 3, {4, 5}}) -- x is {-1, -2, -3, {-4, -5}}
If a binary (two-operand) operator function is passed two sequences then
they must be of the same length. The binary operation is then
applied to corresponding elements taken from the two sequences to get a
sequence of results, with the function applied recursively if required. e.g.
x = sq_add({5, 6, 7, {8, 9}}, {10, 20, 30, {40, 50}}) -- x is {15, 26, 37, {48, 59}}
If a binary operator function is passed one sequence while the other parameter is a
single number (atom) then the single number is effectively repeated to
form a sequence of equal length to the sequence operand. The rules for
operating on two sequences then apply. Some examples:
x = sq_add({5, 6, 7, {8, 9}}, {10, 20, 30, 40}) -- x is {15, 26, 37, {48, 49}}
x = sq_add({5, 6, 7, {8, 9}}, 10) -- x is {15, 16, 17, {18, 19}}
x = {1, 2, 3}
y = {4, 5, 6}
w = sq_mul(5,y) -- w is {20, 25, 30}
z = sq_add(x,y) -- z is {5, 7, 9}
z = sq_lt(x,y) -- z is {1, 1, 1}
w = {{1, 2}, {3, 4}, {5}}
w = sq_mul(w,y) -- w is {{4, 8}, {15, 20}, {30}}
w = sq_and({1, 0, 0, 1},{1, 1, 1, 0}) -- {1, 0, 0, 0}
w = sq_not({1, 5, -2, 0, 0}) -- w is {0, 0, 0, 1, 1}
w = sq_eq({1, 2, 3},{1, 2, 4}) -- w is {1, 1, 0}
w = ({1, 2, 3} = {1, 2, 4}) -- w is 0 (a singular false)
The functions listed below accept either sequence or atom argument(s), unlike the "sq_"-less functions and infix operators which
only accept atoms (apart from the first two columns, however those infix operators/sq-less functions always yield a single boolean result).
You can find their actual implementations in builtins\psqop.e, which is automatically included when needed.
Compatibility Notes
|
RDS Euphoria and OpenEu allow implicit sequence ops whereas Phix requires explicit (functional style) sequence ops.
The simple choice is between infix sequence ops and infix comparison operators; try to have both and the syntax
collapses and/or becomes ambiguous. For example, assuming you need a boolean result, does the inner comparison in a
condition such as (tag="lx")=(flags="rw") reduce to equal(false,false)[T] or equal({1,0},{0,1})[F]?
It depends on how you treat the outer two "=": as sequence operators, or as equality operators.
Both interpretations could be perfectly reasonable, which would result in an ambiguous and
therefore fundamentally broken programming language.
In RDS and OpenEu you can write {1,2,3}+5, which tends to generate a compile time warning or runtime error
in Phix, however you cannot write conditions such as name="pete" and name1<name2 but must instead use
equal(name,"pete") and compare(name1,name2)<0, whereas all four forms are perfectly valid in Phix.
Analysis of existing source code revealed that comparison was far more common than infix sequence maths,
the latter averaging at just once per ten thousand lines of code(!).
Apart from upper/lower, which were horribly slow anyway, I found no other uses of infix sequence relational ops.
Hence the design decision was made that phix would allow infix comparison ops but require (the explicit)
sq_add({1,2,3},5) instead of (the implicit) {1,2,3}+5.
I fully accept that some_long_variable_name = sq_add(some_long_variable_name,1) is less elegant than
some_long_variable_name += 1, but I am just going to say
"yes, but you don't need equal() and compare() absolutely ****** everywhere!"
The phix compiler does a pretty reasonable job of identifying implicit infix operators that ought to be
explicit (function style) and issues "warning: sequence op (sq_xxx) assumed" messages. Particularly when
working with legacy RDS Eu/OpenEuphoria code, as you modify it to get rid of such warnings you should
take the opportunity to look nearby for any that the compiler might have missed.
|