Skip to content

a < b < c is alway TRUE

20 messages · Uwe Ligges, Monika Ferster, Peter Malewski +11 more

#
One of our students did something like:

  x[a < b < c]

instead of 

  x[a < b & b < c]


But why is

  3 < 2 < 1	# [1] TRUE ???


Is there any reason? 
Or wouldn't it be better to get a warning / error?

Uwe Ligges
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Uwe Ligges writes:
 > One of our students did something like:
 > 
 >   x[a < b < c]
 > 
 > instead of 
 > 
 >   x[a < b & b < c]
 > 
 > 
 > But why is
 > 
 >   3 < 2 < 1	# [1] TRUE ???
 > 

3 < 2 < 1 seems to be seen like a double no because 3 < 2 < 1 < 0 returns
F. It looks like the multiplication of -1 what is strange, because F
corresponds to the value 0. So if you do (3<2)*(2<1) you get 0 and not the
value of T (=1).
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Monika Ferster wrote:
3 < 2 is FALSE=0, and 0<1 is always TRUE.

  
    
#
[1] FALSE
[1] TRUE
[1] 0


p.
On Fri, Jul 06, 2001 at 12:08:51PM +0200, Monika Ferster wrote:

  
    
#
I forgot the explanation: R (and s+3) evalutes from left to right and 
converts logical to numeric. see below.
On Fri, Jul 06, 2001 at 12:48:01PM +0200, Peter Malewski wrote:

  
    
#
this is evaluated from left to right:
(3<2)<1

3<2 = FALSE
FALSE<1 = TRUE

what's surprising is the following:
[1] TRUE
[1] FALSE
[1] FALSE
[1] FALSE

because of symmetry i'd expect TRUE>1 to be TRUE.

cu
till

--
"I have seen things you people wouldn't believe.
Attack-ships  on fire off the shoulder of Orion.
I watched seabeams glitter in the dark near the 
Tannhauser gate.
All  those  moments  will  be lost in time like
tears in rain. Time to die."              (Roy)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
The answer is simple: the first inequation 3 < 2 is solved, which gives
FALSE. Then the second inequation to be solved is: FALSE < 1. Since
as.numeric(FALSE) is 0, you have to solve 0 < 1, which is... TRUE. Hence,
this is not a bug, but an incorrect use of the R language.
Best regards,

Philippe Grosjean


...........]<(({?<...............<?}))><...............................
 ) ) ) ) )	 __               	 __
( ( ( ( ( 	|__)              	|  _
 ) ) ) ) )	|   hilippe       	|__)rosjean
( ( ( ( ( 	Marine Biol. Lab., ULB, Belgium
 ) ) ) ) )	                  	 __
( ( ( ( ( 	|\  /|            	|__)
 ) ) ) ) )	| \/ |ariculture &	|__)iostatistics
( ( ( ( (
 ) ) ) ) )	e-mail: phgrosje at ulb.ac.be or phgrosjean at sciviews.org
( ( ( ( ( 	SciViews project coordinator (http://www.sciviews.org)
 ) ) ) ) )      tel: 00-32-2-650.29.70 (lab), 00-32-2-673.31.33 (home)
( ( ( ( (
 ) ) ) ) )      "I'm 100% confident that p is between 0 and 1"
( ( ( ( (                                  L. Gonick & W. Smith (1993)
 ) ) ) ) )
.......................................................................


-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
evaluation from left to right:

3 < 2 < 1 < 0 
reads like
((3<2)<1)<0 
evaluates to
( FALSE < 1) < 0
evaluates to
TRUE < 0 
evaluates to
FALSE

cu
till

--
"I have seen things you people wouldn't believe.
Attack-ships  on fire off the shoulder of Orion.
I watched seabeams glitter in the dark near the 
Tannhauser gate.
All  those  moments  will  be lost in time like
tears in rain. Time to die."              (Roy)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Monika Ferster wrote:
Not really because:
[1] FALSE
[1] FALSE
[1] TRUE

Somehow 3<2<1 remains special.
#
Till Baumgaertel wrote:
ARRRGGH! It's very hot in germany today and my brain seems to have taken
its holidays. ;-)
Thanks to all who responded!

Uwe Ligges
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Till Baumgaertel wrote:
Not surprising at all; the symmetric case is
[1] TRUE
[1] FALSE

TRUE is neither greater nor less than 1; it's exactly 1.
And also note that not(<) is >=, and not >.

-d

  
    
#
----- Original Message -----
From: "Till Baumgaertel" <till.baumgaertel at epost.de>
To: <r-help at stat.math.ethz.ch>
Cc: "Uwe Ligges" <ligges at statistik.uni-dortmund.de>
Sent: Friday, July 06, 2001 5:21 AM
Subject: Re: [R] a < b < c is alway TRUE
TRUE is being treated as equal to 1, so TRUE >= 1, returns TRUE. However,
non-zero values are treated as TRUE when coercing numerical values.
[1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE

-Bill

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On Fri, 6 Jul 2001 13:21:51 +0200, you wrote in message
<3B45BB6F.6582.E1B7B at localhost>:
In R like C, FALSE is 0 and TRUE is 1.  This is a bad thing, but it's
too late to change it now.  With that substitution, all the results
look reasonable:  0>1, 1<1 and 1>1 are all false, but 0<1 is true.

Why a bad thing?  Because it leads to absurdities like this whole
thread has been discussing!

What should they have done?  They should have done what Fortran,
Pascal, etc. do, and have a separate logical or boolean type that
isn't automatically converted to a numerical type.  In Pascal for
instance, "3 < 2 < 1" is flagged as a syntax error, because you can't
compare a boolean to an integer.  If you really want to do the weird
comparison that R is doing, you need to enter it as "ord(3 < 2) < 1",
and any reader will see that you're doing something weird.

Duncan Murdoch
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
i think this is a misunderstanding: this thread is not from absurdistan but 
from userland.
in my understanding R compares better to an comuter algebra system like 
mathematica than to a programming language like pascal or so. 

i don't know the mathematica-syntax for the natural "3 < 2 < 1", but i think 
it's a BAD idea to force *users* to write something weired like "ord(3 < 2) < 
1". 

in an *application-oriented* statistical software-system natural syntax should 
be preferred to a "programmological"-syntax. thus it would be more user-
friendly to re-write the parser/scanner parts of R in a way that "3 < 2 < 1" is 
naturally-correct evaluated to FALSE. 

on the other hand, r is open-source and i could do it myself...

cu
till

--
"I have seen things you people wouldn't believe.
Attack-ships  on fire off the shoulder of Orion.
I watched seabeams glitter in the dark near the 
Tannhauser gate.
All  those  moments  will  be lost in time like
tears in rain. Time to die."              (Roy)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On Fri, 6 Jul 2001, Duncan Murdoch wrote:
Well, actually R does have a separate logical type for precisely this
reason. That's why, say
  2+2==4
evaluates to TRUE in R, not to 1, and why logical subscripts are different
from integer subscripts
For example
  x[is.na(x)]
returns the non-missing elements of x, but x[as.numeric(is.na(x))] returns
as many copies of the first elements as there are missing elements.

The feature/bug/wart in R that causes this whole discussion is that
numerical operators in R try to coerce their arguments to numbers, so that
if a or b is logical in
  a<b
we actually evaluate
  as.numeric(a)<as.numeric(b)

Also, we coerce going the other way in if() statements, to make
	if(length(x))
work. This latter coercion is relatively recent and was done for
compatibility with C programmers writing in S.

Certainly a<b<c has no sensible use: if c is numeric it is nonense and if
c is logical it is c & !(a<b).  I would even contend that it is a bad sign
if you know what
	3<2<1
will evaluate to without careful thought or testing on a copy of R.


	-thomas

Thomas Lumley			Asst. Professor, Biostatistics
tlumley at u.washington.edu	University of Washington, Seattle

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Well now, look.

If I write down
   3 + 2 * 7
we HAVE to have some agreement on how to do evaluate that, because 
different ways give different results. Same thing with
   3 < 2 < 1
We have to have rules that govern how it is interpreted.

We have rules. They are simple and easily understood. Others have 
already reminded us what they are.

With the small, simple, addition of rules for converting between 
numeric and logical types, the rules that govern 3 < 2 < 1 are the 
same as those that govern an expression like
   10/2*5
which is also ambiguous without an agreement on what the rules are. 
The type conversion rule is nothing new--many other programming 
languages also interpret 0 as false and 1 as true in various 
contexts. For example, try this fortran program:

       program foo
       if (1) write(*,*) 'true'
       if (0) write(*,*) 'false'
       end

This type conversion rule is not a bad thing. It's just a rule. All 
rules have pros and cons. Different languages make different choices. 
So what?

We might think that 3 < 2 < 1 is an expression that makes sense, in 
human terms, (perhaps because it kind of connects with the concept of 
transitivity), and therefore R ought to interpret it that way. But 
what about
   3 < 2 > 5
Huh? It's kind of nonsense. Unless you have well defined rules of syntax.

If you write expressions in language A but think they're going to get 
interpreted according to the rules of language B, you're going to get 
in trouble. The individual who posted the original question, when he 
realized his mistake, said, in effect -- Oh, of course, I just had a 
momentary lapse. (I think that's a fair characterization, apologies 
if it's not.) He didn't start complaining about what he thought the 
rules ought to be. In the present case the rules just aren't that 
weird. In my opinion they are simple and reasonable.

soapbox off

-Don
#
----- Original Message -----
From: Thomas Lumley <tlumley at u.washington.edu>
To: Duncan Murdoch <murdoch at stats.uwo.ca>
Cc: <r-help at stat.math.ethz.ch>
Sent: Friday, July 06, 2001 8:29 AM
Subject: Re: [R] a < b < c is alway TRUE
[1] TRUE
[1] TRUE
....But you knew that....



 and why logical subscripts are different
-.-.-
http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._.
_._
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
On Fri, 6 Jul 2001 13:50:49 -0700, you wrote:

            
When I try that in g77, I get syntax errors:
I don't doubt there is some dialect of Fortran that accepts such
constructions, but it's not a dialect that I'd want to use.

As a general principle, code should be easy to read and understand by
the target audience.  If your audience is C programmers, then it's
fine to write junk like "if (1) ...", but if your audience is
statisticians, it's better if what you write is closer to standard
mathematical syntax.  Since 0 and 1 are numbers, not logical values,
it would be better if they were treated as such in R.  Since "3 < 2 <
1" has the interpretation "false" in standard mathematical notation,
if R is to accept it, it would be better if it had the same value in
R.

HOWEVER, R is already old, and is essentially S, which is very old.  
"3 < 2 < 1" has a well-defined meaning in R.  Changing it now would be
a bad thing.  Adding warnings (or even a lint-like utility to check
through R source code) for constructions like this which are likely
sources of bugs would be a good thing, but there are a lot of good
things to do, and only a finite amount of time for people to do them.
Adding this wouldn't  be at the top of my priority list.

Duncan Murdoch
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Duncan Murdoch <dmurdoch at pair.com> writes:
(S is not *that* old (New S, 1988), but it does build on principles of
parser construction that are a decade or more older.)

The general principle is that rules should be clear and consistent!
You don't get anywhere by assuming that computer scientists don't know
what they are doing and trying to change rules to suite a naive
audience. Hardly any programming language allows the 1 < x < 2
construct. Either they throw an error or they do something unexpected
(but logical) due to type coercion. (Also, I don't think any versions
of *formal* mathematical logic would allow that notation, relational
operators are binary.) 

Whenever you try to make a language do something "intuitive" you also
find gotchas lurking inside, and of a different sort than what you
could figure out by considering the rules as they are, instead of what
you expect them to be.

Consider the following:

x <- rep(NA,10)
x < 0

This will work fine and the result of the comparison is a vector of
NA's. However, NA is a logical constant, so if you tried to prevent
comparisons of logicals to numericals, it would bomb. These all-NA
vectors can creep in all over the place, so you'd get to pepper large
portions of your code with checks like

if (is.logical(x) && all(is.na(x))) rep(NA,length(x)) else x < 0

(There have been countless of these isues coming up over the years,
and most often, once the full implications of a change of semantics
has been realized, they have ended with a "perhaps Uncle John was
right after all"...)
#
If memory serves, one main reason we allowed (silent) conversion from
logical (FALSE, TRUE) to numeric (0, 1) was for indexing.  Programming
tricks of the form of:

   c("negative", "positive")[ (x >= 0) + 1]

Not that I'm advocating this as good practice, but it provided a compact
way to generate information.  (and, yes, we picked up Fortran (and APL)
style indexing from 1 rather than C style indexing from 0, so we did
need to add the 1)

Converting logical to numeric and then using the result in a comparison
operation, as opposed to an arithmetic operation, seems unlikely to be
what the user intended, on the other hand.  As Duncan Murdoch commented,
putting out a warning for the expression
  a < b < c
would seem a good thing, if not exactly high priority.

Most people with any substantial computing experience would probably
realize that what they meant to say was
  a < b & b < c
If it wasn't and they wanted the warning message to shut up, they would
need to write
 as.numeric( a< b) < c

Yes, we probably should have been less fond of "cute" programming tricks
like the example.  In our defense, though, sometimes they helped people
to program in "whole object" terms, particularly in the days when
interfacing to C and other languages was less flexible.

John