sergutsan / JDecafCompiler

A Java precompiler for educational purposes
1 stars 0 forks source link

== should behave as .equals() #1

Closed sergutsan closed 9 years ago

sergutsan commented 11 years ago

One thing that novice programmers find really confusing is that == does not work in the same way for ints and for Strings. As we know, Strings in Java must be compared with .equals(), but this is something that is counterintuitive. It is bad enough that we need to say == and not just =, .equals() is too much.

To make matters worse, == sometimes works as expected, as illustrated by this code:

String s1 = "AAA"; String s2 = "AAA"; String s3 = new String("AAA"); int count = 0; if (s1 == s1) count++; if (s1 == s2) count++; if (s1 == s3) count++; System.out.println("There are " + count + " out of 3 cases where == behaves more or less in the way novices expect.");

that outputs

There are 2 out of 3 cases where == behaves more or less in the way novices expect.

Because of these two factors:

  1. The syntax of .equals() is difficult for novices
  2. The behaviour of == with String is really difficult to understand.

I recommend that

In Java Decaf, == and .equals() are synonyms, i.e. all Java Decaf references to == are substituted by Java's .equals() ---except between primitive types of course---.

Or at least, do this for Strings.

sergutsan commented 10 years ago

Any update on this? 0:-)

sergutsan commented 10 years ago

Thanks to auto-boxing and unboxing, maybe a simpler solution can be:

  1. Box all primitives, i.e. change all 'int' for 'Integer', etc
  2. Change all '==' for '.equals()'
sergutsan commented 10 years ago

First part implemented in 7d02707, 7cf191c, 629310a, and 05cef2c.

sergutsan commented 10 years ago

Maybe the approach from #issuecomment-58523631is not that good. Look at the following code:

String str = System.console().readLine();
int i = Integer.parseInt(str);
int j = i;
print(i);
while (j>0)
{
  j--;
  if(i % j == 0)
  {
    println(i + " is not a prime number");
    break;
  }
}
println(i + " is a prime number");

The line " if(i % j == 0)" cannot be easily transformed into something that works. It requires syntactic analysis to understand that an expression like "i % j" or "i + j" results in an int, that it should be bracketed, and then boxed.

Either we create a proper compiler for Java Decaf or we think this == vs .equals() problem in a different way. Problem is, I do not know what to do apart from a proper compiler... how can the following code be transformed otherwise?

if ("string" == myString)
sergutsan commented 10 years ago

The "box exerything and then substitute all =='s with .equal()" was a bad idea, as illustrated by the following example:

if (1 + 1 == 2) {
    println("It works!");
}

which results in a cryptic error:

Error on line 1 in file:/tmp/error4.jdc
Problem: bad operand types for binary operator '+'
  first type:  java.lang.Integer
  second type: boolean

If we try to fix the code with brackets:

if ((1 + 1) == 2) {
    println("It works!");
}

then we get an even more cryptic error message:

Error on line 1 in file:/tmp/error4.jdc
Problem: int cannot be dereferenced