Why does == and equals produce different results? - reflection

Executing the following code:
inline fun <reified R> foobar() {
println(R::class == Double::class)
println(R::class.equals(Double::class))
}
fun main(args: Array<String>) {
foobar<Double>()
}
Produces the following output:
false
true
Why is there a difference between == and equals in this case? IntelliJ itself is suggesting that I replace the equals call with ==. Also, I could have sworn this code using == was working in the past.
Using kotlin version 1.1.0-rc91

This behavior is a known issue in code generation for class tokens of reified type parameters, it's tracked here: KT-17748.

Related

Return integer using TclTK from C library

I have C code that uses Tcl/Tk library. I then create a library using this C code which is then linked to R language package. I have a function in the C code:
int doSomething(){
if(TRUE){
return TCL_OK;
else{
TCL_RESULT3("Error")
return TCL_OK;
}
Currently, I use TCL_RESULT3("Error") in the C code, and then in R check if result <- tclvalue(tcl(...)) #calls doSomething() returns a string with Error:
if (startsWith(result, "Error"))
{
return(FALSE)
}
return(TRUE)
and base further actions in R on the returned value.
However, even though there is an error, I still call TCL_OK because TCL_ERROR produces something that R cannot seem to handle (at least it is not straightforward). My question is if it is possible to restructure my function as:
int doSomething(){
if(TRUE){
return TCL_OK;
else{
return TCL_ERROR;
}
and have R understand what is being returned. Currently, if TCL_OK is returned, then result will be an empty string "". If TCL_ERROR is returned, then result will yield: Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] . which R does not know how to handle.
Is it possible to have R handle such an error (i.e. return a value of FALSE if this error pops up) or is checking for an error message using TCL_RESULT3() in conjunction with TCL_OK the best method for such a process?
When your C code returns TCL_ERROR (instead of TCL_OK) that's an error condition, which is logically like an exception in other languages. Can R handle those? Yes (apparently; I know very little R). Here's one way (there are others, of course; the right choice depends on what you're doing and the likely cause of the exception).
result <- tryCatch(
{
# This is where you put in the code to call into Tcl
tclvalue(tcl(...)) # calls doSomething()
},
error = function(err) {
message(paste("error occurred in Tcl code:", err))
return(NaN) # Need an alternative result value here
}
)
Note that if you're calling an arbitrary Tcl command, you pretty much have to handle exceptions. Failures are a fact of life, and you need to allow for them in robust code.

Kotlin tail recursive function causing stack overflow

I was working on this easy problem to practice basic Kotlin, and I ran into a stack overflow with the following code on the recursive return line:
class Solution {
fun isPalindrome(s: String): Boolean {
val cleaned = s.toLowerCase().replace(Regex("[^a-z0-9]"), "")
tailrec fun isPalindrome(start: Int, end: Int): Boolean {
if (start >= end) return true
return cleaned[start] == cleaned[end] && isPalindrome(start+1, end-1)
}
return isPalindrome(0, cleaned.length-1)
}
}
My understanding of tailrec is that it's supposed to convert my recursive function into an iterative one, which wouldn't be susceptible to this sort of crash. If I didn't implement tail recursion correctly, the compiler is supposed to issue an error.
Can someone explain to me why this crashes on large inputs, just like a standard recursive call would?
This behavior looks like a missing optimization of tail calls in short circuiting operators, where the fact that the last operand is being evaluated means that the expression result doesn't depend anymore on the previous operands.
Meanwhile you can rewrite your return statement as
return if (cleaned[start] != cleaned[end]) false else isPalindrome(start+1, end-1)
to get the same result + tail call optimization.

if {...} else {...} : Does the line break between "}" and "else" really matters?

I write my if {...} else {...} statement in R in the following way as I find it more readable.
Testifelse = function(number1)
{
if(number1>1 & number1<=5)
{
number1 =1
}
else if ((number1>5 & number1 < 10))
{
number1 =2
}
else
{
number1 =3
}
return(number1)
}
According to ?Control:
... In particular, you should not have a newline between } and else to avoid a syntax error in entering a if ... else construct at the keyboard or via source ...
the function above will cause syntax error, but actually it works! What's going on here?
Thanks for your help.
Original question and answer
If we put in R console:
if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}
why does it not work?
R is an interpreted language, so R code is parsed line by line. (Remark by #JohnColeman: This judgement is too broad. Any modern interpreter does some parsing, and an interpreted language like Python has no problem analogous to R's problem here. It is a design decision that the makers of R made, but it wasn't a decision that was forced on them in virtue of the fact that it is interpreted (though doubtless it made the interpreter somewhat easier to write).)
Since
if (1 > 0) {
cat("1\n");
}
makes a complete, legal statement, the parser will treat it as a complete code block. Then, the following
else {
cat("0\n");
}
will run into error, as it is seen as a new code block, while there is no control statement starting with else.
Therefore, we really should do:
if (1 > 0) {
cat("1\n");
} else {
cat("0\n");
}
so that the parser will have no difficulty in identifying them as a whole block.
In compiled language like C, there is no such issue. Because at compilation time, the compiler can "see" all lines of your code.
Final update related to what's going on inside a function
There is really no magic here! The key is the use of {} to manually indicate a code block. We all know that in R,
{statement_1; statement_2; ...; statement_n;}
is treated as a single expression, whose value is statement_n.
Now, let's do:
{
if (1 > 0) {
cat("1\n");
}
else {
cat("0\n");
}
}
It works and prints 1.
Here, the outer {} is a hint to the parser that everything inside is a single expression, so parsing and interpreting should not terminate till reaching the final }. This is exactly what happens in a function, as a function body has {}.

Forcing specific data types as arguments to a function

I was just wondering if there was a way to force a function to only accept certain data types, without having to check for it within the function; or, is this not possible because R's type-checking is done at runtime (as opposed to those programming languages, such as Java, where type-checking is done during compilation)?
For example, in Java, you have to specify a data type:
class t2 {
public int addone (int n) {
return n+1;
}
}
In R, a similar function might be
addone <- function(n)
{
return(n+1)
}
but if a vector is supplied, a vector will (obviously) be returned. If you only want a single integer to be accepted, then is the only way to do to have a condition within the function, along the lines of
addone <- function(n)
{
if(is.vector(n) && length(n)==1)
{
return(n+1)
} else
{
return ("You must enter a single integer")
}
}
Thanks,
Chris
This is entirely possible using S3 classes. Your example is somewhat contrived in the context or R, since I can't think of a practical reason why one would want to create a class of a single value. Nonetheless, this is possible. As an added bonus, I demonstrate how the function addone can be used to add the value of one to numeric vectors (trivial) and character vectors (so A turns to B, etc.):
Start by creating a generic S3 method for addone, utlising the S3 despatch mechanism UseMethod:
addone <- function(x){
UseMethod("addone", x)
}
Next, create the contrived class single, defined as the first element of whatever is passed to it:
as.single <- function(x){
ret <- unlist(x)[1]
class(ret) <- "single"
ret
}
Now create methods to handle the various classes. The default method will be called unless a specific class is defined:
addone.default <- function(x) x + 1
addone.character <- function(x)rawToChar(as.raw(as.numeric(charToRaw(x))+1))
addone.single <- function(x)x + 1
Finally, test it with some sample data:
addone(1:5)
[1] 2 3 4 5 6
addone(as.single(1:5))
[1] 2
attr(,"class")
[1] "single"
addone("abc")
[1] "bcd"
Some additional information:
Hadley's devtools wiki is a valuable source of information on all things, including the S3 object system.
The S3 method doesn't provide strict typing. It can quite easily be abused. For stricter object orientation, have a look at S4 classes, reference based classesor the proto package for Prototype object-based programming.
You could write a wrapper like the following:
check.types = function(classes, func) {
n = as.name
params = formals(func)
param.names = lapply(names(params), n)
handler = function() { }
formals(handler) = params
checks = lapply(seq_along(param.names), function(I) {
as.call(list(n('assert.class'), param.names[[I]], classes[[I]]))
})
body(handler) = as.call(c(
list(n('{')),
checks,
list(as.call(list(n('<-'), n('.func'), func))),
list(as.call(c(list(n('.func')), lapply(param.names, as.name))))
))
handler
}
assert.class = function(x, cls) {
stopifnot(cls %in% class(x))
}
And use it like
f = check.types(c('numeric', 'numeric'), function(x, y) {
x + y
})
> f(1, 2)
[1] 3
> f("1", "2")
Error: cls %in% class(x) is not TRUE
Made somewhat inconvenient by R not having decorators. This is kind of hacky
and it suffers from some serious problems:
You lose lazy evaluation, because you must evaluate an argument to determine
its type.
You still can't check the types until call time; real static type checking
lets you check the types even of a call that never actually happens.
Since R uses lazy evaluation, (2) might make type checking not very useful,
because the call might not actually occur until very late, or never.
The answer to (2) would be to add static type information. You could probably
do this by transforming expressions, but I don't think you want to go there.
I've found stopifnot() to be highly useful for these situations as well.
x <- function(n) {
stopifnot(is.vector(n) && length(n)==1)
print(n)
}
The reason it is so useful is because it provides a pretty clear error message to the user if the condition is false.

alternative to "!is.null()" in R

my R code ends up containing plethora of statements of the form:
if (!is.null(aVariable)) {
do whatever
}
But this kind of statement is hard to read because it contains two negations. I would prefer something like:
if (is.defined(aVariable)) {
do whatever
}
Does a is.defined type function that does the opposite of !is.null exist standard in R?
cheers,
yannick
You may be better off working out what value type your function or code accepts, and asking for that:
if (is.integer(aVariable))
{
do whatever
}
This may be an improvement over isnull, because it provides type checking. On the other hand, it may reduce the genericity of your code.
Alternatively, just make the function you want:
is.defined = function(x)!is.null(x)
If it's just a matter of easy reading, you could always define your own function :
is.not.null <- function(x) !is.null(x)
So you can use it all along your program.
is.not.null(3)
is.not.null(NULL)
Ian put this in the comment, but I think it's a good answer:
if (exists("aVariable"))
{
do whatever
}
note that the variable name is quoted.
I have also seen:
if(length(obj)) {
# do this if object has length
# NULL has no length
}
I don't think it's great though. Because some vectors can be of length 0. character(0), logical(0), integer(0) and that might be treated as a NULL instead of an error.
To handle undefined variables as well as nulls, you can use substitute with deparse:
nullSafe <- function(x) {
if (!exists(deparse(substitute(x))) || is.null(x)) {
return(NA)
} else {
return(x)
}
}
nullSafe(my.nonexistent.var)
The shiny package provides the convenient functions validate() and need() for checking that variables are both available and valid. need() evaluates an expression. If the expression is not valid, then an error message is returned. If the expression is valid, NULL is returned. One can use this to check if a variable is valid. See ?need for more information.
I suggest defining a function like this:
is.valid <- function(x) {
require(shiny)
is.null(need(x, message = FALSE))
}
This function is.valid() will return FALSE if x is FALSE, NULL, NA, NaN, an empty string "", an empty atomic vector, a vector containing only missing values, a logical vector containing only FALSE, or an object of class try-error. In all other cases, it returns TRUE.
That means, need() (and is.valid()) covers a really broad range of failure cases. Instead of writing:
if (!is.null(x) && !is.na(x) && !is.nan(x)) {
...
}
one can write simply:
if (is.valid(x)) {
...
}
With the check for class try-error, it can even be used in conjunction with a try() block to silently catch errors: (see https://csgillespie.github.io/efficientR/programming.html#communicating-with-the-user)
bad = try(1 + "1", silent = TRUE)
if (is.valid(bad)) {
...
}

Resources