# A != b != c

**URL:** <https://discourse.julialang.org/t/a-b-c/1347>\
**Category:** Internals & Design\
**Tags:** proposal\
**Created:** [January 7, 2017, 3:57pm UTC](https://discourse.julialang.org/t/a-b-c/1347 "2017-01-07T15:57:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pint/32/125_2.png) [@pint](https://discourse.julialang.org/u/pint)\
**Post date:** [January 7, 2017, 3:57pm UTC](https://discourse.julialang.org/t/a-b-c/1347/1 "2017-01-07T15:57:38Z")

</div>

`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

---

<div class="post-metadata">

**Author:** ![Evizero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evizero/32/10118_2.png) [@Evizero](https://discourse.julialang.org/u/Evizero)\
**Post date:** [January 7, 2017, 4:09pm UTC](https://discourse.julialang.org/t/a-b-c/1347/2 "2017-01-07T16:09:14Z")

</div>

Why? Even `a < b < c` does not assume transitivity, it just happens that it is the case in most use cases.

```julia
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.

---

<div class="post-metadata">

**Author:** ![pint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pint/32/125_2.png) [@pint](https://discourse.julialang.org/u/pint)\
**Post date:** [January 7, 2017, 4:14pm UTC](https://discourse.julialang.org/t/a-b-c/1347/3 "2017-01-07T16:14:17Z")

</div>

is there a use case in which \< is not transitive?

---

<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:** [January 7, 2017, 4:16pm UTC](https://discourse.julialang.org/t/a-b-c/1347/4 "2017-01-07T16:16:50Z")

</div>

@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`.

---

<div class="post-metadata">

**Author:** ![pint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pint/32/125_2.png) [@pint](https://discourse.julialang.org/u/pint)\
**Post date:** [January 7, 2017, 4:26pm UTC](https://discourse.julialang.org/t/a-b-c/1347/5 "2017-01-07T16:26:24Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 7, 2017, 4:30pm UTC](https://discourse.julialang.org/t/a-b-c/1347/6 "2017-01-07T16:30:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Evizero](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evizero/32/10118_2.png) [@Evizero](https://discourse.julialang.org/u/Evizero)\
**Post date:** [January 7, 2017, 4:32pm UTC](https://discourse.julialang.org/t/a-b-c/1347/7 "2017-01-07T16:32:16Z")

</div>

> [@pint](#):
>
> a \< b \> c too.

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?

---

<div class="post-metadata">

**Author:** ![pint](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pint/32/125_2.png) [@pint](https://discourse.julialang.org/u/pint)\
**Post date:** [January 7, 2017, 4:38pm UTC](https://discourse.julialang.org/t/a-b-c/1347/8 "2017-01-07T16:38:43Z")

</div>

i don’t see how `a <= b < c` can lead to ambiguity.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 7, 2017, 6:07pm UTC](https://discourse.julialang.org/t/a-b-c/1347/9 "2017-01-07T18:07:44Z")

</div>

> [@dpsanders](#):
>
> 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.

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:

```julia
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

```

---

<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:** [January 7, 2017, 6:19pm UTC](https://discourse.julialang.org/t/a-b-c/1347/10 "2017-01-07T18:19:39Z")

</div>

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
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.

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 7, 2017, 6:22pm UTC](https://discourse.julialang.org/t/a-b-c/1347/11 "2017-01-07T18:22:55Z")

</div>

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)

---

<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:** [January 7, 2017, 6:24pm UTC](https://discourse.julialang.org/t/a-b-c/1347/12 "2017-01-07T18:24:10Z")

</div>

> [@ScottPJones](#):
>
> 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.

See [http://docs.julialang.org/en/stable/manual/mathematical-operations/#chaining-comparisons](http://docs.julialang.org/en/stable/manual/mathematical-operations/#chaining-comparisons)

---

<div class="post-metadata">

**Author:** ![ScottPJones](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scottpjones/32/146_2.png) [@ScottPJones](https://discourse.julialang.org/u/ScottPJones)\
**Post date:** [January 7, 2017, 6:30pm UTC](https://discourse.julialang.org/t/a-b-c/1347/13 "2017-01-07T18:30:50Z")

</div>

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!)

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 7, 2017, 8:04pm UTC](https://discourse.julialang.org/t/a-b-c/1347/14 "2017-01-07T20:04:43Z")

</div>

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
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?

---

<div class="post-metadata">

**Author:** ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)\
**Post date:** [January 7, 2017, 8:25pm UTC](https://discourse.julialang.org/t/a-b-c/1347/15 "2017-01-07T20:25:37Z")

</div>

> [@DNF](#):
>
> 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 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.

---

<div class="post-metadata">

**Author:** ![ihnorton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihnorton/32/26_2.png) [@ihnorton](https://discourse.julialang.org/u/ihnorton)\
**Post date:** [January 8, 2017, 9:19pm UTC](https://discourse.julialang.org/t/a-b-c/1347/16 "2017-01-08T21:19:55Z")

</div>

5 posts were merged into an existing topic: [Does Julia ever do outlining?](https://discourse.julialang.org/t/does-julia-ever-do-outlining/1354)

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [January 9, 2017, 8:18pm UTC](https://discourse.julialang.org/t/a-b-c/1347/17 "2017-01-09T20:18:27Z")

</div>

> [@Evizero](#):
>
> Even a \< b \< c does not assume transitivity

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?

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [January 9, 2017, 8:31pm UTC](https://discourse.julialang.org/t/a-b-c/1347/18 "2017-01-09T20:31:59Z")

</div>

> [@pint](#):
>
> is there a use case in which \< is not transitive?

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.

---

<div class="post-metadata">

**Author:** ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)\
**Post date:** [January 9, 2017, 8:58pm UTC](https://discourse.julialang.org/t/a-b-c/1347/19 "2017-01-09T20:58:03Z")

</div>

> [@Palli](#):
>
> It should be in all cases (as logic dictates), the expand you showed, only shows what the current implementations of Julia does.

You’re now actively spreading misinformation. Please stop.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [January 10, 2017, 3:58am UTC](https://discourse.julialang.org/t/a-b-c/1347/20 "2017-01-10T03:58:27Z")

</div>

> [@pint](#):
>
> is there a use case in which \< is not transitive?

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.

[Next page](https://discourse.julialang.org/t/a-b-c/1347.md?page=2)
