<p>It is an old tradition in programming languages to use <code>&amp;</code> and <code>|</code> to represent bitwise operations, and <code>&amp;&amp;</code> and <code>||</code> to represent logical operations.</p>
<p>But these languages, such as C language, had neither <code>bool</code> type nor overloading or other polymorphisms in the design era.</p>
<p>So you do need different operators to distinguish logical operations from bitwise operations.</p>
<p>But I'm thinking about whether this distinction should be made in a strongly typed language if there are polymorphic dispatch methods such as type classes or overloading.</p>

<language-design><logical-operators>
Is it necessary to differentiate between && and & when I support overloads
CC BY-SA 4.0
2023-11-03T07:16:07.523Z
Could you give some scope to what you mean by “necessary” here? Necessary for parsing? (which kind?) For existing tooling? Necessary to avoid programmer errors? Other human-factors reasons? At present there isn’t any objective criterion for assessing the design question at hand, which generally makes for a mishmash of unconnected answer fragments.
Michael Homer
CC BY-SA 4.0
2023-11-03T15:45:26.823Z
Even if you restricted you version of `&` to only work on int-types and your version of `&&` to only work on boolean types, they would still be quite distinct operations, and overloading may generate more semantical confusion than, say, overloading `+` to work with vectors or arrays would do. So this would not entirely be risk free.
pygri
CC BY-SA 4.0
2023-11-03T18:59:05.660Z
Quite-related potential duplicate: [What evidence exists on using & and | as logical operators instead of && and ||?](https://langdev.stackexchange.com/q/3012/133)
Michael Homer
CC BY-SA 4.0
2023-11-05T21:35:09.003Z
Nim works this way: `and`, `or`, `not` and `xor` can be either logical or bitwise depending on the types of arguments.
xigoi
<p>In Tyr, I eventually decided to introduce operators <code>&amp;!</code> for an <em>and</em> function and <code>&amp;&amp;</code> for shortcut <em>and</em> in the <a href="https://github.com/tyr-lang/stdlib/blob/a77849fbf2db09716d7f96fad071c810df8224ab/lang/src/bool.tyr#L12" rel="nofollow noreferrer">bool</a> type. The <a href="https://github.com/tyr-lang/stdlib/blob/a77849fbf2db09716d7f96fad071c810df8224ab/lang/src/integer.tyr#L51" rel="nofollow noreferrer">Integer</a> types use <code>&amp;</code>.</p>
<p>Answering what the question literally asked would be: no. The distinction isn't needed as the three functions have different types. Merging <code>&amp;!</code> and <code>&amp;</code> into the same name would be possible and has actually been the case in the early days of Tyr just because C and many others did it like that.
Merging <code>&amp;!</code> and <code>&amp;&amp;</code> is a lot trickier, because both functions accept the shape (bool, bool) : bool. The effect of such a choice would require the user to specify which function to use explicitly. Without testing, I think that it would be possible by coercing the second argument to the <code>Block[bool]</code> type to pick the short circuit version. This is obviously an issue in practice, because using <code>&amp;&amp;</code> is very common.</p>
<p>Note that the issue isn't the definition of the operators. The issue is the overload resolution for the uses.</p>
<p>Answering what I think the intention of the question is:
There are two reason for splitting the three operators to different names.
First, the operators have different precedence. I wanted to fix the wrong precedence of bit-wise integer operation and the code started to look a lot more natural once I also used a different operator symbol for the least common case.
Second, the eager bool operator is something that is very uncommon. In fact I know style guides that state that &quot;you shouldn't use it at all because most people will not understand the effect anyway&quot;. Hence, I made the language-history-breaking change on the least used operator.</p>

CC BY-SA 4.0
2023-11-03T16:48:45.640Z
2023-11-03T16:48:45.640Z
feldentm
CC BY-SA 4.0
2023-11-03T17:44:39.517Z
`&!` seems to risk confusion with "and not", since the `!` symbol usually means "not".
kaya3
CC BY-SA 4.0
2023-11-03T18:47:35.580Z
I get the idea, but allowing users to define operators means that two subsequent operators are always separated somehow, usually by a blank.
feldentm
<p>One important thing is shortcut evaluation. Many languages support shortcut evaluation on the logical operators, but not on the bitwise operators. If you decide whether to use shortcut evaluation according to the type, it might create confusions about whether the second operand is evaluated.</p>
<p>Many Basic variants use <code>and</code> <code>or</code> for both the logical and bitwise operators. I just tried QB64, and it doesn't appear to support shortcut evaluation at all. This actually doesn't match my memories. I can't imagine how I never encountered <code>if index&lt;=upperbound and do_something(array(index)) then...</code> when I used QBasic many years ago. It is possible that this problem was not that important before the age of object oriented programming. But some languages indeed don't differentiate them.</p>
<p>Also note in C, values are cast to booleans before evaluating a logical operator, whether the booleans mean a standalone type or the two-element subset of integer. <code>1 &amp;&amp; 2</code> would not match <code>1 &amp; 2</code> cast to boolean afterwards. This is supported by many modern languages took inspirations from C, but is not liked by everyone. Some language developers may think it is safer to require the programmer to always cast the value to the right type before using the operators. So this isn't so big a problem that makes it inconsistent. But I doubt the same developer would think it is safe to allow the semantic change that much without reporting an error just by forgetting a type conversion. And I can't think of another reason not supporting automatically casting to booleans.</p>

CC BY-SA 4.0
2023-11-03T12:42:36.647Z
2023-11-03T12:42:36.647Z
user23013
CC BY-SA 4.0
2023-11-03T12:49:29.727Z
Short-circuiting operations is a good idea. Maybe I can use typeclass to add short-circuiting operations to any operator. For operations marked with `@shortcut', just treat the right side of the expression as a closure.
Aster
CC BY-SA 4.0
2023-11-03T15:36:33.830Z
And note that while c++ supports overloading && the type loses short-circuit evaluation if you do (so the uses I've seen for overloading && are in serialization systems that handle the direction-of-operation at the archive level, so you get code like: "archive && obj1 && obj2;" rather than any sort of logical space)
SoronelHaetir
CC BY-SA 4.0
2023-11-03T17:37:15.463Z
I agree. However I find myself wondering whether taking or refusing a potential short-circuit, akin to greedy or frugal matching in regexes, would be better expressed by some higher-level construct which could also be applied to e.g. multiplication by zero.
Mark Morgan Lloyd
# Is it necessary to differentiate between && and & when I support overloads
Posted by: username_0 on 2023-11-03
It is an old tradition in programming languages to use `&` and `|` to represent bitwise operations, and `&&` and `||` to represent logical operations.

But these languages, such as C language, had neither `bool` type nor overloading or other polymorphisms in the design era.

So you do need different operators to distinguish logical operations from bitwise operations.

But I'm thinking about whether this distinction should be made in a strongly typed language if there are polymorphic dispatch methods such as type classes or overloading.
**Tags:** language-design logical-operators
> **Comments:**
> **username_1**: Could you give some scope to what you mean by “necessary” here? Necessary for parsing? (which kind?) For existing tooling? Necessary to avoid programmer errors? Other human-factors reasons? At present there isn’t any objective criterion for assessing the design question at hand, which generally makes for a mishmash of unconnected answer fragments.  
> **username_2**: Even if you restricted you version of `&` to only work on int-types and your version of `&&` to only work on boolean types, they would still be quite distinct operations, and overloading may generate more semantical confusion than, say, overloading `+` to work with vectors or arrays would do. So this would not entirely be risk free.  
> **username_1**: Quite-related potential duplicate: [What evidence exists on using & and | as logical operators instead of && and ||?](https://langdev.stackexchange.com/q/3012/133)  
> **username_3**: Nim works this way: `and`, `or`, `not` and `xor` can be either logical or bitwise depending on the types of arguments.  
---
## 2 answers
### Answer by username_6 on 2023-11-03. Score: 5
One important thing is shortcut evaluation. Many languages support shortcut evaluation on the logical operators, but not on the bitwise operators. If you decide whether to use shortcut evaluation according to the type, it might create confusions about whether the second operand is evaluated.

Many Basic variants use `and` `or` for both the logical and bitwise operators. I just tried QB64, and it doesn't appear to support shortcut evaluation at all. This actually doesn't match my memories. I can't imagine how I never encountered `if index<=upperbound and do_something(array(index)) then...` when I used QBasic many years ago. It is possible that this problem was not that important before the age of object oriented programming. But some languages indeed don't differentiate them.

Also note in C, values are cast to booleans before evaluating a logical operator, whether the booleans mean a standalone type or the two-element subset of integer. `1 && 2` would not match `1 & 2` cast to boolean afterwards. This is supported by many modern languages took inspirations from C, but is not liked by everyone. Some language developers may think it is safer to require the programmer to always cast the value to the right type before using the operators. So this isn't so big a problem that makes it inconsistent. But I doubt the same developer would think it is safe to allow the semantic change that much without reporting an error just by forgetting a type conversion. And I can't think of another reason not supporting automatically casting to booleans.
> **Comments:**
> **username_0** (2023-11-03): Short-circuiting operations is a good idea. Maybe I can use typeclass to add short-circuiting operations to any operator. For operations marked with `@shortcut', just treat the right side of the expression as a closure.  
> **username_7** (2023-11-03): And note that while c++ supports overloading && the type loses short-circuit evaluation if you do (so the uses I've seen for overloading && are in serialization systems that handle the direction-of-operation at the archive level, so you get code like: "archive && obj1 && obj2;" rather than any sort of logical space)  
> **username_8** (2023-11-03): I agree. However I find myself wondering whether taking or refusing a potential short-circuit, akin to greedy or frugal matching in regexes, would be better expressed by some higher-level construct which could also be applied to e.g. multiplication by zero.  
---
### Answer by username_4 on 2023-11-03. Score: 1
In Tyr, I eventually decided to introduce operators `&!` for an *and* function and `&&` for shortcut *and* in the [bool](https://github.com/tyr-lang/stdlib/blob/a77849fbf2db09716d7f96fad071c810df8224ab/lang/src/bool.tyr#L12) type. The [Integer](https://github.com/tyr-lang/stdlib/blob/a77849fbf2db09716d7f96fad071c810df8224ab/lang/src/integer.tyr#L51) types use `&`.

Answering what the question literally asked would be: no. The distinction isn't needed as the three functions have different types. Merging `&!` and `&` into the same name would be possible and has actually been the case in the early days of Tyr just because C and many others did it like that.
Merging `&!` and `&&` is a lot trickier, because both functions accept the shape (bool, bool) : bool. The effect of such a choice would require the user to specify which function to use explicitly. Without testing, I think that it would be possible by coercing the second argument to the `Block[bool]` type to pick the short circuit version. This is obviously an issue in practice, because using `&&` is very common.

Note that the issue isn't the definition of the operators. The issue is the overload resolution for the uses.

Answering what I think the intention of the question is:
There are two reason for splitting the three operators to different names.
First, the operators have different precedence. I wanted to fix the wrong precedence of bit-wise integer operation and the code started to look a lot more natural once I also used a different operator symbol for the least common case.
Second, the eager bool operator is something that is very uncommon. In fact I know style guides that state that "you shouldn't use it at all because most people will not understand the effect anyway". Hence, I made the language-history-breaking change on the least used operator.
> **Comments:**
> **username_5** (2023-11-03): `&!` seems to risk confusion with "and not", since the `!` symbol usually means "not".  
> **username_4** (2023-11-03): I get the idea, but allowing users to define operators means that two subsequent operators are always separated somehow, usually by a blank.  
---
