From: RichardOnRails Date: 2009-11-04T12:25:12+09:00 Subject: Re: Ruby doesn't implement x++ for Fixnum's because ??? On Oct 30, 11:05 am, Robert Klemme wrote: > 2009/10/30 RichardOnRails : > > > I'll correct my errors and probably have a new theory subsequently. > > IMHO the story goes like this: absence of postfix ++ and -- is a > consequence of the fact that numeric types are immutable in Ruby which > makes an assignment necessary for these operators.  Although that > would be doable, it would not immediately be obvious when looking at > "foo++".  On the other side, "foo += 1" makes the assignment obvious > while still being pretty concise (you do not have to write "foo = foo > + 1"). > > Which brings us to the question: what is the advantage of immutable > numbers?  First, it avoids errors that could be caused by aliasing > (two objects refer the same object, one of them changes it, it changes > for the other one as well without being expected).  Then, it is quite > natural if you consider mathematical numbers: they cannot change. > > Additionally, the expression "1" can always refer to the same object > (in reality it's a bit different but from a Ruby programmer's > perspective the difference is not noticeable) which in fact makes > using numeric constants very efficient (as opposed to the expression > "'foo'" which constructs a new String instance on every invocation, > albeit with a shared char array underneath which eases the pain a > bit). > > This in turn makes integer math pretty efficient because if numbers > were mutable Ruby would have to create a new object for every result > of an operator evaluation.  I am not saying that Ruby is ideal for > number crunching but it could be significantly slower if certain > design decisions would have been made differently. > > Kind regards > > robert > > -- > remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/ Hi Robert, Thank you for your thoughtful and extensive responses. I apologized earlier for my sloppy analysis. I hope the following offers higher quality. (a) You say, in part: “... immutable numbers? First, it avoids errors that could be caused by aliasing (two objects refer the same object, one of them changes it, it changes for the other one as well without being expected” (b) Dave Black, in his truly excellent “The Well-Grounded Rubyist” says, in part: “Any object that’s represented as an immediate value is always exactly the same object” and “The reason [there’s no x=1; x++] is that , due to the immediate presence of 1 in x, means you’d be changing 1 into 2, and that makes no sense” 1. I’d rather discuss this matter in concrete terms rather than abstractions. Please look at the following method (to generate results) and two statements: def show(v) "Got #{v}, class = #{v.class}, object_id = #{v.object_id} (v.object_id-1)/2 = #{(v.object_id-1)/2 }" end a = 1; show (a) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1 b = 1; show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1 a == b => true Both “a” and “b” have their respective values held as immediate values (embedded in their object_id’s), but they are NOT the same thing because they’re ultimately held in their respective entries in the symbol table. So, object_id’s for Fixnum’s are synthetic. To think that those object_id’s point to a location in a memory area that stores the 32-bit 000...001 (in a 32-bit machine/OS) is to contradict the meaning of immediacy and defeat the very efficiency that immediate values offer. 2. Now please consider the following supplement to the statements above: a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1 = 2 show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1 = 2 show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1 The assignment of “a += 1” to “a” changed a’s object_id to embed a new value: 2. Despite that change of 1 to 2 in a’s object, “b” remains set to 1. “b” did not suffer the calamity of a universal change of all Fixnum 1’s to 2’s. 3. Conclusion: a += 1 is equivalent to a++’s natural meaning. In fact, we further supplement the above statements with: class Fixnum def pp # We can’t define ++ because of a compiler restriction. self + 1 end end a=1; show(a.pp) => Got 2; class = Fixnum; object_id = 5; v >> 1 = 2 show(b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1 Furthermore, pp works fine on the boundary condition for Fixnum’s on a common 32-bit cpu/OS, i.e. 2**30-1: a = 2**30-1; show (a) => Got 1073741823; class = Fixnum; object_id = 2147483647; v >> 1 = 1073741823 a = 2**30; show (a) => Got 1073741824; class = Bignum; object_id = 22737670; v >> 1 = 11368835 So x++ works fine in the form of pp for positive Fixnum’s. I assume it’ll work fine for non-positives, also.. A compiler change to allow “def ++” is necessary to finally add ++ to Fixnum. Again, thanks for your responses to my question. Best wishes, Richard