# "bitwise and" vs "short-circuiting and", the dot version, which one should be used?

**URL:** <https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [May 22, 2023, 10:30am UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211 "2023-05-22T10:30:01Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![maxchendt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxchendt/32/42976_2.png) [@maxchendt](https://discourse.julialang.org/u/maxchendt)\
**Post date:** [May 22, 2023, 10:30am UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/1 "2023-05-22T10:30:01Z")

</div>

In Julia 1.9, both `p .&& q` and `p .& q` are working. But in 1.6.7 LTS, `p .&& q` is invalid

```julia
    p = [true, true, false, false]
    q = [true, false, true, false]

    #p .&& q #invalid syntax &q
    p .& q

```

Should I keep to the `p .& q` version?

But I am thinking the `p .&& q` is more consistent.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 22, 2023, 10:34am UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/2 "2023-05-22T10:34:17Z")

</div>

Depends on whether you want the short-circuiting or don’t. Most often you don’t, in usage like this. I prefer to default to `&`, as it can avoid extra branching.

This seems to be the PR that introduced the change, BTW:

> <https://github.com/JuliaLang/julia/pull/39594>
>
> I have long wanted a proper fix for issue #5187. It was the very first Julia iss…ue I filed.
> This is a shot at such a fix. This PR:
> 
> \* Enables parsing for \`.&&\` and \`.||\`. They are parsed into syntactic \`Expr(:.&&, ...)\` expressions at the same precedence as their respective \`&&\` and \`||\`:
> \`\`\`julia-repl
> julia\> Meta.show\_sexpr(:(a .&& b))
> (:.&&, :a, :b)
> \`\`\`
> 
> \* Unlike all other dotted operators \`.op\` (like \`.+\`), the \`op\`-alone part (\`var"&&"\`) is not an exported name from Base. As such, this effectively lowers to \`broadcasted((x,y)-\>x && y, ...)\`, but instead of using an anonymous function I've named it \`Base.andand\` and \`Base.oror\`:
> \`\`\`julia-repl
> julia\> Meta.@lower a .&& b
> :($(Expr(:thunk, CodeInfo(
> @ none within \`top-level scope'
> 1 ─ %1 = Base.broadcasted(Base.andand, a, b)
> │ %2 = Base.materialize(%1)
> └── return %2
> ))))
> \`\`\`
> 
> \* I've used a named function to enable short-circuiting behavior \_within the broadcast kernel itself\_. In the case that the second argument is a part of the same fused broadcast kernel, it will only evaluate if required:
> \`\`\`julia-repl
> julia\> mutable struct F5187; x; end
> 
> julia\> (f::F5187)(x) = (f.x += x)
> 
> julia\> (iseven.(1:4) .|| (F5187(0)).(ones(4)))
> 4-element Vector{Real}:
> 1.0
> true
> 2.0
> true
> \`\`\`
> 
> \* ~~This also enables support for standalone \`.&&\` and \`.||\` as \`BroadcastFunction\`s, but of course they are not able to short-circuit when used as functions themselves.~~
> 
> Request for feedback
> \--------------------
> 
> \* \[x\] A good bikeshed could be had over the names themselves; the implemented \`andand\` and \`oror\` are cutesy placeholders. We could actually use \`var"&&"\` and \`var"||"\` for these names — and it'd \_almost\_ simplify the implementation, but in order to do so we'd have to actually \_export\_ them from Base, too. It seems like it might just be confusing.  
> \*\*The names are fine\*\*
> \* \[x\] Is this the implementation we want? This uses \`Broadcast.flatten\` to create the lazy function needed for short-circuiting the second argument. This could alternatively be done directly within the parser — perhaps by resurrecting the old 0.5 broadcast parsing behavior. Someone else would have to do that work if they wanted it.  
> \*\*Yes\*\*
> \* \[x\] Do we want to support the stand-alone \`.&&\` and \`.||\` \`BroadcastFunction\`s if they cannot possibly short circuit?  
> \*\*Maybe, but deferred\*\*
> \* \[x\] Should dotted chained comparisons like \`1 .\< A .\< 2\` produce \`(1 .\< A) .&& (A .\< 2)\`? It currently uses \`.&\`. I'm leaning towards keeping the status quo, even though this would represent a departure from the scalar lowering. I'd bet that changing this would be breaking for folks that are effectively working around #39104 (knowingly or not).  
> \*\*Maybe, but breaking and deferred\*\*
> 
> (See also #26792 which made space for this feature.)

---

<div class="post-metadata">

**Author:** ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)\
**Post date:** [May 22, 2023, 12:52pm UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/3 "2023-05-22T12:52:34Z")

</div>

Since this is posted in “New to Julia”: please note that the two operators have completely different precedence for logical comparisons:

```julia
julia> x = [1,2,3,4,5];

julia> x .>= 2 .&& x .< 4
5-element BitVector:
 0
 1
 1
 0
 0

julia> x .>= 2 .& x .< 4
5-element BitVector:
 1
 1
 1
 1
 1

julia> (x .>= 2) .& (x .< 4)
5-element BitVector:
 0
 1
 1
 0
 0

```

Fundamentally, `.&` is intended for bitwise operations and `.&&` for logical operations. They both have appropriate precedence for their use case. But be very careful when using `.&` for logical operations in older versions of Julia - don’t forget to add parentheses!

---

<div class="post-metadata">

**Author:** ![maxchendt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxchendt/32/42976_2.png) [@maxchendt](https://discourse.julialang.org/u/maxchendt)\
**Post date:** [May 22, 2023, 1:14pm UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/4 "2023-05-22T13:14:57Z")

</div>

> [@NiclasMattsson](#):
>
> `x .>= 2 .& x .< 4`

thanks! the `x .>= 2 .& x .< 4` is equivalent to

```julia
(x .>= (2 .& x)) .< 4

```

> [@NiclasMattsson](#):
>
> Fundamentally, `.&` is intended for bitwise operations and `.&&` for logical operations.

Hence, for Julia \>=1.8, use `.&&` is better, I think.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 22, 2023, 1:48pm UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/5 "2023-05-22T13:48:39Z")

</div>

> [@NiclasMattsson](#):
>
> Fundamentally, `.&` is intended for bitwise operations and `.&&` for logical operations.

I don’t know what convention is the most common, but personally I prefer using `&` over `&&` for “logical” operations, too; except if I want the short-circuiting behavior. Sometimes the reason for preferring `&&` is that a branch is simply necessary because some code must be executed only conditionally, while in other cases the motivation is performance (avoid executing expensive branch if that’s not necessary).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 22, 2023, 1:56pm UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/6 "2023-05-22T13:56:07Z")

</div>

> [@nsajko](#):
>
> while in other cases the motivation is performance (avoid executing expensive branch if that’s not necessary).

I would be wary of doing this kind of micro-optimization routinely. Because of the higher precedence mentioned above, `&` is trickier to use and can lead to less-readable code — I would second @NiclasMattsson in suggesting that you should ordinarily default to using `&&` for **all** “logical and” operations, and only micro-optimize to `&` for performance-critical code where benchmarking shows that it helps.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 22, 2023, 2:24pm UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/7 "2023-05-22T14:24:16Z")

</div>

I don’t see the choice of a default AND operator as an optimization at all, though. I mean it’s just a convention, I _have_ to choose one or the other possibility to default to. And I’m not bothered by precedence rules because I like to use extra parentheses anyway when I’m not clear about the precedence.

I guess the most important thing is respecting the style of the surrounding codebase.

---

<div class="post-metadata">

**Author:** ![NiclasMattsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/niclasmattsson/32/21988_2.png) [@NiclasMattsson](https://discourse.julialang.org/u/NiclasMattsson)\
**Post date:** [May 22, 2023, 8:05pm UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/8 "2023-05-22T20:05:25Z")

</div>

Again, since this is “New to Julia” let’s be super clear about the problem with using `.&` for logical operations.

It’s not just that the bug in `x .>= 2 .& x .< 4` is really hard to spot. The major issue is that it **fails silently**. If you’re lucky you might notice that your code is outputting garbage. In some situations you might never even know your code is broken. Perhaps even worse, you might actually find the bug six months after your paper has been published…

My advice: just default to using `.&&` for logic unless you really know what you’re doing. Many Julians may never need the bitwise `.&` operator.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [May 22, 2023, 9:55pm UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/9 "2023-05-22T21:55:11Z")

</div>

The problem with defaulting to `&&` is that it does not support three-valued logic:

```julia
julia> x = [true, false, missing];

julia> y = [true, true, true];

julia> x .&& y
ERROR: TypeError: non-boolean (Missing) used in boolean context

```

On the other hand, `&` does support three-valued logic:

```julia
julia> x .& y
3-element Vector{Union{Missing, Bool}}:
  true
 false
      missing

```

---

<div class="post-metadata">

**Author:** ![i9e1](https://avatars.discourse-cdn.com/v4/letter/i/ac91a4/32.png) [@i9e1](https://discourse.julialang.org/u/i9e1)\
**Post date:** [June 1, 2023, 3:08am UTC](https://discourse.julialang.org/t/bitwise-and-vs-short-circuiting-and-the-dot-version-which-one-should-be-used/99211/10 "2023-06-01T03:08:00Z")

</div>

> [@NiclasMattsson](#):
>
> My advice: just default to using `.&&` for logic unless you really know what you’re doing.

This applies to three valued logic imho. `missing` will error when you want to branch, so you would have to do some fixing than.

Maybe `*` is more explicit in this case (could be taste).

```julia
julia> x = [true, false, missing]; y = [true, true, true];

julia> x .* y
3-element Vector{Union{Missing, Bool}}:
  true
 false
      missing

```

`v1.9.0`, not checked on older versions.
