## What should x < y < z do?

Please compose all posts in Emacs.

Moderators: phlip, Moderators General, Prelates

## What should (x < y < z) mean?

(x < y) < z
9
13%
(x < y) ∧ (y < z)
59
87%

Robert'); DROP TABLE *;
Posts: 730
Joined: Mon Sep 08, 2008 6:46 pm UTC
Location: in ur fieldz

### What should x < y < z do?

A friend pointed this one out to me a couple of hours ago, so I'm asking what you think.

In mathematics, [imath]x < y < z[/imath] is true if y is in between, but not equal to, x and z. But in some programming languages, such as C, x < y < z is guaranteed to evaluate to true if z > 1, because it's actually evaluated as (x<y) < z. (x<y) returns either 0 or 1, and so [0,1] < z is true for all z > 1. In other languages, it works the math way.

Should programming work the math way, or the C way?
...And that is how we know the Earth to be banana-shaped.

enk
Posts: 754
Joined: Mon Sep 10, 2007 12:20 am UTC
Location: Aalborg, Denmark
Contact:

### Re: What should x < y < z do?

The C way is meant for computers more than for humans, and it will lead to errors just like "if (x = 5) ohshit();".
phlip wrote:Ha HA! Recycled emacs jokes.

Thesh
Posts: 5812
Joined: Tue Jan 12, 2010 1:55 am UTC

### Re: What should x < y < z do?

Outside of a programming language, x < y < z should mean x < y and y < z. Within a programming language, I am fine with having to write (x<y) && (y<z). Although I can see how it would be nice in some situations, it makes it more complicated to define the rules.
The rage in their eyes, torches in their hands
And the power of the cross bringing fear to all the land
And darkness will come to us all.

phlip
Restorer of Worlds
Posts: 7550
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

### Re: What should x < y < z do?

I can't remember what language it was, but I'm sure I've used one once that has "a == b == c" meaning "(a==b) && (b == c)", and similarly for inequalities. Also "a == b or c" meaning "(a == b) || (a == c)". Some kind of special-purpose language... maybe Inform? I can't remember.

I guess it's handy syntactic sugar, but that's all it is, and it makes the grammar of the language much more complicated... the equality and inequality tests no longer being binary operators but now arbitrary-size operators...

Code: Select all

`enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}`
[he/him/his]

Thesh
Posts: 5812
Joined: Tue Jan 12, 2010 1:55 am UTC

### Re: What should x < y < z do?

phlip wrote:I can't remember what language it was, but I'm sure I've used one once that has "a == b == c" meaning "(a==b) && (b == c)", and similarly for inequalities. Also "a == b or c" meaning "(a == b) || (a == c)". Some kind of special-purpose language... maybe Inform? I can't remember.

I guess it's handy syntactic sugar, but that's all it is, and it makes the grammar of the language much more complicated... the equality and inequality tests no longer being binary operators but now arbitrary-size operators...

For those two, you could borrow from SQL and keep the grammar simple:

a == all (b,c)
a == any (b,c)
The rage in their eyes, torches in their hands
And the power of the cross bringing fear to all the land
And darkness will come to us all.

Meteorswarm
Posts: 979
Joined: Sun Dec 27, 2009 12:28 am UTC
Location: Ithaca, NY

### Re: What should x < y < z do?

phlip wrote:I can't remember what language it was, but I'm sure I've used one once that has "a == b == c" meaning "(a==b) && (b == c)", and similarly for inequalities. Also "a == b or c" meaning "(a == b) || (a == c)". Some kind of special-purpose language... maybe Inform? I can't remember.

I guess it's handy syntactic sugar, but that's all it is, and it makes the grammar of the language much more complicated... the equality and inequality tests no longer being binary operators but now arbitrary-size operators...

a<b<c seems to work as intended in python:

Code: Select all

`>>> a = 1>>> b = 2>>> c = 3>>> a<b<cTrue>>> a<c<bFalse>>> b<a<cFalse>>> a<cTrue`

and so does a == b == c

Code: Select all

`>>> d = 1>>> a == 1 == dTrue>>> a == 1 == bFalse>>> a == b == dFalse>>> b == 1 == dFalse`
The same as the old Meteorswarm, now with fewer posts!

Xanthir
My HERO!!!
Posts: 5281
Joined: Tue Feb 20, 2007 12:49 am UTC
Contact:

### Re: What should x < y < z do?

Python supports chaining the boolean operators. So does Lisp, because they're not operators, just n-ary functions:

Code: Select all

`(< x y z)#| return true iff (and (< x y) (< y z)) |#(= x y z)#| return true iff (and (= x y) (= y z)) |#`
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

enk
Posts: 754
Joined: Mon Sep 10, 2007 12:20 am UTC
Location: Aalborg, Denmark
Contact:

### Re: What should x < y < z do?

I like how someone changed their vote from the first to the second poll option
phlip wrote:Ha HA! Recycled emacs jokes.

Robert'); DROP TABLE *;
Posts: 730
Joined: Mon Sep 08, 2008 6:46 pm UTC
Location: in ur fieldz

### Re: What should x < y < z do?

Xanthir wrote:Python supports chaining the boolean operators. So does Lisp, because they're not operators, just n-ary functions:

Code: Select all

`(< x y z)#| return true iff (and (< x y) (< y z)) |#(= x y z)#| return true iff (and (= x y) (= y z)) |#`

Though I'd argue that Lisp sidesteps the issue by making (x < y < z) an invalid/nonsensical statement.
...And that is how we know the Earth to be banana-shaped.

troyp
Posts: 557
Joined: Thu May 22, 2008 9:20 pm UTC
Location: Lismore, NSW

### Re: What should x < y < z do?

phlip wrote:I can't remember what language it was, but I'm sure I've used one once that has "a == b == c" meaning "(a==b) && (b == c)", and similarly for inequalities. Also "a == b or c" meaning "(a == b) || (a == c)". Some kind of special-purpose language... maybe Inform? I can't remember.

I guess it's handy syntactic sugar, but that's all it is, and it makes the grammar of the language much more complicated... the equality and inequality tests no longer being binary operators but now arbitrary-size operators...

In Python you can chain as many comparison operators as you like and they're ANDed. I think this is a good choice for Python, and probably most languages. It's not that complicated and the operators are still binary, it's just instead of having, say, a left- or right-associating law, you have a chaining law to interpret a sequence of operations (*). The only thing a bit funny about this is that bool is actually an int subtype in Python, and you can add True + 1 to give 2, which makes a case for having associative comparison operators like in C. Still, no-one really *thinks* of bools as ints (well, I don't anyway), so what the hell - chained comparisons are way more convenient.
That ==...or syntax is just evil though - that's gotta make things more complicated.

I always wish Haskell had declarations for nonassociative (t->t->Bool) operators to allow this sort of chaining so you could just say "infixc 4 >" etc. Haskell already has a very mathy syntax and it should fit right in.

(*) of course, you have to "share" the middle operands between the 2 operators in order to regard them as just binary operators...which I guess is why you're considering them as n-ary compound operators.

chridd
Has a vermicelli title
Posts: 813
Joined: Tue Aug 19, 2008 10:07 am UTC
Location: ...Earth, I guess?
Contact:

### Re: What should x < y < z do?

troyp wrote:I always wish Haskell had declarations for nonassociative (t->t->Bool) operators to allow this sort of chaining so you could just say "infixc 4 >" etc. Haskell already has a very mathy syntax and it should fit right in.
It's possible to define something sort of like that, if you use different symbols for the first and second operators (e.g., x <| y |< z instead of x < y < z).

Spoilered for length:
Spoiler:

Code: Select all

`-- | Define chained operators, for ease of entering expressions like 1 < 2 < 3.-- This module defines three extra variations of each of the operators '<',-- '<=', and '==', for use at the beginning, middle, and end of such chains.-- These operators have vertical bars on the inside of the chain, for instance:---- >x <| y |< z-- >1 <| 2 |<| 3 |<=| 3 |< 4-- >square (0,0) ==| square (0,1) |== square (0,2)---- These operators are defined to be left-associative and the same precedence-- as the ordinary comparison operators.---- Copyright (c) 2010 chriddmodule ChainCompare wherechainBegin :: (a -> b -> Bool) -> a -> b -> Maybe bchainBegin op x y = if x `op` y then Just y else NothingchainEnd :: (a -> b -> Bool) -> Maybe a -> b -> BoolchainEnd op x y = maybe False (`op` y) xchainMiddle :: (a -> b -> Bool) -> Maybe a -> b -> Maybe bchainMiddle = chainBegin . chainEndinfixl 4 <|, |<, |<|(<|) :: Ord a => a -> a -> Maybe a(<|) = chainBegin (<)(|<) :: Ord a => Maybe a -> a -> Bool(|<) = chainEnd (<)(|<|) :: Ord a => Maybe a -> a -> Maybe a(|<|) = chainMiddle (<)infixl 4 <=|, |<=, |<=|(<=|) :: Ord a => a -> a -> Maybe a(<=|) = chainBegin (<=)(|<=) :: Ord a => Maybe a -> a -> Bool(|<=) = chainEnd (<=)(|<=|) :: Ord a => Maybe a -> a -> Maybe a(|<=|) = chainMiddle (<=)infixl 4 ==|, |==, |==|(==|) :: Eq a => a -> a -> Maybe a(==|) = chainBegin (==)(|==) :: Eq a => Maybe a -> a -> Bool(|==) = chainEnd (==)(|==|) :: Eq a => Maybe a -> a -> Maybe a(|==|) = chainMiddle (==)`
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · she(?)(?(?)(?))(?(?(?))(?))(?) · Forum game scores
Avatar: Lilac from Freedom Planet until someone posts in the avatar game
mittfh wrote:I wish this post was very quotable...
flicky1991 wrote:In both cases the quote is "I'm being quoted too much!"

Goplat
Posts: 490
Joined: Sun Mar 04, 2007 11:41 pm UTC

### Re: What should x < y < z do?

Neither, it should be an error. x < y is a boolean, and it doesn't make sense to talk about a boolean being "less than" something unless you treat it as a number (which should require an explicit conversion).

Xanthir
My HERO!!!
Posts: 5281
Joined: Tue Feb 20, 2007 12:49 am UTC
Contact:

### Re: What should x < y < z do?

Well, duh. The question is if *that* behavior makes more sense, or if it's better to be smart about chained comparisons and treat them as sugar for the "(x<y) and (y<z)".
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

troyp
Posts: 557
Joined: Thu May 22, 2008 9:20 pm UTC
Location: Lismore, NSW

### Re: What should x < y < z do?

chridd wrote:It's possible to define something sort of like that, if you use different symbols for the first and second operators (e.g., x <| y |< z instead of x < y < z).

I remember when I first learnt Haskell I made variadic functions and then I tried to modify them to make chained comparators. I had trouble getting it to work with the infix operators though. I didn't want to use new operators, let alone different ones at the first and last positions (but I was using a start and end symbol to enclose the entire expression). I think I gave up on it in the end (it wouldn't have been practical anyway).
Your implementation is quite nice: if you changed the vertical bars to dots, it would look pretty unobtrusive eg.

Code: Select all

`1 <. 2 .<. 4 .>.3`
assuming you're not already using those symbols.
Even so, once you need to use special symbols to chain the operators, I'd probably just prefer the usual syntax

Code: Select all

`1<2 && 2<4 && 4>3`
It's not so bad, although I would still prefer builtin support for chaining

flying sheep
Posts: 63
Joined: Sun Jan 31, 2010 12:35 am UTC

### Re: What should x < y < z do?

Goplat wrote:Neither, it should be an error. x < y is a boolean, and it doesn't make sense to talk about a boolean being "less than" something unless you treat it as a number (which should require an explicit conversion).

if you are designing a language and a certain phrase can be interpretted intuitively and unambiguously by humans, why throw a syntax error?

so this is really about typing and expectations:
if your language is statically typed, it should be interpretted the mathematical way. (x<y<z can only mean one thing or be a syntax error, so it should work)
if your language is dynamically typed (a bool can be compared with a non-bool), it should throw an error, except the language design has guidelines which only alow one way.
e.g. python has the principle of least surprise, so it works like you would expect (the mathematical way)
languages like perl, on the other hand, should really thow an error in this case, nobody has ever suspected perl of having guidelines or the principle of least surprise (more like the principle of least script size)

to sum things up: it should be interpretted the mathematical way or throw an error, if the language design isn’t clear.

Random-person
Posts: 21
Joined: Mon Dec 13, 2010 1:25 am UTC

### Re: What should x < y < z do?

flying sheep wrote:
Goplat wrote:Neither, it should be an error. x < y is a boolean, and it doesn't make sense to talk about a boolean being "less than" something unless you treat it as a number (which should require an explicit conversion).

if you are designing a language and a certain phrase can be interpretted intuitively and unambiguously by humans, why throw a syntax error?

Because x < y < z is very much not something that can be interpreted intuitively and unambiguously by humans!

That's why it's better in some cases to throw an error. Sure, it might be annoying the first time, but you would prevent a bug that could be really nasty.
It all depends on what you think is most important: for a program to be bug free or for a program to be quick and easy to use. I think that both language types should exist, like they do today.

Xanthir
My HERO!!!
Posts: 5281
Joined: Tue Feb 20, 2007 12:49 am UTC
Contact:

### Re: What should x < y < z do?

Wait, what? You should have seen notation like "x < y < z" in high-school Algebra, if not sooner. It should be intuitively obvious.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))

Goplat
Posts: 490
Joined: Sun Mar 04, 2007 11:41 pm UTC

### Re: What should x < y < z do?

It's only obvious because we're used to it. Other operators don't work like that: x + y + z is (x + y) + z, x - y - z is (x - y) - z, x * y * z is (x * y) * z, and x / y / z is (x / y) / z. It's certainly not intuitive at all that just because OP returns a boolean, "x OP y OP z" should instead mean "(x OP y) && (y OP z)".

What if the || operator worked like that? x || y || z would be treated as (x || y) && (y || z), which is logically equivalent to y && (x || z). Not so intuitive now, is it

There is no place for inconsistency in programming languages. Writing bug-free code is hard enough as it is.

flying sheep
Posts: 63
Joined: Sun Jan 31, 2010 12:35 am UTC

### Re: What should x < y < z do?

Goplat wrote:It's only obvious because we're used to it […]
stop right here!
isn’t that what it’s all about?

Robert'); DROP TABLE *;
Posts: 730
Joined: Mon Sep 08, 2008 6:46 pm UTC
Location: in ur fieldz

### Re: What should x < y < z do?

Goplat wrote:What if the || operator worked like that? x || y || z would be treated as (x || y) && (y || z), which is logically equivalent to y && (x || z). Not so intuitive now, is it

But it is, because this is functionally identical to the other possible meaning, (x || y) || z.
...And that is how we know the Earth to be banana-shaped.

Yakk
Poster with most posts but no title.
Posts: 11077
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

### Re: What should x < y < z do?

a OP1 b OP1 c "should" mean OP1( a, b, c ). In effect, demand that your operators be n-ary.

If operators can belong to an operator class, you can talk about operators whose n-ary definition is chained-left-to-right-binary or tree-binary, others whose n-ary definition is left-to-right, others whose n-ary definition is right-to-left, and others whose n-ary definition is pair-wise and and'd (or pairwise and or'd).

a OP1 b OP2 c ... means what? One rule is "you must use brackets". Another is to require that your operators specify order of application and binding.

a+b*c -- should we require brackets? If not, how do we allow user-defined operators as much freedom in terms of order-of-operations as built-in operators?
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

Xanthir
My HERO!!!
Posts: 5281
Joined: Tue Feb 20, 2007 12:49 am UTC
Contact:

### Re: What should x < y < z do?

Goplat wrote:It's only obvious because we're used to it. Other operators don't work like that: x + y + z is (x + y) + z, x - y - z is (x - y) - z, x * y * z is (x * y) * z, and x / y / z is (x / y) / z. It's certainly not intuitive at all that just because OP returns a boolean, "x OP y OP z" should instead mean "(x OP y) && (y OP z)".

What if the || operator worked like that? x || y || z would be treated as (x || y) && (y || z), which is logically equivalent to y && (x || z). Not so intuitive now, is it

There is no place for inconsistency in programming languages. Writing bug-free code is hard enough as it is.

Math operators aren't comparison operators, nor are logical operators. Math operators take numbers as input and produce numbers as output. Logical operators take bools as input and produces bools as output. For both of these, it's sensical that chained operators work by reducing over the list, because the output is a valid input for another round of computation.

Comparison operators take arbitrary comparable values as input and produce bools as output. It does *not* make sense to evaluate these by reducing over the list (particularly as bools aren't comparable, except by arbitrary fiat). It *does* make sense to evaluate these pairwise and then take the AND of all the results.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))