For example, the first output of the following program is 4, but the second is still 7.
program main
integer m,n
m = 7
call corrupt(m)
write (*,*) m
n = 7
write (*,*) n
stop
end program main
subroutine corrupt (a)
integer a
a = 4
return
end call corrupt(7)
which causes a segfault for me. I suppose if you were using a compiler/platform that didn't store constants in read only memory, this might actually work. program main
integer m,n
call corrupt(7)
write (*,*), 7
stop
end program main
subroutine corrupt (a)
integer a
a = 4
return
end
to output 4. Thanks for pointing this out, 'concede_pluto. Pretty weird!The reason was that in one subroutine, a parameter value was stored in a local variable, then used for computation and restored at the end. Since constants was stored in read only memory when using g77 on Linux, but not on the f77 compiler on HPUX, the Linux port would crash, but not the original HPUX version. In that the code you had above would have worked.
I was going to mention Indiana but was more hoping that it wouldn't be mentioned at all.
It is just a bad idea to implement the '==' operator using comparison on addresses instead of on values and I consider languages pretty low-level that do that.
In a sane language == is always a function adhering the attributes of an equivalence relation (reflexivity, symmetry and transivity), where a user can expect an actual value comparison - AFAIK one is advised to overwrite `equals` in e.g. Java, but I do not think this is good design.
//edit:
There is no obvious answer, as one could argue, that languages just use different names for the same concepts ('==' vs 'equals') and consider comparison by value or by reference more fundamental (and choose '==' for that).
I think Python is a good example here, where referential comparison is the `is` operator: `a is b`.
new Long(5) == new Long(5);?
I know why the implementation lets me ask that question and I know why it's false, but I'd say that there's no reasonable question I'd ever want to ask using that expression.If I have a graph data structure then `node == node` with identity does make sense to me in lots of cases.
And what's the value equality of `(new Object()).equals(new Object())` - they have no value.
It's not that reference semantics don't have a place, it's just that the place isn't numbers.
As for your second question, it looks like the type system has two embarrassing questions: what the heck does "new Object()" mean? Nothing worth saying.
Integer a = new Integer(2);
Integer b = a;
Here a == b and no comparison by value. Integer c = new Integer(2);
Then a != c but a.equals(c) (in Java). My point is that I do not agree with that and would like to have a == c, which would be the case if '==' was implemented using comparison by value.a == b is an value-comparison of the identity "value" (in Java it's the memory reference).
Or in other words, how do I know two references are equal (identity equal) without comparing the values of the references?
Logical equality devolves to the same thing at the end.
Certainly, one can come up with examples of how a different operator == would be useful for certain types of objects (including Integer), but the architects of Java strongly felt that an operator should always behave the same, regardless of the type of its operands, unless the operator is + and the objects are Strings.
Um, nonsense?
class Intbox {
public static void main(String[] args) {
Integer a = new Integer(2);
Integer b = a;
System.out.println(a == b);
System.out.println(a.equals(b));
}
}
$ java Intbox
true
true > cat intbox.java
class Intbox {
public static void main(String[] args) {
Integer a = new Integer(2);
Integer b = a;
Integer c = new Integer(2);
System.out.printf("a == b => %b\n", a == b);
System.out.printf("a.equals(b) => %b\n", a.equals(b));
System.out.printf("a == c => %b\n", a == c);
System.out.printf("a.equals(c) => %b\n", a.equals(c));
}
}
> javac intbox.java
> java Intbox
a == b => true
a.equals(b) => true
a == c => false
a.equals(c) => true
Edit to add: Your point regarding that "there is no way to compare equal by identity without also comparing equal by value" is true but doesn't really say much. (I'm not sure if it isn't a tautology?) There are cases where one might want to know whether two objects are the same object, or whether they represent the same value. Which you want depends on context.That's separate from the decision Java made that == was for identity comparison. Some people disagree with that decision.
There is no argument to be made that "comparison by value is just as fundamental a concept as comparison by identity", or that this is just a matter of opinion.
The fact that it is possible to compare equal by value without comparing equal by identity does not contradict that it is impossible to compare equal by identity without also comparing equal by value, however you define "equal by value".
> Your point regarding that "there is no way to compare equal by identity without also comparing equal by value" is true but doesn't really say much. (I'm not sure if it isn't a tautology?)
It's not a tautology; it is one of three requirements defining an equivalence relation. (Equivalence relations are by definition reflexive, which is to say x is equivalent to x for all x.)
I agree that in some sense you can say that "identity comparison is more fundamental that value comparison". As I added in my first comment, I think this is likely a tautology, and doesn't do much work for you at the end of the day. The important thing is keeping the two straight and doing the appropriate comparison depending on the context.
[1] And as I've already mentioned, you can see that this is true by looking at the definition of an equivalence relation. They all treat everything as equivalent to itself.
Two NaNs are equal in identity but not in value, according to the IEEE spec.
A NaN value does not compare equal to itself, because NaN is not thought of as a value at all but rather an error signal ("Not a Number"). You can check whether something is NaN, but that's not a distinction between comparing by identity and comparing by value -- it's a distinction between comparing values and checking for the presence of errors. The analogous operations to (1) comparing NaN to itself (unequal) and (2) checking whether NaN is NaN (yes), for another value such as -0, are (1b) comparing -0 to itself (equal) and (2b) checking whether -0 is NaN (no). They aren't (1c) comparing -0 to itself and (2c) checking whether -0 has the same "identity" as -0.
`a==b` is always an analog for the C code `a==b`, not `* a==*b` and certainly not C++'s `operator==(a, b)`
Apparently it is too hard to move python proper over to that method because of backwards compatibility issues with C extensions.