`a == b == c`

is a very nice construct. `a < b > c`

too. however julia allows `a != b != c`

, but i would call it contraintuitive, because it is true if `a == c`

. my thinking is that != should not allow this at all, for it lacks common sense meaning. but if it is allowed, i would suggest translate to a != b && a != c && b != c

# A != b != c

**pint**#1

**Evizero**#2

Why? Even `a < b < c`

does not assume transitivity, it just happens that it is the case in most use cases.

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

It would seems strange to me that other relations should.

**stevengj**#4

@pint, I think @Evizeroâs point is that `<`

is an arbitrary user-defined function, so there is nothing (except for sanity) stopping you from defining a non-transitive `<`

. The `a < b < c`

implementation does not compare `a < c`

, it only compares `a < b`

and `b < c`

.

Speculation chained comparison optimization (possibly with outlining)

**pint**#5

but that is an abuse of the operator. the != chain is incorrect even if i donât abuse the operator, in fact it gives surprising result even when used with numbers.

**dpsanders**#6

Here the problem would be the user that wrote the chain of `!=`

and expected it to mean something useful.

You wouldnât write that in mathematics expecting it to be meaningful, and so shouldnât write it in code either.

**Evizero**#7

What would happen in your example here then?

Or a simpler example: What would `a <= b < c`

translate to, how do I compare `a`

and `c`

. Is there a operator promote or are all possibilities evaluated?

**Tamas_Papp**#9

I am not sure about even that â below is stylized code for an exercise I sometimes ask students to do, to show how people are not good at generating random numbers:

```
d1 = [rand(1:3, 3) for i in 1:100]
d2 = # ask people to write down "random" triples containing 1:3
twochanges(v) = v[1] != v[2] != v[3]
sum(twochanges(v) for v in d1) # will be lower
sum(twochanges(v) for v in d2) # people tend to favor sequences with changes
```

**stevengj**#10

Note also that chaining works for arbitrary âcomparisonâ operators, including user-defined operators, and does not require transitivity. For example, consider the `â`

operator, which is a synonym for `isapprox`

. This comparison is not transitive, but can be chained:

```
julia> 1 â 1 + 1e-8 â 1 + 2e-8
true
julia> 1 â 1 + 2e-8
false
```

The behavior for `!=`

is consistent with the behavior for other comparison operators: chaining implies pairwise comparisons between adjacent terms only.

**ScottPJones**#11

I hadnât even realized that `a == b == c`

was lowered that way, instead of how it would be in `C/C++`

and C-like languages.

I would have thought that it would mean something totally different, i.e. `(a == b) == c`

, which then return true if `c`

were either `Bool`

or something that converted to `true`

or `false`

and matched the result of `a == b`

.

This may be worth a note in the `C/C++`

differences section of the manual.

(Iâm not saying there is anything *wrong* with the way Julia handles this, just that it can be surprising, hence a desire for having pointed out in an appropriate part of documentation)

**stevengj**#12

**ScottPJones**#13

Ah, thanks! I also wasnât trying to imply that it wasnât well documented *somewhere*, just that it *might* be worth having a line in at least the C/C++ differences section (which I was the initial author of ages ago). What do you think of doing that? (and pointing a reference to the chaining comparisons section there also).

I know of course that chaining worked with `<`

, `<=`

, `>`

and `>=`

, just hadnât realized it worked for arbitrary operators (pretty cool, that!)

**DNF**#14

I must say that I find the current meaning of `a != b != c`

to be exactly what I intuitively expected, and I was thoroughly confused as to what you even meant at first.

I read it like this: `a`

is different from `b`

and `b`

is different from `c`

. So

```
julia> 1 != 2 != 1
true
```

is exactly as it should be. If you want to test pairwise inequality for all combinations, you would do `a != b != c != a`

.

Inequality is not a transitive property, so why do you expect transitive behavior?

**johnmyleswhite**#15

I think youâre getting at the real problem with this kind of discussion: people donât all have the same intuitions, so debating intuitions doesnât generally lead to any improvements in language design.

Method definition overwritten warning for functions with default arguments

**ihnorton**split this topic #16

5 posts were merged into an existing topic: Does Julia ever do outlining?

Speculation chained comparison optimization (possibly with outlining)

Speculation chained comparison optimization (possibly with outlining)

Speculation chained comparison optimization (possibly with outlining)

**Palli**#17

It should be in all cases (as logic dictates), the expand you showed, only shows what the current implementations of Julia does.

In case when you do not have transitive, e.g. a < b > c, or != or the sneaky â (isapprox), then for the optimizer, should split up and optimize the left and right of it separately.

âso there is nothing (except for sanity) stopping you from defining a non-transitive <â

Can that possibility be disallowed so the optimizer does not have to consider that case?

Speculation chained comparison optimization (possibly with outlining)

**Palli**#18

I believe noâŠ but math has a way of surprising meâŠ I donât know half of itâŠ E.g. I didnât give this much though until I realized (with more advanced ânumbersâ they lose more properties):

For complex number (and matrices of anything, except trivial 1x1?) < is not defined. Other than that, I believe when < is defined, itâs always defined the same way. Otherwise, Iâm in troubleâŠ and I really need to know.

Speculation chained comparison optimization (possibly with outlining)

**johnmyleswhite**#19

Youâre now actively spreading misinformation. Please stop.

Speculation chained comparison optimization (possibly with outlining)

**ChrisRackauckas**#20

A linked list chain where you define `a<b`

to mean `a`

is immediately to the left of `b`

? That sounds like a perfectly useful and valid dispatch for `<`

for which it wouldnât be transitive. As @stevengj noted, itâs just an operator, so you can do whatever is sensible with it.