Ruby doesn't implement x++ for Fixnum's because?

Another way to look at it: does Fixnum#+ change the value of its receiver?

···

On Wed, Nov 4, 2009 at 10:23 AM, Martin DeMello <martindemello@gmail.com>wrote:

And how exactly would you change the value of 1 in place?

--
Tony Arcieri
Medioh/Nagravision

Not true. Check out the following, step by step:

def show(v)
  "Got #{v}, class = #{v.class}, object_id = #{v.object_id}
(v.object_id-1)/2 = #{(v.object_id-1)/2 }"
end

class Fixnum
  def pp # We can’t define ++ because of a compiler restriction.
    self + 1
  end
end

These lines show that a & b values are stored in there object_ids held
in the symbol table.
Don’t believe it? Read more.
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

Appending these lines shows that a & b values are distinct.
That is, after incrementing, a =2, b is unchanged; b is not
impacted by a’s change
a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Appending these lines shows the ++’s alias pp works just find
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

Appending these lines show that ++ crosses the Fixnum/Bignum boundary
a = 2**30-1; show (a) => Got 1073741823; class = Fixnum; object_id
= 2147483647; v >> 1 = 1073741823
show(a.pp) => Got 1073741824; class = Bignum; object_id =
22738520; v >> 1 = 11369260 # “v >> 1” is irrelevant, of course.

Do you agree?

Best wishes,
Richard

···

On Nov 4, 9:37 am, Seebs <usenet-nos...@seebs.net> wrote:

On 2009-11-04, Marnen Laibow-Koser <mar...@marnen.org> wrote:

> I believe you are quite wrong. If a destructive function like gsub! can
> be implemented as a method, then I see no reason that +=, |=, or postfix
> ++ couldn't be.

gsub! is implemented as a method on objects which contain data. ++ would
have to be implemented as a method on objects which ARE their data -- which
have no distinction between the object and its "contents".

gsub! can work because somewhere inside the object there is a hunk of storage
which is separate from the object itself. Fixnum has no such storage to
refer to.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nos...@seebs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

++ would have to be implemented as a method on objects which ARE their data

Hi,

>I believe you are quite wrong. If a destructive function like gsub! can
>be implemented as a method, then I see no reason that +=, |=, or postfix
>++ couldn't be.

Only if you accept the language that can change the value of 1 to 2.
I don't.

                                                    matz\.

Hi Matz,

Thank you very much for your brilliant and enormous efforts in
creating Ruby and offering to the programming world as gift.

Only if you accept the language that can change the value of 1 to 2.

I know that you know Ruby extremely well. But I have written the
following tests on this issue of whether "1" ever gets changed to
"2". I assume you have not looked at my post yesterday on this
issue. I'd be honored if you'd
look at the following comments and code and point out anything you
view as erroneous.

BTW, I'm not advocating x++ for Ruby. I'm just trying to understand
whether Ruby would literally change 1 to 2 as opposed to change a
variable that contains 1 to subsequently contain 2.

Best wishes,
Richard

def show(v)
  "Got #{v}, class = #{v.class}, object_id = #{v.object_id}
(v.object_id-1)/2 = #{(v.object_id-1)/2 }"
end

class Fixnum
  def pp # We can’t define ++ because of a compiler restriction.
    self + 1
  end
end

These lines show that a & b values are stored in their object_ids held
in the symbol table.
Don’t believe it? Read more.
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

Appending these lines shows that a & b values are distinct.
That is, after incrementing, a =2, b is unchanged; b is not
impacted by a’s change
a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Appending these lines shows the ++’s alias pp works just find
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

Appending these lines show that ++ crosses the Fixnum/Bignum boundary
a = 2**30-1; show (a) => Got 1073741823; class = Fixnum; object_id
= 2147483647; v >> 1 = 1073741823
show(a.pp) => Got 1073741824; class = Bignum; object_id =
22738520; v >> 1 = 11369260
# “v >> 1” is irrelevant, of course.

···

On Nov 4, 10:59 am, Yukihiro Matsumoto <m...@ruby-lang.org> wrote:

In message "Re: Ruby doesn't implement x++ for Fixnum's because ???" > on Wed, 4 Nov 2009 23:31:46 +0900, Marnen Laibow-Koser <mar...@marnen.org> writes:

Walton Hoops wrote:

From: bascule@gmail.com [mailto:bascule@gmail.com] On Behalf Of Tony
Arcieri
wrote:
I think you're missing why ++ could be useful, and it's precisely
because
Ruby is a "21st century language"

The ++ operator, far more than just being syntactic sugar for +=1,
would
allow you to send an "increment" message to any object, which would
change
its value in place, i.e.

  def ++
    incrementing_logic_goes_here
  end

I could see this as being handy

But you already can with the mechanics of the language that are already
present!

irb(main):003:0> i=15
=> 15
irb(main):004:0> i=i.succ
=> 16
irb(main):005:0> i="15"
=> "15"
irb(main):006:0> i=i.succ
=> "16"
irb(main):007:0> i=1.2
=> 1.2
irb(main):008:0> i=i.succ
NoMethodError: undefined method `succ' for 1.2:Float
        from (irb):8
        from /usr/local/bin/irb:12:in `<main>'

In an object that it makes sense to increment, define the #succ method!
It's that easy!

But i.succ does Not work in the following:

i = 1
while (i < 10)
   puts i.succ
end

the only way to get this to work is to use:
   puts i; i = i.succ

which is not as clean as using puts i++.

···

-----Original Message-----

What's wrong with Array#push? Why do we need Array#<<? How is that any
different?

···

On Thu, Nov 5, 2009 at 3:40 AM, Gavin Sinclair <gsinclair@gmail.com> wrote:

> def ++
> incrementing_logic_goes_here
> end
>
> I could see this as being handy

What's wrong with

def inc
    incrementing_logic_goes_here
end

How is that any different?

--
Tony Arcieri
Medioh/Nagravision

Everything is an object.

Not every object contains separate storage.

When you write "a = 1; b = 1;", a and b do not refer to two separate objects
which happen to have the same numeric value; they refer to a single object
which has an immutable numeric value. You can't increment that value.

-s

···

On 2009-11-04, lith <minilith@gmail.com> wrote:

gsub! can work because somewhere inside the object there is a hunk of storage
which is separate from the object itself. Fixnum has no such storage to
refer to.

I don't think ruby makes the distinction between native types &
objects à la java.

--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
| Seebs.Net <-- lawsuits, religion, and funny pictures
Fair game (Scientology) - Wikipedia <-- get educated!

And how exactly would you change the value of 1 in place?

You don't. Are you insinuating the behavior of Fixnums isn't already
special cased to begin with?

a = 1

a.class #Fixnum

a++ # a is now 2

1.class #Fixnum

1++ # Illegal

So although a is a Fixnum, and 1 is a Fixnum, they respond to ++ differently?

···

On Wed, Nov 4, 2009 at 6:16 PM, Tony Arcieri <tony@medioh.com> wrote:

On Wed, Nov 4, 2009 at 10:23 AM, Martin DeMello <martindemello@gmail.com>wrote:

--
Tony Arcieri
Medioh/Nagravision

--
Paul Smith
http://www.nomadicfun.co.uk

paul@pollyandpaul.co.uk

And how exactly would you change the value of 1 in place?

You don't. Are you insinuating the behavior of Fixnums isn't already
special cased to begin with?

yes, i see your point, but consider:

a = Foo.new()
b = a
c = 42
d = c
a++
p b
c++
p d

martin

···

On Wed, Nov 4, 2009 at 11:46 PM, Tony Arcieri <tony@medioh.com> wrote:

On Wed, Nov 4, 2009 at 10:23 AM, Martin DeMello <martindemello@gmail.com>wrote:

--
Tony Arcieri
Medioh/Nagravision

class Fixnum
  def pp # We can?t define ++ because of a compiler restriction.
    self + 1
  end
end

This doesn't seem to do the right thing.

a = 1
a.pp

Is a now 2? If not, you haven't implemented an increment operator.

Appending these lines shows that a & b values are distinct.
That is, after incrementing, a =2, b is unchanged; b is not
impacted by a?s change
a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1
= 2
show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Right. You've changed which object a refers to, because you've reassigned
a.

Appending these lines shows the ++?s alias pp works just find
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

Not the same. The key is that, after "a += 1", not only do you get 2,
but a is now 2.

Do you agree?

No.

For "a.pp" to be the same as a++ in other languages, you'd have to do:

a = 1; a.pp; show(a) => Got 2

If you don't get a "2" by using a.pp, it's not an increment, just a "one
more than".

Consider a loop:

a = 1
while ((a += 1) < 10) do
  puts a
end

Now, try:

a = 1
while (a.pp < 10) do
  puts a
end

Doesn't do the same thing.

-s

···

On 2009-11-04, RichardOnRails <RichardDummyMailbox58407@USComputerGurus.com> wrote:
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
| Seebs.Net <-- lawsuits, religion, and funny pictures
Fair game (Scientology) - Wikipedia <-- get educated!

RichardOnRails wrote:

BTW, I'm not advocating x++ for Ruby. I'm just trying to understand
whether Ruby would literally change 1 to 2 as opposed to change a
variable that contains 1 to subsequently contain 2.

I am confused.
irb(main):001:0> 1.succ
=> 2
irb(main):002:0> 1.object_id
=> 3
irb(main):003:0> 1.succ.object_id
=> 5
irb(main):004:0>

Is that good enough? If not, I'd recommend taking a look at...
irb(main):004:0> 1.class
=> Fixnum

Fixnum .. Fixed number? :slight_smile:

···

--
Posted via http://www.ruby-forum.com/\.

Variables don't contain values, they refer to objects. That's the
fundamental difference. So if you say, for instance

a = "hello world"
a.upcase!
a #=> "HELLO WORLD"

the message "upcase!" is sent to the *object* "hello world", not the
variable a. To see this:

a = "hello world"
b = a
a.upcase!
a #=> "HELLO WORLD"
b #=> "HELLO WORLD"

Fixnums are immutable objects; you can't have any method that changes
their value. Hence no ++

martin

···

On Thu, Nov 5, 2009 at 12:55 AM, RichardOnRails <RichardDummyMailbox58407@uscomputergurus.com> wrote:

BTW, I'm not advocating x++ for Ruby. I'm just trying to understand
whether Ruby would literally change 1 to 2 as opposed to change a
variable that contains 1 to subsequently contain 2.

Michael W. Ryder wrote:
[...]

But i.succ does Not work in the following:

i = 1
while (i < 10)
   puts i.succ
end

the only way to get this to work is to use:
   puts i; i = i.succ

which is not as clean as using puts i++.

This is unidiomatic Ruby. In fact, it's becoming clear to me that just
about *any* use case for postfix ++ is unidiomatic Ruby. The cleanest
way *in Ruby* of doing what you did would be

(1..10).each {|i| puts i}

Incrementing is handled under the hood.

Best,

···

--
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
--
Posted via http://www.ruby-forum.com/\.

I'd argue it's much, much cleaner. ++ has long been a source
of confusion for C programmers. Consider:

int i = 1;
while (i < 10)
{
  printf("%d,",i++);
}

What does it ouput? 1,2,3,4,5,6,7,8,9, or 2,3,4,5,6,7,8,9,10,?

Because we're all experienced C programmers here we of course know
it to be 1,2,3,4,5,6,7,8,9, but it's not uncommon for experienced C
programmers to make mistakes around a++ vs ++a. On the other hand:

int i = 1;
while (i <10)
{
  printf("%d,",i);
  i+=1;
}

Makes it explicitly clear what is happening. Then consider the ruby
direct ruby translation:

i = 1;
while (i <10)
  print "#{i},"
  i+=1;
end

Even a non-programmer is going to have a pretty darn clear idea of
what is going on here. Sure it's one line longer but much more
understandable, and therefore cleaner. If there is one thing
playing Perl Golf should have taught all programmers it's that
shorter != better.

Now consider the ruby way:

10.times do |i|
  print "#{i},"
end

Some length as the C code, but much more readable. Heck, it's
almost English! Which is part of the beauty of Ruby: It's simple,
natural, readable syntax. I've seen a lot of arguments that it
doesn't fit with ruby's object model, but to me that's not the key
point. ++ doesn't fit with Ruby's elegant syntax.

···

-----Original Message-----
From: Michael W. Ryder [mailto:_mwryder55@gmail.com]
But i.succ does Not work in the following:

i = 1
while (i < 10)
   puts i.succ
end

the only way to get this to work is to use:
   puts i; i = i.succ

which is not as clean as using puts i++.

Hi,

···

In message "Re: Ruby doesn't implement x++ for Fixnum's because ???" on Thu, 5 Nov 2009 04:25:05 +0900, RichardOnRails <RichardDummyMailbox58407@USComputerGurus.com> writes:

BTW, I'm not advocating x++ for Ruby. I'm just trying to understand
whether Ruby would literally change 1 to 2 as opposed to change a
variable that contains 1 to subsequently contain 2.

There's no way to modify local variables by sending message in Ruby.

              matz.

Maybe you'll just have to find another way to print the numbers 1 to
10 :wink:

···

On Nov 5, 7:22 am, "Michael W. Ryder" <_mwryde...@gmail.com> wrote:

But i.succ does Not work in the following:

i = 1
while (i < 10)
puts i.succ
end

the only way to get this to work is to use:
puts i; i = i.succ

which is not as clean as using puts i++.

Hi--

  def ++
    incrementing_logic_goes_here
  end

I could see this as being handy

What's wrong with

def inc
    incrementing_logic_goes_here
end

How is that any different?

What's wrong with Array#push? Why do we need Array#<<? How is that any
different?

irb(main):001:0> .push(1,2,3)
=> [1, 2, 3]
irb(main):002:0> .<<(1,2,3)
ArgumentError: wrong number of arguments (3 for 1)

:slight_smile: But I know that's not what you meant. The thing is, a method
called ++ that did in-place incremention would not be meaningful for
numbers (if I understand correctly that you mean it would be similar
to succ!), and having it for other objects would probably just lead to
more confusion. That's my hunch, at least.

David

···

On Fri, 6 Nov 2009, Tony Arcieri wrote:

On Thu, Nov 5, 2009 at 3:40 AM, Gavin Sinclair <gsinclair@gmail.com> wrote:

--
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)

But Fortran fixed that bug in its first revision!

···

On Wed, Nov 4, 2009 at 11:55 AM, Seebs <usenet-nospam@seebs.net> wrote:

On 2009-11-04, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

In message "Re: Ruby doesn't implement x++ for Fixnum's because ???" >> on Wed, 4 Nov 2009 23:31:46 +0900, Marnen Laibow-Koser <marnen@marnen.org> writes:

I believe you are quite wrong. If a destructive function like gsub! can
be implemented as a method, then I see no reason that +=, |=, or postfix
++ couldn't be.

Only if you accept the language that can change the value of 1 to 2.
I don't.

Hmph. Fortran can change constants, why's Ruby so much less powerful?

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

What's wrong with Array#push? Why do we need Array#<<? How is that any
different?

Apart from David's response, you're proposing that a currently-invalid
method name be allowed. For such a change, there needs to be a good
reason.

Gavin

> class Fixnum
> def pp # We can?t define ++ because of a compiler restriction.
> self + 1
> end
> end

This doesn't seem to do the right thing.

a = 1
a.pp

Is a now 2? If not, you haven't implemented an increment operator.

> Appending these lines shows that a & b values are distinct.
> That is, after incrementing, a =2, b is unchanged; b is not
> impacted by a?s change
> a += 1; show (a) => Got 2; class = Fixnum; object_id = 5; v >> 1
>= 2
> show (b) => Got 1; class = Fixnum; object_id = 3; v >> 1 = 1

Right. You've changed which object a refers to, because you've reassigned
a.

> Appending these lines shows the ++?s alias pp works just find
> 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

Not the same. The key is that, after "a += 1", not only do you get 2,
but a is now 2.

> Do you agree?

No.

For "a.pp" to be the same as a++ in other languages, you'd have to do:

a = 1; a.pp; show(a) => Got 2

If you don't get a "2" by using a.pp, it's not an increment, just a "one
more than".

Consider a loop:

a = 1
while ((a += 1) < 10) do
puts a
end

Now, try:

a = 1
while (a.pp < 10) do
puts a
end

Doesn't do the same thing.

-s
--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nos...@seebs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Hi Peter,

This doesn't seem to do the right thing.

a = 1
a.pp

Is a now 2? If not, you haven't implemented an increment operator.

Thanks for this question. You're so right. I couldn't see it until
you pointed it out.

class Fixnum
  def pp # We can’t define ++ because of a compiler restriction.
    self + 1
  end
end

doesn't change self (which Ruby won't allow for Fixnum's!!! Which, of
course, is why your:

a = 1
while (a.pp < 10) do
  puts a
end

produces an infinite number of 1's ..., or would if RAM were infinite
and hardware addressing mechanisms were infinite.

I grateful for you taking the time to identify my deficiencies.

Best wishes,
Richard

···

On Nov 4, 2:13 pm, Seebs <usenet-nos...@seebs.net> wrote:

On 2009-11-04, RichardOnRails <RichardDummyMailbox58...@USComputerGurus.com> wrote:

I'd call it an oversight, not a personal failing.

It might make sense to want to be able to do
  def pp()
    old = self
    self = self + 1
    old
  end

or something similar, but it's not well-defined. The problem is that
fundamentally, when you have two variables, a and b, which both contain
the object 1 (a Fixnum), there's no way to say "I want the object a points
to to change, but not the object b points to" *in a method call*. Because
the method call works on the object, not the variable.

-s

···

On 2009-11-04, RichardOnRails <RichardDummyMailbox58407@USComputerGurus.com> wrote:

I grateful for you taking the time to identify my deficiencies.

--
Copyright 2009, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
| Seebs.Net <-- lawsuits, religion, and funny pictures
Fair game (Scientology) - Wikipedia <-- get educated!