5 < x != y < 5

Hi All,
I am reviewing The Fast Track to julia. In the Basics section Chaining is mentioned. Three lines of code are:

x = y = z = 1 # right-to-left
0 < x < 3 # true
5 < x != y < 5 # false

It’s the last line that I can’t figure out the logic flow. Can anyone provide me with sufficient details as to how I should evaluate this last line? The Fast Track states it is false as per their comment. I get the same result if I code just the third line and set x=1 and y=1. But if I set x=6 and y=2 it evaluates to true. Any help is greatly appreciated.

Thanks!

Jim

1 Like

https://docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity

they all have the same precedence and are not associative

rather this subsection Mathematical Operations and Elementary Functions · The Julia Language

the last line should be equivalent to (5 < x) && ( x != y) && (y < 5)

13 Likes

Yes, but from line 1: x = y = z = 1

I think the question is more about how to arrive at the answer, than the very specific answer to this specific problem

jling, Thank you so much for the link! I should have checked the Manual as well.

Take care, Jim

sz73, You have the best answer. Thank you for providing the logic! Now it makes sense to me. The link helps as well.

Take care, Jim.

1 Like

I’d suggest the best way to figure this stuff out is to quote the expression and dump it out:

dump(:(5 < x != y < 5))

Then you can reason out why the expression was parsed the way it was after seeing unambiguously how it’s being parsed.

14 Likes

Thanks, pbayer! Yes, it’s the logic I’m trying to figure out and sz73’s equivalent logic definitely helps.

Take care, Jim.

JMW, I will definitely try the dump feature and see what I come up with. Thanks for the insight!

Jim

You can mark his answer as “the answer”, if that helps.

1 Like

Thanks, briochemc. Newbie here. Will do.

Take care, Jim.

1 Like

Or, more easily perhaps, Meta.@dump 5 < x != y < 5

6 Likes

Or even:

julia> Meta.@lower 5 < x != y < 5
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = 5 < x
└──      goto #5 if not %1
2 ─ %3 = x != y
└──      goto #4 if not %3
3 ─ %5 = y < 5
└──      return %5
4 ─      return false
5 ─      return false
))))

:slight_smile:

One day I will find out what a thunk is. Perhaps not today.

3 Likes

Thanks, cormullion! Very helpful.

I had to search for “thunk” and found this: Thunk - Wikipedia. Not sure that helps.

Take care, Jim.

1 Like
dump(:(5 < x != y < 5))
Expr
  head: Symbol comparison
  args: Array{Any}((7,))
    1: Int64 5
    2: Symbol <
    3: Symbol x
    4: Symbol !=
    5: Symbol y
    6: Symbol <
    7: Int64 5

How does this help to understand the behavior of the chaining of the operators?

4 Likes

You’re right: in this example, it doesn’t help because the order of operations isn’t discernable from the parse structure.

As an aside, I hope people would avoid this in real code:
5 < x != y < 5 # false
which is difficult for the reader to understand without thinking a minute or even wondering if it’s a bug. It is more a brain-teaser to illustrate chaining, than a recommendation for actual code. The following is clearer and more explicit:

Chaining is great when it’s simple and close to what you’d write with math, as in the first examples above:

x = y = z = 1 # right-to-left
0 < x < 3 # true

The slowest compiler is the human reader, so try to be helpful to them, or even yourself if you ever return to the code months/years later.

As a cranky person, I also avoid the idiomatic

x == y && dosomething()

to avoid an if statement like

if x == y; dosomething(); end

I think the if makes intent clearer and doesn’t assume all readers to understand short-circuiting. (I also prefer the semi-colons even if they can be omitted, just to make it easier to read.) [edit: bug fix]

6 Likes

apo383,
Makes complete sense! A hacker (of the original sense) might appreciate the most minimal code, but mere mortals (me) need readability and ease of comprehension.