# Julia Language Comparisons Chained Comparisons

## Example

Multiple comparison operators used together are chained, as if connected via the `&&` operator. This can be useful for readable and mathematically concise comparison chains, such as

``````# same as 0 < i && i <= length(A)
isinbounds(A, i)       = 0 < i ≤ length(A)

# same as Set() != x && issubset(x, y)
isnonemptysubset(x, y) = Set() ≠ x ⊆ y
``````

However, there is an important difference between `a > b > c` and `a > b && b > c`; in the latter, the term `b` is evaluated twice. This does not matter much for plain old symbols, but could matter if the terms themselves have side effects. For instance,

``````julia> f(x) = (println(x); 2)
f (generic function with 1 method)

julia> 3 > f("test") > 1
test
true

julia> 3 > f("test") && f("test") > 1
test
test
true
``````

Let’s take a deeper look at chained comparisons, and how they work, by seeing how they are parsed and lowered into expressions. First, consider the simple comparison, which we can see is just a plain old function call:

``````julia> dump(:(a > b))
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol >
2: Symbol a
3: Symbol b
typ: Any
``````

Now if we chain the comparison, we notice that the parsing has changed:

``````julia> dump(:(a > b >= c))
Expr
head: Symbol comparison
args: Array{Any}((5,))
1: Symbol a
2: Symbol >
3: Symbol b
4: Symbol >=
5: Symbol c
typ: Any
``````

After parsing, the expression is then lowered to its final form:

``````julia> expand(:(a > b >= c))
:(begin
unless a > b goto 3
return b >= c
3:
return false
end)
``````

and we note indeed that this is the same as for `a > b && b >= c`:

``````julia> expand(:(a > b && b >= c))
:(begin
unless a > b goto 3
return b >= c
3:
return false
end)
``````