In algebraic theory, terms such as groups and rings are used to define what
addition and multiplication mean. I'm here trying to use something I learned
and forgot a long time ago, so bear with me, but I think the concepts may
apply here.

In Ruby += has been defined as a combination of assignment and the plus
operation (i.e. addition).

In other languages ++ has been defined as the addition with one.

In algebra, the one element is a particularly important element (along with
zero) because you can generate all values by systematically adding the one
element to the previous result, starting with the zero element.

It appears to me that all the talk about why ++ is not valid due to
anti-shoe-box behaviour is beside the point, because the would also be true
for += :
a = 1
a += 2 # ==> 3
We are not redefining any integers here, we are replacing the reference with
a reference to a new object.

The following makes just as much sense as the above:

a = 1
a++ # ==> 2

The point, is that whatever problems there are with ++ and object
modifications applies equally to += and the next, next! method, and these
problems have been solved. We can't, however, define ++ without help from
the Ruby interpreter because ++ should be specially interpreted at the same
level as += becuase assignment to self is not possible.
In other words, ++ is an operator that replaces a reference to one object
with a reference to the next object. This operation may or may not be an
inplace operation. Thus we have ++ and ++!.
In fact this is exactly the same as the next and next! methods, thus we just
need the interpreter to go along with these synonyms. Note that integers do
not have a next! operation and float do not have a next method at all - this
makes perfect sense:

In algebraic terms, there is no 'one' element for Real numbers, while
natural numbers (integers) do have a one element. Furthermore it is not
within the realms of Ruby to redefine the natural numbers, thus no next!
method.

The ++ operator is really a 'generator' in algebraic terms. It should
generate the next element in the set of all elements of a given type, such
as the natural numbers. When a one element is defined, the generator is the
add one operator - it is not necessarily the only generator, but it works.
(stray thought: generators are used on error correcting codes to generate
valid values among all values - a very simple error correcting code would be
to define 0, 4, 8, ..., i.e. generator is x += 4. correct(x) = x + 2 mod 4,
thus if someone accidentally added 1 to x, it won't destroy the
information).

In Ruby we don't really care about exact algebraic generators. For example
it is nice to have the next string: "helo".next ==> "help". This doesn't
generate all valid strings, yet it is rather useful.

Thus we can piggyback on the "next" method to define our generator - or we
may define our generator as "generator" and define next in terms of the
generator whatever...
The default generator can be define based on the one element, whenever it is
defined. As an example, let us define the one element for Float.
Algebraically it doesn't make sense, except by doint so we actually define a
new value type - which incidentally happens to be the natural numbers if we
define one as an arbitrary non-zero float value, it just has a different
representation:

We can define a default generator and a default next method for Object:

class Object
  def generator
    self + one
  end
  def next
    generator
  end
end

Or just ignore the generator stuff:

class Object
   def next
     self + one
    end
end

We can define the one element for any class we like:

class Float
  def one
    1.0
  end
end

a = 1.0
a.next  # ==> 2.0


No we could equally well write

a++ as a synonym for
a = a.next

and

a++! as a synom for
a.next!

Note that we do not have a default definition of next!, but it may be
referencing an object that does have next! defined, such as a string.

Obviously iterators are obvious candiates for ++:
In the following notice the importnat difference between ++ and ++!
If I had used ++! I would not have been able to reference two values
in the collection at the same time, yet I feel ++ does exactly what I expect
in the following. This suggests there really is a difference between ++ and
++! and both are meaningful in their own terms.

if my_collection.size > 1
 begin
  c = 0
  a = my_collection.first
  k = a
  ++a
  while a != my_collection.end
    b = a
    a++
    if a.value > b.value
      a.swap_values b
      c++
  end
 end while c > 0
end

def unique x
  if not my_collection.exist(x)
    return x
  end
  x = x + "~a"
  while my_collection.exist(x)
    x++!
  next
end

Of course, the above examples could be written with next and next!. In
particular, the ++! would probably be nicer using next! But the ++ operator
makes the operation somewhat cleaner that a = a.next.


Mikkel