On 2009-11-08, Tony A. [email protected] wrote:
I can’t think of a language where “variables are objects”.
I’d say they are in C.
In C:
{
int x;
}
x is an object. There is storage which is reserved for x, which is not
associated with any other object, etcetera. Modifications “to x” always
affect this specific object; you can’t make x be some other object, all
you can do is change its contents.
And this isn’t
the issue. The real issue is Numeric values (i.e. “objects”) are
immutable. Other types of objects, however, are mutable. “Everything is an
object”, except some objects are different than others.
I think it is the issue though.
The reason you can write “x = x + 1” in Ruby, but not “x++”, is that you
have to modify the variable, not the object. If x was previously the
Fixnum
1, you don’t want to change 1 to 2 – you want to change x to point to a
different object. You can’t do that by sending x a message, though, you
have to write it in the code that knows about the variable x.
Advocates of allowing a ++ operator are suggesting that the operator have a
dispatch model which alters the local binding when applied to Numeric
types.
(1+2)++
1+2 => the Fixnum 3
What is the local binding which gets incremented? There’s no variable
there,
only an object.
What I really see happening here is that ++ reveals an otherwise
difficult-to-see difference in how immutable and mutable objects behave in
Ruby. There’s no reason Ruby can’t have ++, but it would need special case
behavior, because the behavior of Numerics is already a special case. Any
ugliness surrounding special-case behavior of ++ when implementing it
against Numerics stems from this inconsistency in Ruby itself, not the ++
operator.
I don’t entirely agree. The difference is most obvious with Numerics,
but it’s true of just about anything.
Imagine that we define ++ on an array as equivalent to “a = a + [ nil
]”.
That is, it appends a new value on the end of the array.
Now try setting up an array:
a = Array.new
b = a
a++
How many items does b have? Why, it now has an item, because there is
only
one array. a and b are not arrays; a and b are variables which hold
references to a single array object.
What that means is that, while Numerics have special case behavior, the
special case behavior is the one we actually want.
Ignore the return value for a moment. Clearly, the intent of “a++” is
the same as the intent of “a = a + 1”. But in Ruby, those aren’t the
same thing.
a = Array.new
b = a
a = a + [ nil ]
This makes a and b into two separate objects.
It’s not that I doubt the pragmatism of the immutability of Numeric values
(on the contrary, I’m developing a language where all values are
immutable), but this is really the cause of the problem, and the solution
(special casing how Numerics respond to ++ by providing alterations to the
local binding) causes me no qualms, as it’s only a workaround of the
separation of immutable/mutable objects that’s a fundamental part of Ruby to
begin with.
I disagree, because I think it would violate POLS to have ++ work
differently
on numerics, when clearly, that behavior (alters local binding) is
exactly
what we want… Probably.
Again, I really think the root of this is that ++ is designed for a
language
in which the variable is its own object, not a reference to another
object.
-s