What's an object?

Are you sure Xavier?
I am afraid that in

def x b
  b = ...
you brake the link as shown in the diagram (somehow as having a local
variable shadowing the param)

because if you made

def x b
  b << "hello"

the diagram seems correct, or is it I who misses something here?

Cheers
R.

···

On Fri, Nov 12, 2010 at 12:38 PM, Xavier Noria <fxn@hashref.com> wrote:

On Fri, Nov 12, 2010 at 12:25 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

On Fri, Nov 12, 2010 at 3:01 AM, Xavier Noria <fxn@hashref.com> wrote:

When the function is invoked the pointer is *copied*, that is, an integer
value is copied and linked to a local variable. The exact same thing
happens if the parameter is int i.

The exact same thing also happens with a reference (at least in C++, I don't
know anything about Perl).

The pointer value is copied into the number variable (pass by value).
You can be certain the caller sees the exact same pointer when
the function call returns.

Please re-read your blog with this in mind, since what you right here in
this quote are calling "pass by value" you, in your blog, call
"pass-by-reference".

ImageShack - Best place for all of your image hosting and image sharing needs

No, no. If Ruby did what the diagram shows the program

def m(b)
b = Object.new
p b.object_id
end

a = Object.new
m(a)
p a.object_id

would print the same number because a and b would be pointing to the
same storage area. They aren't.

--
The 1,000,000th fibonacci number contains '42' 2039 times; that is
almost 30 occurrences more than expected (208988 digits).
N.B. The 42nd fibonacci number does not contain '1000000' that is
almost the expected 3.0e-06 times.

How can b change what a points to when, according to your own diagram, b
does not have any reference to a?

Here is the diagram which shows pass-by-reference and
pass-by-object-reference ImageShack - Best place for all of your image hosting and image sharing needs

And I think your confusion itself is adequate justification for Ruby's style
to deserve its own name "pass by object reference"

Also, I would appreciate if more prominent Rubyists would weigh in on this.
So far, I am disagreeing with everyone in this thread. I would like to know
what the people that I have learned to respect think. I just disagree,
because those on the other side seem so conspicuously wrong. But the number
of people on that side seems disconcerting. I would like an objective
measure in the form of people whose conclusions I can't roll my eyes at.

···

On Fri, Nov 12, 2010 at 5:38 AM, Xavier Noria <fxn@hashref.com> wrote:

On Fri, Nov 12, 2010 at 12:25 PM, Josh Cheek <josh.cheek@gmail.com> wrote:
>> The pointer value is copied into the number variable (pass by value).
>> You can be certain the caller sees the exact same pointer when
>> the function call returns.
>>
>>
> Please re-read your blog with this in mind, since what you right here in
> this quote are calling "pass by value" you, in your blog, call
> "pass-by-reference".
>
> ImageShack - Best place for all of your image hosting and image sharing needs

No, no. If Ruby did what the diagram shows the program

   def m(b)
     b = Object.new
     p b.object_id
   end

   a = Object.new
   m(a)
   p a.object_id

would print the same number because a and b would be pointing to the
same storage area. They aren't.

Sorry, I made a mistake.

error:

Having the just reason that it is the Ruby's concept, I lost
another reason why we should regard a method as an object.

corrected:
Having the just reason that it is the Ruby's concept, I lost another
reason why we should NOT regard a method as an object.

···

--
NOBUOKA Yuya

Not sure I follow.

Variables can't store objects, that's guaranteed by the Ruby spec,
they only store references.

There, b holds a reference to a string. Strings are mutable in Ruby,
and << appends in place. The b variable holds a reference to the same
object stored in the variable of the caller. This is no different than
passing a user instance and calling user.name= inside the method.

Let's suppose for a moment that the object_id serves as reference, as
if it was a pointer. Let's imagine "" has object id 2158937800. The
diagram is:

    a -> 2158937800 -> ""
    b -> 2158937800 -> ""

Note that a and b store the same reference value, but they are separate.

If we assign a new string "b" to b inside the method with object id
2158934000 the diagram becomes

    a -> 2158937800 -> ""
    b -> 2158934000 -> "b"

because a and b store different values.

···

On Fri, Nov 12, 2010 at 1:09 PM, Robert Dober <robert.dober@gmail.com> wrote:

Are you sure Xavier?
I am afraid that in

def x b
b = ...
you brake the link as shown in the diagram (somehow as having a local
variable shadowing the param)

because if you made

def x b
b << "hello"

the diagram seems correct, or is it I who misses something here?

The Ruby spec says in section 6.2.1.

"A variable is denoted by a name, and refers to an object, which is
called the value of the variable. A variable itself is not an object.
While a variable can refer to only one object at a time, an object can
be referred to by more than one variable at a time."

Then in section 13.3.3 you'll see that the spec says that you create
local variable bindings from the arguments. For example, regarding
mandatory parameters:

"If Pi is a mandatory parameter, let n be the mandatory-parameter. If
Pi is an optional parameter, let n be the optional-parameter-name.
Create a variable binding with name n and value Ai in Sb."

I admit that the term "reference" is not used. I admit also that the
section about method invocation does not explicitly say "copy" as the
JLS does. But a posteriori the semantics are pass by value.

The binding is local, the variables are not aliases bound to the same
storage area. When you assign to the local variable, the caller is
unaffected. Being able to change the state of a mutable object is
unrelated to call semantics.

Conceptually my diagram lacks the middle boxes that represent the
indirection between the variable and the objects themselves.

I guess MRI binds VALUEs to variables, but I am only talking about
semantics, about how this works conceptually, not about what a
particular implementation does.

···

On Fri, Nov 12, 2010 at 1:28 PM, Josh Cheek <josh.cheek@gmail.com> wrote:

On Fri, Nov 12, 2010 at 5:38 AM, Xavier Noria <fxn@hashref.com> wrote:

On Fri, Nov 12, 2010 at 12:25 PM, Josh Cheek <josh.cheek@gmail.com> wrote:
>> The pointer value is copied into the number variable (pass by value).
>> You can be certain the caller sees the exact same pointer when
>> the function call returns.
>>
>>
> Please re-read your blog with this in mind, since what you right here in
> this quote are calling "pass by value" you, in your blog, call
> "pass-by-reference".
>
> ImageShack - Best place for all of your image hosting and image sharing needs

No, no. If Ruby did what the diagram shows the program

def m(b)
b = Object.new
p b.object_id
end

a = Object.new
m(a)
p a.object_id

would print the same number because a and b would be pointing to the
same storage area. They aren't.

How can b change what a points to when, according to your own diagram, b
does not have any reference to a?

Here is the diagram which shows pass-by-reference and
pass-by-object-reference ImageShack - Best place for all of your image hosting and image sharing needs

And I think your confusion itself is adequate justification for Ruby's style
to deserve its own name "pass by object reference"

Also, I would appreciate if more prominent Rubyists would weigh in on this.
So far, I am disagreeing with everyone in this thread. I would like to know
what the people that I have learned to respect think. I just disagree,
because those on the other side seem so conspicuously wrong. But the number
of people on that side seems disconcerting. I would like an objective
measure in the form of people whose conclusions I can't roll my eyes at.

Sorry, the rightmost arrows should point to the same unique "" here.
Couldn't do proper ascii diagrams with variable-width font.

In the next diagram two arrows are correct.

···

On Fri, Nov 12, 2010 at 1:30 PM, Xavier Noria <fxn@hashref.com> wrote:

a -> 2158937800 -> ""
b -> 2158937800 -> ""

That's actually what I meant: When passing the parameter the diagram
is correct. I do not see any reason why you claim the diagram
incorrect - for what the param passing semantics concerns - only
because Ruby gives you the freedom to reassign the param inside the
body of the method.
I wanted to express that this manipulation should not be used to prove
the correctness or incorectness of a given param passing model.
Clearer?

Cheers
R.

···

On Fri, Nov 12, 2010 at 1:31 PM, Xavier Noria <fxn@hashref.com> wrote:

On Fri, Nov 12, 2010 at 1:09 PM, Robert Dober <robert.dober@gmail.com> wrote:

a -> 2158937800 -> ""
b -> 2158937800 -> ""

Note that a and b store the same reference value, but they are separate.

If we assign a new string "b" to b inside the method with object id
2158934000 the diagram becomes

a -> 2158937800 -> ""
b -> 2158934000 -> "b"

because a and b store different values.

--
The 1,000,000th fibonacci number contains '42' 2039 times; that is
almost 30 occurrences more than expected (208988 digits).
N.B. The 42nd fibonacci number does not contain '1000000' that is
almost the expected 3.0e-06 times.

That's actually what I meant: When passing the parameter the diagram
is correct. I do not see any reason why you claim the diagram
incorrect - for what the param passing semantics concerns - only
because Ruby gives you the freedom to reassign the param inside the
body of the method.

You think the parameter is an alias, and the local variable masks it
right? As if usage was pass-by-value but you couldn't tell because of
that formality. Isn't that convoluted? The spec says local variables
are created, why do you think a second local variable is later created?

I wanted to express that this manipulation should not be used to prove
the correctness or incorectness of a given param passing model.
Clearer?

I am not familiar with MRI but I'd swear this is what implements the
argument value copying of pass-by-value semantics (that's from
vm_insnhelper.c in 1.9.2):

  /* copy arguments */
  for (i=0; i < (sp - rsp); i++) {
      p_rsp[i] = rsp[i];
  }

There, rsp has type VALUE*. If I understand the code correctly, that
in turn comes from copying the VALUEs in the argv argument of
vm_call0(). They are all plain assignments, we are just copying
pointers (or immediate values).

···

On Fri, Nov 12, 2010 at 3:56 PM, Robert Dober <robert.dober@gmail.com> wrote:

All you saying is completely clear, but does still not answer my question.

Did you disagree with the diagram because it expresses an alias (I
fail to see that); or because of the fact that the arrow pointing to
the same object is "volatile"?

That was my question, sorry if I was not clear 'nuff or was too
critisizing in the way of asking, I guess I was.

Cheers
R.

···

On Fri, Nov 12, 2010 at 4:18 PM, Xavier Noria <fxn@hashref.com> wrote:

On Fri, Nov 12, 2010 at 3:56 PM, Robert Dober <robert.dober@gmail.com> wrote:

--
The 1,000,000th fibonacci number contains '42' 2039 times; that is
almost 30 occurrences more than expected (208988 digits).
N.B. The 42nd fibonacci number does not contain '1000000' that is
almost the expected 3.0e-06 times.

Let me try to draw a new diagram with words.

When we perform

    x = Object.new

x does not hold an object. The variable holds a reference (my
interpretation of the verb "refers" in the spec). Say that reference
is in the case of MRI the VALUE 2158949260 (that is, a pointer).

So the diagram is inexact and I think I will revise it. The variable x
stores 2158949260, and it is the VM that gives you syntactic sugar
everywhere so that x.nil? follows the pointer for you to reach the
object to be able to send :nil? to it. The boxes in the diagram point
to a value, 1, while it would be more clear to put the 2158949260 in
the box. And perhaps a second box after it with the 1. (And an integer
is also exceptional in MRI, would use a different value).

That'd make the pass-by-value workflow more clear. When you invoke

    def m(y)
    end

passing x as argument, the VM constructs a new local variable y (local
to m), and initializes the variable with the value of x, which is
2158949260.

In this schema, x and y are unrelated variables, bound to unrelated
storage areas that happen to store the same integer value (a C
pointer).

Via the pointer they reach the same object, and that's why you can
change the state of a mutable object. The same pointer reaches the
same object.

If Ruby was pass-by-reference x and y would point to the same box
containing 2158949260. And assignment would change that integer for
both variables.

Do you agree with the picture?

···

On Fri, Nov 12, 2010 at 5:15 PM, Robert Dober <robert.dober@gmail.com> wrote:

On Fri, Nov 12, 2010 at 4:18 PM, Xavier Noria <fxn@hashref.com> wrote:

On Fri, Nov 12, 2010 at 3:56 PM, Robert Dober <robert.dober@gmail.com> wrote:

All you saying is completely clear, but does still not answer my question.

Did you disagree with the diagram because it expresses an alias (I
fail to see that); or because of the fact that the arrow pointing to
the same object is "volatile"?

That was my question, sorry if I was not clear 'nuff or was too
critisizing in the way of asking, I guess I was.

Do you agree with the picture?

Completely!
I agree that we have pass by value. My question is, why do you dislike
this representation for it

def meth a
...

meth(b)

a ---+
       >
       +------> An Object
       >
b---+

I thought it was making things quite clear
Maybe one should add that after

b = 42

the picture changes.

R.

···

On Fri, Nov 12, 2010 at 5:33 PM, Xavier Noria <fxn@hashref.com> wrote:

--
The 1,000,000th fibonacci number contains '42' 2039 times; that is
almost 30 occurrences more than expected (208988 digits).
N.B. The 42nd fibonacci number does not contain '1000000' that is
almost the expected 3.0e-06 times.

Completely!

Aaahhh, perfect :).

I agree that we have pass by value. My question is, why do you dislike
this representation for it

def meth a
...

meth(b)

a ---+
>
+------> An Object
>
b---+

I thought it was making things quite clear
Maybe one should add that after

b = 42

the picture changes.

Because I think the object at the end of the arrow may be misleading
for explaining call semantics.

Problem is those arrows do not mean storage, in my view we really have
two types of arrows. First arrow is

    the variable a _stores_ the reference 2158949300

That's what matters for call semantics, what does the variable hold.
It does not matter whether that integer is a pointer, and if it is a
pointer what does it point to.

A second arrow of a different type points to an object from the pointer box

    2158949300 _refers to_ "say, some string"

That information is helpful and gives the whole picture about how
method invocation relates to objects, but it is in my view beyond call
semantics.

In that sense the diagrams of my post are not clear enough for
depicting what the post wants to explain, I think I'll revise it to
include the reference/pointer boxes.

-- fxn

PS: I have to say that those arrows and boxes match the observed
behavior and MRI implementation, but the spec as far as I can tell
does not imply them with 100% confidence in my opinion.

I do believe that's what the spec *wants* to specify, but the word
"reference" is not used, and the verb "copy" does not appear either.
My interpretation is that the first is there via the verb "refers",
and the fact that variables are not objects. And that in method
invocation "copy" is obviated because we are dealing with pointers and
the mere described assignment is enough. I've written to Matz about
this.

···

On Fri, Nov 12, 2010 at 7:04 PM, Robert Dober <robert.dober@gmail.com> wrote:

Hi,

PS: I have to say that those arrows and boxes match the observed
behavior and MRI implementation, but the spec as far as I can tell
does not imply them with 100% confidence in my opinion.

I do believe that's what the spec *wants* to specify, but the word
"reference" is not used, and the verb "copy" does not appear either.
My interpretation is that the first is there via the verb "refers",
and the fact that variables are not objects. And that in method
invocation "copy" is obviated because we are dealing with pointers and
the mere described assignment is enough. I've written to Matz about
this.

So you guys seem to agree with the basic concept. From CRuby
implementation stand point, variables are fundamentally pointer to the
object (region within a heap), with some exceptions of immediate
values. In that sense, Xavier's description is correct. But we
haven't choose to use those terms in the standard description, just
because the spec should not assume particular implementation detail.
On some alternative implementation, the object might be represented by
mere number, or combination of pointer values.

              matz.

···

In message "Re: what's an object?" on Sat, 13 Nov 2010 15:13:54 +0900, Xavier Noria <fxn@hashref.com> writes:

<snip>
I guess, I eventually understand. It was not the structure of the
diagram, that bothered you but the unclear/undefined/missdefined
semantics of the --->.
You see I understand quickly, if you explain a very long time, thanks.

Robert

···

On Sat, Nov 13, 2010 at 7:13 AM, Xavier Noria <fxn@hashref.com> wrote:

On Fri, Nov 12, 2010 at 7:04 PM, Robert Dober <robert.dober@gmail.com> wrote:

Completely!

Aaahhh, perfect :).

--
The 1,000,000th fibonacci number contains '42' 2039 times; that is
almost 30 occurrences more than expected (208988 digits).
N.B. The 42nd fibonacci number does not contain '1000000' that is
almost the expected 3.0e-06 times.

Excellent.

Then, at the spec level, we can assume that conceptually variables
hold references, whose implementation may vary, and that they refer to
objects. It belongs to the public contract of the language that a
variable does not store an object, and that v.foo asks the interpreter to
send a "foo" message to the object the variable v refers to.

I mean, that's the real and public contract. One can speak informally
about sending a message to v, but when you need to be rigorous about
the formalities of the language (eg in the context of this thread to
explain why Ruby has pass-by-value semantics) the reference in v has
an unspecified implementation, but it is conceptually explicit.

···

On Sat, Nov 13, 2010 at 10:09 AM, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

In message "Re: what's an object?" > on Sat, 13 Nov 2010 15:13:54 +0900, Xavier Noria <fxn@hashref.com> writes:

>PS: I have to say that those arrows and boxes match the observed
>behavior and MRI implementation, but the spec as far as I can tell
>does not imply them with 100% confidence in my opinion.
>
>I do believe that's what the spec *wants* to specify, but the word
>"reference" is not used, and the verb "copy" does not appear either.
>My interpretation is that the first is there via the verb "refers",
>and the fact that variables are not objects. And that in method
>invocation "copy" is obviated because we are dealing with pointers and
>the mere described assignment is enough. I've written to Matz about
>this.

So you guys seem to agree with the basic concept. From CRuby
implementation stand point, variables are fundamentally pointer to the
object (region within a heap), with some exceptions of immediate
values. In that sense, Xavier's description is correct. But we
haven't choose to use those terms in the standard description, just
because the spec should not assume particular implementation detail.
On some alternative implementation, the object might be represented by
mere number, or combination of pointer values.