My memory of Java is a bit rusty but I think this illustrates the point (apologies for egreigious errors :)):
int a;
int b;
Math.Int c;
Math.Int d;
a = 1; c = a;
b = a; b = 4;
d = c; d = 3;
What are the final values of a, b, c and d? The b = a; b = 4; line makes a = 1, b = 4. The d = c; d = 3; makes both d and c 3. At least C makes it clear when you are dealing with a pointer (the location of z, Java equiavalent is a reference).
Actually, to my annoyance, Java doesn't work like that. I'm now trying to work out the right way to explain it, so I'm just going to give up and hand-wave.
If you do: int a=1; Integer b=a; a=2; then b is 1, not 2.
Likewise: Integer a=1; Integer b=a; a=3;, b is still 1.
Assignment always changes the pointer, even with the autoboxing crap.
This leads to hilarious* code which involves passing single-item arrays into function so you can swap objects around, such as (note: horribly contrived example):
boolean try_to_create(Foo[] reference) {
Foo new_obj=new Foo();
// Could it allocate random_resource#3?
if(new_obj.is_valid()) {
// Created a valid reference, so allocated it to the not-really-byref and return true
reference[0]=new_obj;
return true;
}
else {
// Couldn't create a valid reference, so return false
reference[0]=null;
return false;
}
}
* by which I mean 'wrong'. I do not advocate writing stuff like this if you can help it.
The Java stupidity here is not that it has reference types. Instead, it's a combination of two things: (a) mutable numeric types, and (b) an inconsistency in the meaning of `=' (the assignment operator). The inconsistency is probably the bigger problem, actually. The last line you wrote illustrates this perfectly: `d = c' copies a reference, but `d = 3' doesn't – it side-effects the object d refers to instead.
In Lisp, all variables are references to objects, everything is pass-by-reference, and assignment (setf) works by copying pointers about. That said, the above confusion is simply not possible in Lisp. Firstly, all numbers are immutable in Lisp, so there's no way that you can `change' one number somewhere and have another one magically change too. And secondly, `setf' always just copies references about, so you can only possibly change the thing you thought you were changing.
Python has similar problems to Java here, regarding inconsistency of assignment, but only in its compound-assignment operators (`+=' and friends) – sometimes `x += y' means the same as `x = x + y' (e.g., if x refers to an immutable thing like a number, string or tuple), and sometimes it side-effects the object pointed to by x instead (e.g., if x refers to a list).
Anyway, Python's pretty stupid in this respect, but Java making `=' brain-damaged in this way just takes the biscuit.
It's unfair to blame Python for the slightly confusing behaviour of its assignment operators—it only grew them because of the clamour of people coming blindly from more C-like languages for them. Ask for an "enhancement" which doesn't fit in with the design of the language, and you get a wart.
Well, I could ask what a BDFL is for if not to keep the stupid ideas out. But that would be unfair; after all, Guido actually seems to be pretty good at this.
My earlier rant may have mislead you. I'm actually rather fond of Python. The bizarre behaviour of its compound assignment operators is one of the few areas it falls down. (That, and its hopelessly weedy idea of generators. Proper continuations, dammit!)
(no subject)
Date: 2006-04-11 09:48 am (UTC)What are the final values of a, b, c and d? The b = a; b = 4; line makes a = 1, b = 4. The d = c; d = 3; makes both d and c 3. At least C makes it clear when you are dealing with a pointer (the location of z, Java equiavalent is a reference).
(no subject)
Date: 2006-04-11 09:49 am (UTC)(no subject)
Date: 2006-04-11 10:17 am (UTC)If you do:
int a=1; Integer b=a; a=2;then b is 1, not 2.Likewise:
Integer a=1; Integer b=a; a=3;, b is still 1.Assignment always changes the pointer, even with the autoboxing crap.
This leads to hilarious* code which involves passing single-item arrays into function so you can swap objects around, such as (note: horribly contrived example):
boolean try_to_create(Foo[] reference) { Foo new_obj=new Foo(); // Could it allocate random_resource#3? if(new_obj.is_valid()) { // Created a valid reference, so allocated it to the not-really-byref and return true reference[0]=new_obj; return true; } else { // Couldn't create a valid reference, so return false reference[0]=null; return false; } }* by which I mean 'wrong'. I do not advocate writing stuff like this if you can help it.
(no subject)
Date: 2006-04-11 10:25 am (UTC)In Lisp, all variables are references to objects, everything is pass-by-reference, and assignment (setf) works by copying pointers about. That said, the above confusion is simply not possible in Lisp. Firstly, all numbers are immutable in Lisp, so there's no way that you can `change' one number somewhere and have another one magically change too. And secondly, `setf' always just copies references about, so you can only possibly change the thing you thought you were changing.
Python has similar problems to Java here, regarding inconsistency of assignment, but only in its compound-assignment operators (`+=' and friends) – sometimes `x += y' means the same as `x = x + y' (e.g., if x refers to an immutable thing like a number, string or tuple), and sometimes it side-effects the object pointed to by x instead (e.g., if x refers to a list).
Anyway, Python's pretty stupid in this respect, but Java making `=' brain-damaged in this way just takes the biscuit.
(no subject)
Date: 2006-04-11 10:29 am (UTC)(no subject)
Date: 2006-04-11 11:10 am (UTC)(no subject)
Date: 2006-04-11 01:22 pm (UTC)My earlier rant may have mislead you. I'm actually rather fond of Python. The bizarre behaviour of its compound assignment operators is one of the few areas it falls down. (That, and its hopelessly weedy idea of generators. Proper continuations, dammit!)