Forum: Ruby Why no ++ and --?

Posted by Sonja Elen Kisa (sonja)
on 2010-02-08 04:15
"foo += 1" somehow seems less elegant or pretty as "foo++".

Is there any reason Ruby doesn't have ++? Is it something that might be
added in a future version?
Posted by Bill Kelly (Guest)
on 2010-02-08 04:30
(Received via mailing list)
Sonja Elen Kisa wrote:
> "foo += 1" somehow seems less elegant or pretty as "foo++".
> 
> Is there any reason Ruby doesn't have ++? Is it something that might be
> added in a future version?

Here's a lengthy and recent thread on the topic:

http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/349253?349080-351096+split-mode-vertical


Regards,

Bill
Posted by Marnen Laibow-Koser (marnen)
on 2010-02-08 15:24
Sonja Elen Kisa wrote:
> "foo += 1" somehow seems less elegant or pretty as "foo++".
> 
> Is there any reason Ruby doesn't have ++? Is it something that might be
> added in a future version?

The short answer is that it doesn't fit with Ruby's object model, and 
anyway, Ruby's iterators remove most of the need for ++.

Best,
-- 
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
Posted by Tony Arcieri (Guest)
on 2010-02-08 19:47
(Received via mailing list)
On Sun, Feb 7, 2010 at 8:15 PM, Sonja Elen Kisa <sonja@kisa.ca> wrote:

> "foo += 1" somehow seems less elegant or pretty as "foo++".
>
> Is there any reason Ruby doesn't have ++? Is it something that might be
> added in a future version?
>

I think this is something of a dead horse around here.  The short answer 
is:
matz doesn't want it, most rubyists don't want it (and even actively 
oppose
it), therefore it's never going to happen.  Adding ++ would break 
backwards
compatibility with libraries like superators:
http://jicksta.com/posts/superators-add-new-operators-to-ruby

However, there's no technical reason why Ruby can't have a x++ operator
which functions as shorthand for:

   begin; _tmp = x; x += 1; _tmp; end
Posted by Seebs (Guest)
on 2010-02-08 20:21
(Received via mailing list)
On 2010-02-08, Sonja Elen Kisa <sonja@kisa.ca> wrote:
> "foo += 1" somehow seems less elegant or pretty as "foo++".

> Is there any reason Ruby doesn't have ++?

Yes.

> Is it something that might be
> added in a future version?

Very unlikely.

In Ruby, "foo" is not an object, it's a reference to an object.  Not all
objects are mutable.  After:

  foo = 3

"foo" is just a name to refer to the Fixnum 3.  That object CANNOT be
modified.  When you write:
  foo = foo + 1
what happens is:
  We extract the current value of foo (fixnum 3).
  We send that an add message with the other argument being the fixnum 1
  That yields a new object, the fixnum 4
  Foo is changed to be a reference to that new object

You can't increment the underlying object, because fixnums are 
immutable.

-s
Posted by Aldric Giacomoni (trevoke)
on 2010-02-08 20:25
Seebs wrote:
> On 2010-02-08, Sonja Elen Kisa <sonja@kisa.ca> wrote:
>> "foo += 1" somehow seems less elegant or pretty as "foo++".
> 
>> Is there any reason Ruby doesn't have ++?
> 
> Yes.

You know, I really thought the Ruby Way (tm) embraced, nay, espoused 
DRY. I'm going to reference the earlier post.. Which referenced an 
earlier thread..
http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/349253?349080-351096+split-mode-vertical

There's -nothing- which needs to be said which hasn't been said in that 
other thread.

I call this thread dead and buried, right on top of the dead horse which 
has been flogged one too many times, and just to make sure no one 
touches it again, I'll put the word 'nazi' and call Godwin's law on 
myself.
Posted by Marnen Laibow-Koser (marnen)
on 2010-02-08 20:30
Aldric Giacomoni wrote:
> Seebs wrote:
>> On 2010-02-08, Sonja Elen Kisa <sonja@kisa.ca> wrote:
>>> "foo += 1" somehow seems less elegant or pretty as "foo++".
>> 
>>> Is there any reason Ruby doesn't have ++?
>> 
>> Yes.
> 
> You know, I really thought the Ruby Way (tm) embraced, nay, espoused 
> DRY. I'm going to reference the earlier post.. Which referenced an 
> earlier thread..
> http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/349253?349080-351096+split-mode-vertical
> 
> There's -nothing- which needs to be said which hasn't been said in that 
> other thread.
> 
> I call this thread dead and buried, right on top of the dead horse which 
> has been flogged one too many times, and just to make sure no one 
> touches it again, I'll put the word 'nazi' and call Godwin's law on 
> myself.

...which doesn't work when intentionally invoked.  What are you, some 
kind of operator-Nazi? :)

Best,
-- 
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
Posted by Tony Arcieri (Guest)
on 2010-02-08 20:38
(Received via mailing list)
On Mon, Feb 8, 2010 at 12:20 PM, Seebs <usenet-nospam@seebs.net> wrote:

> You can't increment the underlying object, because fixnums are immutable.
>

Not to beat the dead horse any more but...

In a language like Ruby where the binding operates entirely by 
reference, it
would only make sense for the ++ operator to change which object a 
variable
name references (i.e. destructive assignment) as opposed to sending a
message which actually mutates the object it references, especially 
since ++
is an operator intended to work with numbers and Ruby's numbers are
immutable.

Using x++ as a shorthand for:

   begin; _tmp = x; x += 1; _tmp; end

...would be the only sensible implementation.

There exists an operator in Ruby which doesn't send a message: =.  The 
"="
operator modifies the binding.  ++ (and --) would have to do the same.

Unprecedented?  Yes.  But not impossible.
Posted by Rob Biedenharn (Guest)
on 2010-02-08 21:08
(Received via mailing list)
On Feb 8, 2010, at 2:30 PM, Tony Arcieri wrote:
> reference, it
>   begin; _tmp = x; x += 1; _tmp; end
> Tony Arcieri
> Medioh! A Kudelski Brand


Well, I could see a sensible implementation equivalent to:

begin; _tmp = x; x = x.succ; _tmp; end

or perhaps

begin; _tmp = x; x.succ!; _tmp; end

so that's certainly not the "only" sensible implementation :-)

-Rob

P.S. Sorry from flailing the horse.

Rob Biedenharn    http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
Posted by Tony Arcieri (Guest)
on 2010-02-08 21:32
(Received via mailing list)
On Mon, Feb 8, 2010 at 1:07 PM, Rob Biedenharn
<Rob@agileconsultingllc.com>wrote:

> begin; _tmp = x; x.succ!; _tmp; end
>

NoMethodError: undefined method `succ!' for 42:Fixnum

Good luck implementing that one.

There doesn't seem to be much left of this dead horse's flesh.
Posted by Christopher Dicely (Guest)
on 2010-02-14 00:43
(Received via mailing list)
On Sun, Feb 7, 2010 at 7:15 PM, Sonja Elen Kisa <sonja@kisa.ca> wrote:
> "foo += 1" somehow seems less elegant or pretty as "foo++".

"foo += 1" doesn't have the same meaning as "foo++", instead, it is
equivalent to "++foo".
"foo++" is (as others have intimated in suggesting implementations)
equivalent to:
begin
  _temp = foo
  foo += 1
  _temp
end

I wouldn't expect to see postfix-increment/decrement operators added
to Ruby in any near-future version.
Posted by Josh Cheek (Guest)
on 2010-02-14 04:51
(Received via mailing list)
They just plain don't mean the same thing:

In C++, outputs "ref1 = 6 , ref2 = 6" Because ++ changes the underlying
object, and they both referencing that object.
#include "iostream"
int main( ) {
  int actual=5 , &ref1=actual , &ref2=ref1;
  ++ref1;
  std::cout << "ref1 = " << ref1 << ", ref2 = " << ref2 << std::endl;
  return 0;
}

In C, outputs "*ptr1 = 6 , *ptr2 = 6" For the same reason as above, We
increment the value that ptr1 is pointing at, since ptr2 is pointing to 
the
same place, it gets updated also
#include "stdio.h"
int main(){
  int actual=5 , *ptr1=&actual , *ptr2=ptr1;
  ++*ptr1;
  printf( "*ptr1 = %d , *ptr2 = %d\n" , *ptr1 , *ptr2 );
  return 0;
}

In Ruby, outputs "ref1 = 6 , ref2 = 5" Because += creates a new object, 
and
updates one of the references to point to the new place in memory, but 
the
second reference is still pointing to the old number.
actual=5 ; ref1=actual ; ref2=ref1
ref1 += 1
puts "ref1 = #{ref1} , ref2 = #{ref2}"


Numbers are immutable in Ruby, so you cannot increment a number that the
object represents, you can only get a new object containing the next 
number.
And anything referring to the original number will not be updated, that
original number still exists. So where do you compromise? Does ref1++
translate directly to ref1+=1 which would give it very different meaning
than in the languages the people making the requests are coming from, or 
do
you make numbers mutable, which would present other issues that these 
people
would dislike (ie making numbers immutable allows them to mimic the
behaviour of pass by value, but now they would either have to explicitly
duplicate the number before passing it, or they would have to deal with 
the
possibility of the function they are calling having the ability to 
change
it, or some sort of magic such as checking params and duping them before
letting them in)

I think that people who ask for ++ really don't understand what they are
asking for, and think it is just a simple syntactic difference. I also 
think
you can trash a beautiful language by giving in to every half-understood
request for exceptional changes, so I'm very much against adding this, 
my
brain can only remember so many exceptions to the rules.
Posted by Josh Cheek (Guest)
on 2010-02-14 05:31
(Received via mailing list)
I thought it might be interesting to see how Java handles this, since it 
has
both primitives and wrappers.

Outputs
primative1 = 6 , primative2 = 5
immutable1 = 6, immutable2 = 5
mutable1 = 4, mutable2 = 4



public class IntWrapper {
  public static void main(String[] args) {
    // Java does not support references to primitive types, so 
primative2 =
primative1 creates a new int
    // with the same value as primative1. Then when we incrememnt
primative1, primative2's value does not change
    int primative1 = 5;
    int primative2 = primative1;
    primative1++;
    System.out.println( "primative1 = " + primative1 + " , primative2 = 
" +
primative2 );

    // because Integer is immutable, immutable1 and immutable2 end up
pointing to different objects
    // and they have different values. This contradicts the C / C++ 
model,
as well as the general object model
    Integer immutable1 = new Integer(5);
    Integer immutable2 = immutable1;
    immutable1++;
    System.out.println( "immutable1 = " + immutable1 + ", immutable2 = " 
+
immutable2 );

    // an example of how mutable objects behave, that shows the 
difference,
in this case,
    // the object is mutable, so mutable1 and mutable2 both point to the
same object
    // and when it is updated, they both reflect this change
    // using a method .increment() because java does not support 
operator
overloading.
    IntWrapper mutable1 = new IntWrapper(3);
    IntWrapper mutable2 = mutable1;
    mutable1.increment();
    System.out.println( "mutable1 = " + mutable1 + ", mutable2 = " +
mutable2 );
  }

  public int num;
  public IntWrapper( int num ) { this.num = num; }
  public void increment() { num++; }
  public String toString() { return Integer.toString(num); }
}


Ruby avoids the criticism of contradicting the C/C++ model, and general
object model because it's immutable classes don't implement 
self-modifying
methods like ++, every method returns a new object.
Posted by Tony Arcieri (Guest)
on 2010-02-15 23:58
(Received via mailing list)
On Sat, Feb 13, 2010 at 8:48 PM, Josh Cheek <josh.cheek@gmail.com> 
wrote:

> I think that people who ask for ++ really don't understand what they are
> asking for, and think it is just a simple syntactic difference.
>

Sorry to flay the dead horse's sun-bleached bones a bit more, but...

++ and -- (both prefix and postfix), were they to be added to Ruby, 
should
be implemented as little more than syntactic sugar.  Much of the 
opposition
to ++ and -- comes from the idea that they *must* be implemented as 
methods
instead of as syntactic sugar as I've related previously in this post. 
It's
certainly internally consistent to implement all operators as methods, 
and
that's great, but Ruby doesn't implement "=" (or any assignment 
operators
like +=, *= etc) as a method.

Certain combinations of operations like obj[x] += 1 may involve complex
sequence of message dispatches.  This operation sends the [] message to 
obj
with x as a parameter, then invokes the "+" method on the result of 
obj[x],
then invokes the []= method on obj with x and the result of the + 
operation.

So, not to toss any lighter fluid onto the horse's bleached bones, but I
think those opposed to "++" and "--" operators possess an intermediate
understanding of Ruby and don't know that down there in the trenches of 
Ruby
implementation, things are already a bit ugly.  A single operator alone 
may
invoke multiple methods, and combinations thereof may permute that 
further,
particularly when assignment is involved.  Operators ARE NOT directly
equivalent to method calls in all cases.

In a language like Ruby, if you were to introduce "++" and "--" they 
MUST be
classed as assignment operators; otherwise they don't make sense.  Much 
of
the opposition to them seems to center around the "what if ++ and -- 
aren't
assignment operators?" argument which is certainly a dead horse.  I 
freely
admit that trying to implement ++ or -- as anything but compound 
assignment
operators doesn't make any sense whatsoever.

Implementing these operators as syntactic sugar for something like this 
for
x++:

   begin; _tmp = x; x += 1; _tmp; end

...is the only sensible solution, and anything else is a red herring.
Posted by Lui Kore (night_stalker)
on 2010-02-16 04:08
Just think about "a ++ -- - ++ -- b".
It doesn't save typing, you have to type more brakets usually !

"Yo dawg, I herd yo like ++s.
So I put a ++ in your ++ so you can ++ while you ++ "
Posted by lith (Guest)
on 2010-02-16 09:28
(Received via mailing list)
> ++ and -- (both prefix and postfix), were they to be added to Ruby, should
> be implemented as little more than syntactic sugar.

I find that issue interesting in a slightly different perspective.
Shouldn't it be possible to implement that operator right in ruby and
doesn't it point to a shortcoming that there is no way to implement it
(other than using a decorator).
Posted by Lui Kore (night_stalker)
on 2010-02-16 12:11
I don't think there is any problem in implementation, but choosing a 
subset of useful features is more important. Any language that want to 
have every feature will surely fail, think about D.

I wish ++ can be added as a binary operator like it is in Haskell, not 
the self-increamental one.

lith wrote:
>> ++ and -- (both prefix and postfix), were they to be added to Ruby, should
>> be implemented as little more than syntactic sugar.
> 
> I find that issue interesting in a slightly different perspective.
> Shouldn't it be possible to implement that operator right in ruby and
> doesn't it point to a shortcoming that there is no way to implement it
> (other than using a decorator).
Posted by Marnen Laibow-Koser (marnen)
on 2010-02-16 17:00
lith wrote:
>> ++ and -- (both prefix and postfix), were they to be added to Ruby, should
>> be implemented as little more than syntactic sugar.
> 
> I find that issue interesting in a slightly different perspective.
> Shouldn't it be possible to implement that operator right in ruby and
> doesn't it point to a shortcoming that there is no way to implement it
> (other than using a decorator).

No.  The mechanics of assignment in Ruby are such that ++ is simply not 
compatible with the structure of the language.  It belongs to a 
different programming paradigm.

Best,
--
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
Posted by Tony Arcieri (Guest)
on 2010-02-16 17:50
(Received via mailing list)
On Tue, Feb 16, 2010 at 1:28 AM, lith <minilith@gmail.com> wrote:

> I find that issue interesting in a slightly different perspective.
> Shouldn't it be possible to implement that operator right in ruby and
> doesn't it point to a shortcoming that there is no way to implement it
> (other than using a decorator).
>

++ and -- modify their receivers.  Since Ruby's Numeric types are 
immutable,
they cannot be modified.  So the only solution is to implement ++ and -- 
as
assignment operators.

Immutability certainly isn't a shortcoming, in fact it's very much a 
good
thing, especially when concurrency is involved.  My own pet programming
language has no mutable state whatsoever and implements all operators 
that
modify their receivers as assignments.
Posted by lith (Guest)
on 2010-02-16 18:44
(Received via mailing list)
> ++ and -- modify their receivers.  Since Ruby's Numeric types are immutable,
> they cannot be modified.  So the only solution is to implement ++ and -- as
> assignment operators.

Other languages solve similar problems by providing references/
pointers to variable or with macros etc. This isn't about
immutability.
Posted by Seebs (Guest)
on 2010-02-16 18:46
(Received via mailing list)
On 2010-02-16, lith <minilith@gmail.com> wrote:
> I find that issue interesting in a slightly different perspective.
> Shouldn't it be possible to implement that operator right in ruby and
> doesn't it point to a shortcoming that there is no way to implement it
> (other than using a decorator).

I don't think so, no more than it points to a shortcoming of Ruby that
you can't implement = as an operator.

-s
Posted by Seebs (Guest)
on 2010-02-16 18:50
(Received via mailing list)
On 2010-02-16, lith <minilith@gmail.com> wrote:
>> ++ and -- modify their receivers.  Since Ruby's Numeric types are immutable,
>> they cannot be modified.  So the only solution is to implement ++ and -- as
>> assignment operators.

> Other languages solve similar problems by providing references/
> pointers to variable or with macros etc.

I don't think allowing references or pointers to variables would be 
good.
Variables are not objects, they're references already.

> This isn't about immutability.

In practice it is, because when people say "x++", they don't want the 
variable
x to refer to a new object, they want the object x refers to increased.

-s
Posted by Xavier Noria (fxn)
on 2010-02-16 19:09
(Received via mailing list)
On Tue, Feb 16, 2010 at 6:50 PM, Seebs <usenet-nospam@seebs.net> wrote:

> In practice it is, because when people say "x++", they don't want the variable
> x to refer to a new object, they want the object x refers to increased.

Don't agree with that. For me the contract is just about the variable.
People do not want to be able to do ++5, you can't do that in
languages that offer ++ either.
Posted by Seebs (Guest)
on 2010-02-16 19:30
(Received via mailing list)
On 2010-02-16, Xavier Noria <fxn@hashref.com> wrote:
> On Tue, Feb 16, 2010 at 6:50 PM, Seebs <usenet-nospam@seebs.net> wrote:
>> In practice it is, because when people say "x++", they don't want the variable
>> x to refer to a new object, they want the object x refers to increased.

> Don't agree with that. For me the contract is just about the variable.
> People do not want to be able to do ++5, you can't do that in
> languages that offer ++ either.

In C:

++*p;

Has nothing to do with the variable, has everything to do with the 
object
denoted by the expression '*p'.

In C, the variable denotes a region of storage.  In Ruby, it doesn't.

-s
Posted by Xavier Noria (fxn)
on 2010-02-16 19:57
(Received via mailing list)
On Tue, Feb 16, 2010 at 7:30 PM, Seebs <usenet-nospam@seebs.net> wrote:

>
> ++*p;
>
> Has nothing to do with the variable, has everything to do with the object
> denoted by the expression '*p'.
>
> In C, the variable denotes a region of storage.  In Ruby, it doesn't.

You could argue that for += as well:

    *p += 1;

Does that C use case rule out += in Ruby? Nope we have our own +=
right? Same a posteriori for ++ in my opinion. It could be implemented
given the expectations that are reasonable to have in Ruby.
Posted by Tony Arcieri (Guest)
on 2010-02-16 21:10
(Received via mailing list)
On Tue, Feb 16, 2010 at 11:52 AM, Xavier Noria <fxn@hashref.com> wrote:

> You could argue that for += as well:
>
>    *p += 1;
>
> Does that C use case rule out += in Ruby? Nope we have our own +=
> right? Same a posteriori for ++ in my opinion. It could be implemented
> given the expectations that are reasonable to have in Ruby.
>

And += can result in a sequence of message exchanges as well:

obj.meth += 1
obj[member] += 1

These will need to invoke the respective getters and setters for obj, in
addition to invoking '+' on the object returned from the getter.

In that regard += is very much sugar for:

obj.meth = obj.meth + 1
Posted by Aldric Giacomoni (trevoke)
on 2010-02-16 21:52
Sonja Elen Kisa wrote:
> "foo += 1" somehow seems less elegant or pretty as "foo++".
> 
> Is there any reason Ruby doesn't have ++? Is it something that might be
> added in a future version?

foo+=1 follows the POLS.
foo++ leads to tricky behavior and tricky code and "clever" programming, 
which is usually a Bad Thing(tm).
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.