ATM I follow the latter (fourth) approach. My operators are therefore in order (high to low)
1. Address manipulations (as in the other recent thread)
2. Bit-pattern manipulation (&, !, etc)
3. Arithmetic manipulation (+, *, etc)
4. Comparisons (<, !=, etc)
5. Logical manipulation (AND, NOT, etc)
Here's a postulation which doesn't need a reply but you might find it interesting....
I /suggest/ that in expressions as used in programming languages there
is a natural sequence in which values are transformed by the operators -
and that most languages don't follow it!
The sequence is:
1. Addresses
2. Bit patterns
3. Numbers
4. Boolean
As I say, no need to reply. The above is just my rationale for ordering precedences as I have them.
On 08/11/2021 11:21, James Harris wrote:
Here's a postulation which doesn't need a reply but you might find it...
interesting.
I /suggest/ that in expressions as used in programming languages there
is a natural sequence in which values are transformed by the operators
- and that most languages don't follow it!
The sequence is:
1. Addresses
2. Bit patterns
3. Numbers
4. Boolean
As I say, no need to reply. The above is just my rationale for
ordering precedences as I have them.
You're precedences should depend on type?
On 2021-11-08 12:21, James Harris wrote:
ATM I follow the latter (fourth) approach. My operators are therefore
in order (high to low)
1. Address manipulations (as in the other recent thread)
2. Bit-pattern manipulation (&, !, etc)
3. Arithmetic manipulation (+, *, etc)
4. Comparisons (<, !=, etc)
5. Logical manipulation (AND, NOT, etc)
Makes little to no sense.
The precedence rules usually distinguish unary and dyadic operators,
because that is what the reader expects.
The unary operators almost always have a higher precedence.
Which is why
your rules make no sense in the first place:
A + not B
is never
not (A + B)
and
A * -B
is never
- (A * B)
And
- not A
is never
not (-A)
should "not" really had lower precedence than "-".
"not" and "-" have same precedence.
[Mixing prefix and suffix unary operators is fun!]
The exception from the rule are dyadic meta-operators like member
extraction etc. They have the highest precedence (and are "meta" because
some operands are not expressions, normally).
not A.B
means
not (A.B)
While
A.not B
is illegal, because here "not B" is an expression.
Then "+" and "*" never have same precedence in any sane language.
The natural precedence used by sane languages:
1. Namespace, member extraction A.B[C] means "[]"("."(A,B),C)
2. Indexing
3. Unary operators, prefix are right-to-left, suffix are left-to-right
4. Dyadic operators
4.1. Exponentiation (**)
4.2. Multiplicative (*, /)
4.3. Additive (+, -)
4.4. Comparisons (<, >, =)
4.5. Lattice (and, or, xor)
4.1 would conflict with 3 for most readers with background in mathematics:
-A**B
So 4.1 is almost like 3.
If you wanted assignment operator, it should have asymmetric precedence:
A + B := C + D
is expected to be
A + (B := (C + D))
Same is true for exponentiation operator. Most people would read
A**B**C
as
A**(B**C)
Splitting lattice operations into logical and bit-wise is controversial.
You would need two sets of and/or/not operators.
If you want to mix "and" with "or" as C allows for && and ||, then "and"
is an equivalent of "*" and "or" is of "+". Compare:
x * 0 = 0 x and 0 = 0
x + 0 = x x or 0 = x
So you could put bit-wise "and" into multiplicative and "or" into
additive operators.
But as I said it is rather controversial. I would
just forbid mixing arithmetic and lattice operators.
On 2021-11-08 16:39, James Harris wrote:
(using ^ for exponentiation) because ^ has higher precedence than
prefix unary minus. Your mathematicians should be happy. :-)
Traditionally in mathematics circumflex (hat) means something like
"vector".
Using it for exponentiation was one of so many C's blunders.
On 08/11/2021 12:29, Dmitry A. Kazakov wrote:
On 2021-11-08 12:21, James Harris wrote:
ATM I follow the latter (fourth) approach. My operators are therefore
in order (high to low)
1. Address manipulations (as in the other recent thread)
2. Bit-pattern manipulation (&, !, etc)
3. Arithmetic manipulation (+, *, etc)
4. Comparisons (<, !=, etc)
5. Logical manipulation (AND, NOT, etc)
Makes little to no sense.
I'm glad you think so.
;-)
The precedence rules usually distinguish unary and dyadic operators,
because that is what the reader expects.
The unary operators almost always have a higher precedence.
"Almost always"?!
Which is why your rules make no sense in the first place:
A + not B
is never
not (A + B)
and
A * -B
is never
- (A * B)
And
- not A
is never
not (-A)
Those are strange examples. You say they'd never match but I wouldn't
expect them to.
should "not" really had lower precedence than "-".
Well, think of
not A > B
not A <= - F()
The exception from the rule are dyadic meta-operators like member
extraction etc. They have the highest precedence (and are "meta"
because some operands are not expressions, normally).
Exceptions to rules and special 'meta' forms? Has your account been
hijacked, Dmitry? I remember you calling Bart's parsing a "mess" for
similar.
The natural precedence used by sane languages:
1. Namespace, member extraction A.B[C] means "[]"("."(A,B),C)
2. Indexing
Why split namespace and indexing when the operations can be mixed
freely? E.g.
X[i].field.subfield[j].datum
3. Unary operators, prefix are right-to-left, suffix are left-to-right
Are you saying you would put logical NOT in there because it's unary?
4. Dyadic operators
4.1. Exponentiation (**)
4.2. Multiplicative (*, /)
4.3. Additive (+, -)
4.4. Comparisons (<, >, =)
4.5. Lattice (and, or, xor)
Most of those are standard. I have
^ exponentiation
+- monadic plus and minus
*/ times, divide, remainder etc
+- dyadic plus and minus
... all the comparison operators with one precedence
... all the boolean operators with their own precedences
4.1 would conflict with 3 for most readers with background in
mathematics:
-A**B
I would parse that 'correctly' as
- (A ^ B)
(using ^ for exponentiation) because ^ has higher precedence than prefix unary minus. Your mathematicians should be happy. :-)
So 4.1 is almost like 3.
If you wanted assignment operator, it should have asymmetric precedence:
A + B := C + D
is expected to be
A + (B := (C + D))
Same is true for exponentiation operator. Most people would read
A**B**C
as
A**(B**C)
That's how I would parse it - right to left. I think that exponentiation
is the only operator in my entire table which is right-to-left.
Splitting lattice operations into logical and bit-wise is
controversial. You would need two sets of and/or/not operators.
That's no problem. I use symbols for bitwise and words for booleans. For consistency they both follow the same order: not, and, xor, or.
In order of application they would be:
Bitwise:
<< >> shifts
! bitnot
& bitand
% bitxor
# bitor
Then, later:
Boolean
not logical not
and logical and (shortcutting)
xor logical xor
or logical or (shortcutting)
If you want to mix "and" with "or" as C allows for && and ||, then
"and" is an equivalent of "*" and "or" is of "+". Compare:
x * 0 = 0 x and 0 = 0
x + 0 = x x or 0 = x
So you could put bit-wise "and" into multiplicative and "or" into
additive operators.
Sounds as though you and Bart are on the same page on taking a
structural approach to precedences rather than a semantic one.
But as I said it is rather controversial. I would just forbid mixing
arithmetic and lattice operators.
Fine. Though what would a programmer do if he had a genuine need to
'mix' them?
On 08/11/2021 16:37, Dmitry A. Kazakov wrote:
On 2021-11-08 16:39, James Harris wrote:
(using ^ for exponentiation) because ^ has higher precedence than
prefix unary minus. Your mathematicians should be happy. :-)
Traditionally in mathematics circumflex (hat) means something like
"vector".
Unit-vectors IIRC. But that was applied over the variable.
Perhaps ^ was supposed to look like an up-arrow:
https://en.wikipedia.org/wiki/Knuth%27s_up-arrow_notation
But I don't know where using it for power-of originated. I use ^ to mean pointer dereference, taken from Pascal.
On 2021-11-08 17:58, Bart wrote:
But I don't know where using it for power-of originated. I use ^ to
mean pointer dereference, taken from Pascal.
I prefer implicit dereference.
On 08/11/2021 17:36, Dmitry A. Kazakov wrote:
On 2021-11-08 17:58, Bart wrote:
...
But I don't know where using it for power-of originated. I use ^ to
mean pointer dereference, taken from Pascal.
I prefer implicit dereference.
If pointers are implicitly dereferenced what do you do when you want to
get the pointer's value?
On 2021-11-08 16:39, James Harris wrote:
On 08/11/2021 12:29, Dmitry A. Kazakov wrote:
On 2021-11-08 12:21, James Harris wrote:
ATM I follow the latter (fourth) approach. My operators are
therefore in order (high to low)
1. Address manipulations (as in the other recent thread)
2. Bit-pattern manipulation (&, !, etc)
3. Arithmetic manipulation (+, *, etc)
4. Comparisons (<, !=, etc)
5. Logical manipulation (AND, NOT, etc)
Which is why your rules make no sense in the first place:
A + not B
is never
not (A + B)
and
A * -B
is never
- (A * B)
And
- not A
is never
not (-A)
Those are strange examples. You say they'd never match but I wouldn't
expect them to.
These are examples why unary operation should have higher precedence.
should "not" really had lower precedence than "-".
Well, think of
not A > B
not A <= - F()
Even when not is bit-wise?
not A + B * C + D
And you have the problem of mixing unary operators having different precedence:
- not A
E.g. in
- not A + B * C + D
It is inconsistent.
The natural precedence used by sane languages:
1. Namespace, member extraction A.B[C] means "[]"("."(A,B),C)
2. Indexing
Why split namespace and indexing when the operations can be mixed
freely? E.g.
X[i].field.subfield[j].datum
Compare:
field.subfield[j] ---> (field.subfield)[j]
with
field+subfield[j] ---> field + (subfield[j])
4. Dyadic operators
4.1. Exponentiation (**)
4.2. Multiplicative (*, /)
4.3. Additive (+, -)
4.4. Comparisons (<, >, =)
4.5. Lattice (and, or, xor)
Most of those are standard. I have
^ exponentiation
+- monadic plus and minus
*/ times, divide, remainder etc
+- dyadic plus and minus
... all the comparison operators with one precedence
... all the boolean operators with their own precedences
4.1 would conflict with 3 for most readers with background in
mathematics:
-A**B
I would parse that 'correctly' as
- (A ^ B)
To me it is not obvious, why not
(-A) ^ B?
And the counter example is this:
A ^ -B
If ^ preceded -, then that should too become
-(A ^ B)
My choice would be allow
A ^ -B ---> A ^ (-B)
-A ^ B ---> Syntax error, give me parenthesis.
So, unary always precedes dyadic, except the metas.
A**(B**C)
That's how I would parse it - right to left. I think that
exponentiation is the only operator in my entire table which is
right-to-left.
You could have pipelining operators:
"Buddy" >> Wide_Space >> "Hello" >> Stream
Also all prefix operators are right-to-left. Consider this:
* not 0x000FF0
(machine address inverted and then accessed)
Do you really want it to mutate into:
not (*X)
?
But as I said it is rather controversial. I would just forbid mixing
arithmetic and lattice operators.
Fine. Though what would a programmer do if he had a genuine need to
'mix' them?
Require disambiguation per parenthesis.
On 08/11/2021 16:37, Dmitry A. Kazakov wrote:
On 2021-11-08 16:39, James Harris wrote:
On 08/11/2021 12:29, Dmitry A. Kazakov wrote:
On 2021-11-08 12:21, James Harris wrote:
ATM I follow the latter (fourth) approach. My operators are
therefore in order (high to low)
1. Address manipulations (as in the other recent thread)
2. Bit-pattern manipulation (&, !, etc)
3. Arithmetic manipulation (+, *, etc)
4. Comparisons (<, !=, etc)
5. Logical manipulation (AND, NOT, etc)
...
Which is why your rules make no sense in the first place:
A + not B
is never
not (A + B)
and
A * -B
is never
- (A * B)
And
- not A
is never
not (-A)
Those are strange examples. You say they'd never match but I wouldn't
expect them to.
These are examples why unary operation should have higher precedence.
AFAICS having higher precedence does not mean rewriting the expression
with the operators in a different order! Take your first one, A + not B.
I would parse that as
A + (not B)
The natural precedence used by sane languages:
1. Namespace, member extraction A.B[C] means "[]"("."(A,B),C)
2. Indexing
Why split namespace and indexing when the operations can be mixed
freely? E.g.
X[i].field.subfield[j].datum
Compare:
field.subfield[j] ---> (field.subfield)[j]
with
field+subfield[j] ---> field + (subfield[j])
Arithmetic + is neither namespace nor indexing so I don't see the point.
...
4. Dyadic operators
4.1. Exponentiation (**)
4.2. Multiplicative (*, /)
4.3. Additive (+, -)
4.4. Comparisons (<, >, =)
4.5. Lattice (and, or, xor)
Most of those are standard. I have
^ exponentiation
+- monadic plus and minus
*/ times, divide, remainder etc
+- dyadic plus and minus
... all the comparison operators with one precedence
... all the boolean operators with their own precedences
4.1 would conflict with 3 for most readers with background in
mathematics:
-A**B
I would parse that 'correctly' as
- (A ^ B)
To me it is not obvious, why not
(-A) ^ B?
Three reasons:
1. Because ^ has higher precedence than unary minus.
2. Because that's the ordering used in maths.
3. Because the sign will be lost if raised to an even power.
My choice would be allow
A ^ -B ---> A ^ (-B)
-A ^ B ---> Syntax error, give me parenthesis.
I do the first. The second is - (A ^ B). Not sure why you would want
that to be a syntax error.
So, unary always precedes dyadic, except the metas.
Understood but 'metas' such as . ( [ * and & can be normal operators. No
need to parse them separately.
A**(B**C)
That's how I would parse it - right to left. I think that
exponentiation is the only operator in my entire table which is
right-to-left.
You could have pipelining operators:
"Buddy" >> Wide_Space >> "Hello" >> Stream
I don't know what they are but it doesn't matter.
I can make any
operator right associative just by making its precedence an odd number.
Fine. Though what would a programmer do if he had a genuine need to
'mix' them?
Require disambiguation per parenthesis.
Do you mean so that
A + B and C - D
would become either
(A + B) and (C - D)
or
A + (B and C) - D
On 2021-11-08 22:12, James Harris wrote:
On 08/11/2021 17:36, Dmitry A. Kazakov wrote:
On 2021-11-08 17:58, Bart wrote:
...
But I don't know where using it for power-of originated. I use ^ to
mean pointer dereference, taken from Pascal.
I prefer implicit dereference.
If pointers are implicitly dereferenced what do you do when you want
to get the pointer's value?
Nothing dramatic. When the target has the pointer type then that is the pointer's value. When the target has the target type then that is dereferencing.
The problems arise with type inference or bottom-up stuff you and Bart promote. But I want none of these.
On 08/11/2021 21:54, Dmitry A. Kazakov wrote:
On 2021-11-08 22:12, James Harris wrote:
On 08/11/2021 17:36, Dmitry A. Kazakov wrote:
On 2021-11-08 17:58, Bart wrote:
...
But I don't know where using it for power-of originated. I use ^ to
mean pointer dereference, taken from Pascal.
I prefer implicit dereference.
If pointers are implicitly dereferenced what do you do when you want
to get the pointer's value?
Nothing dramatic. When the target has the pointer type then that is
the pointer's value. When the target has the target type then that is
dereferencing.
The problems arise with type inference or bottom-up stuff you and Bart
promote. But I want none of these.
I don't follow. If n is a reference or pointer to a node then I presume
you want to refer to the node as
n
but what if you want the value of n, e.g. to print it, rather than the
value of the node it points at?
On 2021-11-08 23:55, James Harris wrote:
On 08/11/2021 16:37, Dmitry A. Kazakov wrote:
On 2021-11-08 16:39, James Harris wrote:
On 08/11/2021 12:29, Dmitry A. Kazakov wrote:
The natural precedence used by sane languages:
1. Namespace, member extraction A.B[C] means "[]"("."(A,B),C)
2. Indexing
Why split namespace and indexing when the operations can be mixed
freely? E.g.
X[i].field.subfield[j].datum
Compare:
field.subfield[j] ---> (field.subfield)[j]
with
field+subfield[j] ---> field + (subfield[j])
Arithmetic + is neither namespace nor indexing so I don't see the point.
The point is that "." has a higher precedence than [] and "+" has a
lower one. You cannot have them in the same class.
On 09/11/2021 08:51, Dmitry A. Kazakov wrote:
On 2021-11-08 23:55, James Harris wrote:
On 08/11/2021 16:37, Dmitry A. Kazakov wrote:
On 2021-11-08 16:39, James Harris wrote:
On 08/11/2021 12:29, Dmitry A. Kazakov wrote:
...
The natural precedence used by sane languages:
1. Namespace, member extraction A.B[C] means "[]"("."(A,B),C)
2. Indexing
Why split namespace and indexing when the operations can be mixed
freely? E.g.
X[i].field.subfield[j].datum
Compare:
field.subfield[j] ---> (field.subfield)[j]
with
field+subfield[j] ---> field + (subfield[j])
Arithmetic + is neither namespace nor indexing so I don't see the point.
The point is that "." has a higher precedence than [] and "+" has a
lower one. You cannot have them in the same class.
In your example both . and [] have higher precedence than + so + is irrelevant to whether . and [] should be in the same or different
precedence levels. Further, both . and [] are postfix.
Therefore you
could have a chain of them such as
<OP> X.field1[i].field2[j].field3[k]
and that chain will extend for as long as the precedence of . or [] is
higher than the precedence of the operator to the left variable X which
I've called <OP>. Now, if . and [] have higher precedence than all
others which could appear to the left of the variable name (which in
your scheme they do) then however long the chain is all of it will be
applied before <OP>.
? "." is obviously dyadic. [] is not an operator.
There is no such thing as "same" precedence, in the end you must always decide which one takes over:
A.B[C] "." takes precedence over []
A+B[C] [] takes precedence over +
On the second thought, you could argue that . and [] have same "base precedence" combined with the left-to-right rule like in the case of "+"
and "-". That should work, I guess.
But OK, I think one could put them together as long left-to-right holds.
On 2021-11-08 23:55, James Harris wrote:
On 08/11/2021 16:37, Dmitry A. Kazakov wrote:
On 2021-11-08 16:39, James Harris wrote:
On 08/11/2021 12:29, Dmitry A. Kazakov wrote:
These are examples why unary operation should have higher precedence.
AFAICS having higher precedence does not mean rewriting the expression
with the operators in a different order! Take your first one, A + not
B. I would parse that as
A + (not B)
I see the source of confusion.
You want to have the precedence on the
right side of "not" very low, but the one on the left side is very high.
That gives you:
A + not B + C ---> A + (not (B + C))
When *both* sides are low, the result is
A + not B + C ---> not ((A + B) + C)
-A**B
I would parse that 'correctly' as
- (A ^ B)
To me it is not obvious, why not
(-A) ^ B?
Three reasons:
1. Because ^ has higher precedence than unary minus.
But sir, it has a lower precedence! (:-))
2. Because that's the ordering used in maths.
Well, in mathematics it would be
-Aᵇ
There is no confusion because B is in superscript.
3. Because the sign will be lost if raised to an even power.
B looks very uneven today. (:-))
On 2021-11-09 12:02, James Harris wrote:
On 08/11/2021 21:54, Dmitry A. Kazakov wrote:
On 2021-11-08 22:12, James Harris wrote:
On 08/11/2021 17:36, Dmitry A. Kazakov wrote:
On 2021-11-08 17:58, Bart wrote:
...
But I don't know where using it for power-of originated. I use ^
to mean pointer dereference, taken from Pascal.
I prefer implicit dereference.
If pointers are implicitly dereferenced what do you do when you want
to get the pointer's value?
Nothing dramatic. When the target has the pointer type then that is
the pointer's value. When the target has the target type then that is
dereferencing.
The problems arise with type inference or bottom-up stuff you and
Bart promote. But I want none of these.
I don't follow. If n is a reference or pointer to a node then I
presume you want to refer to the node as
n
but what if you want the value of n, e.g. to print it, rather than the
value of the node it points at?
On 09/11/2021 11:44, Dmitry A. Kazakov wrote:
On 2021-11-09 12:02, James Harris wrote:
On 08/11/2021 21:54, Dmitry A. Kazakov wrote:
On 2021-11-08 22:12, James Harris wrote:
On 08/11/2021 17:36, Dmitry A. Kazakov wrote:
On 2021-11-08 17:58, Bart wrote:
...
But I don't know where using it for power-of originated. I use ^ >>>>>>> to mean pointer dereference, taken from Pascal.
I prefer implicit dereference.
If pointers are implicitly dereferenced what do you do when you
want to get the pointer's value?
Nothing dramatic. When the target has the pointer type then that is
the pointer's value. When the target has the target type then that
is dereferencing.
The problems arise with type inference or bottom-up stuff you and
Bart promote. But I want none of these.
I don't follow. If n is a reference or pointer to a node then I
presume you want to refer to the node as
n
but what if you want the value of n, e.g. to print it, rather than
the value of the node it points at?
That's not what I was thinking but it's an interesting idea.
ATM I follow the latter (fourth) approach. My operators are therefore in order (high to low)...
1. Address manipulations (as in the other recent thread)
2. Bit-pattern manipulation (&, !, etc)
3. Arithmetic manipulation (+, *, etc)
4. Comparisons (<, !=, etc)
5. Logical manipulation (AND, NOT, etc)
On Monday, November 8, 2021 at 3:21:47 AM UTC-8, James Harris wrote:
[Again, joining late, haven't read all of the conversation.]
...
ATM I follow the latter (fourth) approach. My operators are therefore in...
order (high to low)
1. Address manipulations (as in the other recent thread)
2. Bit-pattern manipulation (&, !, etc)
3. Arithmetic manipulation (+, *, etc)
4. Comparisons (<, !=, etc)
5. Logical manipulation (AND, NOT, etc)
If I were to redo C's "operator precedence", which is flawed for historical reasons (B and/or BCPL to Blame, handy!), I'd reduce the total number of
the levels in the binary operators (fewer to remember):
1. *, /, %, <<, >>, &
(* and << kinda multiply, / and >> kinda divide, % and & kinda compute modulo,
* and & also kinda multiply)
2. +, -, |, ^
(+, | and ^ kinda add)
3. ==, !=, <=, <, >, >=
(no good reason to separate these)
4. &&
5. ||
6. ?:
I'd likely make =, +=, ++ and such non-expressions and drop the comma operator altogether.
I'd probably rework ?: as well (make it left-associative), not entirely sure.
3. ==, !=, <=, <, >, >=
(no good reason to separate these)
On 13/02/2022 22:22, Alexei A. Frounze wrote:
If I were to redo C's "operator precedence", which is flawed for historical reasons (B and/or BCPL to Blame, handy!), I'd reduce the total number of the levels in the binary operators (fewer to remember):This is not far off the groupings I use. For the operators listed (and
1. *, /, %, <<, >>, &
(* and << kinda multiply, / and >> kinda divide, % and & kinda compute modulo,
* and & also kinda multiply)
2. +, -, |, ^
(+, | and ^ kinda add)
3. ==, !=, <=, <, >, >=
(no good reason to separate these)
4. &&
5. ||
6. ?:
I'd likely make =, +=, ++ and such non-expressions and drop the comma operator altogether.
I'd probably rework ?: as well (make it left-associative), not entirely sure.
using those same names), they are:
1 * / % << >> (shifts scale the value)
2 + - & | ^ (all bitwise ops are the same; they don't scale, so
they belong neither above or below, so why not here)
On Sunday, February 13, 2022 at 5:05:51 PM UTC-8, Bart wrote:
On 13/02/2022 22:22, Alexei A. Frounze wrote:
If I were to redo C's "operator precedence", which is flawed for historical >>> reasons (B and/or BCPL to Blame, handy!), I'd reduce the total number of >>> the levels in the binary operators (fewer to remember):This is not far off the groupings I use. For the operators listed (and
1. *, /, %, <<, >>, &
(* and << kinda multiply, / and >> kinda divide, % and & kinda compute modulo,
* and & also kinda multiply)
2. +, -, |, ^
(+, | and ^ kinda add)
3. ==, !=, <=, <, >, >=
(no good reason to separate these)
4. &&
5. ||
6. ?:
I'd likely make =, +=, ++ and such non-expressions and drop the comma
operator altogether.
I'd probably rework ?: as well (make it left-associative), not entirely sure.
using those same names), they are:
1 * / % << >> (shifts scale the value)
2 + - & | ^ (all bitwise ops are the same; they don't scale, so
they belong neither above or below, so why not here)
If I view bitwise operator operands as just collections of individual/ independent bits, then separating & from | (and ^) lets me use the
same precedence as often used in computer literature (& and |
can actually be spelled as "AND" and "OR" or some other symbol).
And there for individual bits they use & just like everybody normally
uses * and they use | just like everybody normally uses +.
The rules for * and + are very similar to those for & and |.
0 * 0 = 0 = 0 & 0
0 * 1 = 0 = 0 & 1
1 * 0 = 0 = 1 & 0
1 * 1 = 1 = 1 & 1
0 + 0 = 0 = 0 | 0
0 + 1 = 1 = 0 | 1
1 + 0 = 1 = 1 | 0
1 + 1 = non-zero = 1 | 1
a * b = b * a
a + b = b + a
a & b = b & a
a | b = b | a
(a * b) * c = a * (b * c)
(a + b) + c = a + (b + c)
(a & b) & c = a & (b & c)
(a | b) | c = a | (b | c)
(a + b) * c = (a * c) + (b * c)
(a | b) & c = (a & c) | (b & c)
So, it looks pretty natural to me to treat & and | similar to * and +.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 296 |
Nodes: | 16 (2 / 14) |
Uptime: | 43:36:51 |
Calls: | 6,648 |
Files: | 12,193 |
Messages: | 5,329,648 |