Can (a==1 & a==2 & a==3) ever evaluate to TRUE?
A blogpost inspired by a Stackoverflow question: “Can (a==1 && a==2 && a==3) ever evaluate to true?”
Yesterday I run into this topic on SO, about a JavaScript question a user had during a job interview.
The question is quite straightforward:
Is it ever possible that (a==1 && a==2 && a==3) could evaluate to true, in JavaScript?
As a little challenge, I asked myself the same question, but with R (and
with a little transformation): can a==1 & a==2 & a==3
ever evaluate to
TRUE? Once I’ve found how to, I challenged
Twitter, and
was glad to read some creative answers.
One amazing thing with R is that you can achieve the same result by taking several roads. So, here are a compilation of the answers I received.
First question
Ok \#RStats nerds, here's a little enigma for your sunday :)
— Colin Fay (@\_ColinFay) January 21, 2018
How can you make:
x == 1 & x == 2 & x == 3
return
\[1\] TRUE pic.twitter.com/toV55YhjQJ
Overriding base functions
- By Philippe Chataignon :
x <- 1
`&` <- function(x,y) {T}
x == 1 & x == 2 & x == 3
## [1] TRUE
- By Quentin Read :
`&` <- function(x,y) {T}
x == 1 & x == 2 & x == 3
## [1] TRUE
Number 2
\#RStats nerd quizz number 2 :
— Colin Fay (@\_ColinFay) January 21, 2018
How would you code that?
\> x == 1 & x == 2 & x == 3
\[1\] TRUE
\> x == 3 & x == 2 & x == 1
\[1\] FALSE pic.twitter.com/Tqm0bNz1De
Overriding base functions
- By Antonios K :
x = 1; `&` <- `>`
x == 1 & x == 2 & x == 3
## [1] TRUE
x == 3 & x == 2 & x == 1
## [1] FALSE
- By Jorge Loria :
x <-1
`&` <- function(e1,e2) e1
x == 1 & x == 2 & x == 3
## [1] TRUE
x == 3 & x == 2 & x == 1
## [1] FALSE
Question 3
\#RStats nerd quizz number 3 :
— Colin Fay (@\_ColinFay) January 21, 2018
Find how to:
\> x
\[1\] 1
\> x
\[1\] 2
\> x
\[1\] 3 pic.twitter.com/dskLLHdS6d
A really nice way to frame it
make_x <- function(){
counter <- 1
inc <- function() counter <<- counter + 1
value <- function() counter
structure(list(inc = inc, value = value), class = "x")
}
print.x <- function(x){
v <-x$value()
x$inc()
print(v)
v
}
x <- make_x()
x
## [1] 1
x
## [1] 2
x
## [1] 3
- As suggested by Joel Gombin
rm(list=ls())
library(R6)
make_x <- R6Class("x",
public = list(x = 1,
print = function(){
print(self$x)
self$x <- self$x + 1
}
)
)
x <- make_x$new()
x
## [1] 1
x
## [1] 2
x
## [1] 3
x <- structure(0L, class = "x")
print.x <- function(x) print(as.integer(x <<- x + 1L ))
x
## [1] 1
x
## [1] 2
x
## [1] 3
Sadly, these three solutions don’t answer the three questions in one shot.
One answer to rule them all
One answer that can do the three at once, by Alek Vladimir Nevski.
x <- c(1,1)
`==` <- function(foo,bar){foo[1]+bar}
`&` <- function(foo,bar){
if(isTRUE(foo) || identical(foo,FALSE)){
foo+2<bar
}else{
foo < bar
}
}
class(x) <- c("myclass",class(x))
print.myclass = function(x){
t <- x[2];
x[2] <<- x[2]+1;print(t)
}
# First quizz :
x == 1 & x == 2 & x == 3
## [1] TRUE
# Second quizz :
x == 1 & x == 2 & x == 3
## [1] TRUE
x == 3 & x == 2 & x == 1
## [1] FALSE
# Third quizz :
x
## [1] 1
x
## [1] 2
x
## [1] 3
With active binding
What I had in mind from the beginning was to use active binding. I’ll let you dig into this blogpost if ever you want to know more about it, but basically we bind a function to a symbol instead of a value (which is static binding).
It is called active because each time you evaluate this symbol, R executes a function, instead of looking for a value.
So, here’s my way to answer the “Can (a==1 && a==2 && a==3) ever evaluate to true?”:
rm(list=ls())
makeActiveBinding(sym = "x", env = .GlobalEnv,
fun = function(value){
if (missing(value)) {
if (i == 3){
i <<- 1
} else {
i <<- i + 1
}
return(i)
}
}
)
i <- 0
# First quizz :
x == 1 & x == 2 & x == 3
## [1] TRUE
# Second quizz :
x == 1 & x == 2 & x == 3
## [1] TRUE
x == 3 & x == 2 & x == 1
## [1] FALSE
# Third quizz :
x
## [1] 1
x
## [1] 2
x
## [1] 3
Here, the difference is that the values are actually equal: we’re not
changing the way ==
or &
behave - it’s the value of x
that is
changing each time we’re calling it. With active binding, R is executing
the function defined in fun
, a function that takes i, restarts the
counter or incremente it of 1, and returns it.
How is this interesting?
Beside being a nice R brain game, this example is a nice occasion to
introduce about the concept of binding, and remind that we are most of
the time assuming is static: most of the answers (in fact, all except
one) assume that the value of x
is static, and that we should tweak
the other operators :)
Read more about binding:
What do you think?