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

Michael W. Ryder wrote:
[…]

. I much prefer the
simplicity of Basic and C with for loops that can go either direction.

That’s because you’re trying to write C in Ruby. There are far more
idiomatic ways of doing things – and they are clearer, at least in a
Ruby context.

As far as going backwards I use it a lot to parse strings of the form
“city name ST 12345-6789” to City, State, and Zip Code fields. I look
for the first blank from the end of the string and assume everything
after it is the Zip Code, I then find the next two non-blank characters
and assign them to State, and everything else is the City name.

That’s great in a language like C that doesn’t have very good string
handling. The Ruby way to do this would be
city, state, zip = string.split(/\s+/)

No incrementing. No iteration. Just a clear declarative syntax.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Hi –

On Sat, 7 Nov 2009, Marnen Laibow-Koser wrote:

“city name ST 12345-6789” to City, State, and Zip Code fields. I look
for the first blank from the end of the string and assume everything
after it is the Zip Code, I then find the next two non-blank characters
and assign them to State, and everything else is the City name.

That’s great in a language like C that doesn’t have very good string
handling. The Ruby way to do this would be
city, state, zip = string.split(/\s+/)

You’d need to take multi-word city names into account, though. So
maybe:

city, state, zip = /\A(.*)\s+(\S+)\s+(\S+)\Z/.match(str).captures

David


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)

On Nov 4, 4:59 pm, Yukihiro M. [email protected] wrote:

                                                    matz.

Thanks for your response, Matz.
I’ve got to study David Black’s book more thoroughly.

Best wishes,
Richard

David A. Black wrote:

Hi –

On Sat, 7 Nov 2009, Marnen Laibow-Koser wrote:

“city name ST 12345-6789” to City, State, and Zip Code fields. I look
for the first blank from the end of the string and assume everything
after it is the Zip Code, I then find the next two non-blank characters
and assign them to State, and everything else is the City name.

That’s great in a language like C that doesn’t have very good string
handling. The Ruby way to do this would be
city, state, zip = string.split(/\s+/)

You’d need to take multi-word city names into account, though. So
maybe:

city, state, zip = /\A(.*)\s+(\S+)\s+(\S+)\Z/.match(str).captures

Quite right. I was trying for simplicity, but that had indeed crossed
my mind.

David


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)

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Sun, Nov 8, 2009 at 11:48 AM, Tony A. [email protected] wrote:

the issue.
In C++ a variable can actually hold the state of an object rather than
simply a reference to the object.

If you think of object as simply meaning what holds the state of what
is denoted by a variable, then C variables hold objects, and since a
pointer represents state, even pointer’s can be considered objects in
this degenerate (if you will) form.

And that really is the point with the ++ operator, at least if you
want it to have the semantics of C/C++.

the c/c++ expression

b = a++

has the meaning.

  1. copy the current contents of the a variable to b
  2. increment the contents of the variable a according to the static
    type of a, e.g. if it’s an int or a pointer to a char add 1 to it, if
    it’s a pointer to a (4-byte) int add 4 to it, etc.

The original quest in this thread was to do this by defining a ++
method for FixNum (or Integer).

As Matz himself has pointed out in this thread,

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

                                                    matz.

Which is something I’ve said on this thread before (multiple times
IIRC).

This has nothing to do with whether or not the object bound to a
variable is immutable, it has to do with how ruby variable bindings
can and cannot be changed, and that is the whole point.

Now, while it’s true that Fixnums have a property of being represented
by an immediate value rather than a pointer to a ‘boxed’ value, and
this is possible because they are immutable, it doesn’t mean that
local variables with non-immediate bindings can be rebound inside the
invocation of another method.

The only way to define b = a++. in Ruby with C/C++ semantics would be
to alter the parser to treat such expressions as syntactic sugar,
(which was Charle’s proposal), much like += is handled now.

Let’s say this were done, perhaps by the parser treating:

b = a++

as if it were

b, a = a, a.succ

much like it treats

a += 1

as if it were

a = a + 1

The actual parser changes would need to be sensitive to other cases like

foo(b + a++)

which would need to compute a + b before incrementing a.

One could alter what the increment did, by redefining succ or a
particular class, much like redefining + for a given class can alter
the value of a + 1 for a particular binding of a.

But one could still not move the actual change of binding into a
method, any more than you can redefine the ‘=’ part of ‘+=’


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

On Fri, Nov 6, 2009 at 4:30 PM, Seebs [email protected] wrote:

“variables aren’t objects”

I’ve seen this mentioned a few times. I think it’s something of a gross
misstatement of a problem, and a deeper understanding might be able to
peel
away some of the layers of the debate here.

I can’t think of a language where “variables are objects”. 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.

Advocates of allowing a ++ operator are suggesting that the operator
have a
dispatch model which alters the local binding when applied to Numeric
types. I’m further suggesting it be dispatched like any other operator
when
applied to non-numeric types.

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.

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.

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

On Sun, Nov 8, 2009 at 10:45 AM, Rick DeNatale
[email protected]wrote:

variable is immutable, it has to do with how ruby variable bindings
can and cannot be changed, and that is the whole point.

You still seem to be missing what I’m proposing.

For Numerics, ++ would rebind. For everything else, it would be
dispatched
as a message.

Am I being unclear?

Tony A. wrote:

On Sun, Nov 8, 2009 at 10:45 AM, Rick DeNatale
[email protected]wrote:

variable is immutable, it has to do with how ruby variable bindings
can and cannot be changed, and that is the whole point.

You still seem to be missing what I’m proposing.

For Numerics, ++ would rebind. For everything else, it would be
dispatched
as a message.

Yuuuuuuuck! Why do this ugly special-casing for something that’s hardly
ever needed anyway?

Am I being unclear?

No, just silly. :smiley:

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Sun, Nov 8, 2009 at 11:22 AM, Marnen Laibow-Koser
[email protected]wrote:

Yuuuuuuuck! Why do this ugly special-casing for something that’s hardly
ever needed anyway?

To reiterate from my previous message, because the behavior of Numerics
is
already a special case to begin with.

On 2009-11-08, Rick DeNatale [email protected] wrote:

If you think of object as simply meaning what holds the state of what
is denoted by a variable, then C variables hold objects, and since a
pointer represents state, even pointer’s can be considered objects in
this degenerate (if you will) form.

Insofar as anything in C is “an object”, pointers are.

-s

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Tony
To reiterate from my previous message, because the behavior of Numerics
is already a special case to begin with.

How? Because they are immutable? That’s not special casing, that’s just
how the class is designed. I can write an immutable class in Ruby,
without any special casing.

On Sun, Nov 8, 2009 at 11:50 AM, Rick DeNatale
[email protected]wrote:

No, but you ARE missing the fact that the lack of being able to rebind
a variable via a method has NOTHING to do with the class of the object
which is currently bound to that variable.

But the rebinding is being done by an operator, not a method, and
there’s
ample precedent for operators that perform rebinding in Ruby (=, +=, -=,
/=,
etc)

On Sun, Nov 8, 2009 at 1:18 PM, Tony A. [email protected] wrote:

Am I being unclear?
No, but you ARE missing the fact that the lack of being able to rebind
a variable via a method has NOTHING to do with the class of the object
which is currently bound to that variable.

Since ruby variables aren’t typed then the expansion of the syntactic
sugar

b = a++

to “rebind for Numerics and dispatch for everything else” would have
to be something like

if Number === a
b, a = a, a.succ
else
#…
end

But note that in order to add 1 to a number, we still need to dispatch
a method whether that be succ, or + and if we are going to do that we
might just as well expand b = a++ to

b, a = a, a.succ

no matter what a is currently bound to.

Not that I think ++ is valuable enough to change the language.

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

On 2009-11-08, Tony A. [email protected] wrote:

You still seem to be missing what I’m proposing.

For Numerics, ++ would rebind. For everything else, it would be dispatched
as a message.

Am I being unclear?

I don’t think that gives the right semantics in many cases. It’s also
not clear that rebinding works:

array_example.length++

What should this do?

-s

On Sun, Nov 8, 2009 at 11:49 AM, Walton H.
[email protected]wrote:

How? Because they are immutable? That’s not special casing, that’s just
how the class is designed. I can write an immutable class in Ruby,
without any special casing.

Yes, non-Numeric objects can be immutable. However, Numeric objects
can’t
be mutable.

On 2009-11-08, Tony A. [email protected] wrote:

But the rebinding is being done by an operator, not a method, and there’s
ample precedent for operators that perform rebinding in Ruby (=, +=, -=, /=,
etc)

And which of those operators special-case Numeric?

Any of them? I don’t think so.

If it’s to be a rebinding operator, it ought to rebind for everything,
not
just for numerics.

-s

On Sun, Nov 8, 2009 at 12:20 PM, Seebs [email protected] wrote:

I don’t think that gives the right semantics in many cases. It’s also
not clear that rebinding works:

   array_example.length++

What should this do?

Well, this is a very interesting question, as I discovered something
about
Ruby I didn’t know from this…

Say we have:

class Foo
attr_reader :bar

def initialize
@bar = 0
end
end

f = Foo.new
f.bar += 1

What do you think the value of a subsequent call to f.bar will be?

I was surprised to discover that it indeed 1. Somehow += is mutating
the
ivar through a supposed “attr_reader” even though there is no
corresponding
bar= method. In that case += appears to be frobbing the ivar directly.

Very strange. Even worse:

class Foo
def initialize
@bar = 0
end

def bar
@bar + 1
end
end

f = Foo.new
f.bar += 1

Now what do you think the value of a subsequent call to f.bar will be?

Indeed, it would be 3!

I cannot begin to answer this question because Ruby is doing strange and
unexpected things here, at least from my perspective…

On Sun, Nov 8, 2009 at 12:20 PM, Seebs [email protected] wrote:

And which of those operators special-case Numeric?

Any of them? I don’t think so.

Admittedly it would be a first.

If it’s to be a rebinding operator, it ought to rebind for everything, not
just for numerics.

To borrow a phrase from 37signals, “context is more important than
consistency”

From: [email protected] [mailto:[email protected]] On Behalf Of Tony
Yes, non-Numeric objects can be immutable. However, Numeric objects
can’t
be mutable.

Incorrect. In fact the very first message in this thread provided an
example of redifining Fixnum in such a way that it was mutable.