What should x < y < z do?
Moderators: phlip, Moderators General, Prelates
 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?
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 bananashaped.
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.
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.
Summum ius, summa iniuria.
 phlip
 Restorer of Worlds
 Posts: 7551
 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 specialpurpose 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 arbitrarysize operators...
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 arbitrarysize operators...
Code: Select all
enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵╰(ಠ_ಠ ⚠) {exit((int)⚠);}
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 specialpurpose 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 arbitrarysize operators...
For those two, you could borrow from SQL and keep the grammar simple:
a == all (b,c)
a == any (b,c)
Summum ius, summa iniuria.
 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 specialpurpose 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 arbitrarysize operators...
a<b<c seems to work as intended in python:
Code: Select all
>>> a = 1
>>> b = 2
>>> c = 3
>>> a<b<c
True
>>> a<c<b
False
>>> b<a<c
False
>>> a<c
True
and so does a == b == c
Code: Select all
>>> d = 1
>>> a == 1 == d
True
>>> a == 1 == b
False
>>> a == b == d
False
>>> b == 1 == d
False
The same as the old Meteorswarm, now with fewer posts!
 Xanthir
 My HERO!!!
 Posts: 5311
 Joined: Tue Feb 20, 2007 12:49 am UTC
 Location: The Googleplex
 Contact:
Re: What should x < y < z do?
Python supports chaining the boolean operators. So does Lisp, because they're not operators, just nary 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)))
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 nary 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 bananashaped.
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 specialpurpose 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 arbitrarysize 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 rightassociating 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, noone 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 nary compound operators.
 chridd
 Has a vermicelli title
 Posts: 822
 Joined: Tue Aug 19, 2008 10:07 am UTC
 Location: ...Earth, I guess?
 Contact:
Re: What should x < y < z do?
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).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.
Spoilered for length:
Spoiler:
~ chri d. d. /tʃɹɪ.di.di/ (Phonotactics, schmphonotactics) · she(?)(?(?)(?))(?(?(?))(?))(?) · Forum game scores
mittfh wrote:I wish this post was very quotable...
flicky1991 wrote:In both cases the quote is "I'm being quoted too much!"
chridd (on Discord) wrote:SYG'DDummy wrote:Sorry You're Gay Dads
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: 5311
 Joined: Tue Feb 20, 2007 12:49 am UTC
 Location: The Googleplex
 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)))
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
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
 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).
let’s talk about language design:
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 nonbool), 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.

 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).
let’s talk about language design:
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: 5311
 Joined: Tue Feb 20, 2007 12:49 am UTC
 Location: The Googleplex
 Contact:
Re: What should x < y < z do?
Wait, what? You should have seen notation like "x < y < z" in highschool Algebra, if not sooner. It should be intuitively obvious.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))
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 bugfree code is hard enough as it is.
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 bugfree 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?
stop right here!Goplat wrote:It's only obvious because we're used to it […]
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 bananashaped.
 Yakk
 Poster with most posts but no title.
 Posts: 11083
 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 nary.
If operators can belong to an operator class, you can talk about operators whose nary definition is chainedlefttorightbinary or treebinary, others whose nary definition is lefttoright, others whose nary definition is righttoleft, and others whose nary definition is pairwise 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 userdefined operators as much freedom in terms of orderofoperations as builtin operators?
If operators can belong to an operator class, you can talk about operators whose nary definition is chainedlefttorightbinary or treebinary, others whose nary definition is lefttoright, others whose nary definition is righttoleft, and others whose nary definition is pairwise 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 userdefined operators as much freedom in terms of orderofoperations as builtin 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.
Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.
 Xanthir
 My HERO!!!
 Posts: 5311
 Joined: Tue Feb 20, 2007 12:49 am UTC
 Location: The Googleplex
 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 bugfree 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)))
Who is online
Users browsing this forum: No registered users and 5 guests