From: Rob Biedenharn Date: 2013-04-15T23:01:50+09:00 Subject: Re: Wondering why no "increment" or "decrement" operator in ruby --Apple-Mail=_7E6FDFCD-EC10-4A4C-80CD-D7D0E6E0CC45 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 On 2013-Apr-15, at 05:20 , Robert Klemme wrote: > On Mon, Apr 15, 2013 at 5:38 AM, tamouse mailing lists = wrote: > On Sun, Apr 14, 2013 at 10:23 PM, Matthew Kerwin = wrote: > > Incidentally, if you're using MRI, because of a clever optimisation = your > > 'a' variable literally holds the value `1`, not a reference per se. >=20 > I guess I don't understand this last part; I can still call an > instance method on a, so it must be more than just a value..., no? As > I can call an instance method on 1. I guess I don't quite get what you > mean by 'value'... >=20 > I prefer to look at this on the language level and not the MRI = implementation (even though they are closely related). On the language = level the optimization is invisible and hence irrelevant for the = reasoning here. The reason for the absence of an increment operator is = that there was a design decision to make numbers immutable (at least = with regard to their numeric value). If instances of a type are = immutable their state will never change - hence you cannot change them = from representing 1 to 2 etc. >=20 > Having said that, "++a" could be made syntactic sugar for "a+=3D1" but = that would not work if a was referencing a String even though String#+ = is defined. The only way out of this would be to make "++a" syntactic = sugar for something like "a+=3Da.class.one" where Integer would = implement "one" as "return 1". But what would String.one return then? >=20 > Kind regards >=20 > robert >=20 > --=20 > remember.guy do |as, often| as.you_can - without end > http://blog.rubybestpractices.com/ Why wouldn't the syntactic sugar for ++a be a=3Da.succ (for "successor") = since that is defined on more types? =46rom the PIckaxe: So far we=92ve shown ranges of numbers and strings. However, as you=92d = expect from an object- oriented language, Ruby can create ranges based = on objects that you define. The only constraints are that the objects = must respond to succ by returning the next object in sequence and the = objects must be comparable using <=3D>. -- Programming Ruby 1.9 & 2.0, p. 93, Ch.6 Standard Types=20 irb2.0.0> a =3D 1 #2.0.0 =3D> 1 irb2.0.0> a.succ #2.0.0 =3D> 2 irb2.0.0> a =3D "hello" #2.0.0 =3D> "hello" irb2.0.0> a.succ #2.0.0 =3D> "hellp" For String, which does have mutable instances, there's also #succ! to = change the object itself. irb2.0.0> a #2.0.0 =3D> "hello" irb2.0.0> a =3D "hello" #2.0.0 =3D> "hello" irb2.0.0> a.succ #2.0.0 =3D> "hellp" irb2.0.0> a #2.0.0 =3D> "hello" irb2.0.0> a.succ! #2.0.0 =3D> "hellp" irb2.0.0> a #2.0.0 =3D> "hellp" for --a you could use a=3Da.pred (for "predecessor"), but that's only = defined on Integer (and had no built-in use like #succ does). irb2.0.0> a =3D 1=20 #2.0.0 =3D> 1 irb2.0.0> a.pred #2.0.0 =3D> 0 irb2.0.0> a.pred NoMethodError: undefined method `pred' for "hello":String from (irb):5 from /Users/rab/.rbenv/versions/2.0.0-p0/bin/irb:12:in `
' =46rom my Wayback Machine=99, about 25 years ago the company I worked = for had an internally developed C compiler (yes, back in the stone age = before C was even a standard language and gcc was that weird, free = compiler) that actually did define ++ and -- for doubles (floating point = numbers) as a+=3D1.0 and a-=3D1.0 for just this reason. -Rob --Apple-Mail=_7E6FDFCD-EC10-4A4C-80CD-D7D0E6E0CC45 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=windows-1252
On Mon, Apr 15, 2013 at 5:38 AM, tamouse mailing = lists <tamouse.lists@gmail.com> wrote:
On Sun, Apr 14, 2013 at 10:23 PM, Matthew = Kerwin <lists@ruby-forum.com> = wrote:
> Incidentally, if you're using MRI, because of a clever optimisation = your
> 'a' variable literally holds the value `1`, not a reference per = se.

I guess I don't understand this last part; I can still call an
instance method on a, so it must be more than just a value..., no? = As
I can call an instance method on 1. I guess I don't quite get what = you
mean by 'value'...

I prefer to look at this on the language level = and not the MRI implementation (even though they are closely related). =  On the language level the optimization is invisible and hence = irrelevant for the reasoning here.  The reason for the absence of = an increment operator is that there was a design decision to make = numbers immutable (at least with regard to their numeric value). =  If instances of a type are immutable their state will never change = - hence you cannot change them from representing 1 to 2 etc.

Having = said that, "++a" could be made syntactic sugar for "a+=3D1" but that = would not work if a was referencing a String even though String#+ is = defined.  The only way out of this would be to make "++a" syntactic = sugar for something like "a+=3Da.class.one" where Integer would = implement "one" as "return 1".  But what would String.one return = then?

Kind = regards

robert

-- =
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.= com/

Why wouldn't the syntactic sugar for ++a be = a=3Da.succ (for "successor") since that is defined on more types? =46rom = the PIckaxe:

So far we=92ve shown ranges of numbers and strings. = However, as you=92d expect from an object- oriented language, Ruby can create ranges based on objects that you = define. The only constraints are that the objects must respond to = succ by returning the next object in = sequence and the objects must be comparable using <=3D>.

-- = Programming Ruby 1.9 & 2.0, p. 93, Ch.6 Standard = Types 


irb2.0.0= > a =3D 1
#2.0.0 =3D> 1
irb2.0.0> = a.succ
#2.0.0 =3D> 2
irb2.0.0> a =3D = "hello"
#2.0.0 =3D> "hello"
irb2.0.0> = a.succ
#2.0.0 =3D> "hellp"

For = String, which does have mutable instances, there's also #succ! to change = the object itself.

irb2.0.0> = a
#2.0.0 =3D> "hello"
irb2.0.0> a =3D = "hello"
#2.0.0 =3D> "hello"
irb2.0.0> = a.succ
#2.0.0 =3D> "hellp"
irb2.0.0> = a
#2.0.0 =3D> "hello"
irb2.0.0> = a.succ!
#2.0.0 =3D> "hellp"
irb2.0.0> = a
#2.0.0 =3D> "hellp"

for = --a you could use a=3Da.pred (for "predecessor"), but that's only = defined on Integer (and had no built-in use like #succ = does).

irb2.0.0> a =3D = 1 
#2.0.0 =3D> 1
irb2.0.0> = a.pred
#2.0.0 =3D> 0
irb2.0.0> = a.pred
NoMethodError: undefined method `pred' for = "hello":String
from (irb):5
from = /Users/rab/.rbenv/versions/2.0.0-p0/bin/irb:12:in = `<main>'


=46rom my = Wayback Machine=99, about 25 years ago the company I worked for had an = internally developed C compiler (yes, back in the stone age before C was = even a standard language and gcc was that weird, free compiler) that = actually did define ++ and -- for doubles (floating point numbers) as = a+=3D1.0 and a-=3D1.0 for just this = reason.

-Rob

= --Apple-Mail=_7E6FDFCD-EC10-4A4C-80CD-D7D0E6E0CC45--