From: Rick DeNatale on
On Fri, Oct 30, 2009 at 11:05 AM, Robert Klemme
<shortcutter(a)googlemail.com> wrote:
> 2009/10/30 RichardOnRails <RichardDummyMailbox58407(a)uscomputergurus.com>:
>
>> 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").

I think that theres a more fundamental problem with ++ in a language
like ruby, which has to do with the difference between objects and
variables.

The c ++ and -- operators change a variable, NOT a value.

so in C

a = 1
b = a
a++

a is now 2, but b is still 1.

Now, consider not immutable objects, but defining ++ for a mutable
object. I've named the method plus_plus instead of ++ since I can do
the former, but not the latter.

class String
def plus_plus
self << " plus a plus"
end
end


a = "A non-plussed string"
b = a

puts "a is #{a.inspect}"
puts "b is #{b.inspect}"

a.plus_plus

puts "a is #{a.inspect}"
puts "b is #{b.inspect}"

When we run this we see that the result is:

a is "A non-plussed string"
b is "A non-plussed string"
a is "A non-plussed string plus a plus"
b is "A non-plussed string plus a plus"

Because in languages like Ruby with object reference variable
semantics, methods can only operate on objects, not the variables
which reference them.

So if you COULD successfully define Fixnum#++, or Fixnum#plus_plus:

a = 1
a++

could only change the singleton instance of 1 into 2, which probably
isn't something you'd really want to do.

By 'you' I'm not aiming at you Robert.

This reminds me of a very hard bug I encountered years ago when I was
first was learning to program in Fortran. In the original Fortran you
could assign a new value to a subroutine parameter inside the
subroutine. If the actual parameter value was an integer literal, you
could literally change 1 to 2, and that's why I know you probably
don't want to do this.
--
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

From: Marnen Laibow-Koser on
Rajinder Yadav wrote:
[...]
> can you extol

(Not what that word means.)

> your knowledge on me about what method_missing is doing?

http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_object.html#Object.method_missing

Best,
--
Marnen Laibow-Koser
http://www.marnen.org
marnen(a)marnen.org
--
Posted via http://www.ruby-forum.com/.

From: Robert Klemme on
On 10/30/2009 08:03 PM, Rick DeNatale wrote:
> On Fri, Oct 30, 2009 at 11:05 AM, Robert Klemme
> <shortcutter(a)googlemail.com> wrote:
>> 2009/10/30 RichardOnRails <RichardDummyMailbox58407(a)uscomputergurus.com>:
>>
>>> 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").
>
> I think that theres a more fundamental problem with ++ in a language
> like ruby, which has to do with the difference between objects and
> variables.
>
> The c ++ and -- operators change a variable, NOT a value.

How their behavior is defined is completely up to the language designer.
You could make "a++" syntactic sugar for

(_tmp = a; a = a + 1; _tmp)

in the same way as "a += 1" is syntactic sugar for "a = a + 1" or "a ||=
10" is syntactic sugar for "a || a = 10". In fact the sequence in
brackets above would be a completely reasonable way to do it in Ruby:
you could use "a++" in a similar way as in C++ and Java without
sacrificing Fixnum's immutability.

But: you would hide the assignment in the syntactic sugared version and
this could lead to unexpected behavior, like

a = 1
b = a
a++
# now why is b still 1???

For someone unaware of the hidden assignment but aware of the fact that
the object referenced by a must be mutable to make this work it would be
surprising that b is not changed as well. You could only discover that
by looking at #object_id of both (or using #equal?).

> so in C
>
> a = 1
> b = a
> a++
>
> a is now 2, but b is still 1.

Yes - and in C++ you can have it otherwise:

robert(a)fussel:~$ g++ x.cc && ./a.out
a++=1
a=2
b=2
robert(a)fussel:~$ cat x.cc

#include <stdio.h>

int main( int argc, const char* argv[] )
{
int a = 1;
int &b = a;
printf("a++=%d\n", a++);
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}

robert(a)fussel:~$

> Now, consider not immutable objects, but defining ++ for a mutable
> object. I've named the method plus_plus instead of ++ since I can do
> the former, but not the latter.
>
> class String
> def plus_plus
> self << " plus a plus"
> end
> end
>
>
> a = "A non-plussed string"
> b = a
>
> puts "a is #{a.inspect}"
> puts "b is #{b.inspect}"
>
> a.plus_plus
>
> puts "a is #{a.inspect}"
> puts "b is #{b.inspect}"
>
> When we run this we see that the result is:
>
> a is "A non-plussed string"
> b is "A non-plussed string"
> a is "A non-plussed string plus a plus"
> b is "A non-plussed string plus a plus"
>
> Because in languages like Ruby with object reference variable
> semantics, methods can only operate on objects, not the variables
> which reference them.
>
> So if you COULD successfully define Fixnum#++, or Fixnum#plus_plus:
>
> a = 1
> a++
>
> could only change the singleton instance of 1 into 2, which probably
> isn't something you'd really want to do.

Not necessarily. If this was implemented in the language the sequence
"1" would be an object constructor in the same way as string "constants"
are.

robert(a)fussel:~$ ruby1.8 -e '2.times { puts "foo".object_id }'
-605970738
-605970758

That would the only reasonable way to do it. Then there would be no
singleton instance which in turn would have the said performance
implications.

I would consider the example from Fortran that you presented (changing
the value of the constant 1) rather a bug either in the language
implementation or in the design. This does not mean that other
languages would have to repeat that. :-)

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
From: Simon Krahnke on
* Robert Klemme <shortcutter(a)googlemail.com> (23:19) schrieb:

> Yes - and in C++ you can have it otherwise:
>
> robert(a)fussel:~$ g++ x.cc && ./a.out
> a++=1
> a=2
> b=2
> robert(a)fussel:~$ cat x.cc
>
> #include <stdio.h>
>
> int main( int argc, const char* argv[] )
> {
> int a = 1;
> int &b = a;
> printf("a++=%d\n", a++);
> printf("a=%d\n", a);
> printf("b=%d\n", b);
> return 0;
> }

No, you can't:

$ ./ab
a: 2 @ 0xbfe413f8
b: 2 @ 0xbfe413f8

$ cat ab.cc
#include <iostream>

int main(void) {
int a = 1;
int &b = a;
a++;
std::cout << "a: " << a << " @ " << &a << std::endl;
std::cout << "b: " << b << " @ " << &b << std::endl;
return 0;
}

There is only one variable, b is just another name for it.

mfg, simon .... l
From: Christopher Dicely on
On Fri, Oct 30, 2009 at 3:20 PM, Robert Klemme
<shortcutter(a)googlemail.com> wrote:
> On 10/30/2009 08:03 PM, Rick DeNatale wrote:
>>
>> On Fri, Oct 30, 2009 at 11:05 AM, Robert Klemme
>> <shortcutter(a)googlemail.com> wrote:
>>>
>>> 2009/10/30 RichardOnRails <RichardDummyMailbox58407(a)uscomputergurus.com>:
>>>
>>>> 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").
>>
>> I think that theres a more fundamental problem with ++ in a language
>> like ruby, which has to do with the difference between objects and
>> variables.
>>
>> The c ++ and -- operators change a variable, NOT a value.
>
> How their behavior is defined is completely up to the language designer.
>  You could make "a++" syntactic sugar for
>
> (_tmp = a; a = a + 1; _tmp)
>
> in the same way as "a += 1" is syntactic sugar for "a = a + 1" or "a ||= 10"
> is syntactic sugar for "a || a = 10".  In fact the sequence in brackets
> above would be a completely reasonable way to do it in Ruby: you could use
> "a++" in a similar way as in C++ and Java without sacrificing Fixnum's
> immutability.

I think it would make more sense, if you were going to define a "++"
syntax for Ruby, to use "a.succ" rather than "a+1", and if you are
going to create syntax which does an assignment but returns the
pre-assignment value of the variable receiving the assignment, I'd go
further and include a more general form for that, say ":=", such that
"a := b" is equivalent to "(_ = a),(a = b), _" and then define postfix
"++" such that "a++" is "a := a.succ" and prefix "++" such that "++a"
is equivalent to "a = a.succ".